diff options
author | 最萌小汐 <sumneko@hotmail.com> | 2022-04-14 19:52:28 +0800 |
---|---|---|
committer | 最萌小汐 <sumneko@hotmail.com> | 2022-04-14 19:52:28 +0800 |
commit | 045de450dd7a21e5db3b26dff39d5cd1dcf92c76 (patch) | |
tree | c9d07b61895c1a83ed669094c3aabd2d938524f0 /script/vm | |
parent | 6347c005565027cb40c7b9ad70be6edb968dd30f (diff) | |
download | lua-language-server-045de450dd7a21e5db3b26dff39d5cd1dcf92c76.zip |
fix global
Diffstat (limited to 'script/vm')
-rw-r--r-- | script/vm/compiler.lua | 180 | ||||
-rw-r--r-- | script/vm/node.lua | 5 |
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 |