Skip to content

Commit d74c85c

Browse files
committed
stash
1 parent 809fa70 commit d74c85c

File tree

3 files changed

+104
-51
lines changed

3 files changed

+104
-51
lines changed

script/parser/guide.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -433,7 +433,7 @@ function m.getRoot(obj)
433433
error('guide.getRoot overstack')
434434
end
435435

436-
---@param obj parser.object
436+
---@param obj parser.object | { uri: uri }
437437
---@return uri
438438
function m.getUri(obj)
439439
if obj.uri then

script/vm/compiler.lua

Lines changed: 44 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -59,15 +59,27 @@ local function bindDocs(source)
5959
return false
6060
end
6161

62-
---@param source parser.object
62+
---@param source parser.object | vm.variable
6363
---@param key any
6464
---@param pushResult fun(res: parser.object, markDoc?: boolean)
6565
local function searchFieldByLocalID(source, key, pushResult)
6666
local fields
6767
if key then
68-
fields = vm.getVariableSets(source, key)
68+
if source.type == 'variable' then
69+
---@cast source vm.variable
70+
fields = source:getSets(key)
71+
else
72+
---@cast source parser.object
73+
fields = vm.getVariableSets(source, key)
74+
end
6975
else
70-
fields = vm.getVariableFields(source, false)
76+
if source.type == 'variable' then
77+
---@cast source vm.variable
78+
fields = source:getFields(false)
79+
else
80+
---@cast source parser.object
81+
fields = vm.getVariableFields(source, false)
82+
end
7183
end
7284
if not fields then
7385
return
@@ -619,7 +631,7 @@ local function bindAs(source)
619631
return false
620632
end
621633

622-
---@param source parser.object
634+
---@param source parser.object | vm.variable
623635
---@param key? string|vm.global
624636
---@param pushResult fun(source: parser.object)
625637
function vm.compileByParentNode(source, key, pushResult)
@@ -1259,22 +1271,6 @@ local compilerSwitch = util.switch()
12591271
return
12601272
end
12611273
end
1262-
---@cast key string
1263-
vm.compileByParentNode(source.node, key, function (src)
1264-
if src.value then
1265-
if bindDocs(src) then
1266-
vm.setNode(source, vm.compileNode(src))
1267-
elseif src.value.type ~= 'nil' then
1268-
vm.setNode(source, vm.compileNode(src.value))
1269-
local node = vm.getNode(src)
1270-
if node then
1271-
vm.setNode(source, node)
1272-
end
1273-
end
1274-
else
1275-
vm.setNode(source, vm.compileNode(src))
1276-
end
1277-
end)
12781274
end
12791275
end)
12801276
: case 'setglobal'
@@ -1764,6 +1760,34 @@ local compilerSwitch = util.switch()
17641760
end
17651761
end
17661762
end)
1763+
: case 'variable'
1764+
---@param variable vm.variable
1765+
: call(function (variable)
1766+
if variable == vm.getVariable(variable.base) then
1767+
vm.setNode(variable, vm.compileNode(variable.base))
1768+
return
1769+
end
1770+
local parentVariable = variable:getParent()
1771+
local fieldName = variable:getFieldName()
1772+
if not parentVariable or not fieldName then
1773+
return
1774+
end
1775+
vm.compileByParentNode(parentVariable, fieldName, function (src)
1776+
if src.value then
1777+
if bindDocs(src) then
1778+
vm.setNode(variable, vm.compileNode(src))
1779+
elseif src.value.type ~= 'nil' then
1780+
vm.setNode(variable, vm.compileNode(src.value))
1781+
local node = vm.getNode(src)
1782+
if node then
1783+
vm.setNode(variable, node)
1784+
end
1785+
end
1786+
else
1787+
vm.setNode(variable, vm.compileNode(src))
1788+
end
1789+
end)
1790+
end)
17671791

17681792
---@param source parser.object
17691793
local function compileByNode(source)

