diff options
Diffstat (limited to 'test')
31 files changed, 2873 insertions, 2791 deletions
diff --git a/test/basic/init.lua b/test/basic/init.lua index 1b698493..8490d51c 100644 --- a/test/basic/init.lua +++ b/test/basic/init.lua @@ -1,2 +1 @@ require 'basic.textmerger' -require 'basic.noder' diff --git a/test/basic/linker.txt b/test/basic/linker.txt deleted file mode 100644 index ea3ba180..00000000 --- a/test/basic/linker.txt +++ /dev/null @@ -1,141 +0,0 @@ -ast -> linkers = { - ['g|"X"|"Y"|"Z"'] = {src1, src2, src3}, - ['g|"X"|"Y"'] = {src4, src5, src6}, - ['g|"X"'] = {src7, src8, src9}, - ['l|7'] = {src10}, - ['l|7|"x"'] = {src11}, - ['l|11|"k"'] = {src12}, -} - -```lua -x.y.<?z?> = <!f!> - -<?g?> = x.y.z - -t.<!z!> = 1 -x.y = t - -x = { - y = { - <!z!> = 1 - } -} -``` - -expect: 'l|x|y|z' -forward: 'l|x|y|z' -> f -backward: 'l|x|y|z' -> g -last: 'l|x|y' + 'z' - -expect: 'l|x|y' + '|z' -forward: 'l|t' + '|z' -> 'l|t|z' -> t.z -backward: nil -last: 'l|x' + '|y|z' - -expect: 'l|x' + '|y|z' -forward: 'l|0' + '|y|z' -> 'l|0|y|z' -backward: nil -last: nil - -expect: 'l|0|y|z' -forward: nil -backward: nil -last: 'l|0|y' + '|z' - -expect: 'l|0|y' + '|z' -forward: 'l|1'+ '|z' -> 'l|1|z' -> field z -backward: nil -last: 'l|0' + '|y|z' - - -```lua -a = { - b = { - <?c?> = 1, - } -} - -print(a.b.<!c!>) -``` - -expect: 't|3|c' -forward: nil -backward: nil -last: 't|3' + '|c' - -expect: 't|3' + '|c' -forward: nil -backward: 't|2|b' + '|c' -last: nil - -expect: 't|2|b|c' -forward: nil -backward: 't|2|b' + '|c' -last: nil - -```lua ----@return <?A?> -local function f() -end - -local <!x!> = f() -``` - -'d|A' -'f|1|#1' -'f|1' + '|#1' -'l|1' + '|#1' -'s|1' + '|#1' - -```lua ----@generic T ----@param a T ----@return T -local function f(a) end - -local <?c?> - -local <!v!> = f(c) -``` - -'l1' -'l2|@1' -'f|1|@1' -'f|1|#1' - -``` ----@generic T ----@param p T ----@return T -local function f(p) end - -local <?r?> = f(<!k!>) -``` - -l:r -s:1#1 call -l:f#1 call -f:1#1 call -> f:1&T = l:k -l:f@1 --> 从保存的call信息里找到 f:1&T = l:k -l:k - - - -``` ----@generic T, V ----@param p T ----@return fun(V):T, V -local function f(p) end - -local f2 = f(<!k!>) -local <?r?> = f2() -``` - -l:r -s:2|#1 call1 -l:f2|#1 call1 -f:2|#1 call1 -s:1#1|#1 call2 -f:1#1|#1 call2 -> f:1&T = l:k -dfun:1|#1 -dn:V -> f:1&T = l:k diff --git a/test/basic/noder.lua b/test/basic/noder.lua deleted file mode 100644 index 49585ee8..00000000 --- a/test/basic/noder.lua +++ /dev/null @@ -1,143 +0,0 @@ -local noder = require 'core.noder' -local files = require 'files' -local util = require 'utility' -local guide = require 'parser.guide' -local catch = require 'catch' - -local function getSource(pos) - local ast = files.getState('') - return guide.eachSourceContain(ast.ast, pos, function (source) - if source.type == 'local' - or source.type == 'getlocal' - or source.type == 'setlocal' - or source.type == 'setglobal' - or source.type == 'getglobal' - or source.type == 'setfield' - or source.type == 'getfield' - or source.type == 'setmethod' - or source.type == 'getmethod' - or source.type == 'tablefield' - or source.type == 'setindex' - or source.type == 'getindex' - or source.type == 'tableindex' - or source.type == 'label' - or source.type == 'goto' then - return source - end - end) -end - -local CARE = {} -local function TEST(script) - return function (expect) - local newScript, catched = catch(script, '?') - files.setText('', newScript) - local source = getSource(catched['?'][1][1]) - assert(source) - local result = { - id = noder.getID(source), - } - - expect['id'] = expect['id']:gsub('|', '\x1F') - - for key in pairs(CARE) do - assert(result[key] == expect[key]) - end - files.remove('') - end -end - -CARE['id'] = true -TEST [[ -local <?x?> -]] { - id = 'l:6', -} - -TEST [[ -local x -print(<?x?>) -]] { - id = 'l:6', -} - -TEST [[ -local x -<?x?> = 1 -]] { - id = 'l:6', -} - -TEST [[ -print(<?X?>) -]] { - id = 'g:.X', -} - -TEST [[ -print(<?X?>) -]] { - id = 'g:.X', -} - -TEST [[ -local x -print(x.y.<?z?>) -]] { - id = 'l:6|.y|.z', -} - -TEST [[ -local x -function x:<?f?>() end -]] { - id = 'l:6|.f', -} - -TEST [[ -print(X.Y.<?Z?>) -]] { - id = 'g:.X|.Y|.Z', -} - -TEST [[ -function x:<?f?>() end -]] { - id = 'g:.x|.f', -} - -TEST [[ -{ - <?x?> = 1, -} -]] { - id = 't:0|.x', -} - -TEST [[ -return <?X?> -]] { - id = 'g:.X', -} - -TEST [[ -function f() - return <?X?> -end -]] { - id = 'g:.X', -} - -TEST [[ -::<?label?>:: -goto label -]] { - id = 'l:2', -} - -TEST [[ -::label:: -goto <?label?> -]] { - id = 'l:2', -} diff --git a/test/catch.lua b/test/catch.lua index 849be09d..01aac665 100644 --- a/test/catch.lua +++ b/test/catch.lua @@ -41,6 +41,10 @@ return function (script, seps) local result = {} local marks = {} + for s in seps:gmatch '.' do + result[s] = catchedTable() + end + local lineOffset = 1 local line = 0 local skipOffset = 0 @@ -68,9 +72,6 @@ return function (script, seps) local mark = marks[j] if mark.char == text then local position = line * 10000 + offset - skipOffset - lineOffset - if not result[text] then - result[text] = catchedTable() - end result[text][#result[text]+1] = { mark.position, position } table.remove(marks, j) break diff --git a/test/completion/common.lua b/test/completion/common.lua index 8128d2ab..292a2dca 100644 --- a/test/completion/common.lua +++ b/test/completion/common.lua @@ -630,7 +630,7 @@ self.results.list[#self.re<??>] }, { label = 'results', - kind = define.CompletionItemKind.Field, + kind = define.CompletionItemKind.Text, }, } @@ -1192,10 +1192,51 @@ TEST [[ } TEST [[ +---@class ZBBC +---@class ZBBC : Z<??> +]] +(nil) + +TEST [[ ---@class ZABC ---@class ZBBC : <??> ]] -(EXISTS) +(function (results) + local ok + for _, res in ipairs(results) do + if res.label == 'ZABC' then + ok = true + end + if res.label == 'ZBBC' then + error('ZBBC should not be here') + end + end + assert(ok, 'ZABC should be here') +end) + +TEST [[ +---@class ZBBC +---@class ZBBC : <??> +]] +(function (results) + for _, res in ipairs(results) do + if res.label == 'ZBBC' then + error('ZBBC should not be here') + end + end +end) + +TEST [[ +---@class ZABC +---@class ZABC +---@class ZBBC : Z<??> +]] +{ + { + label = 'ZABC', + kind = define.CompletionItemKind.Class, + }, +} TEST [[ ---@class zabc @@ -1485,7 +1526,7 @@ mt.<??> } TEST [[ ----@param x string | "'AAA'" | "'BBB'" | "'CCC'" +---@param x string | "AAA" | "BBB" | "CCC" function f(y, x) end @@ -1493,21 +1534,21 @@ f(1, <??>) ]] { { - label = "'AAA'", + label = '"AAA"', kind = define.CompletionItemKind.EnumMember, }, { - label = "'BBB'", + label = '"BBB"', kind = define.CompletionItemKind.EnumMember, }, { - label = "'CCC'", + label = '"CCC"', kind = define.CompletionItemKind.EnumMember, } } TEST [[ ----@param x string | "'AAA'" | "'BBB'" | "'CCC'" +---@param x string | "AAA" | "BBB" | "CCC" function f(y, x) end @@ -1515,21 +1556,21 @@ f(1,<??>) ]] { { - label = "'AAA'", + label = '"AAA"', kind = define.CompletionItemKind.EnumMember, }, { - label = "'BBB'", + label = '"BBB"', kind = define.CompletionItemKind.EnumMember, }, { - label = "'CCC'", + label = '"CCC"', kind = define.CompletionItemKind.EnumMember, } } TEST [[ ----@param x string | "'AAA'" | "'BBB'" | "'CCC'" +---@param x string | "AAA" | "BBB" | "CCC" function f(x) end @@ -1537,21 +1578,21 @@ f(<??>) ]] { { - label = "'AAA'", + label = '"AAA"', kind = define.CompletionItemKind.EnumMember, }, { - label = "'BBB'", + label = '"BBB"', kind = define.CompletionItemKind.EnumMember, }, { - label = "'CCC'", + label = '"CCC"', kind = define.CompletionItemKind.EnumMember, } } TEST [[ ----@alias Option string | "'AAA'" | "'BBB'" | "'CCC'" +---@alias Option string | "AAA" | "BBB" | "CCC" ---@param x Option function f(x) end @@ -1560,21 +1601,21 @@ f(<??>) ]] { { - label = "'AAA'", + label = '"AAA"', kind = define.CompletionItemKind.EnumMember, }, { - label = "'BBB'", + label = '"BBB"', kind = define.CompletionItemKind.EnumMember, }, { - label = "'CCC'", + label = '"CCC"', kind = define.CompletionItemKind.EnumMember, } } TEST [[ ----@param x string | "'AAA'" | "'BBB'" | "'CCC'" +---@param x string | "AAA" | "BBB" | "CCC" function f(x) end @@ -1605,10 +1646,10 @@ TEST [[ ---@alias XXXX ---comment 1 ---comment 1 ----| '1' +---| 1 ---comment 2 ---comment 2 ----| '2' +---| 2 ---@param x XXXX local function f(x) @@ -1634,10 +1675,10 @@ TEST [[ ---@alias XXXX ---comment 1 ---comment 1 ----| '1' +---| 1 ---comment 2 ---comment 2 ----| '2' +---| 2 ---@param x XXXX local function f(x) end @@ -1645,7 +1686,7 @@ end ---comment 3 ---comment 3 ----| '3' +---| 3 f(<??>) ]] @@ -1719,20 +1760,20 @@ global zzz: integer = 1 TEST [[ ---@param x string ----| "'选项1'" # 注释1 ----| "'选项2'" # 注释2 +---| "选项1" # 注释1 +---| "选项2" # 注释2 function f(x) end f(<??>) ]] { { - label = "'选项1'", + label = '"选项1"', kind = define.CompletionItemKind.EnumMember, description = '注释1', }, { - label = "'选项2'", + label = '"选项2"', kind = define.CompletionItemKind.EnumMember, description = '注释2', }, @@ -1751,49 +1792,49 @@ utf8.charpatter<??> } TEST [[ ----@type "'a'"|"'b'"|"'c'" +---@type "a"|"b"|"c" local x print(x == <??>) ]] { { - label = "'a'", + label = '"a"', kind = define.CompletionItemKind.EnumMember, }, { - label = "'b'", + label = '"b"', kind = define.CompletionItemKind.EnumMember, }, { - label = "'c'", + label = '"c"', kind = define.CompletionItemKind.EnumMember, }, } TEST [[ ----@type "'a'"|"'b'"|"'c'" +---@type "a"|"b"|"c" local x x = <??> ]] { { - label = "'a'", + label = '"a"', kind = define.CompletionItemKind.EnumMember, }, { - label = "'b'", + label = '"b"', kind = define.CompletionItemKind.EnumMember, }, { - label = "'c'", + label = '"c"', kind = define.CompletionItemKind.EnumMember, }, } TEST [[ ----@type "'a'"|"'b'"|"'c'" +---@type "a"|"b"|"c" local x print(x == '<??>') @@ -1817,7 +1858,7 @@ print(x == '<??>') } TEST [[ ----@type "'a'"|"'b'"|"'c'" +---@type "a"|"b"|"c" local x x = '<??>' @@ -1880,6 +1921,7 @@ vvv<??> }, } +--[=[ Cared['insertText'] = true TEST [[ ---@param callback fun(x: number, y: number):string @@ -1903,6 +1945,7 @@ end\ ```" }, } +]=] Cared['insertText'] = nil @@ -2060,85 +2103,85 @@ field cc.aaa: number Cared['description'] = nil TEST [[ ----@type table<string, "'a'"|"'b'"|"'c'"> +---@type table<string, "a"|"b"|"c"> local x x.a = <??> ]] { { - label = "'a'", + label = '"a"', kind = define.CompletionItemKind.EnumMember, }, { - label = "'b'", + label = '"b"', kind = define.CompletionItemKind.EnumMember, }, { - label = "'c'", + label = '"c"', kind = define.CompletionItemKind.EnumMember, }, } TEST [[ ----@type table<string, "'a'"|"'b'"|"'c'"> +---@type table<string, "a"|"b"|"c"> local x x['a'] = <??> ]] { { - label = "'a'", + label = '"a"', kind = define.CompletionItemKind.EnumMember, }, { - label = "'b'", + label = '"b"', kind = define.CompletionItemKind.EnumMember, }, { - label = "'c'", + label = '"c"', kind = define.CompletionItemKind.EnumMember, }, } TEST [[ ----@type table<string, "'a'"|"'b'"|"'c'"> +---@type table<string, "a"|"b"|"c"> local x = { a = <??> } ]] { { - label = "'a'", + label = '"a"', kind = define.CompletionItemKind.EnumMember, }, { - label = "'b'", + label = '"b"', kind = define.CompletionItemKind.EnumMember, }, { - label = "'c'", + label = '"c"', kind = define.CompletionItemKind.EnumMember, }, } TEST [[ ----@type table<string, "'a'"|"'b'"|"'c'"> +---@type table<string, "a"|"b"|"c"> local x = { ['a'] = <??> } ]] { { - label = "'a'", + label = '"a"', kind = define.CompletionItemKind.EnumMember, }, { - label = "'b'", + label = '"b"', kind = define.CompletionItemKind.EnumMember, }, { - label = "'c'", + label = '"c"', kind = define.CompletionItemKind.EnumMember, }, } diff --git a/test/crossfile/allreferences.lua b/test/crossfile/allreferences.lua deleted file mode 100644 index 2753d785..00000000 --- a/test/crossfile/allreferences.lua +++ /dev/null @@ -1,218 +0,0 @@ -local config = require 'config' - -TEST { - { - path = 'a.lua', - content = [[ - local <!f!> = require 'lib' - ]], - }, - { - path = 'lib.lua', - content = [[ - return <!<?function?> () - end!> - ]], - }, -} - -TEST { - { - path = 'a.lua', - content = [[ - local m = {} - function m.<~func~>() - end - return m - ]], - }, - { - path = 'b.lua', - content = [[ - local t = require 'a' - t.<!func!>() - ]], - }, -} - -TEST { - { - path = 'a.lua', - content = [[ - return <~function () end~> - ]], - }, - { - path = 'b.lua', - content = [[ - local t = require 'a' - ]], - }, - { - path = 'b.lua', - content = [[ - local t = require 'a' - ]], - }, - { - path = 'b.lua', - content = [[ - local t = require 'a' - ]], - }, - { - path = 'b.lua', - content = [[ - local <!t!> = require 'a' - ]], - }, -} - -config.set(nil, 'Lua.IntelliSense.traceBeSetted', true) -TEST { - { - path = 'a.lua', - content = [[ - local function <~f~>() - end - - return { - <!f!> = <!f!>, - } - ]] - }, - { - path = 'b.lua', - content = [[ - local t = require 'a' - local <!f!> = t.<!f!> - - <!f!>() - - return { - <!f!> = <!f!>, - } - ]] - } -} - -TEST { - { - path = 'a.lua', - content = [[ - local function <!f!>() - end - - return { - <!f!> = <!f!>, - } - ]] - }, - { - path = 'c.lua', - content = [[ - local t = require 'a' - local <!f!> = t.<!f!> - - <!f!>() - - return { - <!f!> = <!f!>, - } - ]] - }, - { - path = 'b.lua', - content = [[ - local t = require 'a' - local <!f!> = t.<!f!> - - <~f~>() - - return { - <!f!> = <!f!>, - } - ]] - } -} - -TEST { - { - path = 'a.lua', - content = [[ - local function <~f~>() - end - - return { - <!f!> = <!f!>, - } - ]] - }, - { - path = 'b1.lua', - content = [[ - local t = require 'a' - t.<!f!>() - ]] - }, - { - path = 'b2.lua', - content = [[ - local t = require 'a' - t.<!f!>() - ]] - }, - { - path = 'b3.lua', - content = [[ - local t = require 'a' - t.<!f!>() - ]] - }, - { - path = 'b4.lua', - content = [[ - local t = require 'a' - t.<!f!>() - ]] - }, - { - path = 'b5.lua', - content = [[ - local t = require 'a' - t.<!f!>() - ]] - }, - { - path = 'b6.lua', - content = [[ - local t = require 'a' - t.<!f!>() - ]] - }, - { - path = 'b7.lua', - content = [[ - local t = require 'a' - t.<!f!>() - ]] - }, -} - -TEST { - { - path = 'a.lua', - content = [[ - local <~t~> = require 'b' - return <!t!> - ]] - }, - { - path = 'b.lua', - content = [[ - local <!t!> = require 'a' - return <!t!> - ]] - }, -} -config.set(nil, 'Lua.IntelliSense.traceBeSetted', false) diff --git a/test/crossfile/completion.lua b/test/crossfile/completion.lua index c271f598..79762646 100644 --- a/test/crossfile/completion.lua +++ b/test/crossfile/completion.lua @@ -837,7 +837,7 @@ TEST { kind = CompletionItemKind.Variable, description = [[ ```lua -local z: {} +local z: table ```]] }, } diff --git a/test/crossfile/definition.lua b/test/crossfile/definition.lua index eaf12b73..f44f2707 100644 --- a/test/crossfile/definition.lua +++ b/test/crossfile/definition.lua @@ -47,8 +47,8 @@ function TEST(datas) uri, } end - if catched['?'] or catched['~'] then - sourceList = catched['?'] or catched['~'] + if #catched['?'] > 0 or #catched['~'] > 0 then + sourceList = catched['?'] + catched['~'] sourceUri = uri end files.setText(uri, newScript) @@ -149,7 +149,7 @@ config.set(nil, 'Lua.runtime.pathStrict', false) TEST { { path = 'a.lua', - content = 'local <!t!> = 1; return t', + content = 'return <!function () end!>', }, { path = 'b.lua', @@ -160,7 +160,7 @@ TEST { TEST { { path = 'a.lua', - content = 'local <!t!> = 1; return t', + content = 'return <!function () end!>', }, { path = 'b.lua', @@ -188,7 +188,7 @@ local <~t~> TEST { { path = 'a.lua', - content = 'local <!t!> = 1; return t', + content = 'return <!function () end!>', }, { path = 'b.lua', @@ -355,9 +355,7 @@ TEST { { path = 'a.lua', content = [[ - return <!{ - a = 1, - }!> + return <!function () end!> ]], }, { @@ -395,8 +393,8 @@ TEST { { path = 'a.lua', content = [[ - local function <!f!>() - end + local <!function f() + end!> return f ]] }, @@ -455,11 +453,11 @@ TEST { { path = 'a.lua', content = [[ - local function <!f!>() - end + local <!function f() + end!> return { - <!f!> = f, + f = f, } ]] }, @@ -610,7 +608,7 @@ TEST { path = 'a.lua', content = [[ ---@class Class - local <!obj!> + local obj ]] }, { @@ -636,7 +634,7 @@ TEST { path = 'b.lua', content = [[ ---@class Class - local <!obj!> + local obj ]] }, } @@ -800,14 +798,11 @@ TEST { }, } -config.set(nil, 'Lua.IntelliSense.traceFieldInject', true) TEST { { path = 'a.lua', content = [[ -local t = GlobalTable - -t.settings = { +GlobalTable.settings = { <!test!> = 1 } ]] @@ -821,7 +816,27 @@ print(b.<?test?>) ]] } } -config.set(nil, 'Lua.IntelliSense.traceFieldInject', false) + +TEST { + { + path = 'a.lua', + content = [[ +GlobalTable = { + settings = { + <!test!> = 1 + } +} + ]] + }, + { + path = 'b.lua', + content = [[ +local b = GlobalTable.settings + +print(b.<?test?>) + ]] + } +} TEST { { diff --git a/test/crossfile/hover.lua b/test/crossfile/hover.lua index cb9e83aa..4461e775 100644 --- a/test/crossfile/hover.lua +++ b/test/crossfile/hover.lua @@ -44,7 +44,7 @@ function TEST(expect) local script, list = catch(file.content, '?') local uri = furi.encode(file.path) files.setText(uri, script) - if list['?'] then + if #list['?'] > 0 then sourceUri = uri sourcePos = (list['?'][1][1] + list['?'][1][2]) // 2 end @@ -362,22 +362,22 @@ TEST { path = 'b.lua', content = [[ ---@param x string - ---| "'选项1'" # 注释1 - ---| > "'选项2'" # 注释2 + ---| "选项1" # 注释1 + ---| > "选项2" # 注释2 function <?f?>(x) end ]] }, hover = [[ ```lua -function f(x: string|'选项1'|'选项2') +function f(x: string|"选项1"|"选项2") ``` --- ```lua -x: string - | '选项1' -- 注释1 - -> '选项2' -- 注释2 +x: + | "选项1" -- 注释1 + -> "选项2" -- 注释2 ```]] } @@ -390,23 +390,23 @@ TEST { path = 'b.lua', content = [[ ---@alias option - ---| "'选项1'" # 注释1 - ---| > "'选项2'" # 注释2 + ---| "选项1" # 注释1 + ---| > "选项2" # 注释2 ---@param x option function <?f?>(x) end ]] }, hover = [[ ```lua -function f(x: '选项1'|'选项2') +function f(x: "选项1"|"选项2") ``` --- ```lua -x: option - | '选项1' -- 注释1 - -> '选项2' -- 注释2 +x: + | "选项1" -- 注释1 + -> "选项2" -- 注释2 ```]] } @@ -419,8 +419,8 @@ TEST { path = 'b.lua', content = [[ ---@alias option - ---| "'选项1'" # 注释1 - ---| > "'选项2'" # 注释2 + ---| "选项1" # 注释1 + ---| > "选项2" # 注释2 ---@return option x function <?f?>() end ]] @@ -428,15 +428,15 @@ TEST { hover = [[ ```lua function f() - -> x: '选项1'|'选项2' + -> x: "选项1"|"选项2" ``` --- ```lua -x: option - | '选项1' -- 注释1 - -> '选项2' -- 注释2 +x: + | "选项1" -- 注释1 + -> "选项2" -- 注释2 ```]] } @@ -449,8 +449,8 @@ TEST { path = 'b.lua', content = [[ ---@alias option - ---| "'选项1'" # 注释1 - ---| > "'选项2'" # 注释2 + ---| "选项1" # 注释1 + ---| > "选项2" # 注释2 ---@return option function <?f?>() end ]] @@ -458,15 +458,15 @@ TEST { hover = [[ ```lua function f() - -> '选项1'|'选项2' + -> "选项1"|"选项2" ``` --- ```lua -return #1: option - | '选项1' -- 注释1 - -> '选项2' -- 注释2 +return #1: + | "选项1" -- 注释1 + -> "选项2" -- 注释2 ```]] } @@ -673,8 +673,8 @@ TEST {{ path = 'a.lua', content = '', }, { path = 'b.lua', content = [[ ---@param a boolean # xxx - ---| 'true' # ttt - ---| 'false' # fff + ---| true # ttt + ---| false # fff local function <?f?>(a) end ]] @@ -689,7 +689,7 @@ function f(a: boolean|true|false) @*param* `a` — xxx ```lua -a: boolean +a: | true -- ttt | false -- fff ```]]} @@ -825,7 +825,7 @@ local <?food?> }, hover = [[ ```lua -local food: any +local food: unknown ``` --- @@ -976,17 +976,17 @@ end }, hover = [[ ```lua -function f(p: a|b) +function f(p: "a"|"b") ``` --- ```lua -p: T - | a -- comment 1 - -- comment 2 - | b -- comment 3 - -- comment 4 +p: + | "a" -- comment 1 + -- comment 2 + | "b" -- comment 3 + -- comment 4 ```]]} --TEST {{ path = 'a.lua', content = '', }, { @@ -1044,13 +1044,13 @@ end for _, x in ipairs({} and {}) do - print(<?x?>) -- `x` is infered as `string` + print(<?x?>) -- `x` is infered as `string` (fixed bug) end ]], }, hover = [[ ```lua -local x: any +local x: unknown ```]] } diff --git a/test/crossfile/init.lua b/test/crossfile/init.lua index 1ed2a943..aec9a044 100644 --- a/test/crossfile/init.lua +++ b/test/crossfile/init.lua @@ -1,6 +1,5 @@ require 'crossfile.definition' require 'crossfile.references' -require 'crossfile.allreferences' require 'crossfile.hover' require 'crossfile.completion' require 'crossfile.diagnostic' diff --git a/test/crossfile/references.lua b/test/crossfile/references.lua index 18e9c5f9..1a9f2508 100644 --- a/test/crossfile/references.lua +++ b/test/crossfile/references.lua @@ -1,3 +1,4 @@ +---@diagnostic disable: await-in-sync local files = require 'files' local furi = require 'file-uri' local core = require 'core.reference' @@ -68,7 +69,7 @@ function TEST(datas) } end end - if catched['?'] or catched['~'] then + if #catched['?'] > 0 or #catched['~'] > 0 then sourceList = catched['?'] + catched['~'] sourceUri = uri end @@ -100,16 +101,15 @@ end TEST { { - path = 'lib.lua', + path = 'a.lua', content = [[ - return <!function () - end!> + <!ROOT!> = 1 ]], }, { - path = 'a.lua', + path = 'b.lua', content = [[ - local <~f~> = require 'lib' + print(<~ROOT~>) ]], }, } @@ -118,13 +118,13 @@ TEST { { path = 'a.lua', content = [[ - <!ROOT!> = 1 + <~ROOT~> = 1 ]], }, { path = 'b.lua', content = [[ - print(<~ROOT~>) + print(<!ROOT!>) ]], }, } @@ -133,15 +133,41 @@ TEST { { path = 'a.lua', content = [[ - <~ROOT~> = 1 - ]], + ---@type A + local t + + t.<!f!>() + ]] }, { path = 'b.lua', content = [[ - print(<!ROOT!>) - ]], + ---@class A + local mt + + function mt.<~f~>() + end + ]] + } +} + +TEST { + { + path = 'a.lua', + content = [[ + local t = {} + t.<~x~> = 1 + return t + ]] }, + { + path = 'b.lua', + content = [[ + local t = require 'a' + + print(t.<!x!>) + ]] + } } TEST { @@ -149,14 +175,13 @@ TEST { path = 'a.lua', content = [[ local f = require 'lib' - local <~o~> = f() + <!f!>() ]], }, { path = 'lib.lua', content = [[ - return function () - return <!{}!> + return <?function?> () end ]], }, @@ -166,20 +191,78 @@ TEST { { path = 'a.lua', content = [[ - ---@type A - local t + local m = {} + function m.<~func~>() + end + return m + ]], + }, + { + path = 'b.lua', + content = [[ + local t = require 'a' + t.<!func!>() + ]], + }, +} - t.<!f!>() - ]] +TEST { + { + path = 'a.lua', + content = [[ + return <?function?> () end + ]], }, { path = 'b.lua', content = [[ - ---@class A - local mt + local t = require 'a' + ]], + }, + { + path = 'b.lua', + content = [[ + local t = require 'a' + ]], + }, + { + path = 'b.lua', + content = [[ + local t = require 'a' + ]], + }, + { + path = 'b.lua', + content = [[ + local t = require 'a' + <!t!>() + ]], + }, +} - function mt.<~f~>() +TEST { + { + path = 'a.lua', + content = [[ + local function <~f~>() end + + return { + f = <!f!>, + } + ]] + }, + { + path = 'b.lua', + content = [[ + local t = require 'a' + local f = t.f + + f() + + return { + f = f, + } ]] } } @@ -188,17 +271,105 @@ TEST { { path = 'a.lua', content = [[ - local t = {} - t.<~x~> = 1 - return t + local <?function?> f() + end + + return { + f = f, + } ]] }, { path = 'b.lua', content = [[ local t = require 'a' + local f = t.f - print(t.<!x!>) + <!f!>() + + return { + f = f, + } ]] } } + +TEST { + { + path = 'a.lua', + content = [[ + local <?function?> f() + end + + return { + f = f, + } + ]] + }, + { + path = 'b1.lua', + content = [[ + local t = require 'a' + t.<!f!>() + ]] + }, + { + path = 'b2.lua', + content = [[ + local t = require 'a' + t.<!f!>() + ]] + }, + { + path = 'b3.lua', + content = [[ + local t = require 'a' + t.<!f!>() + ]] + }, + { + path = 'b4.lua', + content = [[ + local t = require 'a' + t.<!f!>() + ]] + }, + { + path = 'b5.lua', + content = [[ + local t = require 'a' + t.<!f!>() + ]] + }, + { + path = 'b6.lua', + content = [[ + local t = require 'a' + t.<!f!>() + ]] + }, + { + path = 'b7.lua', + content = [[ + local t = require 'a' + t.<!f!>() + ]] + }, +} + +TEST { + { + path = 'a.lua', + content = [[ + local <~t~> = require 'b' + return <!t!> + ]] + }, + { + path = 'b.lua', + content = [[ + local t = require 'a' + return t + ]] + }, +} diff --git a/test/definition/bug.lua b/test/definition/bug.lua index 77797f40..b564f764 100644 --- a/test/definition/bug.lua +++ b/test/definition/bug.lua @@ -134,7 +134,7 @@ t:<?add?>() TEST [[ local t = {} -t.<!f1!> = 1 +t.f1 = 1 t.<!f2!> = t.f1 print(t.<?f2?>) @@ -142,9 +142,9 @@ print(t.<?f2?>) TEST [[ local t = {} -t.<!f1!> = 1 +t.f1 = 1 t.<!f2!> = t.f1 -t.<!f1!> = t.f2 +t.f1 = t.f2 print(t.<?f2?>) ]] @@ -172,67 +172,65 @@ string.xx:<?format?>() --v.<?bar1?> --]] -config.set(nil, 'Lua.IntelliSense.traceLocalSet', true) TEST [[ local A, B function A:get1() - local <!a!> = B:get() + local a = B:get() return a end function A:get2() - local <!a!> = B:get() + local a = B:get() return a end function A:get3() - local <!a!> = B:get() + local a = B:get() return a end function A:get4() - local <!a!> = B:get() + local a = B:get() return a end function A:get5() - local <!a!> = B:get() + local a = B:get() return a end function A:get6() - local <!a!> = B:get() + local a = B:get() return a end function A:get7() - local <!a!> = B:get() + local a = B:get() return a end function A:get8() - local <!a!> = B:get() + local a = B:get() return a end function B:get() - local <!b!> - <!b!> = A:get1() - <!b!> = A:get2() - <!b!> = A:get3() - <!b!> = A:get4() - <!b!> = A:get5() - <!b!> = A:get6() - <!b!> = A:get7() - <!b!> = A:get8() + local b + b = A:get1() + b = A:get2() + b = A:get3() + b = A:get4() + b = A:get5() + b = A:get6() + b = A:get7() + b = A:get8() return b end local <!b!> = B:get() print(<?b?>) ]] -config.set(nil, 'Lua.IntelliSense.traceLocalSet', false) TEST [[ g[a.b.c] = 1 @@ -253,80 +251,3 @@ local <!v!> = t[a] t[a] = <?v?> ]] - -TEST [[ ----@class A ----@field x number - ----@class B: A ----@field <!x!> boolean - ----@type B -local t - -local <!<?v?>!> = t.x -]] - -TEST [[ ----@class A ----@field <!x!> number - ----@class B: A - ----@type B -local t - -local <!<?v?>!> = t.x -]] - -TEST [[ ----@class A -local A - -function A:x() end - ----@class B: A -local B - -function B:<!x!>() end - ----@type B -local t - -local <!<?v?>!> = t.x -]] - -TEST [[ ----@class A -local A - -function A:<!x!>() end - ----@class B: A -local B - ----@type B -local t - -local <!<?v?>!> = t.x -]] - --- TODO ---TEST [[ ------@class A ---local A --- ------@return A ---function A:x() end --- ------@class B: A ---local <!B!> --- ------@return B ---function B:x() end --- ------@type B ---local t --- ---local <!<?v?>!> = t.x() ---]] diff --git a/test/definition/call.lua b/test/definition/call.lua deleted file mode 100644 index 15364396..00000000 --- a/test/definition/call.lua +++ /dev/null @@ -1,8 +0,0 @@ -TEST [[ -function f() - local <!x!> - return x -end -local <!y!> = f() -print(<?y?>) -]] diff --git a/test/definition/field.lua b/test/definition/field.lua new file mode 100644 index 00000000..5b5b67f9 --- /dev/null +++ b/test/definition/field.lua @@ -0,0 +1,23 @@ +TEST [[ +X.<!y!> = 1 + +local t = X + +print(t.<?y?>) +]] + +TEST [[ +X.x.<!y!> = 1 + +local t = X.x + +print(t.<?y?>) +]] + +TEST [[ +X.x.<!y!> = 1 + +local t = X + +print(t.x.<?y?>) +]] diff --git a/test/definition/function.lua b/test/definition/function.lua index f5d32e78..95dd1b57 100644 --- a/test/definition/function.lua +++ b/test/definition/function.lua @@ -24,6 +24,6 @@ end ]] TEST [[ -local <!f!> = function () end +local <!f!> = <!function () end!> <?f?>() ]] diff --git a/test/definition/init.lua b/test/definition/init.lua index fc2903c1..3badaadf 100644 --- a/test/definition/init.lua +++ b/test/definition/init.lua @@ -34,9 +34,9 @@ function TEST(script) positions[i] = { result.target.start, result.target.finish } end end - assert(founded(catched['!'] or {}, positions)) + assert(founded(catched['!'], positions)) else - assert(catched['!'] == nil) + assert(#catched['!'] == 0) end files.remove('') @@ -44,12 +44,12 @@ end require 'definition.local' require 'definition.set' +require 'definition.field' require 'definition.arg' require 'definition.function' require 'definition.table' require 'definition.method' require 'definition.label' -require 'definition.call' require 'definition.special' require 'definition.bug' require 'definition.luadoc' diff --git a/test/definition/luadoc.lua b/test/definition/luadoc.lua index 8124261c..97b12b85 100644 --- a/test/definition/luadoc.lua +++ b/test/definition/luadoc.lua @@ -17,7 +17,7 @@ local x TEST [[ ---@class Class -local <!t!> +local t ---@type Class local <?<!x!>?> ]] @@ -35,21 +35,59 @@ obj:<?cast?>() TEST [[ ---@class A -local <!mt!> = {} -function mt:cast() -end +---@field x number ----@type A -local <!obj!> -<?obj?>:cast() +---@class B: A +---@field <!x!> boolean + +---@type B +local t + +t.<?x?> ]] TEST [[ ----@type A -local <?<!obj!>?> +---@class A +---@field <!x!> number +---@class B: A + +---@type B +local t + +t.<?x?> +]] + +TEST [[ ---@class A -local <!mt!> +local A + +function A:x() end + +---@class B: A +local B + +<!function B:x() end!> + +---@type B +local t + +local <!<?v?>!> = t.x +]] + +TEST [[ +---@class A +local A + +<!function A:x() end!> + +---@class B: A +local B + +---@type B +local t + +local <!<?v?>!> = t.x ]] TEST [[ @@ -105,6 +143,20 @@ function f(<?...?>) end ]] TEST [[ +---@alias A <!fun()!> + +---@type A +local <!<?x?>!> +]] + +TEST [[ +---@class A: <!{}!> + +---@type A +local <!<?x?>!> +]] + +TEST [[ ---@overload <!fun(y: boolean)!> ---@param x number ---@param y boolean @@ -116,11 +168,12 @@ print(<?f?>) TEST [[ local function f() - return 1 + local x + return x end ---@class Class -local <!mt!> +local mt ---@type Class local <?<!x!>?> = f() @@ -153,7 +206,7 @@ y.<?a?> TEST [[ ---@class <!loli!> -local <!unit!> +local unit!> function unit:pants() end @@ -184,34 +237,6 @@ AAAA.a.<?SSDF?> ]] TEST [[ ----@class Cat -local <!m!> ---hahaha ----@class Dog -local m2 ----@type Cat -local <?<!v!>?> -]] - -TEST [[ ----@class Cat -local <!m!> --hahaha ----@class Dog -local m2 ----@type Cat -local <?<!v!>?> -]] - -TEST [[ ----@class Cat - local <!m!> ---hahaha - - ---@class Dog - local m2 - ---@type Cat - local <?<!v!>?> -]] - -TEST [[ ---@return <!fun()!> local function f() end @@ -224,8 +249,8 @@ TEST [[ ---@return T local function f(p) end -local <!k!> -local <?<!r!>?> = f(<!k!>) +local k = <!function () end!> +local <?<!r!>?> = f(k) ]] TEST [[ @@ -286,22 +311,28 @@ print(v1.<?bar1?>) TEST [[ ---@class A -local <!t!> +local t + +t.<!x!> = 1 ---@type A[] local b -local <?<!c!>?> = b[1] +local c = b[1] +c.<?x?> ]] TEST [[ ---@class A -local <!t!> +local t + +t.<!x!> = 1 ----@type table<number, A> +---@type { [number]: A } local b -local <?<!c!>?> = b[1] +local c = b[1] +c.<?x?> ]] TEST [[ @@ -309,7 +340,7 @@ TEST [[ local Foo = {} function Foo:<!bar1!>() end ----@type table<number, Foo> +---@type { [number]: Foo } local v1 print(v1[1].<?bar1?>) ]] @@ -323,7 +354,7 @@ function Foo:<!bar1!>() end local Foo2 = {} function Foo2:bar1() end ----@type Foo2<number, Foo> +---@type { [number]: Foo } local v1 print(v1[1].<?bar1?>) ]] @@ -355,16 +386,16 @@ TEST [[ ---@type fun(x: T):T local f -local <?<!v2!>?> = f(<!{}!>) +local <?<!v2!>?> = f(<!function () end!>) ]] TEST [[ ---@generic T ---@param x T ---@return fun():T -local function f(<!x!>) end +local function f(x) end -local v1 = f(<!{}!>) +local v1 = f(<!function () end!>) local <?<!v2!>?> = v1() ]] @@ -373,7 +404,7 @@ TEST [[ ---@type fun(x: T):fun():T local f -local v1 = f(<!{}!>) +local v1 = f(<!function () end!>) local <?<!v2!>?> = v1() ]] @@ -383,7 +414,7 @@ TEST [[ local function f(x) end local v1 = f() -local <?<!v2!>?> = v1(<!{}!>) +local <?<!v2!>?> = v1(<!function () end!>) ]] TEST [[ @@ -393,72 +424,150 @@ TEST [[ local function f(x) end ---@class A -local <!a!> +local a +a.<!x!> = 1 ---@type A[] local b -local <?<!c!>?> = f(b) +local c = f(b) +c.<?x?> ]] TEST [[ ---@generic V ----@param x table<number, V> +---@param x { [number]: V } ---@return V local function f(x) end ---@class A -local <!a!> +local a +a.<!x!> = 1 ----@type table<number, A> +---@type { [number]: A } local b -local <?<!c!>?> = f(b) +local c = f(b) +c.<?x?> ]] TEST [[ ---@generic V ----@param x V[] +---@param x { [number]: V } ---@return V local function f(x) end ---@class A -local <!a!> +local a +a.<!x!> = 1 ----@type table<number, A> +---@type { [integer]: A } local b -local <?<!c!>?> = f(b) +local c = f(b) +c.<?x?> ]] TEST [[ ---@generic V ----@param x table<number, V> +---@param x { [integer]: V } ---@return V local function f(x) end ---@class A -local <!a!> +local a +a.x = 1 + +---@type { [number]: A } +local b + +local c = f(b) +c.<?x?> +]] + +TEST [[ +---@generic V +---@param x { [number]: V } +---@return V +local function f(x) end + +---@class A +local a +a.<!x!> = 1 ---@type A[] local b -local <?<!c!>?> = f(b) +local c = f(b) +c.<?x?> ]] TEST [[ ---@generic K ----@param x table<K, number> +---@param x { [K]: number } ---@return K local function f(x) end ---@class A -local <!a!> +local a +a.<!x!> = 1 ----@type table<A, number> +---@type { [A]: number } local b -local <?<!c!>?> = f(b) +local c = f(b) +c.<?x?> +]] + +TEST [[ +---@generic K +---@param x { [K]: A } +---@return K +local function f(x) end + +---@class A +local a +a.x = 1 + +---@type A[] +local b + +local c = f(b) +c.<?x?> +]] + +TEST [[ +---@generic K +---@param x { [K]: number } +---@return K +local function f(x) end + +---@class A +local a +a.<!x!> = 1 + +---@type { [A]: integer } +local b + +local c = f(b) +c.<?x?> +]] + +TEST [[ +---@generic K +---@param x { [K]: integer } +---@return K +local function f(x) end + +---@class A +local a +a.x = 1 + +---@type { [A]: number } +local b + +local c = f(b) +c.<?x?> ]] TEST [[ @@ -466,9 +575,6 @@ TEST [[ ---@return fun(t: V[]):V local function f() end ----@class A -local <!a!> - ---@type A[] local b @@ -485,59 +591,95 @@ TEST [[ local function f(t) end ---@class A -local <!a!> +local a +a.<!x!> = 1 ---@type A[] local b local f2, c = f(b) -local <?<!d!>?> = f2(c) +local d = f2(c) +d.<?x?> ]] TEST [[ ----@class C -local <!v1!> - ---@generic V, T ---@param t T ---@return fun(t: V): V ---@return T local function iterator(t) end -for <!v!> in iterator(<!v1!>) do +for <!v!> in iterator(<!function () end!>) do print(<?v?>) end ]] TEST [[ ----@class C -local <!v!> +---@alias C <!fun()!> ----@type C -local <!v1!> +---@type C[] +local v1 ---@generic V, T ---@param t T ----@return fun(t: V): V +---@return fun(t: V[]): V ---@return T local function iterator(t) end -for <!v!> in iterator(<!v1!>) do +for <!v!> in iterator(v1) do print(<?v?>) end ]] TEST [[ ----@class C -local <!v!> +---@class TT<V>: { <!x: V!> } ----@type C[] +---@type TT<A> +local t + +---@class A: <!{}!> + +print(t.<?x?>) +]] + +TEST [[ +---@alias TT<V> { <!x: V!> } + +---@type TT<A> +local t + +---@class A: <!{}!> + +print(t.<?x?>) +]] + +TEST [[ +---@class TT<V>: { [number]: V } + +---@type TT<<!{}!>> local v1 ---@generic V, T ---@param t T ----@return fun(t: V[]): V +---@return fun(t: { [number]: V }): V +---@return T +local function iterator(t) end + +for <!v!> in iterator(v1) do + print(<?v?>) +end +]] + +TEST [[ +---@class TT<K, V>: { [K]: V } + +---@type TT<number, <!{}!>> +local v1 + +---@generic V, T +---@param t T +---@return fun(t: { [number]: V }): V ---@return T local function iterator(t) end @@ -551,12 +693,32 @@ TEST [[ local Foo = {} function Foo:<!bar1!>() end +---@type { [number]: Foo } +local v1 + +---@generic T: table, V +---@param t T +---@return fun(table: { [number]: V }, i?: integer):integer, V +---@return T +---@return integer i +local function ipairs(t) end + +for i, v in ipairs(v1) do + print(v.<?bar1?>) +end +]] + +TEST [[ +---@class Foo +local Foo = {} +function Foo:<!bar1!>() end + ---@type table<number, Foo> local v1 ---@generic T: table, V ---@param t T ----@return fun(table: V[], i?: integer):integer, V +---@return fun(table: { [number]: V }, i?: integer):integer, V ---@return T ---@return integer i local function ipairs(t) end @@ -615,7 +777,7 @@ function Foo:<!bar1!>() end ---@generic T: table, V ---@param t T ----@return fun(table: V[], i?: integer):integer, V +---@return fun(table: table<number, V>, i?: integer):integer, V ---@return T ---@return integer i local function ipairs(t) end @@ -660,22 +822,22 @@ print(t.<?x?>) TEST [[ ---@class A ----@field <![1]!>? boolean +---@field [1]? <!{}!> local t -print(t[<?1?>]) +local <!<?v?>!> = t[1] ]] TEST [[ ----@type { <![1]?: boolean!> } +---@type { [1]?: <!{}!> } local t -print(t[<?1?>]) +local <!<?v?>!> = t[1] ]] TEST [[ ---@class A ----@field <!['xx']!>? boolean +---@field <!['xx']!>? <!{}!> local t print(t.<?xx?>) diff --git a/test/definition/special.lua b/test/definition/special.lua index 3f0d076a..531c5d93 100644 --- a/test/definition/special.lua +++ b/test/definition/special.lua @@ -32,24 +32,28 @@ local obj = setmetatable({}, { __index = mt }) obj:<?method1?>() ]] -TEST [[ -local mt -function mt:<!method1!>() -end - -setmetatable(api, { __index = mt }) -api:<?method1?>() -]] +-- 不再支持在变量的引用中使用 setmetatable 操作。 +-- 这会将引用转换为定义,为了搜索定义去检查引用性价比太差了。 +-- 如果有必要,请使用 ---@class 系统。 -TEST [[ -local mt -local api -function mt:<!method1!>() -end +--TEST [[ +--local mt +--function mt:<!method1!>() +--end +-- +--setmetatable(api, { __index = mt }) +--api:<?method1?>() +--]] -setmetatable(api, { __index = mt }) -api:<?method1?>() -]] +--TEST [[ +--local mt +--local api +--function mt:<!method1!>() +--end +-- +--setmetatable(api, { __index = mt }) +--api:<?method1?>() +--]] -- TODO 不支持从方法内部找外部的赋值 --TEST [[ diff --git a/test/definition/table.lua b/test/definition/table.lua index 61e8746d..66e71b0c 100644 --- a/test/definition/table.lua +++ b/test/definition/table.lua @@ -134,32 +134,44 @@ local y = { t.<?insert?>() ]] + +TEST [[ +local x +x.y.<!z!> = 1 +print(x.y.<?z?>) +]] + + +TEST [[ +local x +x.y = { + <!z!> = 1 +} +print(x.y.<?z?>) +]] + +TEST [[ +local x = { + y = { + <!z!> = 1 + } +} +print(x.y.<?z?>) +]] + TEST [[ local function f() - local t = {} - t.field1 = { + local t = { <!x!> = 1, - y = 1, - z = 1, - } - t.field2 = { - x = 1, - y = 1, - z = 1, - } - t.field3 = { - x = 1, - y = 1, - z = 1, } return t end local t = f() -t.field1.<?x?> +t.<?x?> ]] -TEST [[ -local t = { <!a!> } - -print(t[<?1?>]) -]] +--TEST [[ +--local t = { <!a!> } +-- +--print(t[<?1?>]) +--]] diff --git a/test/diagnostics/common.lua b/test/diagnostics/common.lua new file mode 100644 index 00000000..6aa1dd6a --- /dev/null +++ b/test/diagnostics/common.lua @@ -0,0 +1,1389 @@ +local config = require 'config' + +TEST [[ +local <!x!> +]] + +TEST [[ +local y +local x <close> = y +]] + +TEST [[ +local function x() +end +x() +]] + +TEST [[ +return function (x) + x.a = 1 +end +]] + +TEST [[ +local <!t!> = {} +<!t!>.a = 1 +]] + +TEST [[ +local <!function <!x!>() +end!> +]] + + +TEST [[ +local <!x!> = <!function () end!> +]] + +TEST [[ +local <!x!> +<!x!> = <!function () end!> +]] + +TEST [[ +local <!function x() +end!> +local <!function <!y!>() + x() +end!> +]] + +TEST [[ +local print, _G +print(<!x!>) +print(<!log!>) +print(<!X!>) +print(<!Log!>) +print(<!y!>) +print(Z) +print(_G) +Z = 1 +]] + +TEST [[ +::<!LABEL!>:: +]] + +TEST [[ +<! !> +]] + +TEST [[ + +<! !> +]] + +TEST [[ +X = 1<! !> +]] + +TEST [[ +X = [=[ + ]=] +]] + +TEST [[ +local x +print(x) +local <!x!> +print(x) +]] + +TEST [[ +local x +print(x) +local <!x!> +print(x) +local <!x!> +print(x) +]] + +TEST [[ +local _ +print(_) +local _ +print(_) +local _ENV +<!print!>(_ENV) -- 由于重定义了_ENV,因此print变为了未定义全局变量 +]] + +TEST [[ +local x +return x, function (<!x!>) + return x +end +]] + +TEST [[ +print(1) +_ENV = nil +]] + +TEST [[ +local _ENV = { print = print } +print(1) +]] + +config.get(nil, 'Lua.diagnostics.disable')['undefined-env-child'] = true +TEST [[ +_ENV = nil +<!GLOBAL!> = 1 --> _ENV.GLOBAL = 1 +]] + +TEST [[ +_ENV = nil +local _ = <!print!> --> local _ = _ENV.print +]] + +TEST [[ +_ENV = {} +GLOBAL = 1 --> _ENV.GLOBAL = 1 +]] + +TEST [[ +_ENV = {} +local _ = print --> local _ = _ENV.print +]] + +TEST [[ +GLOBAL = 1 +_ENV = nil +]] + +config.get(nil, 'Lua.diagnostics.disable')['undefined-env-child'] = nil +TEST [[ +<!print() +('string')!>:sub(1, 1) +]] + +TEST [[ +print() +('string') +]] + +TEST [[ +pairs +{} +{} +]] + +TEST [[ +local x +return x + : f(1) + : f(1) +]] + +TEST [[ +return { + <!print + 'string'!> +} +]] + +TEST [[ +return { + <!print + { + x = 1, + }!> +} +]] + +TEST [[ +print() +'string' +]] + +TEST [[ +print +{ + x = 1, +} +]] + +TEST [[ +local function x(a, b) + return a, b +end +x(1, 2, <!3!>) +]] + +TEST [[ +local function x(a, b, ...) + return a, b, ... +end +x(1, 2, 3, 4, 5) +]] + +TEST [[ +local m = {} +function m:x(a, b) + return a, b +end +m:x(1, 2, <!3!>) +]] + +TEST [[ +local m = {} +function m:x(a, b) + return a, b +end +m.x(1, 2, 3, <!4!>) +]] + +TEST [[ +local m = {} +function m.x(a, b) + return a, b +end +m:x(1, <!2!>, <!3!>, <!4!>) +]] + +TEST [[ +local m = {} +function m.x() +end +m:x() +]] + +TEST [[ +InstanceName = 1 +Instance = _G[InstanceName] +]] + +TEST [[ +local _ = (''):sub(1, 2) +]] + +TEST [=[ +return [[ + +]] +]=] + +config.get(nil, 'Lua.diagnostics.disable')['close-non-object'] = true +TEST [[ +local _ <close> = function () end +]] + +config.get(nil, 'Lua.diagnostics.disable')['close-non-object'] = nil +TEST [[ +local _ <close> = <!1!> +]] + +config.get(nil, 'Lua.diagnostics.disable')['unused-local'] = true +TEST [[ +local f = <!function () end!> +]] + +TEST [[ +local f;f = <!function () end!> +]] + +TEST [[ +local <!function f() end!> +]] + +config.get(nil, 'Lua.diagnostics.disable')['unused-local'] = nil +TEST [[ +local mt, x +function mt:m() + function x:m() + end +end +return mt, x +]] + +TEST [[ +local mt = {} +function mt:f() +end +return mt +]] + +TEST [[ +local <!mt!> = {} +function <!mt!>:f() +end +]] + +TEST [[ +local <!x!> = {} +<!x!>.a = 1 +]] + +TEST [[ +local <!x!> = {} +<!x!>['a'] = 1 +]] + +TEST [[ +local function f(<!self!>) +end +f() +]] + +TEST [[ +local function f(<!...!>) +end +f() +]] + +TEST [[ +local function f(var) + print(var) +end +local var +f(var) +]] + +TEST [[ +local function f(a, b) + return a, b +end +f(1, 2, <!3!>, <!4!>) +]] + +TEST [[ +local mt = {} +function mt:f(a, b) + return a, b +end +mt.f(1, 2, 3, <!4!>) +]] + + +TEST [[ +local mt = {} +function mt.f(a, b) + return a, b +end +mt:f(1, <!2!>, <!3!>, <!4!>) +]] + +TEST [[ +local mt = {} +function mt:f(a, b) + return a, b +end +mt:f(1, 2, <!3!>, <!4!>) +]] + +TEST [[ +local function f(a, b, ...) + return a, b, ... +end +f(1, 2, 3, 4) +]] + +TEST [[ +local _ = next({}, 1, <!2!>) +print(1, 2, 3, 4, 5) +]] + +TEST [[ +local function f(callback) + callback(1, 2, 3) +end +f(function () end) +]] + +--TEST [[ +--local realTostring = tostring +--tostring = function () end +--tostring(<!1!>) +--tostring = realTostring +--tostring(1) +--]] + +TEST [[ +<!aa!> = 1 +tostring = 1 +ROOT = 1 +_G.bb = 1 +]] + +TEST [[ +local f = load('') +f(1, 2, 3) +]] + +TEST [[ +local _ = <!unpack!>() +]] + +TEST [[ +X = table[<!x!>] +]] + +TEST [[ +return { + <!x!> = 1, + y = 2, + <!x!> = 3, +} +]] + +TEST [[ +return { + x = 1, + y = 2, +}, { + x = 1, + y = 2, +} +]] + +TEST [[ +local m = {} +function m.open() +end + +m:open() +]] + +TEST [[ +local m = {} +function m:open() +end + +m.open('ok') +]] + +TEST [[ +<!if true then +end!> +]] + +TEST [[ +<!if true then +else +end!> +]] + +TEST [[ +if true then +else + return +end +]] + +TEST [[ +while true do +end +]] + +TEST [[ +<!for _ = 1, 10 do +end!> +]] + +TEST [[ +<!for _ in pairs(_VERSION) do +end!> +]] + +TEST [[ +local _ = 1, <!2!> +]] + +TEST [[ +_ = 1, <!2!> +]] + +TEST [[ +local function x() + do + local k + print(k) + x() + end + local k = 1 + print(k) +end +]] + +TEST [[ +local function x() + local loc + x() + print(loc) +end +]] + +TEST [[ +local <!t!> = {} +<!t!>[1] = 1 +]] + +TEST [[ +T1 = 1 +_ENV.T2 = 1 +_G.T3 = 1 +_ENV._G.T4 = 1 +_G._G._G.T5 = 1 +rawset(_G, 'T6', 1) +rawset(_ENV, 'T7', 1) +print(T1) +print(T2) +print(T3) +print(T4) +print(T5) +print(T6) +print(T7) +]] + +TEST [[ +local x +x = <!x or 0 + 1!> +]] + +TEST [[ +local x, y +x = <!x + y or 0!> +]] + +TEST [[ +local x, y, z +x = x and y or '' .. z +]] + +TEST [[ +local x +x = x or -1 +]] + +TEST [[ +local x +x = x or (0 + 1) +]] + +TEST [[ +local x, y +x = (x + y) or 0 +]] + +TEST [[ +local t = {} +t.a = 1 +t.a = 2 +return t +]] + +TEST [[ +table.insert({}, 1, 2, <!3!>) +]] + +TEST [[ +while true do + break + <!print() + print()!> +end +]] + +TEST [[ +local x, <!y!>, <!z!> = 1 +print(x, y, z) +]] + +TEST [[ +local x, y, <!z!> = 1, 2 +print(x, y, z) +]] + +TEST [[ +local x, y, z = print() +print(x, y, z) +]] + +TEST [[ +local x, y, z +print(x, y, z) +]] + +TEST [[ +local x, y, z +x, <!y!>, <!z!> = 1 +print(x, y, z) +]] + +TEST [[ +X, <!Y!>, <!Z!> = 1 +]] + +TEST [[ +T = {} +T.x, <!T.y!>, <!T.z!> = 1 +]] + +TEST [[ +T = {} +T['x'], <!T['y']!>, <!T['z']!> = 1 +]] + +--TEST [[ +-----@class <!Class!> +-----@class <!Class!> +--]] + +TEST [[ +---@alias <!A!> integer +---@alias <!A!> integer +]] + +TEST [[ +---@class A : <!B!> +]] + +TEST [[ +---@class <!A : B!> +---@class <!B : C!> +---@class <!C : D!> +---@class <!D : A!> +]] + +TEST [[ +---@class A : B +---@class B : C +---@class C : D +---@class D +]] + +TEST [[ +---@type <!A!> +]] + +TEST [[ +---@class A +---@type A|<!B!>|<!C!> +]] + +TEST [[ +---@class AAA +---@alias B AAA + +---@type B +]] + +TEST [[ +---@alias B <!AAA!> +]] + +TEST [[ +---@class A +---@class B +---@alias <!A!> B +]] + +TEST [[ +---@param x <!Class!> +]] + +TEST [[ +---@class Class +---@param <!y!> Class +local function f(x) + return x +end +f() +]] + +TEST [[ +---@class Class +---@param <!y!> Class +function F(x) + return x +end +F() +]] + +TEST [[ +---@class Class +---@param <!x!> Class +---@param y Class +---@param <!x!> Class +local function f(x, y) + return x, y +end +f() +]] + +TEST [[ +---@field <!x Class!> +---@class Class +]] + +TEST [[ +---@class Class + +---@field <!x Class!> +]] + +TEST [[ +---@class Class +--- +---@field x Class +]] + +TEST [[ +---@class Class +---@field x Class +---@field <!x!> Class +]] + +TEST [[ +---@class Class : any +]] + +TEST [[ +---@type fun(a: integer) +local f +f() +]] + +TEST [[ +---@class c +c = {} +]] + +TEST [[ +---@generic T: any +---@param v T +---@param message any +---@return T +function assert(v, message) + return v, message +end +]] + +TEST [[ +---@type string +---| +]] + +TEST [[ +---@type +---| 'xx' +]] + +TEST [[ +---@class class +local t +]] +---[==[ +-- checkUndefinedField 通用 +TEST [[ +---@class Foo +---@field field1 integer +local mt = {} +function mt:Constructor() + self.field2 = 1 +end +function mt:method1() return 1 end +function mt.method2() return 2 end + +---@class Bar: Foo +---@field field4 integer +local mt2 = {} + +---@type Foo +local v +print(v.field1 + 1) +print(v.<!field2!> + 1) +print(v.<!field3!> + 1) +print(v:method1()) +print(v.method2()) +print(v:<!method3!>()) + +---@type Bar +local v2 +print(v2.field1 + 1) +print(v2.<!field2!> + 1) +print(v2.<!field3!> + 1) +print(v2.field4 + 1) +print(v2:method1()) +print(v2.method2()) +print(v2:<!method3!>()) + +local v3 = {} +print(v3.abc) + +---@class Bar2 +local mt3 +function mt3:method() return 1 end +print(mt3:method()) +]] + +-- checkUndefinedField 通过type找到class +TEST [[ +---@class Foo +local Foo +function Foo:method1() end + +---@type Foo +local v +v:method1() +v:<!method2!>() -- doc.class.name +]] + +-- checkUndefinedField 通过type找到class,涉及到 class 继承版 +TEST [[ +---@class Foo +local Foo +function Foo:method1() end +---@class Bar: Foo +local Bar +function Bar:method3() end + +---@type Bar +local v +v:method1() +v:<!method2!>() -- doc.class.name +v:method3() +]] + +-- checkUndefinedField 类名和类变量同名,类变量被直接使用 +TEST [[ +---@class Foo +local Foo +function Foo:method1() end +Foo:<!method2!>() -- doc.class +Foo:<!method2!>() -- doc.class +]] + +-- checkUndefinedField 没有@class的不检测 +TEST [[ +local Foo +function Foo:method1() + return Foo:method2() -- table +end +]] + +-- checkUndefinedField 类名和类变量不同名,类变量被直接使用、使用self +TEST [[ +---@class Foo +local mt +function mt:method1() + mt.<!method2!>() -- doc.class + self.method1() + return self.<!method2!>() -- doc.class.name +end +]] + +-- checkUndefinedField 当会推导成多个class类型时 +TEST [[ +---@class Foo +local mt +function mt:method1() end + +---@class Bar +local mt2 +function mt2:method2() end + +---@type Foo +local v +---@type Bar +local v2 +v2 = v -- TODO 这里应该给警告 +v2:<!method1!>() +v2:method2() +]] + +TEST [[ +---@type table +T1 = {} +print(T1.f1) +---@type tablelib +T2 = {} +print(T2.<!f2!>) +]] +--]==] +TEST [[ +---@overload fun(...) +local function f() end + +f(1) +]] + +TEST [[ +for i = <!10, 1!> do + print(i) +end +]] + +TEST [[ +for i = <!10, 1, 5!> do + print(i) +end +]] + +TEST [[ +for i = 1, 1 do + print(i) +end +]] + +TEST [[ +---@param a number +return function (<!a!>) +end +]] + +TEST [[ +---@meta + +---@param a number +return function (a) +end +]] + +TEST [[ +local m = {} + +function <!m:fff!>() +end + +function <!m:fff!>() +end + +return m +]] + +TEST [[ +local m = {} + +function m:fff() +end + +do + function m:fff() + end +end + +return m +]] + +TEST [[ +local m = {} + +m.x = true +m.x = false + +return m +]] + +TEST [[ +local m = {} + +m.x = io.open() +m.x = nil + +return m +]] + +TEST [[ +---@class A +---@field a boolean + +---@return A +local function f() end + +local r = f() +r.x = 1 + +return r.x +]] + +TEST [[ +---@diagnostic disable-next-line +x = 1 +]] + +TEST [[ +---@diagnostic disable-next-line: lowercase-global +x = 1 +]] + +TEST [[ +---@diagnostic disable-next-line: unused-local +<!x!> = 1 +]] + +TEST [[ +---@diagnostic disable +x = 1 +]] + +TEST [[ +---@diagnostic disable +---@diagnostic enable +<!x!> = 1 +]] + +TEST [[ +---@diagnostic disable +---@diagnostic disable +---@diagnostic enable +x = 1 +]] + +TEST [[ +---@diagnostic disable-next-line: <!xxx!> +]] + +TEST [[ +local mt = {} + +function mt:a(x) + return self, x +end + +function mt:b(y) + self:a(1):b(2) + return y +end + +return mt +]] + +TEST [[ +local function each() + return function () + end +end + +for x in each() do + print(x) +end +]] + +TEST [[ +---@type string +local s + +print(s:upper()) +]] + +TEST [[ +local t = (). +return t +]] + +TEST [[ +return { + [1] = 1, + ['1'] = 1, +} +]] + +TEST [[ +return { + [print()] = 1, + [print()] = 1, +} +]] + +TEST [[ +---@type { x: number, y: number} +---| "'resume'" +]] + +TEST [[ +return { + 1, <!2!>, 3, + [<!2!>] = 4, +} +]] + +TEST [[ +--- @class Emit +--- @field on fun(eventName: string, cb: function) +--- @field on fun(eventName: '"died"', cb: fun(i: integer)) +--- @field on fun(eventName: '"won"', cb: fun(s: string)) +local emit = {} +]] + +TEST [[ +--- @class Emit +--- @field on fun(eventName: string, cb: function) +--- @field on fun(eventName: '"died"', cb: fun(i: integer)) +--- @field on fun(eventName: '"won"', cb: fun(s: string)) +--- @field <!on!> fun(eventName: '"died"', cb: fun(i: integer)) +local emit = {} +]] + +-- redundant-return +TEST [[ +local function f() + <!return!> +end +f() +]] + +TEST [[ +local function f() + return nil +end +f() +]] + +TEST [[ +local function f() + local function x() + <!return!> + end + x() + return true +end +f() +]] + +TEST [[ +local function f() + local function x() + return true + end + return x() +end +f() +]] + +TEST [[ +---@type file* +local f +local _ = f:read '*a' +local _ = f:read('*a') +]] + +TEST [[ +function F() + <!coroutine.yield!>() +end +]] + +TEST [[ +---@async +function F() + coroutine.yield() +end +]] + +TEST [[ +---@type async fun() +local f + +function F() + <!f!>() +end +]] + +TEST [[ +---@type async fun() +local f + +---@async +function F() + f() +end +]] + +TEST [[ +local function f(cb) + cb() +end + +<!f!>(function () ---@async + return nil +end) +]] + +TEST [[ +local function f(cb) + pcall(cb) +end + +<!f!>(function () ---@async + return nil +end) +]] + +TEST [[ +---@param c any +local function f(c) + return c +end + +f(function () ---@async + return nil +end) +]] + +TEST [[ +---@param ... any +local function f(...) + return ... +end + +f(function () ---@async + return nil +end) +]] + +TEST [[ +---@vararg any +local function f(...) + return ... +end + +f(function () ---@async + return nil +end) +]] + +TEST [[ +local function f(...) + return ... +end + +f(function () ---@async + return nil +end) +]] + +TEST [[ +local function f(...) + return ... +end + +f(1, function () ---@async + return nil +end) +]] + +TEST [[ +---@nodiscard +local function f() + return 1 +end + +<!f()!> +]] + +TEST [[ +---@nodiscard +local function f() + return 1 +end + +X = f() +]] + +config.get(nil, 'Lua.diagnostics.neededFileStatus')['not-yieldable'] = 'Any' +TEST [[ +---@param cb fun() +local function f(cb) + return cb +end + +---@async +local function af() + return nil +end + +f(<!af!>) +]] + +TEST [[ +---@param cb async fun() +local function f(cb) + return cb +end + +---@async +local function af() + return nil +end + +f(af) +]] + +TEST [[ +local function f(cb) + cb() +end + +local function af() + <!f!>(function () ---@async + return nil + end) +end + +return af +]] + +TEST [[ +local function f(cb) + cb() +end + +---@async +local function af() + f(function () ---@async + return nil + end) +end + +return af +]] + +TEST [[ +local _ = type(function () ---@async + return nil +end) +]] + +TEST [[ +---@param ... number +local function f(...) + return ... +end + +return f +]] + +TEST [[ +---@type fun(...: string) +]] + +TEST [[ +---@type fun(xxx, yyy, ...): boolean +]] + +TEST [[ +local <!x!> + +return { + x = 1, +} +]] + +TEST [[ +---@class A #1 +]] + +TEST [[ +---@class A 1 +]] + +TEST [[ +return ('1'):gsub() +]] + +TEST [[ +local value +value = '1' +value = value:gsub() +]] diff --git a/test/diagnostics/init.lua b/test/diagnostics/init.lua index 58414b60..75d9da6c 100644 --- a/test/diagnostics/init.lua +++ b/test/diagnostics/init.lua @@ -43,1543 +43,11 @@ function TEST(script, ...) error(('%s\n%s'):format(util.dump(catched['!']), util.dump(results))) end else - assert(catched['!'] == nil) + assert(#catched['!'] == 0) end files.remove('') end -TEST [[ -local <!x!> -]] - -TEST [[ -local y -local x <close> = y -]] - -TEST [[ -local function x() -end -x() -]] - -TEST [[ -return function (x) - x.a = 1 -end -]] - -TEST [[ -local <!t!> = {} -<!t!>.a = 1 -]] - -TEST [[ -local <!function <!x!>() -end!> -]] - - -TEST [[ -local <!x!> = <!function () end!> -]] - -TEST [[ -local <!x!> -<!x!> = <!function () end!> -]] - -TEST [[ -local <!function x() -end!> -local <!function <!y!>() - x() -end!> -]] - -TEST [[ -local print, _G -print(<!x!>) -print(<!log!>) -print(<!X!>) -print(<!Log!>) -print(<!y!>) -print(Z) -print(_G) -Z = 1 -]] - -TEST [[ -::<!LABEL!>:: -]] - -TEST [[ -<! !> -]] - -TEST [[ - -<! !> -]] - -TEST [[ -X = 1<! !> -]] - -TEST [[ -X = [=[ - ]=] -]] - -TEST [[ -local x -print(x) -local <!x!> -print(x) -]] - -TEST [[ -local x -print(x) -local <!x!> -print(x) -local <!x!> -print(x) -]] - -TEST [[ -local _ -print(_) -local _ -print(_) -local _ENV -<!print!>(_ENV) -- 由于重定义了_ENV,因此print变为了未定义全局变量 -]] - -TEST [[ -local x -return x, function (<!x!>) - return x -end -]] - -TEST [[ -print(1) -_ENV = nil -]] - -TEST [[ -local _ENV = { print = print } -print(1) -]] - -config.get(nil, 'Lua.diagnostics.disable')['undefined-env-child'] = true -TEST [[ -_ENV = nil -<!GLOBAL!> = 1 --> _ENV.GLOBAL = 1 -]] - -TEST [[ -_ENV = nil -local _ = <!print!> --> local _ = _ENV.print -]] - -TEST [[ -_ENV = {} -GLOBAL = 1 --> _ENV.GLOBAL = 1 -]] - -TEST [[ -_ENV = {} -local _ = print --> local _ = _ENV.print -]] - -TEST [[ -GLOBAL = 1 -_ENV = nil -]] - -config.get(nil, 'Lua.diagnostics.disable')['undefined-env-child'] = nil -TEST [[ -<!print() -('string')!>:sub(1, 1) -]] - -TEST [[ -print() -('string') -]] - -TEST [[ -pairs -{} -{} -]] - -TEST [[ -local x -return x - : f(1) - : f(1) -]] - -TEST [[ -return { - <!print - 'string'!> -} -]] - -TEST [[ -return { - <!print - { - x = 1, - }!> -} -]] - -TEST [[ -print() -'string' -]] - -TEST [[ -print -{ - x = 1, -} -]] - -TEST [[ -local function x(a, b) - return a, b -end -x(1, 2, <!3!>) -]] - -TEST [[ -local function x(a, b, ...) - return a, b, ... -end -x(1, 2, 3, 4, 5) -]] - -TEST [[ -local m = {} -function m:x(a, b) - return a, b -end -m:x(1, 2, <!3!>) -]] - -TEST [[ -local m = {} -function m:x(a, b) - return a, b -end -m.x(1, 2, 3, <!4!>) -]] - -TEST [[ -local m = {} -function m.x(a, b) - return a, b -end -m:x(1, <!2!>, <!3!>, <!4!>) -]] - -TEST [[ -local m = {} -function m.x() -end -m:x() -]] - -TEST [[ -InstanceName = 1 -Instance = _G[InstanceName] -]] - -TEST [[ -local _ = (''):sub(1, 2) -]] - -TEST [=[ -return [[ - -]] -]=] - -config.get(nil, 'Lua.diagnostics.disable')['close-non-object'] = true -TEST [[ -local _ <close> = function () end -]] - -config.get(nil, 'Lua.diagnostics.disable')['close-non-object'] = nil -TEST [[ -local _ <close> = <!1!> -]] - -config.get(nil, 'Lua.diagnostics.disable')['unused-local'] = true -TEST [[ -local f = <!function () end!> -]] - -TEST [[ -local f;f = <!function () end!> -]] - -TEST [[ -local <!function f() end!> -]] - -config.get(nil, 'Lua.diagnostics.disable')['unused-local'] = nil -TEST [[ -local mt, x -function mt:m() - function x:m() - end -end -return mt, x -]] - -TEST [[ -local mt = {} -function mt:f() -end -return mt -]] - -TEST [[ -local <!mt!> = {} -function <!mt!>:f() -end -]] - -TEST [[ -local <!x!> = {} -<!x!>.a = 1 -]] - -TEST [[ -local <!x!> = {} -<!x!>['a'] = 1 -]] - -TEST [[ -local function f(<!self!>) -end -f() -]] - -TEST [[ -local function f(<!...!>) -end -f() -]] - -TEST [[ -local function f(var) - print(var) -end -local var -f(var) -]] - -TEST [[ -local function f(a, b) - return a, b -end -f(1, 2, <!3!>, <!4!>) -]] - -TEST [[ -local mt = {} -function mt:f(a, b) - return a, b -end -mt.f(1, 2, 3, <!4!>) -]] - - -TEST [[ -local mt = {} -function mt.f(a, b) - return a, b -end -mt:f(1, <!2!>, <!3!>, <!4!>) -]] - -TEST [[ -local mt = {} -function mt:f(a, b) - return a, b -end -mt:f(1, 2, <!3!>, <!4!>) -]] - -TEST [[ -local function f(a, b, ...) - return a, b, ... -end -f(1, 2, 3, 4) -]] - -TEST [[ -local _ = next({}, 1, <!2!>) -print(1, 2, 3, 4, 5) -]] - -TEST [[ -local function f(callback) - callback(1, 2, 3) -end -f(function () end) -]] - ---TEST [[ ---local realTostring = tostring ---tostring = function () end ---tostring(<!1!>) ---tostring = realTostring ---tostring(1) ---]] - -TEST [[ -<!aa!> = 1 -tostring = 1 -ROOT = 1 -_G.bb = 1 -]] - -TEST [[ -local f = load('') -f(1, 2, 3) -]] - -TEST [[ -local _ = <!unpack!>() -]] - -TEST [[ -X = table[<!x!>] -]] - -TEST [[ -return { - <!x!> = 1, - y = 2, - <!x!> = 3, -} -]] - -TEST [[ -return { - x = 1, - y = 2, -}, { - x = 1, - y = 2, -} -]] - -TEST [[ -local m = {} -function m.open() -end - -m:open() -]] - -TEST [[ -local m = {} -function m:open() -end - -m.open('ok') -]] - -TEST [[ -<!if true then -end!> -]] - -TEST [[ -<!if true then -else -end!> -]] - -TEST [[ -if true then -else - return -end -]] - -TEST [[ -while true do -end -]] - -TEST [[ -<!for _ = 1, 10 do -end!> -]] - -TEST [[ -<!for _ in pairs(_VERSION) do -end!> -]] - -TEST [[ -local _ = 1, <!2!> -]] - -TEST [[ -_ = 1, <!2!> -]] - -TEST [[ -local function x() - do - local k - print(k) - x() - end - local k = 1 - print(k) -end -]] - -TEST [[ -local function x() - local loc - x() - print(loc) -end -]] - -TEST [[ -local <!t!> = {} -<!t!>[1] = 1 -]] - -TEST [[ -T1 = 1 -_ENV.T2 = 1 -_G.T3 = 1 -_ENV._G.T4 = 1 -_G._G._G.T5 = 1 -rawset(_G, 'T6', 1) -rawset(_ENV, 'T7', 1) -print(T1) -print(T2) -print(T3) -print(T4) -print(T5) -print(T6) -print(T7) -]] - -TEST [[ -local x -x = <!x or 0 + 1!> -]] - -TEST [[ -local x, y -x = <!x + y or 0!> -]] - -TEST [[ -local x, y, z -x = x and y or '' .. z -]] - -TEST [[ -local x -x = x or -1 -]] - -TEST [[ -local x -x = x or (0 + 1) -]] - -TEST [[ -local x, y -x = (x + y) or 0 -]] - -TEST [[ -local t = {} -t.a = 1 -t.a = 2 -return t -]] - -TEST [[ -table.insert({}, 1, 2, <!3!>) -]] - -TEST [[ -while true do - break - <!print() - print()!> -end -]] - -TEST [[ -local x, <!y!>, <!z!> = 1 -print(x, y, z) -]] - -TEST [[ -local x, y, <!z!> = 1, 2 -print(x, y, z) -]] - -TEST [[ -local x, y, z = print() -print(x, y, z) -]] - -TEST [[ -local x, y, z -print(x, y, z) -]] - -TEST [[ -local x, y, z -x, <!y!>, <!z!> = 1 -print(x, y, z) -]] - -TEST [[ -X, <!Y!>, <!Z!> = 1 -]] - -TEST [[ -T = {} -T.x, <!T.y!>, <!T.z!> = 1 -]] - -TEST [[ -T = {} -T['x'], <!T['y']!>, <!T['z']!> = 1 -]] - ---TEST [[ ------@class <!Class!> ------@class <!Class!> ---]] - -TEST [[ ----@class A : <!B!> -]] - -TEST [[ ----@class <!A : B!> ----@class <!B : C!> ----@class <!C : D!> ----@class <!D : A!> -]] - -TEST [[ ----@class A : B ----@class B : C ----@class C : D ----@class D -]] - -TEST [[ ----@type <!A!> -]] - -TEST [[ ----@class A ----@type A|<!B!>|<!C!> -]] - -TEST [[ ----@class AAA ----@alias B AAA - ----@type B -]] - -TEST [[ ----@alias B <!AAA!> -]] - -TEST [[ ----@class A ----@class B ----@alias <!A B!> -]] - -TEST [[ ----@param x <!Class!> -]] - -TEST [[ ----@class Class ----@param <!y!> Class -local function f(x) - return x -end -f() -]] - -TEST [[ ----@class Class ----@param <!y!> Class -function F(x) - return x -end -F() -]] - -TEST [[ ----@class Class ----@param <!x!> Class ----@param y Class ----@param <!x!> Class -local function f(x, y) - return x, y -end -f() -]] - -TEST [[ ----@field <!x Class!> ----@class Class -]] - -TEST [[ ----@class Class - ----@field <!x Class!> -]] - -TEST [[ ----@class Class ---- ----@field x Class -]] - -TEST [[ ----@class Class ----@field x Class ----@field <!x!> Class -]] - -TEST [[ ----@class Class : any -]] - -TEST [[ ----@type fun(a: integer) -local f -f() -]] - -TEST [[ ----@class c -c = {} -]] - -TEST [[ ----@generic T: any ----@param v T ----@param message any ----@return T -function assert(v, message) - return v, message -end -]] - -TEST [[ ----@type string ----| -]] - -TEST [[ ----@type ----| 'xx' -]] - -TEST [[ ----@class class -local t -]] ----[==[ --- checkUndefinedField 通用 -TEST [[ ----@class Foo ----@field field1 integer -local mt = {} -function mt:Constructor() - self.field2 = 1 -end -function mt:method1() return 1 end -function mt.method2() return 2 end - ----@class Bar: Foo ----@field field4 integer -local mt2 = {} - ----@type Foo -local v -print(v.field1 + 1) -print(v.field2 + 1) -print(v.<!field3!> + 1) -print(v:method1()) -print(v.method2()) -print(v:<!method3!>()) - ----@type Bar -local v2 -print(v2.field1 + 1) -print(v2.field2 + 1) -print(v2.<!field3!> + 1) -print(v2.field4 + 1) -print(v2:method1()) -print(v2.method2()) -print(v2:<!method3!>()) - -local v3 = {} -print(v3.abc) - ----@class Bar2 -local mt3 -function mt3:method() return 1 end -print(mt3:method()) -]] - --- checkUndefinedField 通过type找到class -TEST [[ ----@class Foo -local Foo -function Foo:method1() end - ----@type Foo -local v -v:method1() -v:<!method2!>() -- doc.class.name -]] - --- checkUndefinedField 通过type找到class,涉及到 class 继承版 -TEST [[ ----@class Foo -local Foo -function Foo:method1() end ----@class Bar: Foo -local Bar -function Bar:method3() end - ----@type Bar -local v -v:method1() -v:<!method2!>() -- doc.class.name -v:method3() -]] - --- checkUndefinedField 类名和类变量同名,类变量被直接使用 -TEST [[ ----@class Foo -local Foo -function Foo:method1() end -Foo:<!method2!>() -- doc.class -Foo:<!method2!>() -- doc.class -]] - --- checkUndefinedField 没有@class的不检测 -TEST [[ -local Foo -function Foo:method1() - return Foo:method2() -- table -end -]] - --- checkUndefinedField 类名和类变量不同名,类变量被直接使用、使用self -TEST [[ ----@class Foo -local mt -function mt:method1() - mt.<!method2!>() -- doc.class - self.method1() - return self.<!method2!>() -- doc.class.name -end -]] - --- checkUndefinedField 当会推导成多个class类型时 -TEST [[ ----@class Foo -local mt -function mt:method1() end - ----@class Bar -local mt2 -function mt2:method2() end - ----@type Foo -local v ----@type Bar -local v2 -v2 = v -- TODO 这里应该给警告 -v2:<!method1!>() -v2:method2() -]] - -TEST [[ ----@type table -T1 = {} -print(T1.f1) ----@type tablelib -T2 = {} -print(T2.<!f2!>) -]] ---]==] -TEST [[ ----@overload fun(...) -local function f() end - -f(1) -]] - -TEST [[ -for i = <!10, 1!> do - print(i) -end -]] - -TEST [[ -for i = <!10, 1, 5!> do - print(i) -end -]] - -TEST [[ -for i = 1, 1 do - print(i) -end -]] - -TEST [[ ----@param a number -return function (<!a!>) -end -]] - -TEST [[ ----@meta - ----@param a number -return function (a) -end -]] - -TEST [[ -local m = {} - -function <!m:fff!>() -end - -function <!m:fff!>() -end - -return m -]] - -TEST [[ -local m = {} - -function m:fff() -end - -do - function m:fff() - end -end - -return m -]] - -TEST [[ -local m = {} - -m.x = true -m.x = false - -return m -]] - -TEST [[ -local m = {} - -m.x = io.open() -m.x = nil - -return m -]] - -TEST [[ ----@class A ----@field a boolean - ----@return A -local function f() end - -local r = f() -r.x = 1 - -return r.x -]] - -TEST [[ ----@diagnostic disable-next-line -x = 1 -]] - -TEST [[ ----@diagnostic disable-next-line: lowercase-global -x = 1 -]] - -TEST [[ ----@diagnostic disable-next-line: unused-local -<!x!> = 1 -]] - -TEST [[ ----@diagnostic disable -x = 1 -]] - -TEST [[ ----@diagnostic disable ----@diagnostic enable -<!x!> = 1 -]] - -TEST [[ ----@diagnostic disable ----@diagnostic disable ----@diagnostic enable -x = 1 -]] - -TEST [[ ----@diagnostic disable-next-line: <!xxx!> -]] - -TEST [[ -local mt = {} - -function mt:a(x) - return self, x -end - -function mt:b(y) - self:a(1):b(2) - return y -end - -return mt -]] - -TEST [[ -local function each() - return function () - end -end - -for x in each() do - print(x) -end -]] - -TEST [[ ----@type string -local s - -print(s:upper()) -]] - -TEST [[ -local t = (). -return t -]] - -TEST [[ -return { - [1] = 1, - ['1'] = 1, -} -]] - -TEST [[ -return { - [print()] = 1, - [print()] = 1, -} -]] - -TEST [[ ----@type { x: number, y: number} ----| "'resume'" -]] - -TEST [[ -return { - 1, <!2!>, 3, - [<!2!>] = 4, -} -]] - -TEST [[ ---- @class Emit ---- @field on fun(eventName: string, cb: function) ---- @field on fun(eventName: '"died"', cb: fun(i: integer)) ---- @field on fun(eventName: '"won"', cb: fun(s: string)) -local emit = {} -]] - -TEST [[ ---- @class Emit ---- @field on fun(eventName: string, cb: function) ---- @field on fun(eventName: '"died"', cb: fun(i: integer)) ---- @field on fun(eventName: '"won"', cb: fun(s: string)) ---- @field <!on!> fun(eventName: '"died"', cb: fun(i: integer)) -local emit = {} -]] - -config.get(nil, 'Lua.diagnostics.neededFileStatus')['unused-local'] = 'None' -TEST [[ ----@param table table ----@param metatable table ----@return table -function Setmetatable(table, metatable) end - -Setmetatable(<!1!>, {}) -]] - -TEST [[ ----@param table table ----@param metatable table ----@return table -function Setmetatable(table, metatable) end - -Setmetatable(<!'name'!>, {}) - -]] - -TEST [[ ----@param table table ----@param metatable table ----@return table -function Setmetatable(table, metatable) end - ----@type table -local name ----@type function -local mt ----err -Setmetatable(name, <!mt!>) -]] - -TEST [[ ----@param p1 string ----@param p2 number ----@return table -local function func1(p1, p2) end - ----@type string -local s ----@type table -local t ----err -func1(s, <!t!>) -]] - -TEST [[ ----@class bird ----@field wing string - ----@class eagle ----@field family bird - ----@class chicken ----@field family bird - ----@param bd eagle -local function fly(bd) end - ----@type chicken -local h -fly(<!h!>) -]] - -TEST [[ ----@overload fun(x: number, y: number) ----@param x boolean ----@param y boolean -local function f(x, y) end - -f(true, true) -- OK -f(0, 0) -- OK - -]] - -TEST [[ ----@class bird -local m = {} -setmetatable(m, {}) -- OK -]] - -TEST [[ ----@class childString: string -local s ----@param name string -local function f(name) end -f(s) -]] - -TEST [[ ----@class childString: string - ----@type string -local s ----@param name childString -local function f(name) end -f(<!s!>) -]] - -TEST [[ ----@alias searchmode '"ref"'|'"def"'|'"field"'|'"allref"'|'"alldef"'|'"allfield"' - ----@param mode searchmode -local function searchRefs(mode)end -searchRefs('ref') -]] - -TEST [[ ----@class markdown -local mt = {} ----@param language string ----@param text string|markdown -function mt:add(language, text) - if not text then - return - end -end ----@type markdown -local desc - -desc:add('md', 'hover') -]] - ----可选参数和枚举 -TEST [[ ----@param str string ----@param mode? '"left"'|'"right"' ----@return string -local function trim(str, mode) - if mode == "left" then - print(1) - end -end -trim('str', 'left') -trim('str', nil) -]] - -config.get(nil, 'Lua.diagnostics.neededFileStatus')['unused-local'] = 'Any' - ----不完整的函数参数定义,会跳过检查 -TEST [[ ----@param mode string -local function status(source, field, mode) - print(source, field, mode) -end -status(1, 2, 'name') -]] - - -TEST [[ ----@alias range {start: number, end: number} ----@param uri string ----@param range range -local function location(uri, range) - print(uri, range) -end ----@type range -local val = {} -location('uri', val) -]] - --- redundant-return -TEST [[ -local function f() - <!return!> -end -f() -]] - -TEST [[ -local function f() - return nil -end -f() -]] - -TEST [[ -local function f() - local function x() - <!return!> - end - x() - return true -end -f() -]] - -TEST [[ -local function f() - local function x() - return true - end - return x() -end -f() -]] - -TEST [[ ----@type file* -local f -local _ = f:read '*a' -local _ = f:read('*a') -]] - -TEST [[ -function F() - <!coroutine.yield!>() -end -]] - -TEST [[ ----@async -function F() - coroutine.yield() -end -]] - -TEST [[ ----@type async fun() -local f - -function F() - <!f!>() -end -]] - -TEST [[ ----@type async fun() -local f - ----@async -function F() - f() -end -]] - -TEST [[ -local function f(cb) - cb() -end - -<!f!>(function () ---@async - return nil -end) -]] - -TEST [[ -local function f(cb) - pcall(cb) -end - -<!f!>(function () ---@async - return nil -end) -]] - -TEST [[ ----@param c any -local function f(c) - return c -end - -f(function () ---@async - return nil -end) -]] - -TEST [[ ----@param ... any -local function f(...) - return ... -end - -f(function () ---@async - return nil -end) -]] - -TEST [[ ----@vararg any -local function f(...) - return ... -end - -f(function () ---@async - return nil -end) -]] - -TEST [[ -local function f(...) - return ... -end - -f(function () ---@async - return nil -end) -]] - -TEST [[ -local function f(...) - return ... -end - -f(1, function () ---@async - return nil -end) -]] - -TEST [[ ----@nodiscard -local function f() - return 1 -end - -<!f()!> -]] - -TEST [[ ----@nodiscard -local function f() - return 1 -end - -X = f() -]] - -config.get(nil, 'Lua.diagnostics.neededFileStatus')['not-yieldable'] = 'Any' -TEST [[ -local function f(cb) - return cb -end - ----@async -local function af() - return nil -end - -f(<!af!>) -]] - -TEST [[ ----@param cb async fun() -local function f(cb) - return cb -end - ----@async -local function af() - return nil -end - -f(af) -]] - -TEST [[ -local function f(cb) - cb() -end - -local function af() - <!f!>(function () ---@async - return nil - end) -end - -return af -]] - -TEST [[ -local function f(cb) - cb() -end - ----@async -local function af() - f(function () ---@async - return nil - end) -end - -return af -]] - -TEST [[ -local _ = type(function () ---@async - return nil -end) -]] - -TEST [[ ----@param ... number -local function f(...) - return ... -end - -return f -]] - -TEST [[ ----@type fun(...: string) -]] - -TEST [[ ----@type fun(xxx, yyy, ...): boolean -]] - -TEST [[ -local <!x!> - -return { - x = 1, -} -]] - -TEST [[ ----@class A #1 -]] - -TEST [[ ----@class A 1 -]] +require 'diagnostics.common' +--require 'diagnostics.type-check' diff --git a/test/diagnostics/type-check.lua b/test/diagnostics/type-check.lua new file mode 100644 index 00000000..9d9eb3ec --- /dev/null +++ b/test/diagnostics/type-check.lua @@ -0,0 +1,164 @@ +local config = require 'config' + +config.get(nil, 'Lua.diagnostics.neededFileStatus')['unused-local'] = 'None' +TEST [[ +---@param table table +---@param metatable table +---@return table +function Setmetatable(table, metatable) end + +Setmetatable(<!1!>, {}) +]] + +TEST [[ +---@param table table +---@param metatable table +---@return table +function Setmetatable(table, metatable) end + +Setmetatable(<!'name'!>, {}) + +]] + +TEST [[ +---@param table table +---@param metatable table +---@return table +function Setmetatable(table, metatable) end + +---@type table +local name +---@type function +local mt +---err +Setmetatable(name, <!mt!>) +]] + +TEST [[ +---@param p1 string +---@param p2 number +---@return table +local function func1(p1, p2) end + +---@type string +local s +---@type table +local t +---err +func1(s, <!t!>) +]] + +TEST [[ +---@class bird +---@field wing string + +---@class eagle +---@field family bird + +---@class chicken +---@field family bird + +---@param bd eagle +local function fly(bd) end + +---@type chicken +local h +fly(<!h!>) +]] + +TEST [[ +---@overload fun(x: number, y: number) +---@param x boolean +---@param y boolean +local function f(x, y) end + +f(true, true) -- OK +f(0, 0) -- OK + +]] + +TEST [[ +---@class bird +local m = {} +setmetatable(m, {}) -- OK +]] + +TEST [[ +---@class childString: string +local s +---@param name string +local function f(name) end +f(s) +]] + +TEST [[ +---@class childString: string + +---@type string +local s +---@param name childString +local function f(name) end +f(<!s!>) +]] + +TEST [[ +---@alias searchmode '"ref"'|'"def"'|'"field"'|'"allref"'|'"alldef"'|'"allfield"' + +---@param mode searchmode +local function searchRefs(mode)end +searchRefs('ref') +]] + +TEST [[ +---@class markdown +local mt = {} +---@param language string +---@param text string|markdown +function mt:add(language, text) + if not text then + return + end +end +---@type markdown +local desc + +desc:add('md', 'hover') +]] + +---可选参数和枚举 +TEST [[ +---@param str string +---@param mode? '"left"'|'"right"' +---@return string +local function trim(str, mode) + if mode == "left" then + print(1) + end +end +trim('str', 'left') +trim('str', nil) +]] + +config.get(nil, 'Lua.diagnostics.neededFileStatus')['unused-local'] = 'Any' + +---不完整的函数参数定义,会跳过检查 +TEST [[ +---@param mode string +local function status(source, field, mode) + print(source, field, mode) +end +status(1, 2, 'name') +]] + + +TEST [[ +---@alias range {start: number, end: number} +---@param uri string +---@param range range +local function location(uri, range) + print(uri, range) +end +---@type range +local val = {} +location('uri', val) +]] diff --git a/test/example/guide.txt b/test/example/guide.txt index cff05faf..1aef61ae 100644 --- a/test/example/guide.txt +++ b/test/example/guide.txt @@ -2718,7 +2718,7 @@ function m.viewInferType(infers) or src.type == 'doc.type.name' or src.type == 'doc.type.array' or src.type == 'doc.type.table' - or src.type == 'doc.type.enum' + or src.type == 'doc.type.string' or src.type == 'doc.resume' then local tp = infer.type or 'any' if not mark[tp] then diff --git a/test/full/example.lua b/test/full/example.lua index ed5c3b16..e8352547 100644 --- a/test/full/example.lua +++ b/test/full/example.lua @@ -5,7 +5,6 @@ local diag = require 'core.diagnostics' local config = require 'config' local fs = require 'bee.filesystem' local luadoc = require "parser.luadoc" -local noder = require 'core.noder' -- 临时 ---@diagnostic disable: await-in-sync diff --git a/test/highlight/init.lua b/test/highlight/init.lua index 8e07c5f0..0cca79f1 100644 --- a/test/highlight/init.lua +++ b/test/highlight/init.lua @@ -1,3 +1,4 @@ +---@diagnostic disable: await-in-sync local core = require 'core.highlight' local files = require 'files' local catch = require 'catch' diff --git a/test/hover/init.lua b/test/hover/init.lua index c5d8a7fc..2ae6837f 100644 --- a/test/hover/init.lua +++ b/test/hover/init.lua @@ -6,18 +6,19 @@ local config = require 'config' rawset(_G, 'TEST', true) local accept = { - ['local'] = true, - ['setlocal'] = true, - ['getlocal'] = true, - ['setglobal'] = true, - ['getglobal'] = true, - ['field'] = true, - ['method'] = true, - ['string'] = true, - ['number'] = true, - ['integer'] = true, - ['doc.type.name'] = true, - ['function'] = true, + ['local'] = true, + ['setlocal'] = true, + ['getlocal'] = true, + ['setglobal'] = true, + ['getglobal'] = true, + ['field'] = true, + ['method'] = true, + ['string'] = true, + ['number'] = true, + ['integer'] = true, + ['doc.type.name'] = true, + ['doc.class.name'] = true, + ['function'] = true, } ---@diagnostic disable: await-in-sync @@ -28,7 +29,7 @@ function TEST(script) local hover = core.byUri('', catched['?'][1][1]) assert(hover) expect = expect:gsub('^[\r\n]*(.-)[\r\n]*$', '%1'):gsub('\r\n', '\n') - local label = tostring(hover):match('```lua[\r\n]*(.-)[\r\n]*```'):gsub('\r\n', '\n') + local label = hover:string():gsub('\r\n', '\n'):match('```lua[\r\n]*(.-)[\r\n]*```') assert(expect == label) files.remove('') end @@ -149,7 +150,7 @@ obj.<?xxx?>() TEST [[ obj.<?xxx?>() ]] -[[global obj.xxx: any]] +[[global obj.xxx: unknown]] TEST [[ local <?x?> = 1 @@ -183,7 +184,7 @@ t = { TEST [[ local <?obj?> = {} ]] -"local obj: {}" +"local obj: table" --TEST [[ --local mt = {} @@ -272,9 +273,8 @@ TEST [[ local type w2l:get_default()[<?type?>] ]] -"local type: any" +"local type: unknown" --- TODO 可选参数(或多原型) TEST [[ <?load?>() ]] @@ -312,7 +312,7 @@ end ]] [[ function x() - -> any + -> unknown ]] TEST [[ @@ -368,19 +368,19 @@ local function f() end local <?n?> = f() ]] -[[local n: any]] +[[local n: unknown]] TEST [[ local <?n?> = table.unpack(t) ]] -[[local n: any]] +[[local n: unknown]] TEST [[ local <?n?> table.pack(n) ]] [[ -local n: any +local n: unknown ]] TEST [[ @@ -451,7 +451,7 @@ local any = collectgarbage() t[any] = any ]] [[ -local t: {} +local t: table ]] TEST[[ @@ -627,7 +627,7 @@ end local <?r?> = a(1) ]] [[ -local r: string +local r: string = "a" ]] TEST[[ @@ -637,7 +637,7 @@ end local _, <?r?> = pcall(a, 1) ]] [[ -local r: string +local r: string = "a" ]] TEST[[ @@ -647,15 +647,6 @@ local <?n?> = rawlen() local n: integer ]] --- TODO 暂未实现 ---TEST[[ ---local <?n?> = pairs() ---]] ---[[ ---function n<next>(table: table [, index: any]) --- -> key: any, value: any ---]] - TEST[[ local <?x?> = '\a' ]] @@ -699,8 +690,8 @@ end ]] [[ function f() - -> any - 2. any + -> nil + 2. nil ]] TEST [[ @@ -710,7 +701,7 @@ end local <?x?> = f() ]] [[ -local x: any +local x: nil ]] TEST [[ @@ -721,7 +712,7 @@ end ]] [[ function f() - -> integer + -> integer|nil ]] TEST [[ @@ -791,7 +782,7 @@ io.<?popen?>() [[ function io.popen(prog: string, mode?: "r"|"w") -> file*? - 2. errmsg?: string + 2. errmsg: string? ]] TEST [[ @@ -838,7 +829,6 @@ local t: { } ]] -config.set(nil, 'Lua.IntelliSense.traceLocalSet', true) TEST [[ local x x = 1 @@ -849,7 +839,6 @@ print(<?x?>) [[ local x: number = 1 ]] -config.set(nil, 'Lua.IntelliSense.traceLocalSet', false) TEST [[ local <?x?> <close> = 1 @@ -1068,7 +1057,7 @@ end local <?r?> = f(1) ]] [[ -local r: integer +local r: integer = 1 ]] TEST [[ @@ -1099,6 +1088,18 @@ TEST [[ ---@vararg Class local function f(...) + local <?t?> = {...} +end +]] +[[ +local t: Class[] +]] + +TEST [[ +---@class Class + +---@vararg Class +local function f(...) local t = {...} local <?v?> = t[1] end @@ -1340,7 +1341,7 @@ TEST [[ local <?f?> ]] [[ -local f: fun(x: boolean):boolean +local f: fun(x?: boolean):boolean? ]] TEST [[ @@ -1364,7 +1365,7 @@ end [[ function f(x: any, y: any) -> first: table - 2. second?: string + 2. second: string? ]] TEST [[ @@ -1396,7 +1397,7 @@ TEST [[ local <?t?> ]] [[ -local t: string|'enum1'|'enum2' +local t: string|"enum1"|"enum2" ]] TEST [[ @@ -1405,7 +1406,7 @@ TEST [[ ---@type <?A?> ]] [[ -展开为 string|'enum1'|'enum2' +展开为 string|"enum1"|"enum2" ]] TEST [[ @@ -1415,7 +1416,7 @@ TEST [[ local <?t?> ]] [[ -local t: string|'enum1'|'enum2' +local t: string|"enum1"|"enum2" ]] TEST [[ @@ -1425,7 +1426,7 @@ TEST [[ local <?t?> ]] [[ -local t: string|'enum1'|'enum2' +local t: string|"enum1"|"enum2" ]] TEST [[ @@ -1511,7 +1512,7 @@ local x --- @type boolean local <?y?> ]] [[ -local y: any +local y: unknown ]] TEST [[ @@ -1571,7 +1572,7 @@ TEST [[ local <?x?>--测试 ]] [[ -local x: any +local x: unknown ]] TEST [[ @@ -1593,7 +1594,7 @@ print(u.x) ]] [[ local u: number { - x: any, + x: unknown, } ]] @@ -1636,7 +1637,7 @@ local f <?f?>() ]] [[ -local f: any +local f: unknown ]] TEST [[ @@ -1675,7 +1676,7 @@ TEST [[ ]] [[ global a: { - b: integer, + b: integer = 600, } ]] @@ -1683,7 +1684,7 @@ TEST [[ a.<?b?> = 10 * 60 ]] [[ -global a.b: integer +global a.b: integer = 600 ]] TEST [[ @@ -1691,7 +1692,7 @@ a.<?b?>.c = 1 * 1 ]] [[ global a.b: { - c: integer, + c: integer = 1, } ]] @@ -1729,37 +1730,20 @@ local t = nil t.<?x?>() ]] [[ -field t.x: any +field t.x: unknown ]] -config.set(nil, 'Lua.IntelliSense.traceLocalSet', true) TEST [[ ---@class A local a -local b = nil +local b b = a print(b.<?x?>) ]] [[ -field A.x: any -]] -config.set(nil, 'Lua.IntelliSense.traceLocalSet', false) - -TEST [[ ----@class A ----@field x number ----@field y number - ----@type A<string, number> -local <?t?> -]] -[[ -local t: A<string, number> { - x: number, - y: number, -} +field A.x: unknown ]] TEST [[ @@ -1803,3 +1787,32 @@ local <?x?> = 1 // 2 local x: integer = 1 ]] config.set(nil, 'Lua.runtime.nonstandardSymbol', {}) + +config.set(nil, 'Lua.hover.expandAlias', false) +TEST [[ +---@alias uri string + +---@type uri +local <?uri?> +]] +[[ +local uri: uri +]] + +config.set(nil, 'Lua.hover.expandAlias', true) +TEST [[ +---@alias uri string + +---@type uri +local <?uri?> +]] +[[ +local uri: string +]] + +TEST [[ +local <?x?> = '1' .. '2' +]] +[[ +local x: string = "12" +]] diff --git a/test/references/all.lua b/test/references/all.lua index 4ba63579..9395df86 100644 --- a/test/references/all.lua +++ b/test/references/all.lua @@ -3,7 +3,7 @@ local config = require 'config' TEST [[ ---@class A local a = {} -a.<?x?> = 1 +a.<~x~> = 1 ---@return A local function f() end @@ -15,7 +15,7 @@ return b.<!x!> TEST [[ ---@class A local a = {} -a.<?x?> = 1 +a.<~x~> = 1 ---@return table ---@return A @@ -26,40 +26,42 @@ return a.x, b.<!x!> ]] TEST [[ -local <?mt?> = {} +local <~mt~> = {} function <!mt!>:x() - <!self!>:x() + self:x() end ]] TEST [[ local mt = {} -function mt:<?x?>() +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 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: How to search references of function? +--[=[ TEST [[ local function f() return <~<!function~> () @@ -77,55 +79,20 @@ end local _, <!f2!> = f() ]] - -config.set(nil, 'Lua.IntelliSense.traceReturn', true) -TEST [[ -local <?x?> -local function f() - return <!x!> -end -local <!y!> = f() -]] - -TEST [[ -local <?x?> -local function f() - return function () - return <!x!> - end -end -local <!y!> = f()() -]] -config.set(nil, 'Lua.IntelliSense.traceReturn', false) +]=] TEST [[ ---@class A local t ---@class B: A -local <?v?> -]] - --- TODO --- 泛型的反向搜索 -do return end -TEST [[ ----@class Dog -local <?Dog?> = {} - ----@generic T ----@param type1 T ----@return T -function foobar(type1) -end - -local <!v1!> = foobar(<!Dog!>) +local <~v~> ]] TEST [[ ---@class Dog local Dog = {} -function Dog:<?eat?>() +function Dog:<~eat~>() end ---@generic T @@ -142,7 +109,7 @@ v1:<!eat!>() TEST [[ ---@class Dog local Dog = {} -function Dog:<?eat?>() +function Dog:<~eat~>() end ---@class Master @@ -159,51 +126,3 @@ 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/common.lua b/test/references/common.lua index b46aa81f..5217200d 100644 --- a/test/references/common.lua +++ b/test/references/common.lua @@ -1,35 +1,35 @@ local config = require "config" TEST [[ -local <?a?> = 1 +local <~a~> = 1 <!a!> = <!a!> ]] TEST [[ -<?a?> = 1 +<~a~> = 1 <!a!> = <!a!> ]] TEST [[ local t -t.<?a?> = 1 +t.<~a~> = 1 t.<!a!> = t.<!a!> ]] TEST [[ -t.<?a?> = 1 +t.<~a~> = 1 t.<!a!> = t.<!a!> ]] TEST [[ :: <!LABEL!> :: -goto <?LABEL?> +goto <~LABEL~> if true then goto <!LABEL!> end ]] TEST [[ -:: <?LABEL?> :: +:: <~LABEL~> :: goto <!LABEL!> if true then goto <!LABEL!> @@ -38,183 +38,128 @@ end TEST [[ local a = 1 -local <?a?> = 1 +local <~a~> = 1 <!a!> = <!a!> ]] TEST [[ -local <!a!> -local <?b?> = <!a!> -]] - -TEST [[ -local <?a?> -local <!b!> = <!a!> -]] - -TEST [[ -local t = { - <!a!> = 1 -} -print(t.<?a?>) +local <~a~> +local b = <!a!> ]] TEST [[ local t = { - <?a?> = 1 + <~a~> = 1 } print(t.<!a!>) ]] TEST [[ -t[<?'a'?>] = 1 +t[<~'a'~>] = 1 print(t.<!a!>) ]] TEST [[ local t = { - [<?'a'?>] = 1 + [<~'a'~>] = 1 } print(t.<!a!>) ]] TEST [[ table.<!dump!>() -function table.<?dump?>() +function table.<~dump~>() end ]] TEST [[ local t = {} -t.<?x?> = 1 +t.<~x~> = 1 t[a.b.c] = 1 ]] TEST [[ local t = {} t.x = 1 -t[a.b.<?x?>] = 1 -]] - -config.set(nil, 'Lua.IntelliSense.traceBeSetted', true) -TEST [[ -local t -local <!f!> = t.<?f?> - -<!f!>() - -return { - <!f!> = <!f!>, -} +t[a.b.<~x~>] = 1 ]] -config.set(nil, 'Lua.IntelliSense.traceBeSetted', false) TEST [[ self = { results = { - <?labels?> = {}, + <~labels~> = {}, } } self[self.results.<!labels!>] = lbl ]] TEST [[ -a.b.<?c?> = 1 +a.b.<~c~> = 1 print(a.b.<!c!>) ]] TEST [[ local <!mt!> = {} -function <!mt!>:x() - <?self?>:x() +function mt:x() + <~self~>:x() end ]] TEST [[ -local mt = {} -function mt:<!x!>() - self:<?x?>() +local <~mt~> = {} +function <!mt!>:x() + self:x() end ]] TEST [[ -a.<!b!>.c = 1 -print(a.<?b?>.c) -]] - -config.set(nil, 'Lua.IntelliSense.traceBeSetted', true) -TEST [[ -local <?f?> -local t = { - <!a!> = <!f!> -} -print(t.<!a!>) -]] -config.set(nil, 'Lua.IntelliSense.traceBeSetted', false) - -TEST [[ -local <!f!> -local <!t!> = <?f?> -]] - -config.set(nil, 'Lua.IntelliSense.traceBeSetted', true) -TEST [[ -local <!f!> -a.<!t!> = <?f?> -]] - -TEST [[ -<!t!>.<!f!> = <?t?> +local mt = {} +function mt:<!x!>() + self:<~x~>() +end ]] -config.set(nil, 'Lua.IntelliSense.traceBeSetted', false) TEST [[ -local <!f!> -local <?t?> = <!f!> +local mt = {} +function mt:<~x~>() + self:<!x!>() +end ]] -config.set(nil, 'Lua.IntelliSense.traceBeSetted', true) TEST [[ -local <!t!> -<!t!>.<!f!> = <?t?> +a.<!b!>.c = 1 +print(a.<~b~>.c) ]] -config.set(nil, 'Lua.IntelliSense.traceBeSetted', false) TEST [[ -_G.<?xxx?> = 1 +_G.<~xxx~> = 1 print(<!xxx!>) ]] TEST [[ ----@class <!Class!> ----@type <?Class?> ----@type <!Class!> -]] - -TEST [[ ----@class <?Class?> +---@class <~Class~> ---@type <!Class!> ---@type <!Class!> ]] TEST [[ ---@class Class -local <?t?> +local <~t~> ---@type Class -local <!x!> +local x ]] TEST [[ ---@class Class -local <!t!> +local t ---@type Class -local <?x?> +local <~x~> ]] -- BUG TEST [[ ----@return <?xxx?> +---@return <~xxx~> function f() end ]] @@ -223,19 +168,19 @@ TEST [[ ---@class B: A ---@type A -local <?t?> -]] - -TEST [[ ----@class A -local a - ----@type A -local b - ----@type A -local c - -b.<?x?> = 1 -c.<!x!> = 1 -]] +local <~t~> +]] + +--TEST [[ +-----@class A +--local a +-- +-----@type A +--local b +-- +-----@type A +--local c +-- +--b.<~x~> = 1 +--c.<!x!> = 1 +--]] diff --git a/test/references/init.lua b/test/references/init.lua index 81dfb481..1b1cc73b 100644 --- a/test/references/init.lua +++ b/test/references/init.lua @@ -1,3 +1,4 @@ +---@diagnostic disable: await-in-sync local core = require 'core.reference' local files = require 'files' local catch = require 'catch' @@ -23,7 +24,7 @@ function TEST(script) files.setText('', newScript) local input = catched['?'] + catched['~'] - local expect = catched['!'] + catched['?'] + local expect = catched['!'] + catched['~'] local results = core('', input[1][1]) if results then local positions = {} diff --git a/test/rename/init.lua b/test/rename/init.lua index 31421ada..64e3916a 100644 --- a/test/rename/init.lua +++ b/test/rename/init.lua @@ -1,3 +1,4 @@ +---@diagnostic disable: await-in-sync local core = require 'core.rename' local files = require 'files' local catch = require 'catch' @@ -90,7 +91,6 @@ local function f(b) end ]] ---config.set('Lua.IntelliSense.traceBeSetted', true) TEST ('a', '!!!') [[ t = { a = 0 diff --git a/test/type_inference/init.lua b/test/type_inference/init.lua index 7316730e..bad1a876 100644 --- a/test/type_inference/init.lua +++ b/test/type_inference/init.lua @@ -1,6 +1,6 @@ local files = require 'files' local guide = require 'parser.guide' -local infer = require 'core.infer' +local infer = require 'vm.infer' local config = require 'config' local catch = require 'catch' @@ -8,17 +8,21 @@ rawset(_G, 'TEST', true) local function getSource(pos) local ast = files.getState('') - return guide.eachSourceContain(ast.ast, pos, function (source) + local result + guide.eachSourceContain(ast.ast, pos, function (source) if source.type == 'local' or source.type == 'getlocal' or source.type == 'setlocal' or source.type == 'setglobal' or source.type == 'getglobal' or source.type == 'field' - or source.type == 'method' then - return source + or source.type == 'method' + or source.type == 'function' + or source.type == 'table' then + result = source end end) + return result end function TEST(wanted) @@ -27,9 +31,9 @@ function TEST(wanted) files.setText('', newScript) local source = getSource(catched['?'][1][1]) assert(source) - local result = infer.searchAndViewInfers(source) + local result = infer.getInfer(source):view() if wanted ~= result then - infer.searchAndViewInfers(source) + infer.getInfer(source):view() end assert(wanted == result) files.remove('') @@ -52,12 +56,38 @@ TEST 'number' [[ local <?var?> = 1.0 ]] +TEST 'unknown' [[ +local <?var?> +]] + +TEST 'unknown' [[ +local <?var?> +var = y +]] + +TEST 'any' [[ +function f(<?x?>) + +end +]] + +TEST 'any' [[ +function f(<?x?>) + x = 1 +end +]] + +TEST 'number' [[ +local <?var?> +var = 1 +var = 1.0 +]] + TEST 'string' [[ local var = '111' t.<?x?> = var ]] -config.set(nil, 'Lua.IntelliSense.traceLocalSet', true) TEST 'string' [[ local <?var?> var = '111' @@ -68,7 +98,6 @@ local var var = '111' print(<?var?>) ]] -config.set(nil, 'Lua.IntelliSense.traceLocalSet', false) TEST 'function' [[ function <?xx?>() @@ -80,19 +109,17 @@ local function <?xx?>() end ]] -config.set(nil, 'Lua.IntelliSense.traceLocalSet', true) TEST 'function' [[ local xx <?xx?> = function () end ]] -config.set(nil, 'Lua.IntelliSense.traceLocalSet', false) TEST 'table' [[ local <?t?> = {} ]] -TEST 'any' [[ +TEST 'unknown' [[ <?x?>() ]] @@ -100,7 +127,7 @@ TEST 'boolean' [[ <?x?> = not y ]] -TEST 'any' [[ +TEST 'integer' [[ <?x?> = #y ]] @@ -112,7 +139,7 @@ TEST 'integer' [[ <?x?> = #{} ]] -TEST 'any' [[ +TEST 'number' [[ <?x?> = - y ]] @@ -120,7 +147,7 @@ TEST 'number' [[ <?x?> = - 1.0 ]] -TEST 'any' [[ +TEST 'integer' [[ <?x?> = ~ y ]] @@ -144,7 +171,7 @@ TEST 'boolean' [[ <?x?> = a == b ]] -TEST 'any' [[ +TEST 'integer' [[ <?x?> = a << b ]] @@ -152,7 +179,7 @@ TEST 'integer' [[ <?x?> = 1 << 2 ]] -TEST 'any' [[ +TEST 'string' [[ <?x?> = a .. b ]] @@ -160,7 +187,15 @@ TEST 'string' [[ <?x?> = 'a' .. 'b' ]] -TEST 'any' [[ +TEST 'string' [[ +<?x?> = 'a' .. 1 +]] + +TEST 'string' [[ +<?x?> = 'a' .. 1.0 +]] + +TEST 'number' [[ <?x?> = a + b ]] @@ -168,6 +203,10 @@ TEST 'number' [[ <?x?> = 1 + 2.0 ]] +TEST 'integer' [[ +<?x?> = 1 + 2 +]] + TEST 'tablelib' [[ ---@class tablelib table = {} @@ -185,29 +224,38 @@ TEST 'function' [[ ---@class stringlib local string -string.sub = function () end +string.xxx = function () end + +return ('x').<?xxx?> +]] + +TEST 'function' [[ +---@class stringlib +String = {} + +String.xxx = function () end -return ('x').<?sub?> +return ('x').<?xxx?> ]] TEST 'function' [[ ---@class stringlib local string -string.sub = function () end +string.xxx = function () end -<?x?> = ('x').sub +<?x?> = ('x').xxx ]] TEST 'function' [[ ---@class stringlib local string -string.sub = function () end +string.xxx = function () end _VERSION = 'Lua 5.4' -<?x?> = _VERSION.sub +<?x?> = _VERSION.xxx ]] TEST 'table' [[ @@ -221,7 +269,7 @@ end <?y?> = x() ]] -TEST 'integer' [[ +TEST 'integer|nil' [[ local function x() return 1 return nil @@ -229,7 +277,7 @@ end <?y?> = x() ]] -TEST 'any' [[ +TEST 'unknown|nil' [[ local function x() return a return nil @@ -237,7 +285,7 @@ end <?y?> = x() ]] -TEST 'any' [[ +TEST 'unknown|nil' [[ local function x() return nil return f() @@ -245,6 +293,14 @@ end <?y?> = x() ]] +TEST 'unknown' [[ +local function x() + return nil + return f() +end +_, <?y?> = x() +]] + TEST 'integer' [[ local function x() return 1 @@ -292,7 +348,7 @@ local <?x?> = f() --]] -- 不根据对方函数内的使用情况来推测 -TEST 'any' [[ +TEST 'unknown' [[ local function x(a) _ = a + 1 end @@ -300,7 +356,7 @@ local b x(<?b?>) ]] -TEST 'any' [[ +TEST 'unknown' [[ local function x(a, ...) local _, <?b?>, _ = ... end @@ -308,18 +364,18 @@ x(nil, 'xx', 1, true) ]] -- 引用不跨越参数 -TEST 'any' [[ +TEST 'unknown' [[ local function x(a, ...) return true, 'ss', ... end local _, _, _, <?b?>, _ = x(nil, true, 1, 'yy') ]] -TEST 'any' [[ +TEST 'unknown' [[ local <?x?> = next() ]] -TEST 'any' [[ +TEST 'unknown' [[ local a, b function a() return b() @@ -342,6 +398,11 @@ TEST 'string' [[ local <?x?> ]] +TEST '1' [[ +---@type 1 +local <?v?> +]] + TEST 'string[]' [[ ---@class string @@ -358,7 +419,62 @@ local <?x?> ]] TEST '"enum1"|"enum2"' [[ ----@type '"enum1"' | '"enum2"' +---@type 'enum1' | 'enum2' +local <?x?> +]] + +TEST '"enum1"|"enum2"' [[ +---@type 'enum1' | 'enum2' +local <?x?> +]] + +config.set(nil, 'Lua.hover.expandAlias', false) +TEST 'A' [[ +---@alias A 'enum1' | 'enum2' + +---@type A +local <?x?> +]] + +TEST 'A' [[ +---@alias A 'enum1' | 'enum2' | A + +---@type A +local <?x?> +]] + +TEST 'A' [[ +---@alias A 'enum1' | 'enum2' | B + +---@type A +local <?x?> +]] +config.set(nil, 'Lua.hover.expandAlias', true) +TEST '"enum1"|"enum2"' [[ +---@alias A 'enum1' | 'enum2' + +---@type A +local <?x?> +]] + +TEST '"enum1"|"enum2"' [[ +---@alias A 'enum1' | 'enum2' | A + +---@type A +local <?x?> +]] + +TEST '"enum1"|"enum2"|B' [[ +---@alias A 'enum1' | 'enum2' | B + +---@type A +local <?x?> +]] + +TEST '1|true' [[ +---@alias A 1 | true + +---@type A local <?x?> ]] @@ -367,6 +483,21 @@ TEST 'fun()' [[ local <?x?> ]] +TEST 'fun(a: string, b: any, ...: any)' [[ +---@type fun(a: string, b, ...) +local <?x?> +]] + +TEST 'fun(a: string, b: any, c?: boolean, ...: any):c, d?, ...' [[ +---@type fun(a: string, b, c?: boolean, ...):c, d?, ... +local <?x?> +]] + +TEST 'table' [[ +---@type { [string]: string } +local <?x?> +]] + TEST 'table<string, number>' [[ ---@class string ---@class number @@ -414,13 +545,29 @@ print(t.<?a?>) ]] TEST '"aaa"|"bbb"' [[ ----@type table<string, '"aaa"'|'"bbb"'> +---@type table<string, 'aaa'|'bbb'> local t = {} print(t.<?a?>) ]] TEST 'integer' [[ +---@generic K +---@type fun(a?: K):K +local f + +local <?n?> = f(1) +]] + +TEST 'unknown' [[ +---@generic K +---@type fun(a?: K):K +local f + +local <?n?> = f(nil) +]] + +TEST 'integer' [[ ---@class integer ---@generic T: table, V @@ -537,22 +684,120 @@ local t local <?k?>, v = f2(t) ]] +TEST 'fun(a: <V>):integer, <V>' [[ +---@generic K, V +---@param a K +---@return fun(a: V):K, V +local function f(a) end + +local <?f2?> = f(1) +]] + +TEST 'integer' [[ +---@generic K, V +---@param a K +---@return fun(a: V):K, V +local function f(a) end + +local f2 = f(1) +local <?i?>, v = f2(true) +]] + +TEST 'boolean' [[ +---@generic K, V +---@param a K +---@return fun(a: V):K, V +local function f(a) end + +local f2 = f(1) +local i, <?v?> = f2(true) +]] + +TEST 'fun(table: table<<K>, <V>>, index?: <K>):<K>, <V>' [[ +---@generic T: table, K, V +---@param t T +---@return fun(table: table<K, V>, index?: K):K, V +---@return T +---@return nil +local function pairs(t) end + +local <?next?> = pairs(dummy) +]] + TEST 'string' [[ ----@class string +---@generic T: table, K, V +---@param t T +---@return fun(table: table<K, V>, index?: K):K, V +---@return T +---@return nil +local function pairs(t) end + +local next = pairs(dummy) + +---@type table<string, boolean> +local t +local <?k?>, v = next(t) +]] +TEST 'boolean' [[ ---@generic T: table, K, V ---@param t T ----@return fun(table: table<K, V>, index: K):K, V +---@return fun(table: table<K, V>, index?: K):K, V ---@return T ---@return nil local function pairs(t) end -local f = pairs(t) +local next = pairs(dummy) ---@type table<string, boolean> local t +local k, <?v?> = next(t) +]] + +TEST 'string' [[ +---@generic T: table, K, V +---@param t T +---@return fun(table: table<K, V>, index?: K):K, V +---@return T +---@return nil +local function pairs(t) end + +local next = pairs(dummy) + +---@type table<string, boolean> +local t +local <?k?>, v = next(t, nil) +]] + +TEST 'boolean' [[ +---@generic T: table, K, V +---@param t T +---@return fun(table: table<K, V>, index?: K):K, V +---@return T +---@return nil +local function pairs(t) end + +local next = pairs(dummy) -for <?k?>, v in f, t do +---@type table<string, boolean> +local t +local k, <?v?> = next(t, nil) +]] + +TEST 'string' [[ +---@generic T: table, K, V +---@param t T +---@return fun(table: table<K, V>, index?: K):K, V +---@return T +---@return nil +local function pairs(t) end + +local next = pairs(dummy) + +---@type table<string, boolean> +local t + +for <?k?>, v in next, t do end ]] @@ -575,8 +820,6 @@ end ]] TEST 'string' [[ ----@class string - ---@generic T: table, K, V ---@param t T ---@return fun(table: table<K, V>, index?: K):K, V @@ -591,8 +834,6 @@ end ]] TEST 'boolean' [[ ----@class boolean - ---@generic T: table, K, V ---@param t T ---@return fun(table: table<K, V>, index: K):K, V @@ -608,8 +849,6 @@ end ]] TEST 'boolean' [[ ----@class boolean - ---@generic T: table, V ---@param t T ---@return fun(table: V[], i?: integer):integer, V @@ -625,8 +864,6 @@ end ]] TEST 'boolean' [[ ----@class boolean - ---@generic T: table, K, V ---@param t T ---@return fun(table: table<K, V>, index: K):K, V @@ -642,8 +879,6 @@ end ]] TEST 'integer' [[ ----@class integer - ---@generic T: table, K, V ---@param t T ---@return fun(table: table<K, V>, index?: K):K, V @@ -749,13 +984,13 @@ string.gsub():gsub():<?gsub?>() ]] config.set(nil, 'Lua.hover.enumsLimit', 5) -TEST 'a|b|c|d|e...(+5)' [[ +TEST '"a"|"b"|"c"|"d"|"e"...(+5)' [[ ---@type 'a'|'b'|'c'|'d'|'e'|'f'|'g'|'h'|'i'|'j' local <?t?> ]] config.set(nil, 'Lua.hover.enumsLimit', 1) -TEST 'a...(+9)' [[ +TEST '"a"...(+9)' [[ ---@type 'a'|'b'|'c'|'d'|'e'|'f'|'g'|'h'|'i'|'j' local <?t?> ]] @@ -828,13 +1063,18 @@ TEST 'fun():number, boolean' [[ local <?t?> ]] ---[[ -l:value -l:work|&1|&1 -f:|&1|&1 -dfun:|&1 -dn:Class + +TEST 'fun(value: Class)' [[ +---@class Class + +---@param callback fun(value: Class) +function work(callback) +end + +work(<?function?> (value) +end) ]] + TEST 'Class' [[ ---@class Class @@ -846,14 +1086,14 @@ work(function (<?value?>) end) ]] -TEST 'Class' [[ +TEST 'fun(value: Class)' [[ ---@class Class ---@param callback fun(value: Class) function work(callback) end -pcall(work, function (<?value?>) +pcall(work, <?function?> (value) end) ]] @@ -919,11 +1159,22 @@ end --f = function (<?x?>) end --]] +TEST 'fun(i: integer)' [[ +--- @class Emit +--- @field on fun(eventName: string, cb: function) +--- @field on fun(eventName: 'died', cb: fun(i: integer)) +--- @field on fun(eventName: 'won', cb: fun(s: string)) +local emit = {} + +emit.on("died", <?function?> (i) +end) +]] + TEST 'integer' [[ --- @class Emit --- @field on fun(eventName: string, cb: function) ---- @field on fun(eventName: '"died"', cb: fun(i: integer)) ---- @field on fun(eventName: '"won"', cb: fun(s: string)) +--- @field on fun(eventName: 'died', cb: fun(i: integer)) +--- @field on fun(eventName: 'won', cb: fun(s: string)) local emit = {} emit.on("died", function (<?i?>) @@ -933,8 +1184,8 @@ end) TEST 'integer' [[ --- @class Emit --- @field on fun(self: Emit, eventName: string, cb: function) ---- @field on fun(self: Emit, eventName: '"died"', cb: fun(i: integer)) ---- @field on fun(self: Emit, eventName: '"won"', cb: fun(s: string)) +--- @field on fun(self: Emit, eventName: 'died', cb: fun(i: integer)) +--- @field on fun(self: Emit, eventName: 'won', cb: fun(s: string)) local emit = {} emit:on("died", function (<?i?>) @@ -971,14 +1222,14 @@ local x <?x?> = 1 ]] -TEST 'any' [[ +TEST 'unknown' [[ ---@return number local function f(x) local <?y?> = x() end ]] -TEST 'any' [[ +TEST 'unknown' [[ local mt ---@return number @@ -987,7 +1238,7 @@ function mt:f() end local <?v?> = mt() ]] -TEST 'any' [[ +TEST 'unknown' [[ local <?mt?> ---@class X @@ -1001,7 +1252,7 @@ local mt function mt:f(<?x?>) end ]] -TEST 'any' [[ +TEST 'unknown' [[ local <?mt?> ---@type number @@ -1031,6 +1282,22 @@ mt:loop(function (<?i?>) end) ]] +TEST 'C' [[ +---@class D +---@field y integer # D comment + +---@class C +---@field x integer # C comment +---@field d D + +---@param c C +local function f(c) end + +f <?{?> + x = , +} +]] + TEST 'integer' [[ ---@class D ---@field y integer # D comment @@ -1076,3 +1343,79 @@ function F(<?x?>) end ---@param x boolean function F(x) end ]] + +TEST 'B' [[ +---@class A +local A + +---@return A +function A:x() end + +---@class B: A +local B + +---@return B +function B:x() end + +---@type B +local t + +local <?v?> = t.x() +]] + +TEST 'function' [[ +---@overload fun() +function <?f?>() end +]] + +TEST 'integer' [[ +---@type table<string, integer> +local t + +t.<?a?> +]] + +TEST '"a"|"b"|"c"' [[ +---@type table<string, "a"|"b"|"c"> +local t + +t.<?a?> +]] + +TEST 'integer' [[ +---@class A +---@field x integer + +---@type A +local t +t.<?x?> +]] + +TEST 'boolean' [[ +local <?var?> = true +var = 1 +var = 1.0 +]] + +TEST 'unknown' [[ +---@return ... +local function f() end + +local <?x?> = f() +]] + +TEST 'unknown' [[ +---@return ... +local function f() end + +local _, <?x?> = f() +]] + +TEST 'unknown' [[ +local t = { + x = 1, + y = 2, +} + +local <?x?> = t[#t] +]] |