diff options
author | 最萌小汐 <sumneko@hotmail.com> | 2022-02-16 20:05:16 +0800 |
---|---|---|
committer | 最萌小汐 <sumneko@hotmail.com> | 2022-02-16 20:05:16 +0800 |
commit | ef2e67cc15093909b7055c0671e777b53cb327fa (patch) | |
tree | d6501aef59271ba58ad31e7b4341e1a2d1447c94 /script/vm | |
parent | e5768e9415d310552acbb93fae1d2286d98adb3c (diff) | |
download | lua-language-server-ef2e67cc15093909b7055c0671e777b53cb327fa.zip |
update
Diffstat (limited to 'script/vm')
-rw-r--r-- | script/vm/getDef.lua | 44 | ||||
-rw-r--r-- | script/vm/node/compiler.lua | 20 | ||||
-rw-r--r-- | script/vm/state.lua | 46 |
3 files changed, 92 insertions, 18 deletions
diff --git a/script/vm/getDef.lua b/script/vm/getDef.lua index 1251d2cd..339053e4 100644 --- a/script/vm/getDef.lua +++ b/script/vm/getDef.lua @@ -62,7 +62,37 @@ simpleMap = util.switch() end) : getMap() -local noderMap = util.switch() +local searchFieldMap = util.switch() + : case 'table' + : call(function (node, key, results) + for _, field in ipairs(node) do + if field.type == 'tablefield' + or field.type == 'tableindex' then + if guide.getKeyName(field) == key then + results[#results+1] = field + end + end + end + end) + : getMap() + +local compiledMap;compiledMap = util.switch() + : case 'field' + : call(function (source, results) + local parent = source.parent + compiledMap[parent.type](parent, results) + end) + : case 'getfield' + : case 'setfield' + : call(function (source, results) + local node = compiler.compileNode(guide.getUri(source.node), source.node) + if not node then + return + end + if searchFieldMap[node.type] then + searchFieldMap[node.type](node, guide.getKeyName(source), results) + end + end) : getMap() ---@param source parser.object @@ -91,12 +121,10 @@ end ---@param source parser.object ---@param results parser.object[] -local function searchByNode(source, results) - local uri = guide.getUri(source) - local node = compiler.compileNode(uri, source) - local noder = noderMap[node.type] - if noder then - noder(node, results) +local function searchByCompiled(source, results) + local compiled = compiledMap[source.type] + if compiled then + compiled(source, results) end end @@ -107,7 +135,7 @@ function vm.getDefs(source) searchBySimple(source, results) searchByGlobal(source, results) - searchByNode(source, results) + searchByCompiled(source, results) return results end diff --git a/script/vm/node/compiler.lua b/script/vm/node/compiler.lua index 2dfd6efd..71d872b8 100644 --- a/script/vm/node/compiler.lua +++ b/script/vm/node/compiler.lua @@ -23,6 +23,26 @@ function m.getGlobalID(...) end local compilerMap = util.switch() + : case 'local' + : call(function (uri, source) + local value = source.value + if not value then + return + end + if value.type == 'table' + or value.type == 'integer' + or value.type == 'number' + or value.type == 'string' + or value.type == 'function' then + source._compiled = value + state.declareLiteral(uri, value) + state.subscribeLiteral(value, source) + end + end) + : case 'getlocal' + : call(function (uri, source) + source._compiled = m.compileNode(uri, source.node) + end) : getMap() ---@param uri uri diff --git a/script/vm/state.lua b/script/vm/state.lua index cec9eb6f..0048649e 100644 --- a/script/vm/state.lua +++ b/script/vm/state.lua @@ -6,11 +6,15 @@ local global = require 'vm.node.global' local m = {} ---@type table<string, vm.node.global> m.globals = util.defaultTable(global) ----@type table<uri, { globals: table }> -m.subscriptions = util.defaultTable(function () - return { - globals = {}, - } +---@type table<uri, table<string, boolean>> +m.globalSubs = util.defaultTable(function () + return {} +end) +---@type table<uri, parser.object[]> +m.literals = util.multiTable(2) +---@type table<parser.object, table<parser.object, boolean>> +m.literalSubs = util.multiTable(2, function () + return setmetatable({}, util.MODE_K) end) ---@param name string @@ -18,7 +22,7 @@ end) ---@param source parser.object ---@return vm.node.global function m.declareGlobal(name, uri, source) - m.subscriptions[uri].globals[name] = true + m.globalSubs[uri][name] = true local node = m.globals[name] node:addSet(uri, source) return node @@ -29,18 +33,40 @@ end ---@return vm.node.global function m.getGlobal(name, uri) if uri then - m.subscriptions[uri].globals[name] = true + m.globalSubs[uri][name] = true end return m.globals[name] end +---@param uri uri +---@param source parser.object +function m.declareLiteral(uri, source) + local literals = m.literals[uri] + literals[#literals+1] = source +end + +---@param literal parser.object +---@param source parser.object +function m.subscribeLiteral(literal, source) + m.literalSubs[literal][source] = true +end + ---@param uri uri function m.dropUri(uri) - local subscription = m.subscriptions[uri] - m.subscriptions[uri] = nil - for name in pairs(subscription.globals) do + local globalSub = m.globalSubs[uri] + m.globalSubs[uri] = nil + for name in pairs(globalSub) do m.globals[name]:dropUri(uri) end + local literals = m.literals[uri] + m.literals[uri] = nil + for _, literal in ipairs(literals) do + local literalSubs = m.literalSubs[literal] + m.literalSubs[literal] = nil + for source in pairs(literalSubs) do + source._compiled = nil + end + end end return m |