@@ -12,9 +12,8 @@ local util = require 'utility'
1212--- @class vm.tracer
1313--- @field mode tracer.mode
1414--- @field name string
15- --- @field source parser.object
16- --- @field variable vm.variable
17- --- @field assigns parser.object[]
15+ --- @field source parser.object | vm.variable
16+ --- @field assigns (parser.object | vm.variable )[]
1817--- @field assignMap table<parser.object , true>
1918--- @field getMap table<parser.object , true>
2019--- @field careMap table<parser.object , true>
@@ -30,7 +29,7 @@ mt.fastCalc = true
3029
3130--- @return parser.object[]
3231function mt :getCasts ()
33- local root = guide .getRoot (self .source )
32+ local root = guide .getRoot (self .main )
3433 if not root ._casts then
3534 root ._casts = {}
3635 local docs = root .docs
@@ -92,12 +91,16 @@ function mt:collectCare(obj)
9291end
9392
9493function mt :collectLocal ()
95- local startPos = self .source .start
94+ local startPos = self .source .base . start
9695 local finishPos = 0
9796
98- local variable = self .variable
97+ local variable = self .source
9998
100- assert (variable )
99+ if variable .base .type ~= ' local'
100+ and variable .base .type ~= ' self' then
101+ self .assigns [# self .assigns + 1 ] = variable
102+ self .assignMap [self .source ] = true
103+ end
101104
102105 for _ , set in ipairs (variable .sets ) do
103106 self .assigns [# self .assigns + 1 ] = set
@@ -121,18 +124,14 @@ function mt:collectLocal()
121124 if cast .name [1 ] == self .name
122125 and cast .start > startPos
123126 and cast .finish < finishPos
124- and vm .getCastTargetHead (cast ) == self . source then
127+ and vm .getCastTargetHead (cast ) == variable . base then
125128 self .casts [# self .casts + 1 ] = cast
126129 end
127130 end
128131
129132 if # self .casts > 0 then
130133 self .fastCalc = false
131134 end
132-
133- if variable ~= vm .getVariable (self .source ) then
134- self .fastCalc = false
135- end
136135end
137136
138137function mt :collectGlobal ()
@@ -173,17 +172,20 @@ end
173172--- @param finish integer
174173--- @return parser.object ?
175174function mt :getLastAssign (start , finish )
176- local assign
177- for _ , obj in ipairs (self .assigns ) do
178- if obj .type == ' local'
179- or obj .type == ' self' then
180- assign = obj
181- break
175+ local lastAssign
176+ for _ , assign in ipairs (self .assigns ) do
177+ local obj
178+ if assign .type == ' variable' then
179+ --- @cast assign vm.variable
180+ obj = assign .base
181+ else
182+ --- @cast assign parser.object
183+ obj = assign
182184 end
183185 if obj .start < start then
184186 goto CONTINUE
185187 end
186- if (obj .range or obj .start ) >= finish then
188+ if (obj .effect or obj . range or obj .start ) >= finish then
187189 break
188190 end
189191 local objBlock = guide .getTopBlock (obj )
@@ -192,11 +194,11 @@ function mt:getLastAssign(start, finish)
192194 end
193195 if objBlock .start <= finish
194196 and objBlock .finish >= finish then
195- assign = obj
197+ lastAssign = obj
196198 end
197199 :: CONTINUE::
198200 end
199- return assign
201+ return lastAssign
200202end
201203
202204--- @param pos integer
@@ -656,9 +658,7 @@ local lookIntoChild = util.switch()
656658 and call .type == ' call'
657659 and call .node .special == ' type'
658660 and call .args
659- and call .args [1 ]
660- and call .args [1 ].type == ' getlocal'
661- and call .args [1 ].node == tracer .source then
661+ and tracer .getMap [call .args [1 ]] then
662662 if action .op .type == ' ==' then
663663 topNode :narrow (tracer .uri , checker [1 ])
664664 if outNode then
@@ -790,23 +790,28 @@ end
790790--- @field package _tracer vm.tracer
791791
792792--- @param mode tracer.mode
793- --- @param source parser.object
793+ --- @param source parser.object | vm.variable
794794--- @param name string
795- --- @param variable vm.variable ?
796795--- @return vm.tracer ?
797- local function createTracer (mode , source , name , variable )
798- local node = vm .compileNode (variable or source )
796+ local function createTracer (mode , source , name )
797+ local node = vm .compileNode (source )
799798 local tracer = node ._tracer
800799 if tracer then
801800 return tracer
802801 end
803- local main = guide .getParentBlock (source )
802+ local main
803+ if source .type == ' variable' then
804+ --- @cast source vm.variable
805+ main = guide .getParentBlock (source .base )
806+ else
807+ --- @cast source parser.object
808+ main = guide .getParentBlock (source )
809+ end
804810 if not main then
805811 return nil
806812 end
807813 tracer = setmetatable ({
808814 source = source ,
809- variable = variable ,
810815 mode = mode ,
811816 name = name ,
812817 assigns = {},
833838--- @param source parser.object
834839--- @return vm.node ?
835840function vm .traceNode (source )
836- local mode , base , name , variable
841+ local mode , base , name
837842 if vm .getGlobalNode (source ) then
838843 base = vm .getGlobalBase (source )
839844 if not base then
@@ -842,15 +847,14 @@ function vm.traceNode(source)
842847 mode = ' global'
843848 name = base .global :getCodeName ()
844849 else
845- variable = vm .getVariable (source )
846- if not variable then
850+ base = vm .getVariable (source )
851+ if not base then
847852 return nil
848853 end
849- base = variable :getBase ()
850- name = variable :getCodeName ()
854+ name = base :getCodeName ()
851855 mode = ' local'
852856 end
853- local tracer = createTracer (mode , base , name , variable )
857+ local tracer = createTracer (mode , base , name )
854858 if not tracer then
855859 return nil
856860 end
0 commit comments