@@ -4,6 +4,7 @@ local guide = require 'parser.guide'
44local 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'
1819local 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
176178end
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
180236function compileVariables (source , base )
@@ -283,38 +339,11 @@ end
283339--- @param includeGets boolean
284340--- @return parser.object[] ?
285341function 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 )
318347end
319348
320349--- @param source parser.object
0 commit comments