1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
|
local guide = require 'parser.guide'
local config = require 'config'
local type = type
local setmetatable = setmetatable
local ipairs = ipairs
_ENV = nil
---@class engineer
local mt = {}
mt.__index = mt
mt.type = 'engineer'
--- 获取对象作为域时的名字
function mt:getFieldName(obj)
if obj.type == 'getglobal' or obj.type == 'setglobal' then
return obj[1]
end
return nil
end
--- 查找所有局部变量引用
function mt:eachRefAsLocal(obj, callback)
callback(obj, 'local')
if obj.ref then
for _, ref in ipairs(obj.ref) do
local refObj = self.root[ref]
if refObj.type == 'setlocal' then
callback(self.root[ref], 'set')
elseif refObj.type == 'getlocal' then
callback(self.root[ref], 'get')
end
end
end
end
--- 查找所有全局变量引用
function mt:eachRefAsGlobal(obj, callback)
local version = config.config.runtime.version
if version ~= 'Lua 5.1' and version ~= 'LuaJIT' then
self:eachRefAsField(obj, callback)
return
end
end
--- 查找所有域引用
function mt:eachRefAsField(obj, callback)
local nodeID = obj.node
if not nodeID then
return
end
local node = self.root[nodeID]
local key = guide.getKeyName(obj)
if not key then
return
end
guide.eachField(self.value, node, key, function ()
end)
end
--- 查找所有引用
function mt:eachRef(obj, callback)
if obj.type == 'local' then
self:eachRefAsLocal(obj, callback)
elseif obj.type == 'getlocal' or obj.type == 'setlocal' then
local loc = self.root[obj.loc]
self:eachRefAsLocal(loc, callback)
elseif obj.type == 'setglobal' or obj.type == 'getglobal' then
self:eachRefAsGlobal(obj, callback)
end
end
return function (ast)
if not ast.vm then
ast.vm = {}
end
local self = setmetatable({
step = 0,
root = ast.root,
}, mt)
return self
end
|