diff options
author | 最萌小汐 <sumneko@hotmail.com> | 2022-04-09 02:33:17 +0800 |
---|---|---|
committer | 最萌小汐 <sumneko@hotmail.com> | 2022-04-09 02:33:17 +0800 |
commit | af4e3094bd5592d2e9d6a769ef1d7a1660b3e48e (patch) | |
tree | 2ba0f8c655818ca144354e207a70c5e1589b4a64 /script/vm | |
parent | 52847c66b6cdf310176056617806867eae23571e (diff) | |
download | lua-language-server-af4e3094bd5592d2e9d6a769ef1d7a1660b3e48e.zip |
update
Diffstat (limited to 'script/vm')
-rw-r--r-- | script/vm/compiler.lua | 16 | ||||
-rw-r--r-- | script/vm/def.lua | 2 | ||||
-rw-r--r-- | script/vm/doc.lua | 2 | ||||
-rw-r--r-- | script/vm/field.lua | 12 | ||||
-rw-r--r-- | script/vm/generic.lua | 5 | ||||
-rw-r--r-- | script/vm/global-manager.lua | 2 | ||||
-rw-r--r-- | script/vm/global.lua | 45 | ||||
-rw-r--r-- | script/vm/ref.lua | 11 | ||||
-rw-r--r-- | script/vm/sign.lua | 11 | ||||
-rw-r--r-- | script/vm/type.lua | 27 |
10 files changed, 82 insertions, 51 deletions
diff --git a/script/vm/compiler.lua b/script/vm/compiler.lua index 2af1746a..87306550 100644 --- a/script/vm/compiler.lua +++ b/script/vm/compiler.lua @@ -358,7 +358,7 @@ local function getReturn(func, index, args) or cnode.type == 'doc.type.function' then local returnNode = m.getReturnOfFunction(cnode, index) if returnNode and returnNode.type == 'generic' then - returnNode = returnNode:resolve(args) + returnNode = returnNode:resolve(guide.getUri(func), args) end if returnNode and returnNode.type ~= 'doc.generic.name' then result = result or union() @@ -953,15 +953,16 @@ local compilerSwitch = util.switch() : case 'doc.type.name' : call(function (source) if source.signs then + local uri = guide.getUri(source) nodeMgr.setNode(source, source) local global = globalMgr.getGlobal('type', source[1]) - for _, set in ipairs(global:getSets()) do + 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(source.signs) + local resolved = ext._generic:resolve(uri, source.signs) nodeMgr.setNode(source, resolved) end end @@ -970,7 +971,7 @@ local compilerSwitch = util.switch() end if set.type == 'doc.alias' then if set.extends._generic then - local resolved = set.extends._generic:resolve(source.signs) + local resolved = set.extends._generic:resolve(uri, source.signs) nodeMgr.setNode(source, resolved) end end @@ -1409,10 +1410,11 @@ end ---@param source vm.node local function compileByGlobal(source) if source.type == 'global' then + local uri = guide.getUri(source) nodeMgr.setNode(source, source) if source.cate == 'variable' then local hasMarkDoc - for _, set in ipairs(source:getSets()) do + for _, set in ipairs(source:getSets(uri)) do if set.bindDocs then if bindDocs(set) then nodeMgr.setNode(source, m.compileNode(set)) @@ -1420,7 +1422,7 @@ local function compileByGlobal(source) end end end - for _, set in ipairs(source:getSets()) do + for _, set in ipairs(source:getSets(uri)) do if set.value then if not hasMarkDoc or guide.isLiteral(set.value) then nodeMgr.setNode(source, m.compileNode(set.value)) @@ -1429,7 +1431,7 @@ local function compileByGlobal(source) end end if source.cate == 'type' then - for _, set in ipairs(source:getSets()) do + for _, set in ipairs(source:getSets(uri)) do if set.type == 'doc.class' then if set.extends then for _, ext in ipairs(set.extends) do diff --git a/script/vm/def.lua b/script/vm/def.lua index 017d776a..887da8e9 100644 --- a/script/vm/def.lua +++ b/script/vm/def.lua @@ -94,7 +94,7 @@ local searchFieldSwitch = util.switch() if node.cate == 'variable' then local newGlobal = globalMgr.getGlobal('variable', node.name, key) if newGlobal then - for _, set in ipairs(newGlobal:getSets()) do + for _, set in ipairs(newGlobal:getSets(suri)) do pushResult(set) end end diff --git a/script/vm/doc.lua b/script/vm/doc.lua index 16ac0778..1367bbc2 100644 --- a/script/vm/doc.lua +++ b/script/vm/doc.lua @@ -15,7 +15,7 @@ function vm.getDocSets(suri, name) if not global then return {} end - return global:getSets() + return global:getSets(suri) else return globalMgr.getGlobalSets(suri, 'type') end diff --git a/script/vm/field.lua b/script/vm/field.lua index 563c7868..d79e3f6a 100644 --- a/script/vm/field.lua +++ b/script/vm/field.lua @@ -3,25 +3,23 @@ local vm = require 'vm.vm' local util = require 'utility' local compiler = require 'vm.compiler' local guide = require 'parser.guide' -local localID = require 'vm.local-id' -local globalMgr = require 'vm.global-manager' -local nodeMgr = require 'vm.node' local searchByNodeSwitch = util.switch() : case 'global' ---@param global vm.node.global - : call(function (global, pushResult) - for _, set in ipairs(global:getSets()) do + : call(function (suri, global, pushResult) + for _, set in ipairs(global:getSets(suri)) do pushResult(set) end end) - : default(function (source, pushResult) + : default(function (suri, source, pushResult) pushResult(source) end) local function searchByNode(source, pushResult) + local uri = guide.getUri(source) compiler.compileByParentNode(source, nil, function (field) - searchByNodeSwitch(field.type, field, pushResult) + searchByNodeSwitch(field.type, uri, field, pushResult) end) end diff --git a/script/vm/generic.lua b/script/vm/generic.lua index 28caa2db..bacea1e8 100644 --- a/script/vm/generic.lua +++ b/script/vm/generic.lua @@ -109,10 +109,11 @@ local function cloneObject(node, resolved) return node end +---@param uri uri ---@param argNodes vm.node[] ---@return parser.object -function mt:resolve(argNodes) - local resolved = self.sign:resolve(argNodes) +function mt:resolve(uri, argNodes) + local resolved = self.sign:resolve(uri, argNodes) local newProto = cloneObject(self.proto, resolved) return newProto end diff --git a/script/vm/global-manager.lua b/script/vm/global-manager.lua index 66bb0aba..317b128b 100644 --- a/script/vm/global-manager.lua +++ b/script/vm/global-manager.lua @@ -286,7 +286,7 @@ function m.hasGlobalSets(suri, cate, name) if not global then return false end - local sets = global:getSets() + local sets = global:getSets(suri) if #sets == 0 then return false end diff --git a/script/vm/global.lua b/script/vm/global.lua index 0f457279..8df8b692 100644 --- a/script/vm/global.lua +++ b/script/vm/global.lua @@ -1,4 +1,5 @@ local util = require 'utility' +local scope= require 'workspace.scope' ---@class vm.node.global.link ---@field gets parser.object[] @@ -6,8 +7,8 @@ local util = require 'utility' ---@class vm.node.global ---@field links table<uri, vm.node.global.link> ----@field setsCache parser.object[] ----@field getsCache parser.object[] +---@field setsCache table<uri, parser.object[]> +---@field getsCache table<uri, parser.object[]> ---@field cate vm.global.cate local mt = {} mt.__index = mt @@ -31,29 +32,53 @@ function mt:addGet(uri, source) end ---@return parser.object[] -function mt:getSets() +function mt:getSets(suri) if not self.setsCache then self.setsCache = {} - for _, link in pairs(self.links) do + end + ---@type scope + local scp = suri and scope.getScope(suri) or nil + local cacheUri = scp and scp.uri or '<fallback>' + if self.setsCache[cacheUri] then + return self.setsCache[cacheUri] + end + self.setsCache[cacheUri] = {} + local cache = self.setsCache[cacheUri] + for uri, link in pairs(self.links) do + if not scp + or scp:isChildUri(uri) + or scp:isLinkedUri(uri) then for _, source in ipairs(link.sets) do - self.setsCache[#self.setsCache+1] = source + cache[#cache+1] = source end end end - return self.setsCache + return cache end ---@return parser.object[] -function mt:getGets() +function mt:getGets(suri) if not self.getsCache then self.getsCache = {} - for _, link in pairs(self.links) do + end + ---@type scope + local scp = suri and scope.getScope(suri) or nil + local cacheUri = scp and scp.uri or '<fallback>' + if self.getsCache[cacheUri] then + return self.getsCache[cacheUri] + end + self.getsCache[cacheUri] = {} + local cache = self.getsCache[cacheUri] + for uri, link in pairs(self.links) do + if not scp + or scp:isChildUri(uri) + or scp:isLinkedUri(uri) then for _, source in ipairs(link.gets) do - self.getsCache[#self.getsCache+1] = source + cache[#cache+1] = source end end end - return self.getsCache + return cache end ---@param uri uri diff --git a/script/vm/ref.lua b/script/vm/ref.lua index f7f1a6d1..e1bdf81d 100644 --- a/script/vm/ref.lua +++ b/script/vm/ref.lua @@ -135,21 +135,21 @@ local function searchField(source, pushResult, defMap, fileNotify) end ---@async guide.eachSourceType(state.ast, 'getfield', function (src) - if src.field[1] == key then + if src.field and src.field[1] == key then checkDef(src) await.delay() end end) ---@async guide.eachSourceType(state.ast, 'getmethod', function (src) - if src.method[1] == key then + if src.method and src.method[1] == key then checkDef(src) await.delay() end end) ---@async guide.eachSourceType(state.ast, 'getindex', function (src) - if src.index.type == 'string' and src.index[1] == key then + if src.index and src.index.type == 'string' and src.index[1] == key then checkDef(src) await.delay() end @@ -269,11 +269,12 @@ local function searchByNode(source, pushResult) end local function searchByDef(source, pushResult) + local defMap = {} if source.type == 'function' or source.type == 'doc.type.function' then - return + defMap[source] = true + return defMap end - local defMap = {} local defs = vm.getDefs(source) for _, def in ipairs(defs) do pushResult(def) diff --git a/script/vm/sign.lua b/script/vm/sign.lua index eae549e4..d5168f2c 100644 --- a/script/vm/sign.lua +++ b/script/vm/sign.lua @@ -15,9 +15,10 @@ function mt:addSign(node) self.signList[#self.signList+1] = node end +---@param uri uri ---@param argNodes vm.node[] ---@return table<string, vm.node> -function mt:resolve(argNodes) +function mt:resolve(uri, argNodes) if not argNodes then return nil end @@ -57,18 +58,18 @@ function mt:resolve(argNodes) local uvalueNode = compiler.compileNode(ufield.extends) if ufieldNode.type == 'doc.generic.name' and uvalueNode.type == 'doc.generic.name' then -- { [number]: number} -> { [K]: V } - local tfieldNode = vm.getTableKey(node, 'any') - local tvalueNode = vm.getTableValue(node, 'any') + local tfieldNode = vm.getTableKey(uri, node, 'any') + local tvalueNode = vm.getTableValue(uri, node, 'any') resolve(ufieldNode, tfieldNode) resolve(uvalueNode, tvalueNode) else if ufieldNode.type == 'doc.generic.name' then -- { [number]: number}|number[] -> { [K]: number } - local tnode = vm.getTableKey(node, uvalueNode) + local tnode = vm.getTableKey(uri, node, uvalueNode) resolve(ufieldNode, tnode) else -- { [number]: number}|number[] -> { [number]: V } - local tnode = vm.getTableValue(node, ufieldNode) + local tnode = vm.getTableValue(uri, node, ufieldNode) resolve(uvalueNode, tnode) end end diff --git a/script/vm/type.lua b/script/vm/type.lua index 4cac9723..0f6c8238 100644 --- a/script/vm/type.lua +++ b/script/vm/type.lua @@ -4,11 +4,12 @@ local globalMgr = require 'vm.global-manager' ---@class vm local vm = require 'vm.vm' +---@param uri uri ---@param child vm.node|string ---@param parent vm.node|string ---@param mark? table ---@return boolean -function vm.isSubType(child, parent, mark) +function vm.isSubType(uri, child, parent, mark) if type(parent) == 'string' then parent = globalMgr.getGlobal('type', parent) end @@ -26,7 +27,7 @@ function vm.isSubType(child, parent, mark) if child.type == 'doc.type' then for _, typeUnit in ipairs(child.types) do - if not vm.isSubType(typeUnit, parent) then + if not vm.isSubType(uri, typeUnit, parent) then return false end end @@ -40,7 +41,7 @@ function vm.isSubType(child, parent, mark) if child.type == 'global' and child.cate == 'type' then if parent.type == 'doc.type' then for _, typeUnit in ipairs(parent.types) do - if vm.isSubType(child, typeUnit) then + if vm.isSubType(uri, child, typeUnit) then return true end end @@ -59,11 +60,11 @@ function vm.isSubType(child, parent, mark) return false end mark[child.name] = true - for _, set in ipairs(child:getSets()) do + for _, set in ipairs(child:getSets(uri)) do if set.type == 'doc.class' and set.extends then for _, ext in ipairs(set.extends) do if ext.type == 'doc.extends.name' - and vm.isSubType(globalMgr.getGlobal('type', ext[1]), parent, mark) then + and vm.isSubType(uri, globalMgr.getGlobal('type', ext[1]), parent, mark) then return true end end @@ -71,7 +72,7 @@ function vm.isSubType(child, parent, mark) if set.type == 'doc.alias' and set.extends then for _, ext in ipairs(set.extends.types) do if ext.type == 'doc.type.name' - and vm.isSubType(globalMgr.getGlobal('type', ext[1]), parent, mark) then + and vm.isSubType(uri, globalMgr.getGlobal('type', ext[1]), parent, mark) then return true end end @@ -83,20 +84,21 @@ function vm.isSubType(child, parent, mark) return false end +---@param uri uri ---@param tnode vm.node ---@param knode vm.node -function vm.getTableValue(tnode, knode) +function vm.getTableValue(uri, tnode, knode) local result for tn in nodeMgr.eachNode(tnode) do if tn.type == 'doc.type.table' then for _, field in ipairs(tn.fields) do - if vm.isSubType(field.name, knode) then + if vm.isSubType(uri, field.name, knode) then result = nodeMgr.mergeNode(result, compiler.compileNode(field.extends)) end end end if tn.type == 'doc.type.array' then - if vm.isSubType(globalMgr.getGlobal('type', 'integer'), knode) then + if vm.isSubType(uri, globalMgr.getGlobal('type', 'integer'), knode) then result = nodeMgr.mergeNode(result, compiler.compileNode(tn.node)) end end @@ -117,20 +119,21 @@ function vm.getTableValue(tnode, knode) return result end +---@param uri uri ---@param tnode vm.node ---@param vnode vm.node -function vm.getTableKey(tnode, vnode) +function vm.getTableKey(uri, tnode, vnode) local result for tn in nodeMgr.eachNode(tnode) do if tn.type == 'doc.type.table' then for _, field in ipairs(tn.fields) do - if vm.isSubType(field.extends, vnode) then + if vm.isSubType(uri, field.extends, vnode) then result = nodeMgr.mergeNode(result, compiler.compileNode(field.name)) end end end if tn.type == 'doc.type.array' then - if vm.isSubType(tn.node, vnode) then + if vm.isSubType(uri, tn.node, vnode) then result = nodeMgr.mergeNode(result, globalMgr.getGlobal('type', 'integer')) end end |