summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--script/core/hover/table.lua2
-rw-r--r--script/core/rename.lua10
-rw-r--r--script/vm/compiler.lua16
-rw-r--r--script/vm/def.lua2
-rw-r--r--script/vm/doc.lua2
-rw-r--r--script/vm/field.lua12
-rw-r--r--script/vm/generic.lua5
-rw-r--r--script/vm/global-manager.lua2
-rw-r--r--script/vm/global.lua45
-rw-r--r--script/vm/ref.lua11
-rw-r--r--script/vm/sign.lua11
-rw-r--r--script/vm/type.lua27
12 files changed, 89 insertions, 56 deletions
diff --git a/script/core/hover/table.lua b/script/core/hover/table.lua
index 8f9beefe..31036edd 100644
--- a/script/core/hover/table.lua
+++ b/script/core/hover/table.lua
@@ -165,7 +165,7 @@ return function (source)
for view in infer.getInfer(source):eachView() do
if view == 'string'
- or vm.isSubType(view, 'string') then
+ or vm.isSubType(uri, view, 'string') then
return nil
end
end
diff --git a/script/core/rename.lua b/script/core/rename.lua
index f1ee93c5..ec21e87c 100644
--- a/script/core/rename.lua
+++ b/script/core/rename.lua
@@ -195,10 +195,11 @@ local function ofGlobal(source, newname, callback)
if not global then
return
end
- for _, set in ipairs(global:getSets()) do
+ local uri = guide.getUri(source)
+ for _, set in ipairs(global:getSets(uri)) do
ofFieldThen(key, set, newname, callback)
end
- for _, get in ipairs(global:getGets()) do
+ for _, get in ipairs(global:getGets(uri)) do
ofFieldThen(key, get, newname, callback)
end
end
@@ -217,7 +218,8 @@ local function ofDocTypeName(source, newname, callback)
if not global then
return
end
- for _, doc in ipairs(global:getSets()) do
+ local uri = guide.getUri(source)
+ for _, doc in ipairs(global:getSets(uri)) do
if doc.type == 'doc.class' then
callback(doc, doc.class.start, doc.class.finish, newname)
end
@@ -225,7 +227,7 @@ local function ofDocTypeName(source, newname, callback)
callback(doc, doc.alias.start, doc.alias.finish, newname)
end
end
- for _, doc in ipairs(global:getGets()) do
+ for _, doc in ipairs(global:getGets(uri)) do
if doc.type == 'doc.type.name' then
callback(doc, doc.start, doc.finish, newname)
end
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