summaryrefslogtreecommitdiff
path: root/script
diff options
context:
space:
mode:
author最萌小汐 <sumneko@hotmail.com>2022-02-16 20:05:16 +0800
committer最萌小汐 <sumneko@hotmail.com>2022-02-16 20:05:16 +0800
commitef2e67cc15093909b7055c0671e777b53cb327fa (patch)
treed6501aef59271ba58ad31e7b4341e1a2d1447c94 /script
parente5768e9415d310552acbb93fae1d2286d98adb3c (diff)
downloadlua-language-server-ef2e67cc15093909b7055c0671e777b53cb327fa.zip
update
Diffstat (limited to 'script')
-rw-r--r--script/utility.lua31
-rw-r--r--script/vm/getDef.lua44
-rw-r--r--script/vm/node/compiler.lua20
-rw-r--r--script/vm/state.lua46
4 files changed, 121 insertions, 20 deletions
diff --git a/script/utility.lua b/script/utility.lua
index 6758a47f..0e4df627 100644
--- a/script/utility.lua
+++ b/script/utility.lua
@@ -21,9 +21,8 @@ local getupvalue = debug.getupvalue
local mathHuge = math.huge
local inf = 1 / 0
local nan = 0 / 0
-local utf8 = utf8
local error = error
-local upvalueid = debug.upvalueid
+local assert = assert
_ENV = nil
@@ -730,4 +729,32 @@ function m.defaultTable(default)
end })
end
+function m.multiTable(count, default)
+ local current
+ if default then
+ current = setmetatable({}, { __index = function (t, k)
+ local v = default(k)
+ t[k] = v
+ return v
+ end })
+ else
+ current = setmetatable({}, { __index = function (t, k)
+ local v = {}
+ t[k] = v
+ return v
+ end })
+ end
+ for _ = 3, count do
+ current = setmetatable({}, { __index = function (t, k)
+ t[k] = current
+ return current
+ end })
+ end
+ return current
+end
+
+m.MODE_K = { __mode = 'k' }
+m.MODE_V = { __mode = 'v' }
+m.MODE_KV = { __mode = 'kv' }
+
return m
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