summaryrefslogtreecommitdiff
path: root/script/vm
diff options
context:
space:
mode:
author最萌小汐 <sumneko@hotmail.com>2022-02-16 16:24:13 +0800
committer最萌小汐 <sumneko@hotmail.com>2022-02-16 16:24:13 +0800
commiteaa677572486a8c8fa1a140b2dcbbff18b09d7d5 (patch)
treeb9f7024e20895655c6db3593e05b417c2fb1975b /script/vm
parent4e5ede23db35012ce0f2d9ec9a9425375f4f5062 (diff)
downloadlua-language-server-eaa677572486a8c8fa1a140b2dcbbff18b09d7d5.zip
update
Diffstat (limited to 'script/vm')
-rw-r--r--script/vm/getDef.lua30
-rw-r--r--script/vm/getDocs.lua2
-rw-r--r--script/vm/node/compiler.lua71
-rw-r--r--script/vm/node/global.lua29
-rw-r--r--script/vm/state.lua2
5 files changed, 94 insertions, 40 deletions
diff --git a/script/vm/getDef.lua b/script/vm/getDef.lua
index 5546617a..2ba4c379 100644
--- a/script/vm/getDef.lua
+++ b/script/vm/getDef.lua
@@ -49,17 +49,10 @@ local simpleMap;simpleMap = util.switch()
: getMap()
local noderMap = util.switch()
- : case 'global'
- ---@param node vm.node.global
- : call(function (node, results)
- for _, set in ipairs(node:getSets()) do
- results[#results+1] = set
- end
- end)
: getMap()
----@param source parser.guide.object
----@param results parser.guide.object[]
+---@param source parser.object
+---@param results parser.object[]
local function searchBySimple(source, results)
local simple = simpleMap[source.type]
if simple then
@@ -67,9 +60,12 @@ local function searchBySimple(source, results)
end
end
----@param source parser.guide.object
----@param results parser.guide.object[]
+---@param source parser.object
+---@param results parser.object[]
local function searchByGlobal(source, results)
+ if source.type == 'field' then
+ source = source.parent
+ end
local global = source._globalID
if not global then
return
@@ -79,8 +75,8 @@ local function searchByGlobal(source, results)
end
end
----@param source parser.guide.object
----@param results parser.guide.object[]
+---@param source parser.object
+---@param results parser.object[]
local function searchByNode(source, results)
local uri = guide.getUri(source)
local node = compiler.compileNode(uri, source)
@@ -90,8 +86,8 @@ local function searchByNode(source, results)
end
end
----@param source parser.guide.object
----@return parser.guide.object[]
+---@param source parser.object
+---@return parser.object[]
function vm.getDefs(source)
local results = {}
@@ -102,8 +98,8 @@ function vm.getDefs(source)
return results
end
----@param source parser.guide.object
----@return parser.guide.object[]
+---@param source parser.object
+---@return parser.object[]
function vm.getAllDefs(source)
return vm.getDefs(source)
end
diff --git a/script/vm/getDocs.lua b/script/vm/getDocs.lua
index a8c5da29..d13878e6 100644
--- a/script/vm/getDocs.lua
+++ b/script/vm/getDocs.lua
@@ -8,7 +8,7 @@ local define = require 'proto.define'
---获取class与alias
---@param name? string
----@return parser.guide.object[]
+---@return parser.object[]
function vm.getDocDefines(uri, name)
local cache = vm.getCache 'getDocDefines'
if cache[name] then
diff --git a/script/vm/node/compiler.lua b/script/vm/node/compiler.lua
index db5cd486..2dfd6efd 100644
--- a/script/vm/node/compiler.lua
+++ b/script/vm/node/compiler.lua
@@ -2,8 +2,7 @@ local guide = require 'parser.guide'
local util = require 'utility'
local state = require 'vm.state'
----@class parser.guide.object
----@field _compiledGlobal boolean
+---@class parser.object
---@field _compiledNodes boolean
---@field _compiled any
---@field _globalID vm.node.global
@@ -13,14 +12,21 @@ local m = {}
---@class vm.node.unknown
m.UNKNOWN = { type = 'unknown' }
+m.GLOBAL_SPLITE = '\x1F'
---@alias vm.node vm.node.unknown | vm.node.global | vm.node.class
+---@param ... string
+---@return string
+function m.getGlobalID(...)
+ return table.concat({...}, m.GLOBAL_SPLITE)
+end
+
local compilerMap = util.switch()
: getMap()
---@param uri uri
----@param source parser.guide.object
+---@param source parser.object
---@return vm.node
function m.compileNode(uri, source)
if source._compiled then
@@ -35,6 +41,17 @@ function m.compileNode(uri, source)
end
local compilerGlobalMap = util.switch()
+ : case 'local'
+ : call(function (uri, source)
+ if source.tag ~= '_ENV' then
+ return
+ end
+ if source.ref then
+ for _, ref in ipairs(source.ref) do
+ m.compileGlobalNode(uri, ref)
+ end
+ end
+ end)
: case 'setglobal'
: call(function (uri, source)
local name = guide.getKeyName(source)
@@ -46,11 +63,45 @@ local compilerGlobalMap = util.switch()
local global = state.getGlobal(name)
global:addGet(uri, source)
source._globalID = global
+
+ local nxt = source.next
+ if nxt then
+ m.compileGlobalNode(uri, nxt)
+ end
+ end)
+ : case 'setfield'
+ ---@param uri uri
+ ---@param source parser.object
+ : call(function (uri, source)
+ local parent = source.node._globalID
+ if not parent then
+ return
+ end
+ local name = m.getGlobalID(parent:getName(), guide.getKeyName(source))
+ source._globalID = state.declareGlobal(name, uri, source)
+ end)
+ : case 'getfield'
+ ---@param uri uri
+ ---@param source parser.object
+ : call(function (uri, source)
+ local parent = source.node._globalID
+ if not parent then
+ return
+ end
+ local name = m.getGlobalID(parent:getName(), guide.getKeyName(source))
+ local global = state.getGlobal(name)
+ global:addGet(uri, source)
+ source._globalID = global
+
+ local nxt = source.next
+ if nxt then
+ m.compileGlobalNode(uri, nxt)
+ end
end)
: getMap()
---@param uri uri
----@param source parser.guide.object
+---@param source parser.object
function m.compileGlobalNode(uri, source)
if source._globalID ~= nil then
return
@@ -63,19 +114,11 @@ function m.compileGlobalNode(uri, source)
end
---编译全局变量的node
----@param root parser.guide.object
+---@param root parser.object
function m.compileGlobals(root)
- if root._compiledGlobal then
- return
- end
- root._compiledGlobal = true
local uri = guide.getUri(root)
local env = guide.getENV(root)
- if env.ref then
- for _, ref in ipairs(env.ref) do
- m.compileGlobalNode(uri, ref)
- end
- end
+ m.compileGlobalNode(uri, env)
end
return m
diff --git a/script/vm/node/global.lua b/script/vm/node/global.lua
index 0e293ca3..499e526b 100644
--- a/script/vm/node/global.lua
+++ b/script/vm/node/global.lua
@@ -1,24 +1,33 @@
local util = require 'utility'
+---@class vm.node.global.link
+---@field gets parser.object[]
+---@field sets parser.object[]
+
---@class vm.node.global
----@field links table<uri, { gets: table, sets: table }>
----@field setsCache parser.guide.object[]
----@field getsCache parser.guide.object[]
+---@field links table<uri, vm.node.global.link>
+---@field setsCache parser.object[]
+---@field getsCache parser.object[]
local mt = {}
mt.__index = mt
mt.type = 'global'
mt.name = ''
+---@param uri uri
+---@param source parser.object
function mt:addSet(uri, source)
local link = self.links[uri]
link.sets[#link.sets+1] = source
end
+---@param uri uri
+---@param source parser.object
function mt:addGet(uri, source)
local link = self.links[uri]
link.gets[#link.gets+1] = source
end
+---@return parser.object[]
function mt:getSets()
if not self.setsCache then
self.setsCache = {}
@@ -31,6 +40,7 @@ function mt:getSets()
return self.setsCache
end
+---@return parser.object[]
function mt:getGets()
if not self.getsCache then
self.getsCache = {}
@@ -43,22 +53,27 @@ function mt:getGets()
return self.getsCache
end
+---@param uri uri
function mt:dropUri(uri)
self.links[uri] = nil
self.setsCache = nil
self.getsCache = nil
end
+---@return string
+function mt:getName()
+ return self.name
+end
+
---@return vm.node.global
return function (name)
- local global = setmetatable({
+ return setmetatable({
name = name,
links = util.defaultTable(function ()
return {
- sets = {},
- gets = {},
+ sets = {},
+ gets = {},
}
end),
}, mt)
- return global
end
diff --git a/script/vm/state.lua b/script/vm/state.lua
index 87376952..cec9eb6f 100644
--- a/script/vm/state.lua
+++ b/script/vm/state.lua
@@ -15,7 +15,7 @@ end)
---@param name string
---@param uri uri
----@param source parser.guide.object
+---@param source parser.object
---@return vm.node.global
function m.declareGlobal(name, uri, source)
m.subscriptions[uri].globals[name] = true