From 7f95e6f71862967bcdc9ca1d78a1947dd177ca3e Mon Sep 17 00:00:00 2001 From: lizho Date: Tue, 30 Jan 2024 09:36:41 +0800 Subject: [PATCH 1/2] support tuple type --- script/parser/luadoc.lua | 71 +++++++++++++++++++++++ script/vm/infer.lua | 20 ++++--- test/diagnostics/assign-type-mismatch.lua | 7 +++ test/hover/init.lua | 11 ++++ 4 files changed, 100 insertions(+), 9 deletions(-) diff --git a/script/parser/luadoc.lua b/script/parser/luadoc.lua index 227808a0a..1a777be19 100644 --- a/script/parser/luadoc.lua +++ b/script/parser/luadoc.lua @@ -369,6 +369,75 @@ local function parseTable(parent) return typeUnit end +local function parseTuple(parent) + if not checkToken('symbol', '[', 1) then + return nil + end + nextToken() + local typeUnit = { + type = 'doc.type.table', + start = getStart(), + parent = parent, + fields = {}, + isTuple = true, + } + + local index = 1 + while true do + if checkToken('symbol', ']', 1) then + nextToken() + break + end + local field = { + type = 'doc.type.field', + parent = typeUnit, + } + + do + local needCloseParen + if checkToken('symbol', '(', 1) then + nextToken() + needCloseParen = true + end + field.name = { + type = 'doc.type', + start = getFinish(), + firstFinish = getFinish(), + finish = getFinish(), + parent = field, + } + field.name.types = { + [1] = { + type = 'doc.type.integer', + start = getFinish(), + finish = getFinish(), + parent = field.name, + [1] = index, + } + } + index = index + 1 + field.extends = parseType(field) + field.optional = field.extends.optional + field.start = field.extends.start + field.finish = field.extends.finish + if needCloseParen then + nextSymbolOrError ')' + end + end + + typeUnit.fields[#typeUnit.fields+1] = field + if checkToken('symbol', ',', 1) + or checkToken('symbol', ';', 1) then + nextToken() + else + nextSymbolOrError(']') + break + end + end + typeUnit.finish = getFinish() + return typeUnit +end + local function parseSigns(parent) if not checkToken('symbol', '<', 1) then return nil @@ -682,6 +751,7 @@ end function parseTypeUnit(parent) local result = parseFunction(parent) or parseTable(parent) + or parseTuple(parent) or parseString(parent) or parseCode(parent) or parseInteger(parent) @@ -864,6 +934,7 @@ local docSwitch = util.switch() while true do local extend = parseName('doc.extends.name', result) or parseTable(result) + or parseTuple(result) if not extend then pushWarning { type = 'LUADOC_MISS_CLASS_EXTENDS_NAME', diff --git a/script/vm/infer.lua b/script/vm/infer.lua index f2673ed3e..3f3d0e3a8 100644 --- a/script/vm/infer.lua +++ b/script/vm/infer.lua @@ -157,22 +157,24 @@ local viewNodeSwitch;viewNodeSwitch = util.switch() end infer._hasClass = true local buf = {} - buf[#buf+1] = '{ ' + buf[#buf+1] = source.isTuple and '[' or '{ ' for i, field in ipairs(source.fields) do if i > 1 then buf[#buf+1] = ', ' end - local key = field.name - if key.type == 'doc.type' then - buf[#buf+1] = ('[%s]: '):format(vm.getInfer(key):view(uri)) - elseif type(key[1]) == 'string' then - buf[#buf+1] = key[1] .. ': ' - else - buf[#buf+1] = ('[%q]: '):format(key[1]) + if not source.isTuple then + local key = field.name + if key.type == 'doc.type' then + buf[#buf+1] = ('[%s]: '):format(vm.getInfer(key):view(uri)) + elseif type(key[1]) == 'string' then + buf[#buf+1] = key[1] .. ': ' + else + buf[#buf+1] = ('[%q]: '):format(key[1]) + end end buf[#buf+1] = vm.getInfer(field.extends):view(uri) end - buf[#buf+1] = ' }' + buf[#buf+1] = source.isTuple and ']' or ' }' return table.concat(buf) end) : case 'doc.type.string' diff --git a/test/diagnostics/assign-type-mismatch.lua b/test/diagnostics/assign-type-mismatch.lua index d46325633..dc55a7dac 100644 --- a/test/diagnostics/assign-type-mismatch.lua +++ b/test/diagnostics/assign-type-mismatch.lua @@ -98,6 +98,13 @@ local t = {} t['x'] = nil ]] +TEST [[ +---@type [boolean] +local t = { = nil } + +t = nil +]] + TEST [[ local t = { true } diff --git a/test/hover/init.lua b/test/hover/init.lua index 63220a59c..0cfce3a42 100644 --- a/test/hover/init.lua +++ b/test/hover/init.lua @@ -1228,6 +1228,17 @@ local local x: table ]] +TEST [[ +---@type [ClassA, ClassB] +local +]] +[[ +local x: [ClassA, ClassB] { + [1]: ClassA, + [2]: ClassB, +} +]] + --TEST [[ -----@class ClassA -----@class ClassB From 7503881344501248ac36d25d85dfc560809ced21 Mon Sep 17 00:00:00 2001 From: lizho Date: Tue, 30 Jan 2024 15:45:10 +0800 Subject: [PATCH 2/2] fix LSP crashes when parsing tuples --- script/parser/luadoc.lua | 3 +++ 1 file changed, 3 insertions(+) diff --git a/script/parser/luadoc.lua b/script/parser/luadoc.lua index 1a777be19..6d9bad0d6 100644 --- a/script/parser/luadoc.lua +++ b/script/parser/luadoc.lua @@ -417,6 +417,9 @@ local function parseTuple(parent) } index = index + 1 field.extends = parseType(field) + if not field.extends then + break + end field.optional = field.extends.optional field.start = field.extends.start field.finish = field.extends.finish