summaryrefslogtreecommitdiff
path: root/script-beta/src/core/reference.lua
diff options
context:
space:
mode:
author最萌小汐 <sumneko@hotmail.com>2019-11-22 23:26:32 +0800
committer最萌小汐 <sumneko@hotmail.com>2019-11-22 23:26:32 +0800
commitd0ff66c9abe9d6abbca12fd811e0c3cb69c1033a (patch)
treebb34518d70b85de7656dbdbe958dfa221a3ff3b3 /script-beta/src/core/reference.lua
parent0a2c2ad15e1ec359171fb0dd4c72e57c5b66e9ba (diff)
downloadlua-language-server-d0ff66c9abe9d6abbca12fd811e0c3cb69c1033a.zip
整理一下目录结构
Diffstat (limited to 'script-beta/src/core/reference.lua')
-rw-r--r--script-beta/src/core/reference.lua84
1 files changed, 84 insertions, 0 deletions
diff --git a/script-beta/src/core/reference.lua b/script-beta/src/core/reference.lua
new file mode 100644
index 00000000..7e265e97
--- /dev/null
+++ b/script-beta/src/core/reference.lua
@@ -0,0 +1,84 @@
+local guide = require 'parser.guide'
+local files = require 'files'
+local vm = require 'vm'
+
+local function isFunction(source, offset)
+ if source.type ~= 'function' then
+ return false
+ end
+ -- 必须点在 `function` 这个单词上才能查找函数引用
+ return offset >= source.start and offset < source.start + #'function'
+end
+
+local function findRef(source, offset, callback)
+ if source.type ~= 'local'
+ and source.type ~= 'getlocal'
+ and source.type ~= 'setlocal'
+ and source.type ~= 'setglobal'
+ and source.type ~= 'getglobal'
+ and source.type ~= 'field'
+ and source.type ~= 'tablefield'
+ and source.type ~= 'method'
+ and source.type ~= 'string'
+ and source.type ~= 'number'
+ and source.type ~= 'boolean'
+ and source.type ~= 'goto'
+ and source.type ~= 'label'
+ and not isFunction(source, offset) then
+ return
+ end
+ vm.eachRef(source, function (info)
+ if info.mode == 'declare'
+ or info.mode == 'set'
+ or info.mode == 'get'
+ or info.mode == 'return' then
+ local src = info.source
+ local root = guide.getRoot(src)
+ local uri = root.uri
+ if src.type == 'setfield'
+ or src.type == 'getfield'
+ or src.type == 'tablefield' then
+ callback(src.field, uri)
+ elseif src.type == 'setindex'
+ or src.type == 'getindex'
+ or src.type == 'tableindex' then
+ callback(src.index, uri)
+ elseif src.type == 'getmethod'
+ or src.type == 'setmethod' then
+ callback(src.method, uri)
+ else
+ callback(src, uri)
+ end
+ end
+ if info.mode == 'value' then
+ local src = info.source
+ local root = guide.getRoot(src)
+ local uri = root.uri
+ if src.type == 'function' then
+ if src.parent.type == 'return' then
+ callback(src, uri)
+ end
+ end
+ end
+ end)
+end
+
+return function (uri, offset)
+ local ast = files.getAst(uri)
+ if not ast then
+ return nil
+ end
+ local results = {}
+ guide.eachSourceContain(ast.ast, offset, function (source)
+ findRef(source, offset, function (target, uri)
+ results[#results+1] = {
+ target = target,
+ uri = files.getOriginUri(uri),
+ }
+ end)
+ end)
+ if #results == 0 then
+ return nil
+ end
+ return results
+end