diff options
-rw-r--r-- | script/core/completion/completion.lua | 8 | ||||
-rw-r--r-- | script/core/diagnostics/duplicate-set-field.lua | 2 | ||||
-rw-r--r-- | script/core/hover/description.lua | 2 | ||||
-rw-r--r-- | script/core/signature.lua | 2 | ||||
-rw-r--r-- | script/core/type-definition.lua | 2 | ||||
-rw-r--r-- | script/vm/compiler.lua | 19 | ||||
-rw-r--r-- | script/vm/field.lua | 22 | ||||
-rw-r--r-- | script/vm/local-id.lua | 29 | ||||
-rw-r--r-- | script/vm/vm.lua | 12 | ||||
-rw-r--r-- | test/hover/init.lua | 2 |
10 files changed, 64 insertions, 36 deletions
diff --git a/script/core/completion/completion.lua b/script/core/completion/completion.lua index 6a979af9..76dd6480 100644 --- a/script/core/completion/completion.lua +++ b/script/core/completion/completion.lua @@ -183,7 +183,7 @@ local function getSnip(source) end local defs = vm.getRefs(source) for _, def in ipairs(defs) do - def = searcher.getObjectValue(def) or def + def = vm.getObjectValue(def) or def if def ~= source and def.type == 'function' then local uri = guide.getUri(def) local text = files.getText(uri) @@ -458,7 +458,7 @@ local function checkFieldFromFieldToIndex(state, name, src, parent, word, startP end local function checkFieldThen(state, name, src, word, startPos, position, parent, oop, results) - local value = searcher.getObjectValue(src) or src + local value = vm.getObjectValue(src) or src local kind = define.CompletionItemKind.Field if value.type == 'function' or value.type == 'doc.type.function' then @@ -537,7 +537,7 @@ local function checkFieldOfRefs(refs, state, word, startPos, position, parent, o end local funcLabel if config.get(state.uri, 'Lua.completion.showParams') then - local value = searcher.getObjectValue(src) or src + local value = vm.getObjectValue(src) or src if value.type == 'function' or value.type == 'doc.type.function' then funcLabel = name .. getParams(value, oop) @@ -1494,7 +1494,7 @@ local function tryCallArg(state, position, results) end local defs = vm.getDefs(call.node) for _, def in ipairs(defs) do - def = searcher.getObjectValue(def) or def + def = vm.getObjectValue(def) or def local enums = getCallEnumsAndFuncs(def, argIndex, oop, call) if enums then mergeEnums(myResults, enums, arg) diff --git a/script/core/diagnostics/duplicate-set-field.lua b/script/core/diagnostics/duplicate-set-field.lua index f8201309..96abe37c 100644 --- a/script/core/diagnostics/duplicate-set-field.lua +++ b/script/core/diagnostics/duplicate-set-field.lua @@ -29,7 +29,7 @@ return function (uri, callback) if not name then goto CONTINUE end - local value = searcher.getObjectValue(nxt) + local value = vm.getObjectValue(nxt) if not value or value.type ~= 'function' then goto CONTINUE end diff --git a/script/core/hover/description.lua b/script/core/hover/description.lua index 741d7cbd..83f4bcca 100644 --- a/script/core/hover/description.lua +++ b/script/core/hover/description.lua @@ -201,7 +201,7 @@ local function isFunction(source) if source.type == 'function' then return true end - local value = searcher.getObjectValue(source) + local value = vm.getObjectValue(source) if not value then return false end diff --git a/script/core/signature.lua b/script/core/signature.lua index e136bce9..449f1c8c 100644 --- a/script/core/signature.lua +++ b/script/core/signature.lua @@ -125,7 +125,7 @@ local function makeSignatures(text, call, pos) local defs = vm.getDefs(node) local mark = {} for _, src in ipairs(defs) do - src = searcher.getObjectValue(src) or src + src = vm.getObjectValue(src) or src if src.type == 'function' or src.type == 'doc.type.function' then if not mark[src] then diff --git a/script/core/type-definition.lua b/script/core/type-definition.lua index 6bee7193..f45cb352 100644 --- a/script/core/type-definition.lua +++ b/script/core/type-definition.lua @@ -134,7 +134,7 @@ return function (uri, offset) local defs = vm.getDefs(source) local values = {} for _, src in ipairs(defs) do - local value = searcher.getObjectValue(src) + local value = vm.getObjectValue(src) if value and value ~= src and guide.isLiteral(value) then values[value] = true end diff --git a/script/vm/compiler.lua b/script/vm/compiler.lua index d1f8c601..058f80ec 100644 --- a/script/vm/compiler.lua +++ b/script/vm/compiler.lua @@ -21,7 +21,8 @@ local searchFieldSwitch = util.switch() for _, field in ipairs(node) do if field.type == 'tablefield' or field.type == 'tableindex' then - if guide.getKeyName(field) == key then + if not key + or key == guide.getKeyName(field) then pushResult(field) end end @@ -48,9 +49,9 @@ local searchFieldSwitch = util.switch() end) : case 'local' : call(function (node, key, pushResult) - local sources = localID.getSources(node, key) - if sources then - for _, src in ipairs(sources) do + local fields = key and localID.getSources(node, key) or localID.getFields(node) + if fields then + for _, src in ipairs(fields) do pushResult(src) end end @@ -71,7 +72,8 @@ local searchFieldSwitch = util.switch() local fieldNode = m.compileNode(fieldKey) for fn in nodeMgr.eachNode(fieldNode) do if fn.type == 'global' and fn.cate == 'type' then - if fn.name == 'any' + if not key + or fn.name == 'any' or (fn.name == 'boolean' and type(key) == 'boolean') or (fn.name == 'number' and type(key) == 'number') or (fn.name == 'integer' and math.tointeger(key)) @@ -82,7 +84,7 @@ local searchFieldSwitch = util.switch() end end if fieldKey.type == 'doc.field.name' then - if fieldKey[1] == key then + if not key or fieldKey[1] == key then pushResult(field.extends) end end @@ -103,7 +105,8 @@ function m.getClassFields(node, key, pushResult) -- check ---@field local hasFounded for _, field in ipairs(set.fields) do - if guide.getKeyName(field) == key then + if not key + or guide.getKeyName(field) == key then hasFounded = true pushResult(field) end @@ -341,7 +344,7 @@ local function compileByLocalID(source) end ---@param source vm.node ----@param key any +---@param key? any ---@param pushResult fun(source: parser.object) function m.compileByParentNode(source, key, pushResult) local parentNode = m.compileNode(source) diff --git a/script/vm/field.lua b/script/vm/field.lua index c30e112d..52c56e7f 100644 --- a/script/vm/field.lua +++ b/script/vm/field.lua @@ -7,26 +7,10 @@ local localID = require 'vm.local-id' local globalMgr = require 'vm.global-manager' local nodeMgr = require 'vm.node' -local searchNodeSwitch = util.switch() - : case 'table' - : call(function (node, pushResult) - for _, field in ipairs(node) do - if field.type == 'tablefield' - or field.type == 'tableindex' then - pushResult(field) - end - end - end) - local function searchByNode(source, pushResult) - local node = compiler.compileNode(source) - if not node then - return - end - - for n in nodeMgr.eachNode(node) do - searchNodeSwitch(n.type, n, pushResult) - end + compiler.compileByParentNode(source, nil, function (field) + pushResult(field) + end) end ---@param source parser.object diff --git a/script/vm/local-id.lua b/script/vm/local-id.lua index 4c9da197..8d530beb 100644 --- a/script/vm/local-id.lua +++ b/script/vm/local-id.lua @@ -109,6 +109,9 @@ function m.compileLocalID(source) return end compileSwitch(source.type, source) + if not source._localID then + return + end local root = guide.getRoot(source) if not root._localIDs then root._localIDs = util.multiTable(2) @@ -153,4 +156,30 @@ function m.getSources(source, key) return root._localIDs[id] end +---@param source parser.object +---@return parser.object[] +function m.getFields(source) + local id = m.getID(source) + if not id then + return nil + end + local root = guide.getRoot(source) + if not root._localIDs then + return nil + end + -- TODOļ¼optimize + local fields = {} + for lid, sources in pairs(root._localIDs) do + if lid ~= id + and util.stringStartWith(lid, id) + -- only one field + and not lid:find(m.ID_SPLITE, #id + 2) then + for _, src in ipairs(sources) do + fields[#fields+1] = src + end + end + end + return fields +end + return m diff --git a/script/vm/vm.lua b/script/vm/vm.lua index e524589c..d370de0d 100644 --- a/script/vm/vm.lua +++ b/script/vm/vm.lua @@ -49,6 +49,18 @@ function m.getKeyType(source) return guide.getKeyType(source) end +---@param source parser.object +---@return parser.object? +function m.getObjectValue(source) + if source.value then + return source.value + end + if source.special == 'rawset' then + return source.args and source.args[3] + end + return nil +end + m.cacheTracker = setmetatable({}, weakMT) function m.flushCache() diff --git a/test/hover/init.lua b/test/hover/init.lua index 1493dfd9..fe8b0e3f 100644 --- a/test/hover/init.lua +++ b/test/hover/init.lua @@ -414,7 +414,7 @@ t.a = true ]] [[ local t: { - a: boolean|integer = 1|true, + a: boolean|integer = 1, } ]] |