summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author最萌小汐 <sumneko@hotmail.com>2021-05-08 17:14:27 +0800
committer最萌小汐 <sumneko@hotmail.com>2021-05-08 17:14:27 +0800
commit0af503e8ebe11fd6226c0363d40473007dbe1f6d (patch)
tree88a504b188edb22450905b56419c4d459ab1f197
parent589055fefb2210b82dbd4a5cb601a230a1953d3b (diff)
downloadlua-language-server-0af503e8ebe11fd6226c0363d40473007dbe1f6d.zip
stash
-rw-r--r--script/core/linker.lua15
-rw-r--r--script/core/searcher.lua50
-rw-r--r--test/definition/luadoc.lua80
3 files changed, 135 insertions, 10 deletions
diff --git a/script/core/linker.lua b/script/core/linker.lua
index 76d8bf35..af3be6ee 100644
--- a/script/core/linker.lua
+++ b/script/core/linker.lua
@@ -131,6 +131,7 @@ local function getKey(source)
or source.type == 'doc.vararg'
or source.type == 'doc.field.name'
or source.type == 'doc.type.table'
+ or source.type == 'doc.type.array'
or source.type == 'doc.type.function' then
return source.start, nil
elseif source.type == 'doc.see.field' then
@@ -180,7 +181,10 @@ local function checkMode(source)
return 'dfun:'
end
if source.type == 'doc.type.table' then
- return 'dtbl:'
+ return 'dtable:'
+ end
+ if source.type == 'doc.type.array' then
+ return 'darray:'
end
if source.type == 'doc.vararg' then
return 'dv:'
@@ -467,6 +471,15 @@ local function compileLink(source)
pushForward(valueID, getID(source.value))
end
end
+ if source.type == 'doc.type.array' then
+ if source.node then
+ local nodeID = ('%s%s'):format(
+ id,
+ SPLIT_CHAR
+ )
+ pushForward(nodeID, getID(source.node))
+ end
+ end
-- 将函数的返回值映射到具体的返回值上
if source.type == 'function' then
-- 检查实体返回值
diff --git a/script/core/searcher.lua b/script/core/searcher.lua
index 3a4e5d76..4a78dca8 100644
--- a/script/core/searcher.lua
+++ b/script/core/searcher.lua
@@ -247,25 +247,57 @@ function m.searchRefsByID(status, uri, expect, mode)
local callStash = {}
+ local function getGenericID(typeUnit, call, index)
+ local key = typeUnit[1]
+ local generics = typeUnit.typeGeneric[key]
+ local callParam = call.args[index]
+ if not callParam then
+ return nil
+ end
+ if typeUnit.literal then
+ if callParam.type == 'string' then
+ return generics, ('dn:%s'):format(callParam[1] or '')
+ end
+ else
+ return generics, linker.getID(callParam)
+ end
+ return nil
+ end
+
local function genericStashParam(docType, call, index)
for _, typeUnit in ipairs(docType.types) do
if typeUnit.typeGeneric then
- local key = typeUnit[1]
- local generics = typeUnit.typeGeneric[key]
- local callParam = call.args[index]
- if callParam then
- if typeUnit.literal then
- if callParam.type == 'string' then
- genericStashMap[generics] = ('dn:%s'):format(callParam[1] or '')
+ local generics, id = getGenericID(typeUnit, call, index)
+ if id then
+ genericStashMap[generics] = id
+ end
+ end
+ -- 支持 V[]
+ if typeUnit.type == 'doc.type.array' then
+ if typeUnit.node.typeGeneric then
+ local generics, id = getGenericID(typeUnit.node, call, index)
+ if id then
+ genericStashMap[generics] = id .. linker.SPLIT_CHAR
+ end
+ end
+ end
+ -- 支持 table<number, V>
+ if typeUnit.type == 'doc.type.table' then
+ if typeUnit.value then
+ for _, typeUnit2 in ipairs(typeUnit.value.types) do
+ if typeUnit2.typeGeneric then
+ local generics, id = getGenericID(typeUnit2, call, index)
+ if id then
+ genericStashMap[generics] = id .. linker.SPLIT_CHAR
+ end
end
- else
- genericStashMap[generics] = linker.getID(callParam)
end
end
end
end
end
+ -- TODO 这里的实现是有问题的,在多次穿透泛型时可能出错,不过错就错吧,让用户自己写注解
local function genericStash(source)
if source.type ~= 'function'
and source.type ~= 'doc.type.function' then
diff --git a/test/definition/luadoc.lua b/test/definition/luadoc.lua
index 74cc5c81..3620f25e 100644
--- a/test/definition/luadoc.lua
+++ b/test/definition/luadoc.lua
@@ -282,6 +282,26 @@ print(v1.<?bar1?>)
]]
TEST [[
+---@class A
+local <!t!>
+
+---@type A[]
+local b
+
+local <?<!c!>?> = b[1]
+]]
+
+TEST [[
+---@class A
+local <!t!>
+
+---@type table<number, A>
+local b
+
+local <?<!c!>?> = b[1]
+]]
+
+TEST [[
---@class Foo
local Foo = {}
function Foo:<!bar1!>() end
@@ -347,6 +367,66 @@ local <?<!v2!>?> = v1(<!{}!>)
]]
TEST [[
+---@generic V
+---@param x V[]
+---@return V
+local function f(x) end
+
+---@class A
+local <!a!>
+
+---@type A[]
+local b
+
+local <?<!c!>?> = f(b)
+]]
+
+TEST [[
+---@generic V
+---@param x table<number, V>
+---@return V
+local function f(x) end
+
+---@class A
+local <!a!>
+
+---@type table<number, A>
+local b
+
+local <?<!c!>?> = f(b)
+]]
+
+TEST [[
+---@generic V
+---@param x V[]
+---@return V
+local function f(x) end
+
+---@class A
+local <!a!>
+
+---@type table<number, A>
+local b
+
+local <?<!c!>?> = f(b)
+]]
+
+TEST [[
+---@generic V
+---@param x table<number, V>
+---@return V
+local function f(x) end
+
+---@class A
+local <!a!>
+
+---@type A[]
+local b
+
+local <?<!c!>?> = f(b)
+]]
+
+TEST [[
---@class Foo
local Foo = {}
function Foo:<!bar1!>() end