summaryrefslogtreecommitdiff
path: root/script/vm
diff options
context:
space:
mode:
author最萌小汐 <sumneko@hotmail.com>2022-04-14 19:52:28 +0800
committer最萌小汐 <sumneko@hotmail.com>2022-04-14 19:52:28 +0800
commit045de450dd7a21e5db3b26dff39d5cd1dcf92c76 (patch)
treec9d07b61895c1a83ed669094c3aabd2d938524f0 /script/vm
parent6347c005565027cb40c7b9ad70be6edb968dd30f (diff)
downloadlua-language-server-045de450dd7a21e5db3b26dff39d5cd1dcf92c76.zip
fix global
Diffstat (limited to 'script/vm')
-rw-r--r--script/vm/compiler.lua180
-rw-r--r--script/vm/node.lua5
2 files changed, 107 insertions, 78 deletions
diff --git a/script/vm/compiler.lua b/script/vm/compiler.lua
index 66492a5e..20f0e4e3 100644
--- a/script/vm/compiler.lua
+++ b/script/vm/compiler.lua
@@ -17,9 +17,9 @@ local vm = require 'vm.vm'
local searchFieldSwitch = util.switch()
: case 'table'
- : call(function (suri, node, key, pushResult)
+ : call(function (suri, source, key, pushResult)
local hasFiled = false
- for _, field in ipairs(node) do
+ for _, field in ipairs(source) do
if field.type == 'tablefield'
or field.type == 'tableindex' then
local fieldKey = guide.getKeyName(field)
@@ -50,31 +50,8 @@ local searchFieldSwitch = util.switch()
end
end
end)
- : case 'global'
- ---@param node vm.global
- : call(function (suri, node, key, pushResult)
- if node.cate == 'variable' then
- if key then
- if type(key) ~= 'string' then
- return
- end
- local global = globalMgr.getGlobal('variable', node.name, key)
- if global then
- pushResult(global)
- end
- else
- local globals = globalMgr.getFields('variable', node.name)
- for _, global in ipairs(globals) do
- pushResult(global)
- end
- end
- end
- if node.cate == 'type' then
- vm.getClassFields(suri, node, key, pushResult)
- end
- end)
: case 'string'
- : call(function (suri, node, key, pushResult)
+ : call(function (suri, source, key, pushResult)
-- change to `string: stringlib` ?
local stringlib = globalMgr.getGlobal('type', 'stringlib')
if stringlib then
@@ -96,18 +73,18 @@ local searchFieldSwitch = util.switch()
end
end)
: case 'doc.type.array'
- : call(function (suri, node, key, pushResult)
+ : call(function (suri, source, key, pushResult)
if type(key) == 'number' then
if key < 1
or not math.tointeger(key) then
return
end
end
- pushResult(node.node)
+ pushResult(source.node)
end)
: case 'doc.type.table'
- : call(function (suri, node, key, pushResult)
- for _, field in ipairs(node.fields) do
+ : call(function (suri, source, key, pushResult)
+ for _, field in ipairs(source.fields) do
local fieldKey = field.name
if fieldKey.type == 'doc.type' then
local fieldNode = vm.compileNode(fieldKey)
@@ -131,6 +108,63 @@ local searchFieldSwitch = util.switch()
end
end
end)
+ : case 'global'
+ : call(function (suri, node, key, pushResult)
+ if node.cate == 'variable' then
+ if key then
+ if type(key) ~= 'string' then
+ return
+ end
+ local global = globalMgr.getGlobal('variable', node.name, key)
+ if global then
+ pushResult(global)
+ end
+ else
+ local globals = globalMgr.getFields('variable', node.name)
+ for _, global in ipairs(globals) do
+ pushResult(global)
+ end
+ end
+ end
+ if node.cate == 'type' then
+ vm.getClassFields(suri, node, key, pushResult)
+ end
+ end)
+ : default(function (suri, source, key, pushResult)
+ local node = source._globalNode
+ if not node then
+ return
+ end
+ if node.cate == 'variable' then
+ if key then
+ if type(key) ~= 'string' then
+ return
+ end
+ local global = globalMgr.getGlobal('variable', node.name, key)
+ if global then
+ 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
+ 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
+ if node.cate == 'type' then
+ vm.getClassFields(suri, node, key, pushResult)
+ end
+ end)
function vm.getClassFields(suri, node, key, pushResult)
@@ -168,15 +202,6 @@ function vm.getClassFields(suri, node, key, pushResult)
pushResult(field)
end
end)
- if src._globalNode then
- searchFieldSwitch('global', suri, src._globalNode, key, function (field)
- local fieldKey = field:getKeyName()
- if not searchedFields[fieldKey] then
- hasFounded[fieldKey] = true
- pushResult(field)
- end
- end)
- end
end
end
-- look into extends(if field not found)
@@ -1510,63 +1535,64 @@ local function compileByNode(source)
end
---@param source vm.object
-local function compileByGlobal(uri, source)
- uri = uri or guide.getUri(source)
- if source.type == 'global' then
- vm.setNode(source, source)
- if source.cate == 'variable' then
- local hasMarkDoc
- for _, set in ipairs(source:getSets(uri)) do
- if set.bindDocs then
- if bindDocs(set) then
- vm.setNode(source, vm.compileNode(set))
- hasMarkDoc = true
- end
+local function compileByGlobal(source)
+ local globalNode = source._globalNode
+ if not globalNode then
+ return
+ end
+ local uri = guide.getUri(source)
+ vm.setNode(source, globalNode)
+ if globalNode.cate == 'variable' then
+ local hasMarkDoc
+ for _, set in ipairs(globalNode:getSets(uri)) do
+ if set.bindDocs then
+ if bindDocs(set) then
+ vm.setNode(source, vm.compileNode(set))
+ hasMarkDoc = true
end
end
- for _, set in ipairs(source:getSets(uri)) do
- if set.value then
- if not hasMarkDoc or guide.isLiteral(set.value) then
- vm.setNode(source, vm.compileNode(set.value))
- end
+ end
+ for _, set in ipairs(globalNode:getSets(uri)) do
+ if set.value then
+ if not hasMarkDoc or guide.isLiteral(set.value) then
+ vm.setNode(source, vm.compileNode(set.value))
end
end
end
- if source.cate == 'type' then
- 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
- if ext.type == 'doc.type.table' then
- if not ext._generic then
- vm.setNode(source, vm.compileNode(ext))
- end
+ end
+ if globalNode.cate == 'type' then
+ for _, set in ipairs(globalNode: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))
end
end
end
end
- if set.type == 'doc.alias' then
- if not set.extends._generic then
- vm.setNode(source, vm.compileNode(set.extends))
- end
+ end
+ if set.type == 'doc.alias' then
+ if not set.extends._generic then
+ vm.setNode(source, vm.compileNode(set.extends))
end
end
end
- return
- end
- if source._globalNode then
- vm.setNode(source, vm.compileNode(source._globalNode, uri))
- return
end
end
---@param source vm.object
----@param uri? uri
---@return vm.node
-function vm.compileNode(source, uri)
+function vm.compileNode(source)
if not source then
error('Can not compile nil node')
end
+
+ if source.type == 'global' then
+ return source
+ end
+
local cache = vm.getNode(source)
if cache ~= nil then
return cache
@@ -1574,7 +1600,7 @@ function vm.compileNode(source, uri)
local node = vm.createNode()
vm.setNode(source, node, true)
- compileByGlobal(uri, source)
+ compileByGlobal(source)
compileByNode(source)
node = vm.getNode(source)
diff --git a/script/vm/node.lua b/script/vm/node.lua
index b43bea3a..ea6a5874 100644
--- a/script/vm/node.lua
+++ b/script/vm/node.lua
@@ -196,13 +196,16 @@ function mt:eachObject()
end
end
----@param source vm.object
+---@param source parser.object | vm.generic
---@param node vm.node | vm.object
---@param cover? boolean
function vm.setNode(source, node, cover)
if not node then
error('Can not set nil node')
end
+ if source.type == 'global' then
+ error('Can not set node to global')
+ end
if cover then
vm.nodeCache[source] = node
return