diff options
author | 最萌小汐 <sumneko@hotmail.com> | 2019-11-11 20:46:18 +0800 |
---|---|---|
committer | 最萌小汐 <sumneko@hotmail.com> | 2019-11-11 20:46:18 +0800 |
commit | 025b80013795760483e75fc2487e439a0f62cfeb (patch) | |
tree | 0634c74606de42f6bdb03535678f8173205410ed | |
parent | b6ca9b20db4a7b28a4e0adb7f8b24da4356e45a7 (diff) | |
download | lua-language-server-025b80013795760483e75fc2487e439a0f62cfeb.zip |
link管理
-rw-r--r-- | server-beta/src/files.lua | 47 | ||||
-rw-r--r-- | server-beta/src/searcher/eachRef.lua | 20 | ||||
-rw-r--r-- | server-beta/src/searcher/getGlobals.lua | 7 | ||||
-rw-r--r-- | server-beta/src/searcher/getLinks.lua | 32 | ||||
-rw-r--r-- | server-beta/src/searcher/init.lua | 1 | ||||
-rw-r--r-- | server-beta/src/searcher/searcher.lua | 41 | ||||
-rw-r--r-- | server-beta/test/crossfile/init.lua | 2 | ||||
-rw-r--r-- | server-beta/test/crossfile/references.lua | 134 |
8 files changed, 160 insertions, 124 deletions
diff --git a/server-beta/src/files.lua b/server-beta/src/files.lua index 0f3d721f..a3cf3e8e 100644 --- a/server-beta/src/files.lua +++ b/server-beta/src/files.lua @@ -73,6 +73,7 @@ function m.setText(uri, text) file.lines = nil file.ast = nil file.globals = nil + file.links = nil m.globalVersion = m.globalVersion + 1 searcher.refreshCache() @@ -194,30 +195,6 @@ function m.getOriginUri(uri) return file.uri end ---- 获取全局变量 -function m.getGlobals(uri) - if platform.OS == 'Windows' then - uri = uri:lower() - end - local file = m.fileMap[uri] - if not file then - return nil - end - if file.globals then - return file.globals - end - local ast = m.getAst(uri) - if not ast then - return nil - end - file.globals = {} - local globals = searcher.getGlobals(ast.ast) - for name in pairs(globals) do - file.globals[name] = true - end - return file.globals -end - --- 寻找全局变量 function m.findGlobals(name) local uris = {} @@ -239,6 +216,28 @@ function m.findGlobals(name) return uris end +--- 寻找link自己的其他文件 +function m.findLinkTo(uri) + if platform.OS == 'Windows' then + uri = uri:lower() + end + local result = {} + for _, file in pairs(m.fileMap) do + if file.links == nil then + local ast = m.getAst(uri) + if ast then + file.links = searcher.getLinks(ast.ast) + else + file.links = false + end + end + if file.links and file.links[uri] then + result[#result+1] = file.uri + end + end + return result +end + --- 判断文件名相等 function m.eq(a, b) if platform.OS == 'Windows' then diff --git a/server-beta/src/searcher/eachRef.lua b/server-beta/src/searcher/eachRef.lua index e5877ae7..21e9b401 100644 --- a/server-beta/src/searcher/eachRef.lua +++ b/server-beta/src/searcher/eachRef.lua @@ -73,18 +73,14 @@ local function ofSpecialCall(call, func, index, callback) end elseif name == 'require' then if index == 1 then - local args = call.args - if args[1] then - local literal = guide.getLiteral(args[1]) - if type(literal) == 'string' then - local result = workspace.findUrisByRequirePath(literal, true) - local myUri = guide.getRoot(call).uri - for _, uri in ipairs(result) do - if not files.eq(uri, myUri) then - local ast = files.getAst(uri) - if ast then - searcher.eachRef(ast.ast, callback) - end + local result = searcher.getLinkUris(call) + if result then + local myUri = guide.getRoot(call).uri + for _, uri in ipairs(result) do + if not files.eq(uri, myUri) then + local ast = files.getAst(uri) + if ast then + searcher.eachRef(ast.ast, callback) end end end diff --git a/server-beta/src/searcher/getGlobals.lua b/server-beta/src/searcher/getGlobals.lua index 4519985b..c5737881 100644 --- a/server-beta/src/searcher/getGlobals.lua +++ b/server-beta/src/searcher/getGlobals.lua @@ -1,8 +1,7 @@ local guide = require 'parser.guide' local searcher = require 'searcher.searcher' -local function getGlobals(source) - local root = guide.getRoot(source) +local function getGlobals(root) local env = guide.getENV(root) local cache = {} local mark = {} @@ -32,7 +31,7 @@ end function searcher.getGlobals(source) source = guide.getRoot(source) local cache = searcher.cache.getGlobals[source] - if cache then + if cache ~= nil then return cache end local unlock = searcher.lock('getGlobals', source) @@ -40,7 +39,7 @@ function searcher.getGlobals(source) return nil end cache = getGlobals(source) - searcher.cache.getGlobals[source] = cache + searcher.cache.getGlobals[source] = cache or false unlock() return cache end diff --git a/server-beta/src/searcher/getLinks.lua b/server-beta/src/searcher/getLinks.lua new file mode 100644 index 00000000..32b29be1 --- /dev/null +++ b/server-beta/src/searcher/getLinks.lua @@ -0,0 +1,32 @@ +local guide = require 'parser.guide' +local searcher = require 'searcher.searcher' + +local function getLinks(root) + local cache = {} + guide.eachSourceType(root, 'call', function (info) + local uris = searcher.getLinkUris(info.source) + if uris then + for i = 1, #uris do + local uri = uris[i] + cache[uri] = true + end + end + end) + return cache +end + +function searcher.getLinks(source) + source = guide.getRoot(source) + local cache = searcher.cache.getLinks[source] + if cache ~= nil then + return cache + end + local unlock = searcher.lock('getLinks', source) + if not unlock then + return nil + end + cache = getLinks(source) + searcher.cache.getLinks[source] = cache or false + unlock() + return cache +end diff --git a/server-beta/src/searcher/init.lua b/server-beta/src/searcher/init.lua index cd59fa4a..a43c8d96 100644 --- a/server-beta/src/searcher/init.lua +++ b/server-beta/src/searcher/init.lua @@ -2,6 +2,7 @@ local searcher = require 'searcher.searcher' require 'searcher.eachField' require 'searcher.eachRef' require 'searcher.getGlobals' +require 'searcher.getLinks' require 'searcher.isGlobal' require 'searcher.getLibrary' return searcher diff --git a/server-beta/src/searcher/searcher.lua b/server-beta/src/searcher/searcher.lua index c7355f93..a17db8df 100644 --- a/server-beta/src/searcher/searcher.lua +++ b/server-beta/src/searcher/searcher.lua @@ -3,6 +3,8 @@ local util = require 'utility' local setmetatable = setmetatable local assert = assert +local require = require +local type = type _ENV = nil @@ -73,32 +75,21 @@ function m.getSpecialName(source) return spName end ---- 遍历特殊对象 ----@param callback fun(name:string, source:table) -function m.eachSpecial(callback) - local cache = m.cache.specials - if cache then - for i = 1, #cache do - callback(cache[i][1], cache[i][2]) +--- 获取link的uri +function m.getLinkUris(call) + local workspace = require 'workspace' + local func = call.node + local name = m.getSpecialName(func) + if name == 'require' then + local args = call.args + if not args[1] then + return nil end - return - end - cache = {} - m.cache.specials = cache - guide.eachSource(m.ast, function (source) - if source.type == 'getlocal' - or source.type == 'getglobal' - or source.type == 'local' - or source.type == 'field' - or source.type == 'string' then - local name = m.getSpecialName(source) - if name then - cache[#cache+1] = { name, source } - end + local literal = guide.getLiteral(args[1]) + if type(literal) ~= 'string' then + return nil end - end) - for i = 1, #cache do - callback(cache[i][1], cache[i][2]) + return workspace.findUrisByRequirePath(literal, true) end end @@ -113,6 +104,7 @@ function m.refreshCache() eachRef = {}, eachField = {}, getGlobals = {}, + getLinks = {}, isGlobal = {}, specialName = {}, getLibrary = {}, @@ -122,6 +114,7 @@ function m.refreshCache() eachRef = {}, eachField = {}, getGlobals = {}, + getLinks = {}, getLibrary = {}, } m.cacheTracker[m.cache] = true diff --git a/server-beta/test/crossfile/init.lua b/server-beta/test/crossfile/init.lua index 836d201c..42fb1147 100644 --- a/server-beta/test/crossfile/init.lua +++ b/server-beta/test/crossfile/init.lua @@ -1,5 +1,5 @@ require 'crossfile.definition' +require 'crossfile.references' --require 'crossfile.hover' --require 'crossfile.completion' --require 'crossfile.document_symbol' ---require 'crossfile.references' diff --git a/server-beta/test/crossfile/references.lua b/server-beta/test/crossfile/references.lua index 9f81707c..0b44b3f4 100644 --- a/server-beta/test/crossfile/references.lua +++ b/server-beta/test/crossfile/references.lua @@ -1,8 +1,6 @@ -local service = require 'service' -local workspace = require 'workspace' -local fs = require 'bee.filesystem' -local core = require 'core' -local uric = require 'uri' +local files = require 'files' +local furi = require 'file-uri' +local core = require 'core.reference' rawset(_G, 'TEST', true) @@ -34,18 +32,21 @@ local function eq(a, b) return a == b end -local function catch_target(script) +local function catch_target(script, sep) local list = {} local cur = 1 + local cut = 0 while true do - local start, finish = script:find('<[!?].-[!?]>', cur) + local start, finish = script:find(('<%%%s.-%%%s>'):format(sep, sep), cur) if not start then break end - list[#list+1] = { start + 2, finish - 2 } + list[#list+1] = { start - cut, finish - 4 - cut } cur = finish + 1 + cut = cut + 4 end - return list + local new_script = script:gsub(('<%%%s(.-)%%%s>'):format(sep, sep), '%1') + return new_script, list end local function founded(targets, results) @@ -54,7 +55,10 @@ local function founded(targets, results) end for _, target in ipairs(targets) do for _, result in ipairs(results) do - if target[1] == result[1] and target[2] == result[2] then + if target[1] == result[1] + and target[2] == result[2] + and target[3] == result[3] + then goto NEXT end end @@ -64,58 +68,69 @@ local function founded(targets, results) return true end -local function compileAll(lsp) - while lsp._needCompile[1] do - lsp:compileVM(lsp._needCompile[1]) - end -end - -function TEST(data) - local lsp = service() - local ws = workspace(lsp, 'test') - lsp.workspace = ws - ws.root = ROOT - - local mainUri - local pos - local expect = {} - for _, info in ipairs(data) do - local uri = uric.encode(fs.path(info.path)) - ws:addFile(uric.decode(uri)) - end - for _, info in ipairs(data) do - local uri = uric.encode(fs.path(info.path)) - local script = info.content - local list = catch_target(script) - for _, location in ipairs(list) do - expect[#expect+1] = { - location[1], - location[2], - uri, - } +function TEST(datas) + files.removeAll() + + local targetList = {} + local sourceList + local sourceUri + for i, data in ipairs(datas) do + local uri = furi.encode(data.path) + local new, list = catch_target(data.content, '!') + if new ~= data.content or data.target then + if data.target then + targetList[#targetList+1] = { + data.target[1], + data.target[2], + uri, + } + else + for _, position in ipairs(list) do + targetList[#targetList+1] = { + position[1], + position[2], + uri, + } + end + end + data.content = new end - local start = script:find('<?', 1, true) - local finish = script:find('?>', 1, true) - if start then - mainUri = uri - pos = (start + finish) // 2 + 1 + new, list = catch_target(data.content, '~') + if new ~= data.content then + sourceList = list + sourceUri = uri + data.content = new end - local newScript = script:gsub('<[!?]', ' '):gsub('[!?]>', ' ') - lsp:saveText(uri, 1, newScript) - compileAll(lsp) + new, list = catch_target(data.content, '?') + if new ~= data.content then + sourceList = list + sourceUri = uri + data.content = new + for _, position in ipairs(list) do + targetList[#targetList+1] = { + position[1], + position[2], + uri, + } + end + end + files.setText(uri, data.content) end - local vm = lsp:loadVM(mainUri) - - compileAll(lsp) - - assert(vm) - local result = core.definition(vm, pos, 'reference') - if expect then - assert(result) - assert(founded(expect, result)) + local sourcePos = (sourceList[1][1] + sourceList[1][2]) // 2 + local positions = core(sourceUri, sourcePos) + if positions then + local result = {} + for i, position in ipairs(positions) do + result[i] = { + position.target.start, + position.target.finish, + position.uri, + } + end + assert(founded(targetList, result)) else - assert(result == nil) + assert(#targetList == 0) end end @@ -145,9 +160,10 @@ TEST { { path = 'lib.lua', content = [[ - return <?function () - end?> + return <~function~> () + end ]], + target = {20, 46}, }, } |