Skip to content

Commit 3b42eaf

Browse files
author
Steve Ives
committed
Corrected an issue that was causing field loop expansion tokens and field loop expression tokens to be incorrectly processed when a key segment loop was embedded within a key loop, which was in turn embedded within a field loop. When field loop tokens are used within the context of a key segment loop they are supposed to be processed in the context of the field associated with the current key segment being processed by the key segment loop that immediately contains the tokens. However they were actually being processed in the context of the current field in the outer field loop.
1 parent cbd32ac commit 3b42eaf

File tree

4 files changed

+44
-21
lines changed

4 files changed

+44
-21
lines changed

CodeGenEngine/ExpressionEvaluators/ExpressionEvaluatorFieldLoop.dbl

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,7 @@ namespace CodeGen.Engine
266266
proc
267267

268268
lambda isFieldOrSegmentLoop(node) (node .is. FieldLoopNode || node .is. SegmentLoopNode)
269-
data loop, @LoopNode, loops.First(isFieldOrSegmentLoop)
269+
data loop, @LoopNode, loops.Last(isFieldOrSegmentLoop)
270270

271271
data str, @RpsStructure, ^null
272272
data field, @RpsField, ^null
@@ -296,7 +296,7 @@ namespace CodeGen.Engine
296296
;;Now get a handle on the full definition of the key segment we're dealing with
297297
data segment, @RpsKeySegment, ((@RelationSegmentLoopNode)loop).CurrentSegment
298298

299-
;;And get a hangle on the field associated with the current segment
299+
;;And get a handle on the field associated with the current segment
300300
;;Could return null if it a "literal" segment
301301
lambda isSegmentField(fld) (fld.Name == segment.Field)
302302
field = str.Fields.FirstOrDefault(isSegmentField)
@@ -306,17 +306,9 @@ namespace CodeGen.Engine
306306
else if (loop .is. SegmentLoopNode)
307307
begin
308308
;;We're in a regular key segment loop
309-
310-
;;Get a handle on the structure being processed
309+
;;Get handles on the current structure, field, and index
311310
str = template.Context.CurrentStructure
312-
313-
;;Amd the current key segment
314-
data segment, @RpsKeySegment, ((@SegmentLoopNode)loop).CurrentSegment
315-
316-
;;And the field associated with the key segment
317-
lambda isSegmentField(fld) (fld.Name == segment.Field)
318-
field = str.Fields.First(isSegmentField)
319-
311+
field = ((@SegmentLoopNode)loop).CurrentField
320312
index = ((@SegmentLoopNode)loop).CurrentIndex
321313
end
322314

CodeGenEngine/TokenExpanders/TokenExpanderFieldLoop.dbl

Lines changed: 40 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -170,15 +170,43 @@ namespace CodeGen.Engine
170170
specific, @Func<RpsStructure, RpsField, string>
171171
endparams
172172
proc
173-
lambda isFieldLoop(node) node .is. FieldLoopNode
174-
data fieldLoop, @FieldLoopNode, ^as(loops.FirstOrDefault(isFieldLoop), FieldLoopNode)
175-
176-
if (fieldLoop != ^null) then
177-
mreturn specific(template.Context.CurrentStructure, fieldLoop.CurrentField)
178-
else
173+
174+
lambda isFieldOrSegmentLoop(node) (node .is. FieldLoopNode || node .is. SegmentLoopNode)
175+
data loop, @LoopNode, loops.Last(isFieldOrSegmentLoop)
176+
177+
data str, @RpsStructure
178+
data fld, @RpsField
179+
180+
if (loop .is. FieldLoopNode) then
179181
begin
180-
lambda isSegmentLoop(node) node .is. SegmentLoopNode
181-
data segloop, @SegmentLoopNode, ^as(loops.FirstOrDefault(isSegmentLoop), SegmentLoopNode)
182+
;;We're in a field loop
183+
str = template.Context.CurrentStructure
184+
fld = ((@FieldLoopNode)loop).CurrentField
185+
end
186+
else if (loop .is. RelationSegmentLoopNode) then
187+
begin
188+
;;We're in a relation key segment loop
189+
190+
;;First get a handle on the outer relation loop that must be above us in the tree
191+
lambda isRelationLoop(node) (node .is. RelationLoopNode)
192+
data relationLoop, @RelationLoopNode, ^as(loops.First(isRelationLoop), @RelationLoopNode)
193+
194+
;;Determine which structure we're dealing with, based on the TYPE of relation segment loop (FROM_KEY_SEGMENT_LOOP or TO_KEY_SEGMENT_LOOP)
195+
str = loop.OpenToken.Value.StartsWith("FROM_KEY_SEGMENT_LOOP") ? template.Context.CurrentStructure : relationLoop.ToStructure
196+
197+
;;Now get a handle on the full definition of the key segment we're dealing with
198+
data segment, @RpsKeySegment, ((@RelationSegmentLoopNode)loop).CurrentSegment
199+
200+
;;And get a handle on the field associated with the current segment
201+
;;Could return null if it a "literal" segment
202+
lambda isSegmentField(f) (f.Name == segment.Field)
203+
fld = str.Fields.FirstOrDefault(isSegmentField)
204+
205+
end
206+
else if (loop .is. SegmentLoopNode)
207+
begin
208+
;;We're in a regular key segment loop
209+
data segloop = (@SegmentLoopNode)loop
182210

183211
;;There are some scenarios where field loop tokens are theoretically valid,
184212
;;But where in some specific scenarios there may be no current field.
@@ -189,9 +217,12 @@ namespace CodeGen.Engine
189217
if (segloop.CurrentField == ^null)
190218
throw new ApplicationException(String.Format("Can't use field loop token in segment loop for structure {0} key {1} segment {2}. No associated field!",template.Context.CurrentStructure.Name, segloop.CurrentKey.Name, segloop.CurrentIndex + 1))
191219

192-
mreturn specific(template.Context.CurrentStructure, segloop.CurrentField)
220+
str = template.Context.CurrentStructure
221+
fld = segloop.CurrentField
193222
end
194223

224+
mreturn specific(str, fld)
225+
195226
endmethod
196227

197228
private static method expandFieldAltName, string

Documentation/CodeGen.chm

708 Bytes
Binary file not shown.

Documentation/CodeGen.hsm

2.67 KB
Binary file not shown.

0 commit comments

Comments
 (0)