summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author最萌小汐 <sumneko@hotmail.com>2019-11-11 20:46:18 +0800
committer最萌小汐 <sumneko@hotmail.com>2019-11-11 20:46:18 +0800
commit025b80013795760483e75fc2487e439a0f62cfeb (patch)
tree0634c74606de42f6bdb03535678f8173205410ed
parentb6ca9b20db4a7b28a4e0adb7f8b24da4356e45a7 (diff)
downloadlua-language-server-025b80013795760483e75fc2487e439a0f62cfeb.zip
link管理
-rw-r--r--server-beta/src/files.lua47
-rw-r--r--server-beta/src/searcher/eachRef.lua20
-rw-r--r--server-beta/src/searcher/getGlobals.lua7
-rw-r--r--server-beta/src/searcher/getLinks.lua32
-rw-r--r--server-beta/src/searcher/init.lua1
-rw-r--r--server-beta/src/searcher/searcher.lua41
-rw-r--r--server-beta/test/crossfile/init.lua2
-rw-r--r--server-beta/test/crossfile/references.lua134
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},
},
}