script/vm/variable.lua

Lines changed: 59 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ local guide = require 'parser.guide'
44
local vm = require 'vm.vm'
55

66
---@class vm.variable
7+
---@field uri uri
78
---@field root parser.object
89
---@field id string
910
---@field base parser.object
@@ -18,6 +19,7 @@ mt.type = 'variable'
1819
local function createVariable(root, id)
1920
local variable = setmetatable({
2021
root = root,
22+
uri = root.uri,
2123
id = id,
2224
sets = {},
2325
gets = {},
@@ -175,6 +177,60 @@ function mt:getCodeName()
175177
return name
176178
end
177179

180+
---@return vm.variable?
181+
function mt:getParent()
182+
local parentID = self.id:match('^(.+)' .. vm.ID_SPLITE)
183+
if not parentID then
184+
return nil
185+
end
186+
return self.root._variableNodes[parentID]
187+
end
188+
189+
---@return string?
190+
function mt:getFieldName()
191+
return self.id:match(vm.ID_SPLITE .. '(.-)$')
192+
end
193+
194+
---@param key? string
195+
function mt:getSets(key)
196+
if not key then
197+
return self.sets
198+
end
199+
local id = self.id .. vm.ID_SPLITE .. key
200+
local variable = self.root._variableNodes[id]
201+
return variable.sets
202+
end
203+
204+
---@param includeGets boolean?
205+
function mt:getFields(includeGets)
206+
local id = self.id
207+
local root = self.root
208+
-- TODO:optimize
209+
local clock = os.clock()
210+
local fields = {}
211+
for lid, variable in pairs(root._variableNodes) do
212+
if lid ~= id
213+
and util.stringStartWith(lid, id)
214+
and lid:sub(#id + 1, #id + 1) == vm.ID_SPLITE
215+
-- only one field
216+
and not lid:find(vm.ID_SPLITE, #id + 2) then
217+
for _, src in ipairs(variable.sets) do
218+
fields[#fields+1] = src
219+
end
220+
if includeGets then
221+
for _, src in ipairs(variable.gets) do
222+
fields[#fields+1] = src
223+
end
224+
end
225+
end
226+
end
227+
local cost = os.clock() - clock
228+
if cost > 1.0 then
229+
log.warn('variable-id getFields takes %.3f seconds', cost)
230+
end
231+
return fields
232+
end
233+
178234
---@param source parser.object
179235
---@param base parser.object
180236
function compileVariables(source, base)
@@ -283,38 +339,11 @@ end
283339
---@param includeGets boolean
284340
---@return parser.object[]?
285341
function vm.getVariableFields(source, includeGets)
286-
local id = vm.getVariableID(source)
287-
if not id then
288-
return nil
289-
end
290-
local root = guide.getRoot(source)
291-
if not root._variableNodes then
342+
local variable = vm.getVariable(source)
343+
if not variable then
292344
return nil
293345
end
294-
-- TODO:optimize
295-
local clock = os.clock()
296-
local fields = {}
297-
for lid, variable in pairs(root._variableNodes) do
298-
if lid ~= id
299-
and util.stringStartWith(lid, id)
300-
and lid:sub(#id + 1, #id + 1) == vm.ID_SPLITE
301-
-- only one field
302-
and not lid:find(vm.ID_SPLITE, #id + 2) then
303-
for _, src in ipairs(variable.sets) do
304-
fields[#fields+1] = src
305-
end
306-
if includeGets then
307-
for _, src in ipairs(variable.gets) do
308-
fields[#fields+1] = src
309-
end
310-
end
311-
end
312-
end
313-
local cost = os.clock() - clock
314-
if cost > 1.0 then
315-
log.warn('variable-id getFields takes %.3f seconds', cost)
316-
end
317-
return fields
346+
return variable:getFields(includeGets)
318347
end
319348

320349
---@param source parser.object

0 commit comments

Comments
 (0)