summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--changelog.md1
-rw-r--r--script/core/diagnostics/circle-doc-class.lua32
-rw-r--r--script/core/diagnostics/undefined-doc-class.lua37
-rw-r--r--script/core/hover/label.lua10
-rw-r--r--script/parser/guide.lua16
-rw-r--r--script/parser/luadoc.lua34
-rw-r--r--test/definition/luadoc.lua13
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?>
+]]