summaryrefslogtreecommitdiff
path: root/server/src/matcher/signature.lua
diff options
context:
space:
mode:
Diffstat (limited to 'server/src/matcher/signature.lua')
-rw-r--r--server/src/matcher/signature.lua66
1 files changed, 66 insertions, 0 deletions
diff --git a/server/src/matcher/signature.lua b/server/src/matcher/signature.lua
new file mode 100644
index 00000000..97b8fc00
--- /dev/null
+++ b/server/src/matcher/signature.lua
@@ -0,0 +1,66 @@
+local hover = require 'matcher.hover'
+
+local function isContainPos(obj, pos)
+ if obj.start <= pos and obj.finish + 1 >= pos then
+ return true
+ end
+ return false
+end
+
+local function findArgCount(args, pos)
+ for i, arg in ipairs(args) do
+ if isContainPos(arg, pos) then
+ return i
+ end
+ end
+ return #args + 1
+end
+
+-- 找出范围包含pos的,且有dirty标记的call
+local function findDirtyCall(vm, pos)
+ local results = {}
+ for _, call in ipairs(vm.results.calls) do
+ if call.args.dirty and isContainPos(call.args, pos) then
+ local n = findArgCount(call.args, pos)
+ results[#results+1] = {
+ func = call.func,
+ var = vm.results.sources[call.lastObj],
+ source = call.lastObj,
+ select = n,
+ args = call.args,
+ }
+ end
+ end
+ -- 可能处于 'func1(func2(' 的嵌套中,因此距离越远的函数层级越低
+ table.sort(results, function (a, b)
+ return a.args.start < b.args.start
+ end)
+ return results
+end
+
+local function parseCall(call)
+ local results = hover(call.var, call.source, nil, call.select)
+ return results[1], results[2]
+end
+
+return function (vm, pos)
+ local calls = findDirtyCall(vm, pos)
+ if #calls == 0 then
+ return nil
+ end
+
+ local results = {}
+ for i, call in ipairs(calls) do
+ local label, description = parseCall(call)
+ results[i] = {
+ label = label,
+ description = description,
+ arg = {
+ label = 'a',
+ description = '参数说明',
+ }
+ }
+ end
+
+ return results
+end