summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--script/core/infer.lua14
-rw-r--r--script/parser/guide.lua112
-rw-r--r--script/parser/newparser.lua10
-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
8 files changed, 162 insertions, 108 deletions
diff --git a/script/core/infer.lua b/script/core/infer.lua
index d98449d1..35a054ca 100644
--- a/script/core/infer.lua
+++ b/script/core/infer.lua
@@ -396,7 +396,7 @@ function m.viewDocFunction(doc)
end
---显示对象的推断类型
----@param source parser.guide.object
+---@param source parser.object
---@param mark table
---@return string
local function searchInfer(source, infers, mark)
@@ -467,7 +467,7 @@ local function getCachedInfers(source, field)
end
---搜索对象的推断类型
----@param source parser.guide.object
+---@param source parser.object
---@param field? string
---@param mark? table
---@return string[]
@@ -511,7 +511,7 @@ function m.searchInfers(source, field, mark)
end
---搜索对象的字面量值
----@param source parser.guide.object
+---@param source parser.object
---@param field? string
---@param mark? table
---@return table
@@ -532,7 +532,7 @@ function m.searchLiterals(source, field, mark)
end
---搜索并显示推断值
----@param source parser.guide.object
+---@param source parser.object
---@param field? string
---@return string
function m.searchAndViewLiterals(source, field, mark)
@@ -548,7 +548,7 @@ function m.searchAndViewLiterals(source, field, mark)
end
---判断对象的推断值是否是 true
----@param source parser.guide.object
+---@param source parser.object
---@param mark? table
function m.isTrue(source, mark)
if not source then
@@ -594,7 +594,7 @@ function m.hasType(source, tp, mark)
end
---搜索并显示推断类型
----@param source parser.guide.object
+---@param source parser.object
---@param field? string
---@return string
function m.searchAndViewInfers(source, field, mark)
@@ -611,7 +611,7 @@ function m.searchAndViewInfers(source, field, mark)
end
---搜索并显示推断的class
----@param source parser.guide.object
+---@param source parser.object
---@return string?
function m.getClass(source)
if not source then
diff --git a/script/parser/guide.lua b/script/parser/guide.lua
index 1ee6fceb..638c08bf 100644
--- a/script/parser/guide.lua
+++ b/script/parser/guide.lua
@@ -1,61 +1,61 @@
local error = error
local type = type
----@class parser.guide.object
----@field bindDocs parser.guide.object[]
----@field bindGroup parser.guide.object[]
----@field bindSources parser.guide.object[]
----@field value parser.guide.object
----@field parent parser.guide.object
+---@class parser.object
+---@field bindDocs parser.object[]
+---@field bindGroup parser.object[]
+---@field bindSources parser.object[]
+---@field value parser.object
+---@field parent parser.object
---@field type string
---@field special string
---@field tag string
----@field args parser.guide.object[]
----@field locals parser.guide.object[]
----@field returns parser.guide.object[]
+---@field args parser.object[]
+---@field locals parser.object[]
+---@field returns parser.object[]
---@field uri uri
---@field start integer
---@field finish integer
---@field effect integer
---@field attrs string[]
----@field specials parser.guide.object[]
----@field labels parser.guide.object[]
----@field node parser.guide.object
+---@field specials parser.object[]
+---@field labels parser.object[]
+---@field node parser.object
---@field dummy boolean
----@field field parser.guide.object
----@field method parser.guide.object
----@field index parser.guide.object
----@field extends parser.guide.object[]
----@field types parser.guide.object[]
----@field fields parser.guide.object[]
----@field typeGeneric table<integer, parser.guide.object[]>
----@field tkey parser.guide.object
----@field tvalue parser.guide.object
+---@field field parser.object
+---@field method parser.object
+---@field index parser.object
+---@field extends parser.object[]
+---@field types parser.object[]
+---@field fields parser.object[]
+---@field typeGeneric table<integer, parser.object[]>
+---@field tkey parser.object
+---@field tvalue parser.object
---@field tindex integer
----@field op parser.guide.object
----@field next parser.guide.object
----@field docParam parser.guide.object
+---@field op parser.object
+---@field next parser.object
+---@field docParam parser.object
---@field sindex integer
----@field name parser.guide.object
----@field call parser.guide.object
----@field closure parser.guide.object
----@field proto parser.guide.object
----@field exp parser.guide.object
+---@field name parser.object
+---@field call parser.object
+---@field closure parser.object
+---@field proto parser.object
+---@field exp parser.object
---@field isGeneric boolean
----@field alias parser.guide.object
----@field class parser.guide.object
----@field vararg parser.guide.object
----@field param parser.guide.object
----@field overload parser.guide.object
+---@field alias parser.object
+---@field class parser.object
+---@field vararg parser.object
+---@field param parser.object
+---@field overload parser.object
---@field docParamMap table<string, integer>
---@field upvalues table<string, string[]>
----@field ref parser.guide.object[]
+---@field ref parser.object[]
---@field returnIndex integer
----@field docs parser.guide.object[]
+---@field docs parser.object[]
---@field state table
---@field comment table
---@field optional boolean
----@field _root parser.guide.object
+---@field _root parser.object
---@class guide
---@field debugMode boolean
@@ -142,7 +142,7 @@ local childMap = {
['doc.diagnostic'] = {'#names'},
}
----@type table<string, fun(obj: parser.guide.object, list: parser.guide.object[])>
+---@type table<string, fun(obj: parser.object, list: parser.object[])>
local compiledChildMap = setmetatable({}, {__index = function (self, name)
local defs = childMap[name]
if not defs then
@@ -222,7 +222,7 @@ local function formatNumber(n)
end
--- 是否是字面量
----@param obj parser.guide.object
+---@param obj parser.object
---@return boolean
function m.isLiteral(obj)
local tp = obj.type
@@ -236,7 +236,7 @@ function m.isLiteral(obj)
end
--- 获取字面量
----@param obj parser.guide.object
+---@param obj parser.object
---@return any
function m.getLiteral(obj)
local tp = obj.type
@@ -253,8 +253,8 @@ function m.getLiteral(obj)
end
--- 寻找父函数
----@param obj parser.guide.object
----@return parser.guide.object
+---@param obj parser.object
+---@return parser.object
function m.getParentFunction(obj)
for _ = 1, 1000 do
obj = obj.parent
@@ -270,8 +270,8 @@ function m.getParentFunction(obj)
end
--- 寻找所在区块
----@param obj parser.guide.object
----@return parser.guide.object
+---@param obj parser.object
+---@return parser.object
function m.getBlock(obj)
for _ = 1, 1000 do
if not obj then
@@ -299,8 +299,8 @@ function m.getBlock(obj)
end
--- 寻找所在父区块
----@param obj parser.guide.object
----@return parser.guide.object
+---@param obj parser.object
+---@return parser.object
function m.getParentBlock(obj)
for _ = 1, 1000 do
obj = obj.parent
@@ -316,8 +316,8 @@ function m.getParentBlock(obj)
end
--- 寻找所在可break的父区块
----@param obj parser.guide.object
----@return parser.guide.object
+---@param obj parser.object
+---@return parser.object
function m.getBreakBlock(obj)
for _ = 1, 1000 do
obj = obj.parent
@@ -336,8 +336,8 @@ function m.getBreakBlock(obj)
end
--- 寻找doc的主体
----@param obj parser.guide.object
----@return parser.guide.object
+---@param obj parser.object
+---@return parser.object
function m.getDocState(obj)
for _ = 1, 1000 do
local parent = obj.parent
@@ -353,8 +353,8 @@ function m.getDocState(obj)
end
--- 寻找所在父类型
----@param obj parser.guide.object
----@return parser.guide.object
+---@param obj parser.object
+---@return parser.object
function m.getParentType(obj, want)
for _ = 1, 1000 do
obj = obj.parent
@@ -369,8 +369,8 @@ function m.getParentType(obj, want)
end
--- 寻找根区块
----@param obj parser.guide.object
----@return parser.guide.object
+---@param obj parser.object
+---@return parser.object
function m.getRoot(obj)
local source = obj
if source._root then
@@ -394,7 +394,7 @@ function m.getRoot(obj)
error('guide.getRoot overstack')
end
----@param obj parser.guide.object
+---@param obj parser.object
---@return uri
function m.getUri(obj)
if obj.uri then
@@ -1101,7 +1101,7 @@ function m.getPath(a, b, sameFunction)
end
---是否是全局变量(包括 _G.XXX 形式)
----@param source parser.guide.object
+---@param source parser.object
---@return boolean
function m.isGlobal(source)
if source._isGlobal ~= nil then
diff --git a/script/parser/newparser.lua b/script/parser/newparser.lua
index e4884212..66df7046 100644
--- a/script/parser/newparser.lua
+++ b/script/parser/newparser.lua
@@ -2588,9 +2588,9 @@ local function skipSeps()
end
end
----@return parser.guide.object first
----@return parser.guide.object second
----@return parser.guide.object[] rest
+---@return parser.object first
+---@return parser.object second
+---@return parser.object[] rest
local function parseSetValues()
skipSpace()
local first = parseExp()
@@ -2645,8 +2645,8 @@ local function pushActionIntoCurrentChunk(action)
end
end
----@return parser.guide.object second
----@return parser.guide.object[] rest
+---@return parser.object second
+---@return parser.object[] rest
local function parseVarTails(parser, isLocal)
if Tokens[Index + 1] ~= ',' then
return
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