diff options
-rw-r--r-- | changelog.md | 1 | ||||
-rw-r--r-- | script/core/diagnostics/circle-doc-class.lua | 32 | ||||
-rw-r--r-- | script/core/diagnostics/undefined-doc-class.lua | 37 | ||||
-rw-r--r-- | script/core/hover/label.lua | 10 | ||||
-rw-r--r-- | script/parser/guide.lua | 16 | ||||
-rw-r--r-- | script/parser/luadoc.lua | 34 | ||||
-rw-r--r-- | test/definition/luadoc.lua | 13 |
7 files changed, 90 insertions, 53 deletions
diff --git a/changelog.md b/changelog.md index 57110d70..971b5192 100644 --- a/changelog.md +++ b/changelog.md @@ -3,6 +3,7 @@ ## 1.16.0 * `NEW` file encoding supports `ansi` * `NEW` completion: supports interface, see [#384](https://github.com/sumneko/lua-language-server/issues/384) +* `NEW` `LuaDoc`: supports multiple class inheritance: `---@class Food: Burger, Pizza, Pie, Pasta` * `CHG` rename `table*` to `tablelib` * `CHG` `LuaDoc`: revert compatible with `--@`, see [#392](https://github.com/sumneko/lua-language-server/issues/392) * `CHG` improve performance diff --git a/script/core/diagnostics/circle-doc-class.lua b/script/core/diagnostics/circle-doc-class.lua index 7ef76603..f3721fd9 100644 --- a/script/core/diagnostics/circle-doc-class.lua +++ b/script/core/diagnostics/circle-doc-class.lua @@ -28,21 +28,23 @@ return function (uri, callback) goto CONTINUE end if current.extends then - local newName = current.extends[1] - if newName == myName then - callback { - start = doc.start, - finish = doc.finish, - message = lang.script('DIAG_CIRCLE_DOC_CLASS', myName) - } - goto CONTINUE - end - if not mark[newName] then - mark[newName] = true - local docs = vm.getDocTypes(newName) - for _, otherDoc in ipairs(docs) do - if otherDoc.type == 'doc.class.name' then - list[#list+1] = otherDoc.parent + for _, extend in ipairs(current.extends) do + local newName = extend[1] + if newName == myName then + callback { + start = doc.start, + finish = doc.finish, + message = lang.script('DIAG_CIRCLE_DOC_CLASS', myName) + } + goto CONTINUE + end + if not mark[newName] then + mark[newName] = true + local docs = vm.getDocTypes(newName) + for _, otherDoc in ipairs(docs) do + if otherDoc.type == 'doc.class.name' then + list[#list+1] = otherDoc.parent + end end end end diff --git a/script/core/diagnostics/undefined-doc-class.lua b/script/core/diagnostics/undefined-doc-class.lua index 8e0be20a..7d23971a 100644 --- a/script/core/diagnostics/undefined-doc-class.lua +++ b/script/core/diagnostics/undefined-doc-class.lua @@ -20,28 +20,29 @@ return function (uri, callback) } for _, doc in ipairs(state.ast.docs) do if doc.type == 'doc.class' then - local ext = doc.extends - if not ext then + if not doc.extends then goto CONTINUE end - local name = ext[1] - local docs = vm.getDocTypes(name) - if cache[name] == nil then - cache[name] = false - for _, otherDoc in ipairs(docs) do - if otherDoc.type == 'doc.class.name' then - cache[name] = true - break + for _, ext in ipairs(doc.extends) do + local name = ext[1] + local docs = vm.getDocTypes(name) + if cache[name] == nil then + cache[name] = false + for _, otherDoc in ipairs(docs) do + if otherDoc.type == 'doc.class.name' then + cache[name] = true + break + end end end - end - if not cache[name] then - callback { - start = ext.start, - finish = ext.finish, - related = cache, - message = lang.script('DIAG_UNDEFINED_DOC_CLASS', name) - } + if not cache[name] then + callback { + start = ext.start, + finish = ext.finish, + related = cache, + message = lang.script('DIAG_UNDEFINED_DOC_CLASS', name) + } + end end end ::CONTINUE:: diff --git a/script/core/hover/label.lua b/script/core/hover/label.lua index a82a09ea..dd309c41 100644 --- a/script/core/hover/label.lua +++ b/script/core/hover/label.lua @@ -126,16 +126,22 @@ local function asDocField(source) break end end + local infers = {} + for _, ext in ipairs(source.extends) do + for _, infer in ipairs(vm.getInfers(ext) or {}) do + infers[#infers+1] = infer + end + end if not class then return ('field ?.%s: %s'):format( name, - vm.getInferType(source.extends) + guide.viewInferType(infers) ) end return ('field %s.%s: %s'):format( class.class[1], name, - vm.getInferType(source.extends) + guide.viewInferType(infers) ) end diff --git a/script/parser/guide.lua b/script/parser/guide.lua index 377b1ce8..b099dd9b 100644 --- a/script/parser/guide.lua +++ b/script/parser/guide.lua @@ -90,7 +90,7 @@ m.childMap = { ['unary'] = {1}, ['doc'] = {'#'}, - ['doc.class'] = {'class', 'extends', 'comment'}, + ['doc.class'] = {'class', '#extends', 'comment'}, ['doc.type'] = {'#types', '#enums', 'name', 'comment'}, ['doc.alias'] = {'alias', 'extends', 'comment'}, ['doc.param'] = {'param', 'extends', 'comment'}, @@ -505,8 +505,10 @@ function m.addChilds(list, obj, map) elseif type(key) == 'string' and key:sub(1, 1) == '#' then key = key:sub(2) - for i = 1, #obj[key] do - list[#list+1] = obj[key][i] + if obj[key] then + for i = 1, #obj[key] do + list[#list+1] = obj[key][i] + end end end end @@ -1813,9 +1815,11 @@ function m.checkSameSimpleByDoc(status, obj, start, pushQueue, mode) pushQueue(res, start, true) end if obj.extends then - local pieceResult = stepRefOfDocType(status, obj.extends, 'def') - for _, res in ipairs(pieceResult) do - pushQueue(res, start, true) + for _, ext in ipairs(obj.extends) do + local pieceResult = stepRefOfDocType(status, ext, 'def') + for _, res in ipairs(pieceResult) do + pushQueue(res, start, true) + end end end end diff --git a/script/parser/luadoc.lua b/script/parser/luadoc.lua index eabf8936..13816943 100644 --- a/script/parser/luadoc.lua +++ b/script/parser/luadoc.lua @@ -208,8 +208,7 @@ local function parseClass(parent) if not peekToken() then return result end - nextToken() - if not checkToken('symbol', ':') then + if not checkToken('symbol', ':', 1) then pushError { type = 'LUADOC_MISS_EXTENDS_SYMBOL', start = result.finish + 1, @@ -217,16 +216,27 @@ local function parseClass(parent) } return result end - result.extends = parseName('doc.extends.name', result) - if not result.extends then - pushError { - type = 'LUADOC_MISS_CLASS_EXTENDS_NAME', - start = getFinish(), - finish = getFinish(), - } - return result + nextToken() + + result.extends = {} + + while true do + local extend = parseName('doc.extends.name', result) + if not extend then + pushError { + type = 'LUADOC_MISS_CLASS_EXTENDS_NAME', + start = getFinish(), + finish = getFinish(), + } + return result + end + result.extends[#result.extends+1] = extend + result.finish = getFinish() + if not checkToken('symbol', ',', 1) then + break + end + nextToken() end - result.finish = getFinish() return result end @@ -285,7 +295,7 @@ local function parseTypeUnitTable(parent, node) return nil end nextSymbolOrError('>') - + node.parent = result; result.finish = getFinish() result.key = key diff --git a/test/definition/luadoc.lua b/test/definition/luadoc.lua index 5315b5fd..314af605 100644 --- a/test/definition/luadoc.lua +++ b/test/definition/luadoc.lua @@ -341,3 +341,16 @@ function Foo:<!bar1!>() end local v1 print(v1[1][1].<?bar1?>) ]] + +TEST [[ +---@class X + +---@class Y +---@field <!a!> string + +---@class Z:X, Y + +---@type Z +local z +z.<?a?> +]] |