diff options
-rw-r--r-- | meta/template/basic.lua | 6 | ||||
-rw-r--r-- | script/core/completion/completion.lua | 4 | ||||
-rw-r--r-- | script/core/diagnostics/type-check.lua | 8 | ||||
-rw-r--r-- | script/core/hover/arg.lua | 6 | ||||
-rw-r--r-- | script/core/hover/return.lua | 3 | ||||
-rw-r--r-- | script/core/semantic-tokens.lua | 2 | ||||
-rw-r--r-- | script/parser/luadoc.lua | 173 | ||||
-rw-r--r-- | script/vm/compiler.lua | 5 | ||||
-rw-r--r-- | script/vm/getDocs.lua | 2 | ||||
-rw-r--r-- | script/vm/infer.lua | 8 | ||||
-rw-r--r-- | test/example/guide.txt | 2 | ||||
-rw-r--r-- | test/hover/init.lua | 3 |
12 files changed, 97 insertions, 125 deletions
diff --git a/meta/template/basic.lua b/meta/template/basic.lua index b26d3959..980b3dc1 100644 --- a/meta/template/basic.lua +++ b/meta/template/basic.lua @@ -11,7 +11,7 @@ arg = {} ---@return T function assert(v, message) end ----@alias cgopt +---@alias gcoptions ---|>'"collect"' # ---#DESTAIL 'cgopt.collect' ---| '"stop"' # ---#DESTAIL 'cgopt.stop' ---| '"restart"' # ---#DESTAIL 'cgopt.restart' @@ -28,12 +28,12 @@ function assert(v, message) end ---#if VERSION >= 5.4 then ---#DES 'collectgarbage' ----@param opt? cgopt +---@param opt? gcoptions ---@return any function collectgarbage(opt, ...) end ---#else ---#DES 'collectgarbage' ----@param opt? cgopt +---@param opt? gcoptions ---@param arg? integer ---@return any function collectgarbage(opt, arg) end diff --git a/script/core/completion/completion.lua b/script/core/completion/completion.lua index e7633e7c..f54bd2d1 100644 --- a/script/core/completion/completion.lua +++ b/script/core/completion/completion.lua @@ -1105,7 +1105,7 @@ end local function checkTypingEnum(state, position, defs, str, results) local enums = {} for _, def in ipairs(defs) do - if def.type == 'doc.type.enum' + if def.type == 'doc.type.string' or def.type == 'doc.resume' then enums[#enums+1] = { label = def[1], @@ -1315,7 +1315,7 @@ end local function pushCallEnumsAndFuncs(defs) local results = {} for _, def in ipairs(defs) do - if def.type == 'doc.type.enum' + if def.type == 'doc.type.string' or def.type == 'doc.resume' then results[#results+1] = { label = def[1], diff --git a/script/core/diagnostics/type-check.lua b/script/core/diagnostics/type-check.lua index cbdb40a1..ebfffea0 100644 --- a/script/core/diagnostics/type-check.lua +++ b/script/core/diagnostics/type-check.lua @@ -17,7 +17,7 @@ local typeNameMap = { ['doc.class.name'] = true, ['doc.alias.name'] = true, ['doc.type.name'] = true, - ['doc.type.enum'] = true, + ['doc.type.string'] = true, ['doc.resume'] = true, } @@ -165,7 +165,7 @@ local function getParamTypes(arg) for _, argDef in ipairs(argDefs) do if argDef.type == 'doc.class.name' or argDef.type == 'doc.type.name' - or argDef.type == 'doc.type.enum' + or argDef.type == 'doc.type.string' or argDef.type == 'doc.type.ltable' then types[#types+1] = argDef end @@ -184,7 +184,7 @@ local function getParamTypes(arg) type = 'nil' } end - elseif argDef.type == 'doc.type.enum' + elseif argDef.type == 'doc.type.string' or argDef.type == 'doc.type.ltable' then types[#types+1] = argDef ---变长参数 @@ -316,7 +316,7 @@ local function getArgsInfo(uri, callArgs) -- } -- elseif def.type == 'doc.class.name' -- or def.type == 'doc.type.name' - -- or def.type == 'doc.type.enum' + -- or def.type == 'doc.type.string' -- or def.type == 'doc.type.ltable' then -- if def[1] then -- if not types.typeMap[def[1]] then diff --git a/script/core/hover/arg.lua b/script/core/hover/arg.lua index c2c6a105..c9c81a85 100644 --- a/script/core/hover/arg.lua +++ b/script/core/hover/arg.lua @@ -34,15 +34,15 @@ local function asFunction(source, oop) args[#args+1] = ('%s%s: %s'):format( name, optionalArg(arg) and '?' or '', - infer.viewType(arg) + infer.viewType(arg, 'any') ) elseif arg.type == '...' then args[#args+1] = ('%s: %s'):format( '...', - infer.viewType(arg) + infer.viewType(arg, 'any') ) else - args[#args+1] = ('%s'):format(infer.viewType(arg)) + args[#args+1] = ('%s'):format(infer.viewType(arg, 'any')) end ::CONTINUE:: end diff --git a/script/core/hover/return.lua b/script/core/hover/return.lua index f34f364e..e48febf3 100644 --- a/script/core/hover/return.lua +++ b/script/core/hover/return.lua @@ -64,8 +64,9 @@ local function asFunction(source) for i = 1, num do local rtn = compiler.getReturnOfFunction(source, i) local doc = docs[i] + local name = doc and doc.name and doc.name[1] and (doc.name[1] .. ': ') local text = ('%s%s%s'):format( - doc and doc.name[1] or '', + name or '', infer.viewType(rtn), doc and doc.optional and '?' or '' ) diff --git a/script/core/semantic-tokens.lua b/script/core/semantic-tokens.lua index f57246d3..ec19af1a 100644 --- a/script/core/semantic-tokens.lua +++ b/script/core/semantic-tokens.lua @@ -501,7 +501,7 @@ local Care = util.switch() modifieres = define.TokenModifiers.modification, } end) - : case 'doc.type.enum' + : case 'doc.type.string' : call(function (source, options, results) if not options.annotation then return diff --git a/script/parser/luadoc.lua b/script/parser/luadoc.lua index cf734a53..cfde757b 100644 --- a/script/parser/luadoc.lua +++ b/script/parser/luadoc.lua @@ -193,14 +193,14 @@ local function parseName(tp, parent) return nil end nextToken() - local class = { + local name = { type = tp, start = getStart(), finish = getFinish(), parent = parent, [1] = nameText, } - return class + return name end local function nextSymbolOrError(symbol) @@ -537,23 +537,68 @@ local function parseFunction(parent) end end +local function parseString(parent) + local tp, content = peekToken() + if not tp or tp ~= 'string' then + return nil + end + + nextToken() + -- compatibility + if content:sub(1, 1) == '"' + or content:sub(1, 1) == "'" then + if content:sub(1, 1) == content:sub(-1, -1) then + content = content:sub(2, -2) + end + end + local str = { + type = 'doc.type.string', + start = getStart(), + finish = getFinish(), + parent = parent, + [1] = content, + } + return str +end + +local function parseInteger(parent) + local tp, content = peekToken() + if not tp or tp ~= 'integer' then + return nil + end + + nextToken() + local integer = { + type = 'doc.type.integer', + start = getStart(), + finish = getFinish(), + parent = parent, + [1] = content, + } + return integer +end + function parseTypeUnit(parent) local result = parseFunction(parent) or parseTable(parent) + or parseString(parent) + or parseInteger(parent) + or parseDots('doc.type.name', parent) if not result then - local _, token = nextToken() - result = { - type = 'doc.type.name', - start = getStart(), - finish = getFinish(), - parent = parent, - [1] = token, - } + local literal = checkToken('symbol', '`', 1) + if literal then + nextToken() + end + result = parseName('doc.type.name', parent) + if not result then + return nil + end + if literal then + result.literal = true + nextSymbolOrError '`' + end result.signs = parseSigns(result, 'type') end - if not result then - return nil - end while true do local newResult = parseTypeUnitArray(parent, result) if not newResult then @@ -565,19 +610,21 @@ function parseTypeUnit(parent) end local function parseResume(parent) - local result = { - type = 'doc.resume', - parent = parent, - } - + local default, additional if checkToken('symbol', '>', 1) then nextToken() - result.default = true + default = true end if checkToken('symbol', '+', 1) then nextToken() - result.additional = true + additional = true + end + + local result = parseTypeUnit(parent) + if result then + result.default = default + result.additional = additional end local tp = peekToken() @@ -603,92 +650,16 @@ function parseType(parent) types = {}, } while true do - local tp, content = peekToken() - if not tp then + local typeUnit = parseTypeUnit(result) + if not typeUnit then break end - -- 处理 `T` 的情况 - local typeLiteral = nil - if tp == 'symbol' and content == '`' then - nextToken() - if not checkToken('symbol', '`', 2) then - break - end - tp, content = peekToken() - if not tp then - break - end - -- TypeLiteral,指代类型的字面值。比如,对于类 Cat 来说,它的 TypeLiteral 是 "Cat" - typeLiteral = true + result.types[#result.types+1] = typeUnit + if not result.start then + result.start = typeUnit.start end - if tp == 'name' then - local typeUnit = parseTypeUnit(result) - if not typeUnit then - break - end - if typeLiteral then - nextToken() - typeUnit.literal = true - end - result.types[#result.types+1] = typeUnit - if not result.start then - result.start = typeUnit.start - end - elseif tp == 'string' then - nextToken() - -- compatibility - if content:sub(1, 1) == '"' - or content:sub(1, 1) == "'" then - if content:sub(1, 1) == content:sub(-1, -1) then - content = content:sub(2, -2) - end - end - local typeEnum = { - type = 'doc.type.enum', - start = getStart(), - finish = getFinish(), - parent = result, - [1] = content, - } - result.types[#result.types+1] = typeEnum - if not result.start then - result.start = typeEnum.start - end - elseif tp == 'symbol' and content == '{' then - local typeUnit = parseTypeUnit(result) - if not typeUnit then - break - end - result.types[#result.types+1] = typeUnit - if not result.start then - result.start = typeUnit.start - end - elseif tp == 'symbol' and content == '...' then - nextToken() - local vararg = { - type = 'doc.type.name', - start = getStart(), - finish = getFinish(), - parent = result, - [1] = content, - } - result.types[#result.types+1] = vararg - if not result.start then - result.start = vararg.start - end - elseif tp == 'integer' then - nextToken() - local integer = { - type = 'doc.type.integer', - start = getStart(), - finish = getFinish(), - parent = result, - [1] = content, - } - result.types[#result.types+1] = integer - end if not checkToken('symbol', '|', 1) then break end diff --git a/script/vm/compiler.lua b/script/vm/compiler.lua index 2464fe53..d6caa71f 100644 --- a/script/vm/compiler.lua +++ b/script/vm/compiler.lua @@ -396,6 +396,7 @@ local function selectNode(source, list, index) or n.type == 'doc.type.function' or n.type == 'doc.type.table' or n.type == 'doc.type.integer' + or n.type == 'doc.type.string' or (n.type == 'global' and n.cate == 'type') then hasKnownType = true break @@ -452,7 +453,7 @@ local function setCallArgNode(source, call, callNode, fixIndex) local event = m.compileNode(n.args[eventIndex]) if not event or not eventMap - or event.type ~= 'doc.type.enum' + or event.type ~= 'doc.type.string' or eventMap[event[1]] then local arg = n.args[myIndex] for fn in nodeMgr.eachNode(m.compileNode(arg)) do @@ -712,7 +713,7 @@ local compilerMap = util.switch() : call(function (source) nodeMgr.setNode(source, source) end) - : case 'doc.type.enum' + : case 'doc.type.string' : call(function (source) nodeMgr.setNode(source, source) end) diff --git a/script/vm/getDocs.lua b/script/vm/getDocs.lua index 4204d785..8c15fd99 100644 --- a/script/vm/getDocs.lua +++ b/script/vm/getDocs.lua @@ -69,7 +69,7 @@ function vm.getDocEnums(doc) local results = {} for _, def in ipairs(defs) do - if def.type == 'doc.type.enum' + if def.type == 'doc.type.string' or def.type == 'doc.resume' then results[#results+1] = def end diff --git a/script/vm/infer.lua b/script/vm/infer.lua index 9a1b8276..5ac7d73b 100644 --- a/script/vm/infer.lua +++ b/script/vm/infer.lua @@ -80,7 +80,7 @@ local viewNodeMap = util.switch() : call(function (source, options) options['hasTable'] = true end) - : case 'doc.type.enum' + : case 'doc.type.string' : call(function (source, options) return ('%q'):format(source[1]) end) @@ -187,7 +187,7 @@ end function m.hasType(source, tp) local views = m.getViews(source) - if views[source] then + if views[tp] then return true end @@ -196,7 +196,7 @@ end ---@param source parser.object ---@return string -function m.viewType(source) +function m.viewType(source, default) local views = m.getViews(source) if views['any'] then @@ -204,7 +204,7 @@ function m.viewType(source) end if not next(views) then - return 'unknown' + return default or 'unknown' end local array = {} diff --git a/test/example/guide.txt b/test/example/guide.txt index cff05faf..1aef61ae 100644 --- a/test/example/guide.txt +++ b/test/example/guide.txt @@ -2718,7 +2718,7 @@ function m.viewInferType(infers) or src.type == 'doc.type.name' or src.type == 'doc.type.array' or src.type == 'doc.type.table' - or src.type == 'doc.type.enum' + or src.type == 'doc.type.string' or src.type == 'doc.resume' then local tp = infer.type or 'any' if not mark[tp] then diff --git a/test/hover/init.lua b/test/hover/init.lua index f6172aa1..9cb24d3d 100644 --- a/test/hover/init.lua +++ b/test/hover/init.lua @@ -272,9 +272,8 @@ TEST [[ local type w2l:get_default()[<?type?>] ]] -"local type: any" +"local type: unknown" --- TODO 可选参数(或多原型) TEST [[ <?load?>() ]] |