summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author最萌小汐 <sumneko@hotmail.com>2021-06-09 18:09:49 +0800
committer最萌小汐 <sumneko@hotmail.com>2021-06-09 18:09:49 +0800
commitb21f5d2cd9eaf02986ba526f58f0c5fedbd1fde3 (patch)
treefe489b14cf31612fb9e85cb2e033c841d50dbe33
parent3945d61e1a7dd20b33f7bcd4d5c9c5f09d77b510 (diff)
downloadlua-language-server-b21f5d2cd9eaf02986ba526f58f0c5fedbd1fde3.zip
improve
-rw-r--r--script/core/noder.lua20
-rw-r--r--script/core/searcher.lua27
-rw-r--r--test/references/all.lua135
-rw-r--r--test/references/init.lua136
4 files changed, 171 insertions, 147 deletions
diff --git a/script/core/noder.lua b/script/core/noder.lua
index 866e64d0..c3679612 100644
--- a/script/core/noder.lua
+++ b/script/core/noder.lua
@@ -329,7 +329,7 @@ end
---@param noders noders
---@param id string
---@param forwardID string
-local function pushForward(noders, id, forwardID)
+local function pushForward(noders, id, forwardID, tag)
if not id
or not forwardID
or forwardID == ''
@@ -340,10 +340,10 @@ local function pushForward(noders, id, forwardID)
if not node.forward then
node.forward = {}
end
- if node.forward[forwardID] then
+ if node.forward[forwardID] ~= nil then
return
end
- node.forward[forwardID] = true
+ node.forward[forwardID] = tag or false
node.forward[#node.forward+1] = forwardID
end
@@ -351,7 +351,7 @@ end
---@param noders noders
---@param id string
---@param backwardID string
-local function pushBackward(noders, id, backwardID)
+local function pushBackward(noders, id, backwardID, tag)
if not id
or not backwardID
or backwardID == ''
@@ -362,10 +362,10 @@ local function pushBackward(noders, id, backwardID)
if not node.backward then
node.backward = {}
end
- if node.backward[backwardID] then
+ if node.backward[backwardID] ~= nil then
return
end
- node.backward[backwardID] = true
+ node.backward[backwardID] = tag or false
node.backward[#node.backward+1] = backwardID
end
@@ -423,10 +423,10 @@ function m.compileNode(noders, source)
local valueID = getID(value)
if valueID then
-- x = y : x -> y
- pushForward(noders, id, valueID)
+ pushForward(noders, id, valueID, 'set')
-- 参数禁止反向查找赋值
if valueID:sub(1, 2) ~= 'p:' then
- pushBackward(noders, valueID, id)
+ pushBackward(noders, valueID, id, 'set')
end
end
end
@@ -441,8 +441,8 @@ function m.compileNode(noders, source)
if setmethod and ( setmethod.type == 'setmethod'
or setmethod.type == 'setfield'
or setmethod.type == 'setindex') then
- pushForward(noders, id, getID(setmethod.node))
- pushBackward(noders, getID(setmethod.node), id)
+ pushForward(noders, id, getID(setmethod.node), 'method')
+ pushBackward(noders, getID(setmethod.node), id, 'method')
end
end
-- 分解 @type
diff --git a/script/core/searcher.lua b/script/core/searcher.lua
index 2b8eed41..11e00378 100644
--- a/script/core/searcher.lua
+++ b/script/core/searcher.lua
@@ -219,7 +219,8 @@ function m.searchRefsByID(status, uri, expect, mode)
local mark = {}
local function search(id, field)
- if ignoredIDs[id] and field then
+ local firstID = noder.getFirstID(id)
+ if ignoredIDs[firstID] and (field or firstID ~= id) then
return
end
local cmark = mark[id]
@@ -348,14 +349,27 @@ function m.searchRefsByID(status, uri, expect, mode)
searchID(newID)
end
+ local forwardTag = {}
+ local backwardTag = {}
local function checkForward(id, node, field)
for _, forwardID in ipairs(node.forward) do
+ local tag = node.forward[forwardID]
+ if tag then
+ if backwardTag[tag] and backwardTag[tag] > 0 then
+ goto CONTINUE
+ end
+ forwardTag[tag] = (forwardTag[tag] or 0) + 1
+ end
local targetUri, targetID = noder.getUriAndID(forwardID)
if targetUri and not files.eq(targetUri, uri) then
crossSearch(status, targetUri, targetID .. (field or ''), mode)
else
searchID(targetID or forwardID, field)
end
+ if tag then
+ forwardTag[tag] = forwardTag[tag] - 1
+ end
+ ::CONTINUE::
end
end
@@ -364,12 +378,23 @@ function m.searchRefsByID(status, uri, expect, mode)
return
end
for _, backwardID in ipairs(node.backward) do
+ local tag = node.backward[backwardID]
+ if tag then
+ if forwardTag[tag] and forwardTag[tag] > 0 then
+ goto CONTINUE
+ end
+ backwardTag[tag] = (backwardTag[tag] or 0) + 1
+ end
local targetUri, targetID = noder.getUriAndID(backwardID)
if targetUri and not files.eq(targetUri, uri) then
crossSearch(status, targetUri, targetID .. (field or ''), mode)
else
searchID(targetID or backwardID, field)
end
+ if tag then
+ backwardTag[tag] = backwardTag[tag] - 1
+ end
+ ::CONTINUE::
end
end
diff --git a/test/references/all.lua b/test/references/all.lua
index c27beb3c..a9442ae1 100644
--- a/test/references/all.lua
+++ b/test/references/all.lua
@@ -76,3 +76,138 @@ local function f() end
local a, b = f()
return a.x, b.<!x!>
]]
+
+TEST [[
+local <?mt?> = {}
+function <!mt!>:x()
+ <!self!>:x()
+end
+]]
+
+TEST [[
+local mt = {}
+function mt:<?x?>()
+ self:<!x!>()
+end
+]]
+
+TEST [[
+---@class Dog
+local mt = {}
+function mt:<?eat?>()
+end
+
+---@class Master
+local mt2 = {}
+function mt2:init()
+ ---@type Dog
+ local foo = self:doSomething()
+ ---@type Dog
+ self.dog = getDog()
+end
+function mt2:feed()
+ self.dog:<!eat!>()
+end
+function mt2:doSomething()
+end
+]]
+
+-- 泛型的反向搜索
+TEST [[
+---@class Dog
+local <?Dog?> = {}
+
+---@generic T
+---@param type1 T
+---@return T
+function foobar(type1)
+end
+
+local <!v1!> = foobar(<!Dog!>)
+]]
+
+TEST [[
+---@class Dog
+local Dog = {}
+function Dog:<?eat?>()
+end
+
+---@generic T
+---@param type1 T
+---@return T
+function foobar(type1)
+ return {}
+end
+
+local v1 = foobar(Dog)
+v1:<!eat!>()
+]]
+
+TEST [[
+---@class Dog
+local Dog = {}
+function Dog:<?eat?>()
+end
+
+---@class Master
+local Master = {}
+
+---@generic T
+---@param type1 string
+---@param type2 T
+---@return T
+function Master:foobar(type1, type2)
+ return {}
+end
+
+local v1 = Master:foobar("", Dog)
+v1.<!eat!>()
+]]
+
+TEST [[
+---@class A
+local <?A?>
+
+---@generic T
+---@param self T
+---@return T
+function m.f(self) end
+
+local <!b!> = m.f(<!A!>)
+]]
+
+TEST [[
+---@class A
+local <?A?>
+
+---@generic T
+---@param self T
+---@return T
+function m:f() end
+
+local <!b!> = m.f(<!A!>)
+]]
+
+TEST [[
+---@class A
+local <?A?>
+
+---@generic T
+---@param self T
+---@return T
+function <!A!>.f(self) end
+
+local <!b!> = <!A!>:f()
+]]
+
+TEST [[
+---@class A
+local <?A?>
+
+---@generic T
+---@param self T
+---@return T
+function <!A!>:f() end
+
+local <!b!> = <!A!>:f()
+]]
diff --git a/test/references/init.lua b/test/references/init.lua
index e6abc3bd..e90cb2a8 100644
--- a/test/references/init.lua
+++ b/test/references/init.lua
@@ -218,13 +218,6 @@ end
]]
TEST [[
-local <?mt?> = {}
-function <!mt!>:x()
- <!self!>:x()
-end
-]]
-
-TEST [[
local mt = {}
function mt:<!x!>()
self:<?x?>()
@@ -232,13 +225,6 @@ end
]]
TEST [[
-local mt = {}
-function mt:<?x?>()
- self:<!x!>()
-end
-]]
-
-TEST [[
a.<!b!>.c = 1
print(a.<?b?>.c)
]]
@@ -312,125 +298,3 @@ TEST [[
---@return <?xxx?>
function f() end
]]
-
-TEST [[
----@class Dog
-local mt = {}
-function mt:<?eat?>()
-end
-
----@class Master
-local mt2 = {}
-function mt2:init()
- ---@type Dog
- local foo = self:doSomething()
- ---@type Dog
- self.dog = getDog()
-end
-function mt2:feed()
- self.dog:<!eat!>()
-end
-function mt2:doSomething()
-end
-]]
-
--- TODO 支持泛型
-do return end
-TEST [[
----@class Dog
-local <?Dog?> = {}
-
----@generic T
----@param type1 T
----@return T
-function foobar(type1)
-end
-
-local <!v1!> = foobar(<!Dog!>)
-]]
-
-TEST [[
----@class Dog
-local Dog = {}
-function Dog:<?eat?>()
-end
-
----@generic T
----@param type1 T
----@return T
-function foobar(type1)
- return {}
-end
-
-local v1 = foobar(Dog)
-v1:<!eat!>()
-]]
-
-TEST [[
----@class Dog
-local Dog = {}
-function Dog:<?eat?>()
-end
-
----@class Master
-local Master = {}
-
----@generic T
----@param type1 string
----@param type2 T
----@return T
-function Master:foobar(type1, type2)
- return {}
-end
-
-local v1 = Master:foobar("", Dog)
-v1.<!eat!>()
-]]
-
-TEST [[
----@class A
-local <?A?>
-
----@generic T
----@param self T
----@return T
-function m.f(self) end
-
-local <!b!> = m.f(<!A!>)
-]]
-
-TEST [[
----@class A
-local <?A?>
-
----@generic T
----@param self T
----@return T
-function m:f() end
-
-local <!b!> = m.f(<!A!>)
-]]
-
-TEST [[
----@class A
-local <?A?>
-
----@generic T
----@param self T
----@return T
-function <!A!>.f(self) end
-
-local <!b!> = <!A!>:f()
-]]
-
-TEST [[
----@class A
-local <?A?>
-
----@generic T
----@param self T
----@return T
-function <!A!>:f() end
-
-local <!b!> = <!A!>:f()
-]]