diff options
Diffstat (limited to 'script')
-rw-r--r-- | script/core/completion/completion.lua | 83 | ||||
-rw-r--r-- | script/core/definition.lua | 5 | ||||
-rw-r--r-- | script/core/diagnostics/circle-doc-class.lua | 2 | ||||
-rw-r--r-- | script/core/diagnostics/duplicate-doc-class.lua | 2 | ||||
-rw-r--r-- | script/core/diagnostics/type-check.lua | 14 | ||||
-rw-r--r-- | script/core/diagnostics/undefined-doc-class.lua | 2 | ||||
-rw-r--r-- | script/core/diagnostics/undefined-doc-name.lua | 2 | ||||
-rw-r--r-- | script/core/hover/description.lua | 4 | ||||
-rw-r--r-- | script/core/semantic-tokens.lua | 18 | ||||
-rw-r--r-- | script/parser/guide.lua | 6 | ||||
-rw-r--r-- | script/proto/define.lua | 15 | ||||
-rw-r--r-- | script/vm/compiler.lua | 4 | ||||
-rw-r--r-- | script/vm/doc.lua (renamed from script/vm/getDocs.lua) | 58 | ||||
-rw-r--r-- | script/vm/global-manager.lua | 44 | ||||
-rw-r--r-- | script/vm/infer.lua | 1 | ||||
-rw-r--r-- | script/vm/init.lua | 2 | ||||
-rw-r--r-- | script/vm/local-id.lua | 14 |
17 files changed, 124 insertions, 152 deletions
diff --git a/script/core/completion/completion.lua b/script/core/completion/completion.lua index 76dd6480..aed3e83a 100644 --- a/script/core/completion/completion.lua +++ b/script/core/completion/completion.lua @@ -19,6 +19,7 @@ local guide = require 'parser.guide' local infer = require 'vm.infer' local await = require 'await' local postfix = require 'core.completion.postfix' +local globalMgr = require 'vm.global-manager' local diagnosticModes = { 'disable-next-line', @@ -287,7 +288,7 @@ local function checkLocal(state, word, position, results) if name:sub(1, 1) == '@' then goto CONTINUE end - if infer.hasType(source, 'function') then + if infer.getInfer(source):hasType 'function' then for _, def in ipairs(vm.getDefs(source)) do if def.type == 'function' or def.type == 'doc.type.function' then @@ -335,7 +336,7 @@ local function checkModule(state, word, position, results) local fileName = path:match '[^/\\]*$' local stemName = fileName:gsub('%..+', '') if not locals[stemName] - and not vm.hasGlobalSets(state.uri, stemName) + and not globalMgr.hasGlobalSets(state.uri, 'variable', stemName) and not config.get(state.uri, 'Lua.diagnostics.globals')[stemName] and stemName:match '^[%a_][%w_]*$' and matchKey(word, stemName) then @@ -482,7 +483,7 @@ local function checkFieldThen(state, name, src, word, startPos, position, parent }) return end - if oop and not infer.hasType(src, 'function') then + if oop and not infer.getInfer(src):hasType 'function' then return end local literal = guide.getLiteral(value) @@ -584,17 +585,17 @@ end ---@async local function checkGlobal(state, word, startPos, position, parent, oop, results) local locals = guide.getVisibleLocals(state.ast, position) - local globals = vm.getGlobalSets(state.uri, '*') + local globals = globalMgr.getGlobalSets(state.uri, 'variable') checkFieldOfRefs(globals, state, word, startPos, position, parent, oop, results, locals, 'global') end ---@async local function checkField(state, word, start, position, parent, oop, results) if parent.tag == '_ENV' or parent.special == '_G' then - local globals = vm.getGlobalSets(state.uri, '*') + local globals = globalMgr.getGlobalSets(state.uri, 'variable') checkFieldOfRefs(globals, state, word, start, position, parent, oop, results) else - local refs = vm.getRefs(parent, '*') + local refs = vm.getFields(parent) checkFieldOfRefs(refs, state, word, start, position, parent, oop, results) end end @@ -1106,7 +1107,7 @@ local function checkTypingEnum(state, position, defs, str, results) local enums = {} for _, def in ipairs(defs) do if def.type == 'doc.type.string' - or def.type == 'doc.resume' then + or def.type == 'doc.type.integer' then enums[#enums+1] = { label = def[1], description = def.comment and def.comment.text, @@ -1312,20 +1313,20 @@ function (%s)\ end"):format(table.concat(args, ', ')) end -local function pushCallEnumsAndFuncs(defs) +local function pushCallEnumsAndFuncs(source) + local defs = vm.getDefs(source) local results = {} for _, def in ipairs(defs) do - if def.type == 'doc.type.string' - or def.type == 'doc.resume' then + if def.type == 'doc.type.string' then results[#results+1] = { - label = def[1], + label = util.viewLiteral(def[1]), description = def.comment, kind = define.CompletionItemKind.EnumMember, } end if def.type == 'doc.type.function' then results[#results+1] = { - label = infer.viewDocFunction(def), + label = infer.getInfer(def):view(), description = def.comment, kind = define.CompletionItemKind.Function, insertText = buildInsertDocFunction(def), @@ -1354,17 +1355,17 @@ local function getCallEnumsAndFuncs(source, index, oop, call) for _, doc in ipairs(source.bindDocs) do if doc.type == 'doc.param' and doc.param[1] == arg[1] then - return pushCallEnumsAndFuncs(vm.getDefs(doc.extends)) + return pushCallEnumsAndFuncs(doc.extends) elseif doc.type == 'doc.vararg' and arg.type == '...' then - return pushCallEnumsAndFuncs(vm.getDefs(doc.vararg)) + return pushCallEnumsAndFuncs(doc.vararg) end end end if source.type == 'doc.type.function' then local arg = source.args[index] if arg and arg.extends then - return pushCallEnumsAndFuncs(vm.getDefs(arg.extends)) + return pushCallEnumsAndFuncs(arg.extends) end end if source.type == 'doc.field.name' then @@ -1400,7 +1401,7 @@ local function getCallEnumsAndFuncs(source, index, oop, call) if eventName and eventName == myEventName then local docFunc = doc.extends.types[1].args[2].extends.types[1] results[#results+1] = { - label = infer.viewDocFunction(docFunc), + label = infer.getInfer(docFunc):view(), description = doc.comment, kind = define.CompletionItemKind.Function, insertText = buildInsertDocFunction(docFunc), @@ -1520,7 +1521,7 @@ local function tryTable(state, position, results) if source.type ~= 'table' then tbl = source.parent end - local defs = vm.getDefs(tbl, '*') + local defs = vm.getFields(tbl) for _, field in ipairs(defs) do local name = guide.getKeyName(field) if name and not mark[name] then @@ -1635,19 +1636,20 @@ local function tryluaDocBySource(state, position, source, results) if source.type == 'doc.extends.name' then if source.parent.type == 'doc.class' then local used = {} - for _, doc in ipairs(vm.getDocDefines(state.uri, '*')) do - if doc.type == 'doc.class.name' - and doc.parent ~= source.parent - and not used[doc[1]] - and matchKey(source[1], doc[1]) then - used[doc[1]] = true + for _, doc in ipairs(vm.getDocSets(state.uri)) do + local name = doc.type == 'doc.class' and doc.class[1] + if name + and name ~= source.parent.class[1] + and not used[name] + and matchKey(source[1], name) then + used[name] = true results[#results+1] = { - label = doc[1], + label = name, kind = define.CompletionItemKind.Class, - textEdit = doc[1]:find '[^%w_]' and { + textEdit = name:find '[^%w_]' and { start = source.start, finish = position, - newText = doc[1], + newText = name, }, } end @@ -1656,19 +1658,20 @@ local function tryluaDocBySource(state, position, source, results) return true elseif source.type == 'doc.type.name' then local used = {} - for _, doc in ipairs(vm.getDocDefines(state.uri, '*')) do - if (doc.type == 'doc.class.name' or doc.type == 'doc.alias.name') - and doc.parent ~= source.parent - and not used[doc[1]] - and matchKey(source[1], doc[1]) then - used[doc[1]] = true + for _, doc in ipairs(vm.getDocSets(state.uri)) do + local name = (doc.type == 'doc.class' and doc.class[1]) + or (doc.type == 'doc.alias' and doc.alias[1]) + if name + and not used[name] + and matchKey(source[1], name) then + used[name] = true results[#results+1] = { - label = doc[1], + label = name, kind = define.CompletionItemKind.Class, - textEdit = doc[1]:find '[^%w_]' and { + textEdit = name:find '[^%w_]' and { start = source.start, finish = position, - newText = doc[1], + newText = name, }, } end @@ -1734,17 +1737,17 @@ end local function tryluaDocByErr(state, position, err, docState, results) if err.type == 'LUADOC_MISS_CLASS_EXTENDS_NAME' then - for _, doc in ipairs(vm.getDocDefines(state.uri, '*')) do - if doc.type == 'doc.class.name' - and doc.parent ~= docState then + for _, doc in ipairs(vm.getDocSets(state.uri)) do + if doc.type == 'doc.class' + and doc.class[1] ~= docState.class[1] then results[#results+1] = { - label = doc[1], + label = doc.class[1], kind = define.CompletionItemKind.Class, } end end elseif err.type == 'LUADOC_MISS_TYPE_NAME' then - for _, doc in ipairs(vm.getDocDefines(state.uri, '*')) do + for _, doc in ipairs(vm.getDocSets(state.uri)) do if (doc.type == 'doc.class.name' or doc.type == 'doc.alias.name') then results[#results+1] = { label = doc[1], diff --git a/script/core/definition.lua b/script/core/definition.lua index 78ebce8f..ef183496 100644 --- a/script/core/definition.lua +++ b/script/core/definition.lua @@ -152,7 +152,10 @@ return function (uri, offset) goto CONTINUE end else - if guide.isLiteral(src) and src.type ~= 'function' then + if guide.isLiteral(src) + and src.type ~= 'function' + and src.type ~= 'doc.type.function' + and src.type ~= 'doc.type.table' then goto CONTINUE end end diff --git a/script/core/diagnostics/circle-doc-class.lua b/script/core/diagnostics/circle-doc-class.lua index 6bdad1be..407b7e83 100644 --- a/script/core/diagnostics/circle-doc-class.lua +++ b/script/core/diagnostics/circle-doc-class.lua @@ -39,7 +39,7 @@ return function (uri, callback) end if not mark[newName] then mark[newName] = true - local docs = vm.getDocDefines(uri, newName) + local docs = vm.getDocSets(uri, newName) for _, otherDoc in ipairs(docs) do if otherDoc.type == 'doc.class.name' then list[#list+1] = otherDoc.parent diff --git a/script/core/diagnostics/duplicate-doc-class.lua b/script/core/diagnostics/duplicate-doc-class.lua index 1a37826b..a7f432df 100644 --- a/script/core/diagnostics/duplicate-doc-class.lua +++ b/script/core/diagnostics/duplicate-doc-class.lua @@ -18,7 +18,7 @@ return function (uri, callback) if doc.type == 'doc.alias' then local name = guide.getKeyName(doc) if not cache[name] then - local docs = vm.getDocDefines(uri, name) + local docs = vm.getDocSets(uri, name) cache[name] = {} for _, otherDoc in ipairs(docs) do if otherDoc.type == 'doc.class.name' diff --git a/script/core/diagnostics/type-check.lua b/script/core/diagnostics/type-check.lua index ebfffea0..931e1cf6 100644 --- a/script/core/diagnostics/type-check.lua +++ b/script/core/diagnostics/type-check.lua @@ -17,8 +17,8 @@ local typeNameMap = { ['doc.class.name'] = true, ['doc.alias.name'] = true, ['doc.type.name'] = true, - ['doc.type.string'] = true, - ['doc.resume'] = true, + ['doc.type.string'] = true, + ['doc.type.integer'] = true, } @@ -37,10 +37,10 @@ local function isTable(name) end local function isUserDefineClass(uri, name) - if vm.isBuiltinType(name) then + if guide.isBasicType(name) then return false else - local defs = vm.getDocDefines(uri, name) + local defs = vm.getDocSets(uri, name) for _, v in ipairs(defs) do if v.type == 'doc.class.name' then return true @@ -54,7 +54,7 @@ local function isClassOralias(typeName) if not typeName then return false elseif typeNameMap[typeName] - or vm.isBuiltinType(typeName) then + or guide.isBasicType(typeName) then return true else return false @@ -99,7 +99,7 @@ end -- if not type[1] then -- return -- end --- local docDefs = vm.getDocDefines(type[1]) +-- local docDefs = vm.getDocSets(type[1]) -- for _, doc in ipairs(docDefs) do -- if doc.parent -- and doc.parent.type == 'doc.class' @@ -119,7 +119,7 @@ end local function addFatherClass(uri, infers) for k in pairs(infers) do if type(k) == 'string' then - local docDefs = vm.getDocDefines(uri, k) + local docDefs = vm.getDocSets(uri, k) for _, doc in ipairs(docDefs) do if doc.parent and doc.parent.type == 'doc.class' diff --git a/script/core/diagnostics/undefined-doc-class.lua b/script/core/diagnostics/undefined-doc-class.lua index 715583e7..c9678c13 100644 --- a/script/core/diagnostics/undefined-doc-class.lua +++ b/script/core/diagnostics/undefined-doc-class.lua @@ -23,7 +23,7 @@ return function (uri, callback) end for _, ext in ipairs(doc.extends) do local name = ext[1] - local docs = vm.getDocDefines(uri, name) + local docs = vm.getDocSets(uri, name) if cache[name] == nil then cache[name] = false for _, otherDoc in ipairs(docs) do diff --git a/script/core/diagnostics/undefined-doc-name.lua b/script/core/diagnostics/undefined-doc-name.lua index a8c75c3c..69edb380 100644 --- a/script/core/diagnostics/undefined-doc-name.lua +++ b/script/core/diagnostics/undefined-doc-name.lua @@ -35,7 +35,7 @@ return function (uri, callback) if name == '...' then return end - if vm.isDocDefined(uri, name) + if #vm.getDocSets(uri, name) > 0 or hasNameOfGeneric(name, source) then return end diff --git a/script/core/hover/description.lua b/script/core/hover/description.lua index 83f4bcca..49e8d2bc 100644 --- a/script/core/hover/description.lua +++ b/script/core/hover/description.lua @@ -158,8 +158,8 @@ local function buildEnumChunk(docType, name) end local types = {} for _, tp in ipairs(docType.types) do - if tp.type ~= 'doc.enum' - and tp.type ~= 'doc.resume' then + if tp.type ~= 'doc.string' + and tp.type ~= 'doc.integer' then types[#types+1] = tp[1] end end diff --git a/script/core/semantic-tokens.lua b/script/core/semantic-tokens.lua index 7f58014b..8d991df9 100644 --- a/script/core/semantic-tokens.lua +++ b/script/core/semantic-tokens.lua @@ -513,24 +513,6 @@ local Care = util.switch() modifieres = define.TokenModifiers.static, } end) - : case 'doc.resume' - : call(function (source, options, results) - if not options.annotation then - return - end - results[#results+1] = { - start = source.start, - finish = source.finish, - type = define.TokenTypes.string, - modifieres = define.TokenModifiers.static, - } - local row = guide.rowColOf(source.start) - results[#results+1] = { - start = source.finish, - finish = guide.positionOf(row, guide.getLineRange(options.state, row)), - type = define.TokenTypes.comment, - } - end) : case 'doc.type.function' : call(function (source, options, results) if not options.annotation then diff --git a/script/parser/guide.lua b/script/parser/guide.lua index 15f52585..92e4edab 100644 --- a/script/parser/guide.lua +++ b/script/parser/guide.lua @@ -231,6 +231,10 @@ function m.isLiteral(obj) or tp == 'integer' or tp == 'table' or tp == 'function' + or tp == 'doc.type.function' + or tp == 'doc.type.table' + or tp == 'doc.type.string' + or tp == 'doc.type.integer' end --- 获取字面量 @@ -820,8 +824,6 @@ local isSetMap = { ['doc.class'] = true, ['doc.alias'] = true, ['doc.field'] = true, - ['doc.type.function'] = true, - ['doc.type.table'] = true, ['doc.class.name'] = true, ['doc.alias.name'] = true, ['doc.field.name'] = true, diff --git a/script/proto/define.lua b/script/proto/define.lua index f1487a4d..68fb1d58 100644 --- a/script/proto/define.lua +++ b/script/proto/define.lua @@ -276,21 +276,6 @@ m.BuiltIn = { ['utf8'] = 'default', } -m.BuiltinType = { - ['unknown'] = true, - ['any'] = true, - ['nil'] = true, - ['boolean'] = true, - ['number'] = true, - ['integer'] = true, - ['thread'] = true, - ['table'] = true, - ['string'] = true, - ['userdata'] = true, - ['lightuserdata'] = true, - ['function'] = true, -} - m.InlayHintKind = { Other = 0, Type = 1, diff --git a/script/vm/compiler.lua b/script/vm/compiler.lua index fd1d1d5d..bfed8ffb 100644 --- a/script/vm/compiler.lua +++ b/script/vm/compiler.lua @@ -461,10 +461,6 @@ local function selectNode(source, list, index) local hasKnownType for n in nodeMgr.eachNode(result) do if guide.isLiteral(n) - 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 diff --git a/script/vm/getDocs.lua b/script/vm/doc.lua index 8c15fd99..35750211 100644 --- a/script/vm/getDocs.lua +++ b/script/vm/doc.lua @@ -5,60 +5,22 @@ local vm = require 'vm.vm' local config = require 'config' local collector = require 'core.collector' 'searcher' local define = require 'proto.define' +local globalMgr = require 'vm.global-manager' ---获取class与alias +---@param suri uri ---@param name? string ---@return parser.object[] -function vm.getDocDefines(uri, name) - if type(name) ~= 'string' then - return {} - end - local cache = vm.getCache 'getDocDefines' - if cache[name] then - return cache[name] - end - local results = {} - if name == '*' then - for noders in collector:each(uri, 'def:dn:') do - for id in noder.eachID(noders) do - if id:sub(1, 3) == 'dn:' - and not id:find(noder.SPLIT_CHAR) then - for source in noder.eachSource(noders, id) do - if guide.isSet(source) then - results[#results+1] = source - end - end - end - end +function vm.getDocSets(suri, name) + if name then + local global = globalMgr.getGlobal('type', name) + if not global then + return {} end + return global:getSets() else - local id = 'dn:' .. name - for noders in collector:each(uri, 'def:' .. id) do - for source in noder.eachSource(noders, id) do - if source.type == 'doc.class.name' - or source.type == 'doc.alias.name' then - results[#results+1] = source - end - end - end - end - cache[name] = results - return results -end - -function vm.isDocDefined(uri, name) - if define.BuiltinType[name] then - return true + return globalMgr.getGlobalSets(suri, 'type') end - local id = 'def:dn:' .. name - if collector:has(uri, id) then - return true - end - return false -end - -function vm.isBuiltinType(name) - return define.BuiltinType[name] == true end function vm.getDocEnums(doc) @@ -70,7 +32,7 @@ function vm.getDocEnums(doc) for _, def in ipairs(defs) do if def.type == 'doc.type.string' - or def.type == 'doc.resume' then + or def.type == 'doc.type.integer' then results[#results+1] = def end end diff --git a/script/vm/global-manager.lua b/script/vm/global-manager.lua index eed65c64..5f0b6a14 100644 --- a/script/vm/global-manager.lua +++ b/script/vm/global-manager.lua @@ -89,16 +89,15 @@ local compilerGlobalSwitch = util.switch() : case 'getindex' ---@param source parser.object : call(function (source) - local name + local name = guide.getKeyName(source) + if not name then + return + end if source.node._globalNode then local parentName = source.node._globalNode:getName() - if parentName == '_G' then - name = guide.getKeyName(source) - else - name = parentName .. m.ID_SPLITE .. guide.getKeyName(source) + if parentName ~= '_G' then + name = parentName .. m.ID_SPLITE .. name end - elseif source.node.special == '_G' then - name = guide.getKeyName(source) end local uri = guide.getUri(source) local global = m.declareGlobal('variable', name, uri) @@ -260,6 +259,37 @@ function m.getGlobals(cate) return globals end +---@param suri uri +---@param cate vm.global.cate +---@return parser.object[] +function m.getGlobalSets(suri, cate) + local globals = m.getGlobals(cate) + local result = {} + for _, global in ipairs(globals) do + local sets = global:getSets() + for _, set in ipairs(sets) do + result[#result+1] = set + end + end + return result +end + +---@param suri uri +---@param cate vm.global.cate +---@param name string +---@return boolean +function m.hasGlobalSets(suri, cate, name) + local global = m.getGlobal(cate, name) + if not global then + return false + end + local sets = global:getSets() + if #sets == 0 then + return false + end + return true +end + ---@param source parser.object function m.compileObject(source) if source._globalNode ~= nil then diff --git a/script/vm/infer.lua b/script/vm/infer.lua index bf6df2fb..c0daf00a 100644 --- a/script/vm/infer.lua +++ b/script/vm/infer.lua @@ -156,6 +156,7 @@ function m.getInfer(source) if not node then return m.NULL end + -- TODO: more cache? if node.type == 'union' and node.lastInfer then return node.lastInfer end diff --git a/script/vm/init.lua b/script/vm/init.lua index b5d37136..aa1b908f 100644 --- a/script/vm/init.lua +++ b/script/vm/init.lua @@ -3,7 +3,7 @@ require 'vm.manager' require 'vm.def' require 'vm.ref' require 'vm.field' -require 'vm.getDocs' +require 'vm.doc' require 'vm.getLibrary' require 'vm.getLinks' return vm diff --git a/script/vm/local-id.lua b/script/vm/local-id.lua index 06e086c7..b7a6e6d5 100644 --- a/script/vm/local-id.lua +++ b/script/vm/local-id.lua @@ -33,7 +33,11 @@ local compileSwitch = util.switch() if not parentID then return end - source._localID = parentID .. m.ID_SPLITE .. guide.getKeyName(source) + local key = guide.getKeyName(source) + if type(key) ~= 'string' then + return + end + source._localID = parentID .. m.ID_SPLITE .. key source.field._localID = source._localID if source.type == 'getfield' then m.compileLocalID(source.next) @@ -46,7 +50,11 @@ local compileSwitch = util.switch() if not parentID then return end - source._localID = parentID .. m.ID_SPLITE .. guide.getKeyName(source) + local key = guide.getKeyName(source) + if type(key) ~= 'string' then + return + end + source._localID = parentID .. m.ID_SPLITE .. key source.method._localID = source._localID if source.type == 'getmethod' then m.compileLocalID(source.next) @@ -60,7 +68,7 @@ local compileSwitch = util.switch() return end local key = guide.getKeyName(source) - if not type(key) ~= 'string' then + if type(key) ~= 'string' then return end source._localID = parentID .. m.ID_SPLITE .. key |