summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--script/vm/compiler.lua58
-rw-r--r--script/vm/global-manager.lua4
-rw-r--r--script/vm/global.lua5
-rw-r--r--test/completion/common.lua2
-rw-r--r--test/type_inference/init.lua7
5 files changed, 58 insertions, 18 deletions
diff --git a/script/vm/compiler.lua b/script/vm/compiler.lua
index 1b786cb8..531a0cd2 100644
--- a/script/vm/compiler.lua
+++ b/script/vm/compiler.lua
@@ -14,6 +14,7 @@ local vm = require 'vm.vm'
---@field _compiledNodes boolean
---@field _node vm.node
---@field _localBase table
+---@field _globalBase table
local searchFieldSwitch = util.switch()
: case 'table'
@@ -117,12 +118,22 @@ local searchFieldSwitch = util.switch()
end
local global = globalMgr.getGlobal('variable', node.name, key)
if global then
- pushResult(global)
+ for _, set in ipairs(global:getSets(suri)) do
+ pushResult(set)
+ end
+ for _, get in ipairs(global:getGets(suri)) do
+ pushResult(get)
+ end
end
else
local globals = globalMgr.getFields('variable', node.name)
for _, global in ipairs(globals) do
- pushResult(global)
+ for _, set in ipairs(global:getSets(suri)) do
+ pushResult(set)
+ end
+ for _, get in ipairs(global:getGets(suri)) do
+ pushResult(get)
+ end
end
end
end
@@ -1545,38 +1556,57 @@ end
---@param source vm.object
local function compileByGlobal(source)
- local globalNode = source._globalNode
- if not globalNode then
+ local global = source._globalNode
+ if not global then
return
end
+ local root = guide.getRoot(source)
local uri = guide.getUri(source)
- vm.setNode(source, globalNode)
- if globalNode.cate == 'variable' then
+ if not root._globalBase then
+ root._globalBase = {}
+ end
+ local name = global:asKeyName()
+ if not root._globalBase[name] then
+ root._globalBase[name] = {
+ type = 'globalbase',
+ parent = root,
+ }
+ end
+ local globalNode = vm.getNode(root._globalBase[name])
+ if globalNode then
+ vm.setNode(source, globalNode, true)
+ return
+ end
+ globalNode = vm.createNode(global)
+ vm.setNode(root._globalBase[name], globalNode, true)
+ vm.setNode(source, globalNode, true)
+
+ if global.cate == 'variable' then
local hasMarkDoc
- for _, set in ipairs(globalNode:getSets(uri)) do
+ for _, set in ipairs(global:getSets(uri)) do
if set.bindDocs then
if bindDocs(set) then
- vm.setNode(source, vm.compileNode(set))
+ globalNode:merge(vm.compileNode(set))
hasMarkDoc = true
end
end
end
- for _, set in ipairs(globalNode:getSets(uri)) do
+ for _, set in ipairs(global:getSets(uri)) do
if set.value then
if not hasMarkDoc or guide.isLiteral(set.value) then
- vm.setNode(source, vm.compileNode(set.value))
+ globalNode:merge(vm.compileNode(set.value))
end
end
end
end
- if globalNode.cate == 'type' then
- for _, set in ipairs(globalNode:getSets(uri)) do
+ if global.cate == 'type' then
+ 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 not ext._generic then
- vm.setNode(source, vm.compileNode(ext))
+ globalNode:merge(vm.compileNode(ext))
end
end
end
@@ -1584,7 +1614,7 @@ local function compileByGlobal(source)
end
if set.type == 'doc.alias' then
if not set.extends._generic then
- vm.setNode(source, vm.compileNode(set.extends))
+ globalNode:merge(vm.compileNode(set.extends))
end
end
end
diff --git a/script/vm/global-manager.lua b/script/vm/global-manager.lua
index 3f48197f..9752621e 100644
--- a/script/vm/global-manager.lua
+++ b/script/vm/global-manager.lua
@@ -191,9 +191,7 @@ local compilerGlobalSwitch = util.switch()
local name = source[1]
local type = m.declareGlobal('type', name, uri)
type:addGet(uri, source)
- if source.signs then
- source._globalNode = source
- else
+ if not source.signs then
source._globalNode = type
end
end)
diff --git a/script/vm/global.lua b/script/vm/global.lua
index 9bce3060..1c46c9a3 100644
--- a/script/vm/global.lua
+++ b/script/vm/global.lua
@@ -100,6 +100,11 @@ function mt:getName()
end
---@return string
+function mt:asKeyName()
+ return self.cate .. '|' .. self.name
+end
+
+---@return string
function mt:getKeyName()
return self.name:match('[^' .. ID_SPLITE .. ']+$')
end
diff --git a/test/completion/common.lua b/test/completion/common.lua
index 5ee2b844..4667305f 100644
--- a/test/completion/common.lua
+++ b/test/completion/common.lua
@@ -630,7 +630,7 @@ self.results.list[#self.re<??>]
},
{
label = 'results',
- kind = define.CompletionItemKind.Text,
+ kind = define.CompletionItemKind.Field,
},
}
diff --git a/test/type_inference/init.lua b/test/type_inference/init.lua
index c2bd96b7..4787dd56 100644
--- a/test/type_inference/init.lua
+++ b/test/type_inference/init.lua
@@ -1459,3 +1459,10 @@ local uri
local <?v?> = t[uri]
]]
+
+TEST 'A' [[
+---@class A
+G = {}
+
+<?G?>:A()
+]]