summaryrefslogtreecommitdiff
path: root/script/src/core/find_source.lua
diff options
context:
space:
mode:
Diffstat (limited to 'script/src/core/find_source.lua')
-rw-r--r--script/src/core/find_source.lua59
1 files changed, 59 insertions, 0 deletions
diff --git a/script/src/core/find_source.lua b/script/src/core/find_source.lua
new file mode 100644
index 00000000..a64a047e
--- /dev/null
+++ b/script/src/core/find_source.lua
@@ -0,0 +1,59 @@
+local function isContainPos(obj, pos)
+ if obj.start <= pos and obj.finish >= pos then
+ return true
+ end
+ return false
+end
+
+local function isValidSource(source)
+ return source.start ~= nil and source.start ~= 0
+end
+
+local function matchFilter(source, filter)
+ if not filter then
+ return true
+ end
+ return filter[source.type]
+end
+
+local function findAtPos(vm, pos, filter)
+ local res = {}
+ vm:eachSource(function (source)
+ if isValidSource(source)
+ and isContainPos(source, pos)
+ and matchFilter(source, filter)
+ then
+ res[#res+1] = source
+ end
+ end)
+ if #res == 0 then
+ return nil
+ end
+ table.sort(res, function (a, b)
+ if a == b then
+ return false
+ end
+ local rangeA = a.finish - a.start
+ local rangeB = b.finish - b.start
+ -- 特殊处理:func 'str' 的情况下,list与string的范围会完全相同,此时取string
+ if rangeA == rangeB then
+ if b.type == 'call' and #b == 1 and b[1] == a then
+ return true
+ elseif a.type == 'call' and #a == 1 and a[1] == b then
+ return false
+ else
+ return a.id < b.id
+ end
+ end
+ return rangeA < rangeB
+ end)
+ local source = res[1]
+ if not source then
+ return nil
+ end
+ return source
+end
+
+return function (vm, pos, filter)
+ return findAtPos(vm, pos, filter)
+end