diff --git a/changelog.md b/changelog.md index 6d484d7eb..ba7cd1fd1 100644 --- a/changelog.md +++ b/changelog.md @@ -17,6 +17,7 @@ * `FIX` Generic return can be optional. * `FIX` Fixed the comment calculating in docs `---@param a string?Comment` - now its `Comment` instead of `omment`. * `FIX` Fixed cannot bind variables using tail comment `@class` [#2673](https://github.com/LuaLS/lua-language-server/issues/2673) +* `FIX` Fixed missing field completion for generic class object [#2196](https://github.com/LuaLS/lua-language-server/issues/2196) [#2945](https://github.com/LuaLS/lua-language-server/issues/2945) [#3041](https://github.com/LuaLS/lua-language-server/issues/3041) * `NEW` `---@class` supports attribute `partial`, which will not check missing inherited fields [#3023](https://github.com/LuaLS/lua-language-server/issues/3023) ```lua ---@class Config diff --git a/script/vm/compiler.lua b/script/vm/compiler.lua index 92da538e5..cee5de55e 100644 --- a/script/vm/compiler.lua +++ b/script/vm/compiler.lua @@ -304,6 +304,17 @@ local searchFieldSwitch = util.switch() end end end) + : case 'doc.type.sign' + : call(function (suri, source, key, pushResult) + if not source.node[1] then + return + end + local global = vm.getGlobal('type', source.node[1]) + if not global then + return + end + vm.getClassFields(suri, global, key, pushResult) + end) : case 'global' : call(function (suri, node, key, pushResult) if node.cate == 'variable' then diff --git a/test/completion/common.lua b/test/completion/common.lua index 7f576e0bf..32cc68481 100644 --- a/test/completion/common.lua +++ b/test/completion/common.lua @@ -4572,3 +4572,44 @@ M.create():optional():self() kind = define.CompletionItemKind.EnumMember, }, } + +TEST [[ +---@class Array: { [integer]: T } +---@field length integer +local Array + +function Array:push() end + +---@type Array +local a +print(a.) +]] +{ + include = true, + { + label = 'length', + kind = define.CompletionItemKind.Field, + }, + { + label = 'push(self)', + kind = define.CompletionItemKind.Method, + }, +} + +TEST [[ +---@class Array: { [integer]: T } +---@field length integer +local Array + +function Array:push() end + +---@type Array +local a +print(a:) +]] +{ + { + label = 'push()', + kind = define.CompletionItemKind.Method, + }, +} diff --git a/test/completion/init.lua b/test/completion/init.lua index 1ac7fd4b3..81fd080b8 100644 --- a/test/completion/init.lua +++ b/test/completion/init.lua @@ -40,8 +40,18 @@ local function include(a, b) return false end if tp1 == 'table' then - for k in pairs(a) do - if not eq(a[k], b[k]) then + -- a / b are array of completion results + -- when checking `include`, the array index order is not important + -- thus need to check every results in b + for _, v1 in ipairs(a) do + local ok = false + for _, v2 in ipairs(b) do + if eq(v1, v2) then + ok = true + break + end + end + if not ok then return false end end