summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author最萌小汐 <sumneko@hotmail.com>2021-04-16 15:55:33 +0800
committer最萌小汐 <sumneko@hotmail.com>2021-04-16 15:55:33 +0800
commit776d25a2e68b86c2ac37357a71abcd4f2787498b (patch)
treecbd11fbb1a3eb551fa3ed4b3d9f38edec7487ce2
parenta656626742e3a475731a4d27e0a7f9292ecbaa22 (diff)
downloadlua-language-server-776d25a2e68b86c2ac37357a71abcd4f2787498b.zip
stash
-rw-r--r--script/core/guide.lua46
-rw-r--r--script/core/linker.lua74
-rw-r--r--test/basic/linker.lua50
-rw-r--r--test/references/init.lua6
4 files changed, 90 insertions, 86 deletions
diff --git a/script/core/guide.lua b/script/core/guide.lua
index edd682fc..42ca624a 100644
--- a/script/core/guide.lua
+++ b/script/core/guide.lua
@@ -105,44 +105,52 @@ function m.searchRefs(status, source, mode)
local expects = {}
local index = 0
- local function pushQueue(expect, link)
+ ---添加到队列
+ ---@param id string
+ ---@param expect string
+ local function pushQueue(id, expect)
index = index + 1
- queue[index] = link
+ queue[index] = id
expects[index] = expect
end
- local function pushQueueWithID(obj)
+ local function pushQueueOfSource(obj, expect)
local link = linker.getLink(obj)
if not link then
return
end
- pushQueue(link.id, link)
+ pushQueue(link.id, expect or link.id)
end
- pushQueueWithID(source)
+ pushQueueOfSource(source)
- local function checkForward(link)
+ local function checkForward(link, expect)
if not link.forward then
return
end
for _, forwardSources in ipairs(link.forward) do
- pushQueueWithID(forwardSources)
+ pushQueueOfSource(forwardSources, expect)
end
end
- local function checkBackward(link)
+ local function checkBackward(link, expect)
if not link.backward then
return
end
for _, backSources in ipairs(link.backward) do
- pushQueueWithID(backSources)
+ pushQueueOfSource(backSources, expect)
end
end
---@param link link
- local function checkParentID(link)
- local id = link.id
+ ---@param expect string
+ local function checkParentID(link, expect)
local parentID = link.parentID
+ if not parentID then
+ return
+ end
+ expect = expect:sub(#parentID + 2)
+ pushQueue(parentID, expect)
end
for _ = 1, 1000 do
@@ -152,16 +160,22 @@ function m.searchRefs(status, source, mode)
local link = queue[index]
local expect = expects[index]
index = index - 1
- local links = linker.getLinkersBySource(link.source)
+ local links = linker.getLinksBySource(link.source)
if not links then
goto CONTINUE
end
for _, eachLink in ipairs(links) do
- m.pushResult(status, mode, eachLink.source)
- checkForward(eachLink)
- checkBackward(eachLink)
+ if expect == eachLink.id
+ or expect == '*' then
+ m.pushResult(status, mode, eachLink.source)
+ checkForward(eachLink, '*')
+ checkBackward(eachLink, '*')
+ else
+ checkForward(eachLink, expect)
+ checkBackward(eachLink, expect)
+ end
end
- checkParentID(link)
+ checkParentID(link, expect)
::CONTINUE::
end
end
diff --git a/script/core/linker.lua b/script/core/linker.lua
index 46a76127..b8a7139d 100644
--- a/script/core/linker.lua
+++ b/script/core/linker.lua
@@ -35,30 +35,22 @@ local function getKey(source)
return nil, nil
end
-local function checkGlobal(source)
+local function checkMode(source)
if source.type == 'setglobal'
or source.type == 'getglobal' then
- return true
+ return 'g:'
end
- return nil
-end
-
-local function checkLocal(source)
if source.type == 'local'
or source.type == 'setlocal'
or source.type == 'getlocal' then
- return true
+ return 'l:'
end
if source.type == 'label'
or source.type == 'goto' then
- return true
+ return 'l:'
end
- return nil
-end
-
-local function checkTableField(source)
if source.type == 'table' then
- return true
+ return 'l:'
end
return nil
end
@@ -145,11 +137,15 @@ local function getID(source)
for i = index + 1, #IDList do
IDList[i] = nil
end
+ local mode = checkMode(current)
+ if mode then
+ IDList[#IDList+1] = mode
+ end
util.revertTable(IDList)
local id = table.concat(IDList, '|')
local parentID
- if #IDList > 1 then
- parentID = table.concat(IDList, '|', 1, -2)
+ if index > 1 then
+ parentID = table.concat(IDList, '|', 1, index)
end
return id, current, parentID
end
@@ -161,12 +157,6 @@ end
---@field parentID string
-- 语法树单元
---@field source parser.guide.object
--- 是否是局部变量
----@field loc boolean
--- 是否是全局变量
----@field global boolean
--- 是否是字面量表中的字段
----@field tfield boolean
-- 返回值,文件返回值总是0,函数返回值为第几个返回值
---@field freturn integer
-- 前进的关联单元
@@ -188,17 +178,14 @@ local function createLink(source)
id = id,
source = source,
parentID = parentID,
- loc = checkLocal(node),
- global = checkGlobal(node),
- tfield = checkTableField(node),
freturn = checkFunctionReturn(node),
forward = checkForward(source),
backward = checkBackward(source),
}
end
-local function insertLinker(linkers, tp, link)
- local list = linkers[tp]
+local function insertLinker(linkers, mode, link)
+ local list = linkers[mode]
local id = link.id
if not list[id] then
list[id] = {}
@@ -212,13 +199,30 @@ local m = {}
---根据语法树单元获取关联的link列表
---@param source parser.guide.object
---@return link[]?
-function m.getLinkersBySource(source)
+function m.getLinksBySource(source)
if not source._link then
source._link = createLink(source)
end
return source._link and source._link._links
end
+---根据ID来获取所有的link
+---@param source parser.guide.object
+---@param mode string
+---@param id string
+---@return link[]?
+function m.getLinksByID(source, mode, id)
+ local root = guide.getRoot(source)
+ if not root._linkers then
+ return nil
+ end
+ local linkers = root._linkers[mode]
+ if not linkers then
+ return nil
+ end
+ return linkers[id]
+end
+
---获取source的链接信息
---@param source parser.guide.object
---@return link
@@ -237,24 +241,14 @@ function m.compileLinks(source)
if root._linkers then
return root._linkers
end
- local linkers = {
- loc = {},
- global = {},
- tfield = {},
- }
+ local linkers = {}
guide.eachSource(root, function (src)
local link = m.getLink(src)
if not link then
return
end
- if link.global then
- insertLinker(linkers, 'global', link)
- end
- if link.loc then
- insertLinker(linkers, 'loc', link)
- end
- if link.tfield then
- insertLinker(linkers, 'tfield', link)
+ if link.mode then
+ insertLinker(linkers, link.mode, link)
end
end)
root._linkers = linkers
diff --git a/test/basic/linker.lua b/test/basic/linker.lua
index 3b18ddc9..dd097dfe 100644
--- a/test/basic/linker.lua
+++ b/test/basic/linker.lua
@@ -45,83 +45,79 @@ local function TEST(script)
end
CARE['id'] = true
-CARE['loc'] = true
TEST [[
local <?x?>
]] {
- id = '9',
- loc = true,
+ id = 'l:9',
}
TEST [[
local x
print(<?x?>)
]] {
- id = '7',
- loc = true,
+ id = '7',
+ mode = 'local',
}
TEST [[
local x
<?x?> = 1
]] {
- id = '7',
- loc = true,
+ id = '7',
+ mode = 'local',
}
-CARE['global'] = true
TEST [[
print(<?X?>)
]] {
- id = '"X"',
- global = true,
+ id = '"X"',
+ mode = 'global',
}
TEST [[
print(<?X?>)
]] {
- id = '"X"',
- global = true,
+ id = '"X"',
+ mode = 'global',
}
TEST [[
local x
print(x.y.<?z?>)
]] {
- id = '7|"y"|"z"',
- loc = true,
+ id = '7|"y"|"z"',
+ mode = 'local',
}
TEST [[
local x
function x:<?f?>() end
]] {
- id = '7|"f"',
- loc = true,
+ id = '7|"f"',
+ mode = 'local',
}
TEST [[
print(X.Y.<?Z?>)
]] {
- id = '"X"|"Y"|"Z"',
- global = true,
+ id = '"X"|"Y"|"Z"',
+ mode = 'global',
}
TEST [[
function x:<?f?>() end
]] {
- id = '"x"|"f"',
- global = true,
+ id = '"x"|"f"',
+ mode = 'global',
}
-CARE['tfield'] = true
TEST [[
{
<?x?> = 1,
}
]] {
- id = '1|"x"',
- tfield = true,
+ id = '1|"x"',
+ mode = 'table',
}
CARE['freturn'] = true
@@ -129,7 +125,7 @@ TEST [[
return <?X?>
]] {
id = '"X"',
- global = true,
+ mode = 'global',
freturn = 0,
}
@@ -139,7 +135,7 @@ function f()
end
]] {
id = '"X"',
- global = true,
+ mode = 'global',
freturn = 1,
}
@@ -148,7 +144,7 @@ TEST [[
goto label
]] {
id = '5',
- loc = true,
+ mode = 'local',
}
TEST [[
@@ -156,5 +152,5 @@ TEST [[
goto <?label?>
]] {
id = '3',
- loc = true,
+ mode = 'local',
}
diff --git a/test/references/init.lua b/test/references/init.lua
index e24694d2..66e002a2 100644
--- a/test/references/init.lua
+++ b/test/references/init.lua
@@ -33,7 +33,7 @@ end
function TEST(script)
files.removeAll()
- local target = catch_target(script)
+ local expect = catch_target(script)
local start = script:find('<[?~]')
local finish = script:find('[?~]>')
local pos = (start + finish) // 2 + 1
@@ -46,9 +46,9 @@ function TEST(script)
for i, result in ipairs(results) do
positions[i] = { result.target.start, result.target.finish }
end
- assert(founded(target, positions))
+ assert(founded(expect, positions))
else
- assert(#target == 0)
+ assert(#expect == 0)
end
end