From 1407055930f23b06fbe9a6cc29cc9e54b1356783 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=80=E8=90=8C=E5=B0=8F=E6=B1=90?= Date: Sat, 16 Apr 2022 03:32:43 +0800 Subject: fix definition of `table` --- changelog.md | 3 +- script/parser/guide.lua | 2 +- script/parser/luadoc.lua | 91 ++++++++++++++++++++++++++------------------ script/vm/compiler.lua | 36 +++++++++--------- script/vm/global-manager.lua | 4 +- script/vm/infer.lua | 10 ++++- test/definition/luadoc.lua | 12 ++++++ 7 files changed, 97 insertions(+), 61 deletions(-) diff --git a/changelog.md b/changelog.md index 9a493187..1db4aecd 100644 --- a/changelog.md +++ b/changelog.md @@ -1,9 +1,10 @@ # changelog ## 3.1.0 -* `CHG` inlay-hint: move to LSP and enable by default. Its font is now controlled by the client. +* `CHG` hint: move to LSP and enable by default. Its font is now controlled by the client. * `CHG` hover: split `local` into `local` / `parameter` / `upvalue` / `self`. * `CHG` hover: added parentheses to some words, such as `global` / `field` / `class`. +* `FIX` definition of `table` ## 3.0.2 `2022-4-15` diff --git a/script/parser/guide.lua b/script/parser/guide.lua index 884a5271..0ece65fc 100644 --- a/script/parser/guide.lua +++ b/script/parser/guide.lua @@ -123,7 +123,6 @@ local childMap = { ['doc'] = {'#'}, ['doc.class'] = {'class', '#extends', '#signs', 'comment'}, ['doc.type'] = {'#types', 'name', 'comment'}, - ['doc.type.name'] = {'#signs'}, ['doc.alias'] = {'alias', 'extends', 'comment'}, ['doc.param'] = {'param', 'extends', 'comment'}, ['doc.return'] = {'#returns', 'comment'}, @@ -137,6 +136,7 @@ local childMap = { ['doc.type.literal'] = {'node'}, ['doc.type.arg'] = {'name', 'extends'}, ['doc.type.field'] = {'name', 'extends'}, + ['doc.type.sign'] = {'node', '#signs'}, ['doc.overload'] = {'overload', 'comment'}, ['doc.see'] = {'name', 'field'}, ['doc.version'] = {'#versions'}, diff --git a/script/parser/luadoc.lua b/script/parser/luadoc.lua index 22a2df1b..1d8d7c42 100644 --- a/script/parser/luadoc.lua +++ b/script/parser/luadoc.lua @@ -309,34 +309,21 @@ local function parseTable(parent) return typeUnit end -local function parseSigns(parent, mode) +local function parseSigns(parent) if not checkToken('symbol', '<', 1) then return nil end nextToken() local signs = {} while true do - local sign - if mode == 'name' then - sign = parseName('doc.generic.name', parent) - if not sign then - pushWarning { - type = 'LUADOC_MISS_SIGN_NAME', - start = getFinish(), - finish = getFinish(), - } - break - end - elseif mode == 'type' then - sign = parseType(parent) - if not sign then - pushWarning { - type = 'LUADOC_MISS_TYPE_NAME', - start = getFinish(), - finish = getFinish(), - } - break - end + local sign = parseName('doc.generic.name', parent) + if not sign then + pushWarning { + type = 'LUADOC_MISS_SIGN_NAME', + start = getFinish(), + finish = getFinish(), + } + break end signs[#signs+1] = sign if checkToken('symbol', ',', 1) then @@ -345,17 +332,7 @@ local function parseSigns(parent, mode) break end end - if not checkToken('symbol', '>', 1) then - pushWarning { - type = 'LUADOC_MISS_SYMBOL', - start = getFinish(), - finish = getFinish(), - symbol = { - symbol = '>', - } - } - end - nextToken() + nextSymbolOrError '>' return signs end @@ -376,7 +353,7 @@ local function parseClass(parent) end result.start = getStart() result.finish = getFinish() - result.signs = parseSigns(result, 'name') + result.signs = parseSigns(result) if not checkToken('symbol', ':', 1) then return result end @@ -421,6 +398,42 @@ local function parseTypeUnitArray(parent, node) return result end +local function parseTypeUnitSign(parent, node) + if not checkToken('symbol', '<', 1) then + return nil + end + nextToken() + local result = { + type = 'doc.type.sign', + start = node.start, + finish = getFinish(), + node = node, + parent = parent, + signs = {}, + } + node.parent = result + while true do + local sign = parseType(result) + if not sign then + pushWarning { + type = 'LUA_DOC_MISS_SIGN', + start = getFinish(), + finish = getFinish(), + } + break + end + result.signs[#result.signs+1] = sign + if checkToken('symbol', ',', 1) then + nextToken() + else + break + end + end + nextSymbolOrError '>' + result.finish = getFinish() + return result +end + local function parseDots(tp, parent) if not checkToken('symbol', '...', 1) then return @@ -629,7 +642,13 @@ function parseTypeUnit(parent) result.literal = true nextSymbolOrError '`' end - result.signs = parseSigns(result, 'type') + end + while true do + local newResult = parseTypeUnitSign(parent, result) + if not newResult then + break + end + result = newResult end while true do local newResult = parseTypeUnitArray(parent, result) @@ -777,7 +796,7 @@ local function parseAlias() return nil end result.start = getStart() - result.signs = parseSigns(result, 'name') + result.signs = parseSigns(result) result.extends = parseType(result) if not result.extends then pushWarning { diff --git a/script/vm/compiler.lua b/script/vm/compiler.lua index 3840c857..e3c7e2b9 100644 --- a/script/vm/compiler.lua +++ b/script/vm/compiler.lua @@ -1122,30 +1122,28 @@ local compilerSwitch = util.switch() : call(function (source) vm.setNode(source, source) end) - : case 'doc.type.name' + : case 'doc.type.sign' : call(function (source) - if source.signs then - local uri = guide.getUri(source) - vm.setNode(source, source) - local global = globalMgr.getGlobal('type', source[1]) - for _, set in ipairs(global:getSets(uri)) do - if set.type == 'doc.class' then - if set.extends then - for _, ext in ipairs(set.extends) do - if ext.type == 'doc.type.table' then - if ext._generic then - local resolved = ext._generic:resolve(uri, source.signs) - vm.setNode(source, resolved) - end + local uri = guide.getUri(source) + vm.setNode(source, source) + local global = globalMgr.getGlobal('type', source.node[1]) + for _, set in ipairs(global:getSets(uri)) do + if set.type == 'doc.class' then + if set.extends then + for _, ext in ipairs(set.extends) do + if ext.type == 'doc.type.table' then + if ext._generic then + local resolved = ext._generic:resolve(uri, source.signs) + vm.setNode(source, resolved) end end end end - if set.type == 'doc.alias' then - if set.extends._generic then - local resolved = set.extends._generic:resolve(uri, source.signs) - vm.setNode(source, resolved) - end + end + if set.type == 'doc.alias' then + if set.extends._generic then + local resolved = set.extends._generic:resolve(uri, source.signs) + vm.setNode(source, resolved) end end end diff --git a/script/vm/global-manager.lua b/script/vm/global-manager.lua index 2a3aea2f..1481f14e 100644 --- a/script/vm/global-manager.lua +++ b/script/vm/global-manager.lua @@ -189,9 +189,7 @@ local compilerGlobalSwitch = util.switch() local name = source[1] local type = m.declareGlobal('type', name, uri) type:addGet(uri, source) - if not source.signs then - source._globalNode = type - end + source._globalNode = type end) : case 'doc.extends.name' : call(function (source) diff --git a/script/vm/infer.lua b/script/vm/infer.lua index a5b113d6..a47783f7 100644 --- a/script/vm/infer.lua +++ b/script/vm/infer.lua @@ -87,7 +87,6 @@ local viewNodeSwitch = util.switch() end) : case 'doc.type.name' : call(function (source, infer) - infer._hasClass = true if source.signs then local buf = {} for i, sign in ipairs(source.signs) do @@ -115,6 +114,15 @@ local viewNodeSwitch = util.switch() end return view .. '[]' end) + : case 'doc.type.sign' + : call(function (source, infer) + infer._hasClass = true + local buf = {} + for i, sign in ipairs(source.signs) do + buf[i] = m.getInfer(sign):view() + end + return ('%s<%s>'):format(source.node[1], table.concat(buf, ', ')) + end) : case 'doc.type.table' : call(function (source, infer) infer._hasTable = true diff --git a/test/definition/luadoc.lua b/test/definition/luadoc.lua index d7ac9a5b..19b4421b 100644 --- a/test/definition/luadoc.lua +++ b/test/definition/luadoc.lua @@ -881,3 +881,15 @@ G = { local f f. ]] + +TEST [[ +---@class : {} + +---@type <> +]] + +TEST [[ +---@class + +---@type XXX<> +]] -- cgit v1.2.3