diff --git a/changelog.md b/changelog.md index dc21e32ba..9b0ccd189 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,8 @@ # changelog +## 3.0.1 +* `FIX` [#1033](https://github.com/sumneko/lua-language-server/issues/1033) + ## 3.0.0 `2022-4-10` * `CHG` [break changes](https://github.com/sumneko/lua-language-server/issues/980) diff --git a/script/vm/compiler.lua b/script/vm/compiler.lua index 0becbbf0f..aff58c835 100644 --- a/script/vm/compiler.lua +++ b/script/vm/compiler.lua @@ -144,47 +144,59 @@ local searchFieldSwitch = util.switch() function m.getClassFields(suri, node, key, pushResult) local mark = {} - local function searchClass(class) + local function searchClass(class, searchedFields) local name = class.name if mark[name] then return end mark[name] = true + searchedFields = searchedFields or {} for _, set in ipairs(class:getSets(suri)) do if set.type == 'doc.class' then -- check ---@field - local hasFounded + local hasFounded = {} for _, field in ipairs(set.fields) do + local fieldKey = guide.getKeyName(field) if key == nil - or guide.getKeyName(field) == key then - hasFounded = true - pushResult(field) + or fieldKey == key then + if not searchedFields[fieldKey] then + pushResult(field) + hasFounded[fieldKey] = true + end end end -- check local field and global field if set.bindSources then for _, src in ipairs(set.bindSources) do searchFieldSwitch(src.type, suri, src, key, function (field) - if guide.isSet(field) then - hasFounded = true + local fieldKey = guide.getKeyName(field) + if not searchedFields[fieldKey] + and guide.isSet(field) then + hasFounded[fieldKey] = true pushResult(field) end end) if src._globalNode then searchFieldSwitch('global', suri, src._globalNode, key, function (field) - hasFounded = true - pushResult(field) + local fieldKey = field:getKeyName() + if not searchedFields[fieldKey] then + hasFounded[fieldKey] = true + pushResult(field) + end end) end end end -- look into extends(if field not found) - if not hasFounded and set.extends then + if not hasFounded[key] and set.extends then + for fieldKey in pairs(hasFounded) do + searchedFields[fieldKey] = true + end for _, extend in ipairs(set.extends) do if extend.type == 'doc.extends.name' then local extendType = globalMgr.getGlobal('type', extend[1]) if extendType then - searchClass(extendType) + searchClass(extendType, searchedFields) end end end diff --git a/script/vm/global.lua b/script/vm/global.lua index 8df8b6921..218e09dbe 100644 --- a/script/vm/global.lua +++ b/script/vm/global.lua @@ -15,6 +15,8 @@ mt.__index = mt mt.type = 'global' mt.name = '' +local ID_SPLITE = '\x1F' + ---@param uri uri ---@param source parser.object function mt:addSet(uri, source) @@ -93,6 +95,11 @@ function mt:getName() return self.name end +---@return string +function mt:getKeyName() + return self.name:match('[^' .. ID_SPLITE .. ']+$') +end + ---@return boolean function mt:isAlive() return next(self.links) ~= nil diff --git a/test/hover/init.lua b/test/hover/init.lua index 021746bea..760a9ab90 100644 --- a/test/hover/init.lua +++ b/test/hover/init.lua @@ -1849,3 +1849,20 @@ local x: { [1]: integer = 10, } ]] + +TEST [[ +---@class A +---@field x string + +---@class B: A +---@field y string + +---@type B +local +]] +[[ +local t: B { + x: string, + y: string, +} +]]