Skip to content

Commit e0ff9a8

Browse files
authored
Merge pull request #326 from uhziel/generic-name-string-literal
针对generic,类型参数允许是字符串字面值来表达类型
2 parents f9cf323 + 9586b30 commit e0ff9a8

File tree

3 files changed

+107
-1
lines changed

3 files changed

+107
-1
lines changed

script/parser/guide.lua

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ m.childMap = {
9999
['doc.vararg'] = {'vararg', 'comment'},
100100
['doc.type.table'] = {'key', 'value', 'comment'},
101101
['doc.type.function'] = {'#args', '#returns', 'comment'},
102+
['doc.type.typeliteral'] = {'node'},
102103
['doc.overload'] = {'overload', 'comment'},
103104
['doc.see'] = {'name', 'field'},
104105
}
@@ -1487,6 +1488,25 @@ function m.checkSameSimpleInSpecialBranch(status, obj, start, pushQueue)
14871488
end
14881489
end
14891490

1491+
local function appendValidGenericType(results, status, typeName, obj)
1492+
if typeName.parent.type == 'doc.type.typeliteral' then
1493+
if obj.type == 'string' and status.interface.docType then
1494+
local docs = status.interface.docType(obj[1])
1495+
for i = 1, #docs do
1496+
local doc = docs[i]
1497+
if doc.type == 'doc.class.name'
1498+
or doc.type == 'doc.alias.name' then
1499+
results[#results+1] = doc
1500+
break
1501+
end
1502+
end
1503+
end
1504+
else
1505+
-- 发现没有使用 `T`,则沿用既有逻辑直接返回实参
1506+
results[#results+1] = obj
1507+
end
1508+
end
1509+
14901510
local function stepRefOfGeneric(status, typeUnit, args, mode)
14911511
local results = {}
14921512
if not args then
@@ -1511,7 +1531,7 @@ local function stepRefOfGeneric(status, typeUnit, args, mode)
15111531
and source.parent.type == 'funcargs' then
15121532
for index, arg in ipairs(source.parent) do
15131533
if arg == source then
1514-
results[#results+1] = args[index]
1534+
appendValidGenericType(results, status, typeName, args[index])
15151535
end
15161536
end
15171537
end

script/parser/luadoc.lua

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ Symbol <- ({} {
5656
/ '...'
5757
/ '+'
5858
/ '#'
59+
/ '`'
5960
} {})
6061
-> Symbol
6162
]], {
@@ -450,12 +451,41 @@ function parseType(parent)
450451
if not tp then
451452
break
452453
end
454+
455+
-- 处理 `T` 的情况
456+
local typeLiteral = nil
457+
if tp == 'symbol' and content == '`' then
458+
nextToken()
459+
if not checkToken('symbol', '`', 2) then
460+
break
461+
end
462+
tp, content = peekToken()
463+
if not tp then
464+
break
465+
end
466+
-- TypeLiteral,指代类型的字面值。比如,对于类 Cat 来说,它的 TypeLiteral 是 "Cat"
467+
typeLiteral = {
468+
type = 'doc.type.typeliteral',
469+
parent = result,
470+
start = getStart(),
471+
finish = nil,
472+
node = nil,
473+
}
474+
end
475+
453476
if tp == 'name' then
454477
nextToken()
455478
local typeUnit = parseTypeUnit(result, content)
456479
if not typeUnit then
457480
break
458481
end
482+
if typeLiteral then
483+
nextToken()
484+
typeLiteral.finish = getFinish()
485+
typeLiteral.node = typeUnit
486+
typeUnit.parent = typeLiteral
487+
typeUnit = typeLiteral
488+
end
459489
result.types[#result.types+1] = typeUnit
460490
if not result.start then
461491
result.start = typeUnit.start

test/definition/luadoc.lua

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,3 +197,59 @@ TEST [[
197197
---@type Cat
198198
local <?<!v!>?>
199199
]]
200+
201+
TEST [[
202+
---@class Foo
203+
local Foo = {}
204+
function Foo:<!bar1!>() end
205+
206+
---@generic T
207+
---@param arg1 T
208+
---@return T
209+
function Generic(arg1) print(arg1) end
210+
211+
local v1 = Generic(Foo)
212+
print(v1.<?bar1?>)
213+
]]
214+
215+
TEST [[
216+
---@class Foo
217+
local Foo = {}
218+
function Foo:bar1() end
219+
220+
---@generic T
221+
---@param arg1 T
222+
---@return T
223+
function Generic(arg1) print(arg1) end
224+
225+
local v1 = Generic("Foo")
226+
print(v1.<?bar1?>)
227+
]]
228+
229+
TEST [[
230+
---@class Foo
231+
local Foo = {}
232+
function Foo:bar1() end
233+
234+
---@generic T
235+
---@param arg1 `T`
236+
---@return T
237+
function Generic(arg1) print(arg1) end
238+
239+
local v1 = Generic(Foo)
240+
print(v1.<?bar1?>)
241+
]]
242+
243+
TEST [[
244+
---@class Foo
245+
local Foo = {}
246+
function Foo:<!bar1!>() end
247+
248+
---@generic T
249+
---@param arg1 `T`
250+
---@return T
251+
function Generic(arg1) print(arg1) end
252+
253+
local v1 = Generic("Foo")
254+
print(v1.<?bar1?>)
255+
]]

0 commit comments

Comments
 (0)