@@ -191,7 +191,7 @@ public override QsTypeKind onTypeParameter(QsTypeParameter tp)
191191
192192
193193 private IdentifierLocation ( Func < Identifier , bool > trackId , QsLocation defaultOffset ) :
194- base ( null , new OnTypedExpression < TypeLocation > ( null , _ => new TypeLocation ( ) , recur : true ) )
194+ base ( null , new OnTypedExpression < TypeLocation > ( null , _ => new TypeLocation ( ) ) )
195195 {
196196 this . TrackIdentifier = trackId ?? throw new ArgumentNullException ( nameof ( trackId ) ) ;
197197 this . Locations = ImmutableList < IdentifierReferences . Location > . Empty ;
@@ -278,82 +278,88 @@ private void OnExpression(TypedExpression ex)
278278
279279 // routines for finding all symbols/identifiers
280280
281+ /// <summary>
282+ /// Generates a look-up for all used local variables and their location in any of the transformed scopes,
283+ /// as well as one for all local variables reassigned in any of the transformed scopes and their locations.
284+ /// Note that the location information is relative to the root node, i.e. the start position of the containing specialization declaration.
285+ /// </summary>
281286 public class __AccumulateIdentifiers__
282287 : QsSyntaxTreeTransformation < __AccumulateIdentifiers__ . TransformationState >
283288 {
284-
285289 public class TransformationState
286290 {
291+ internal QsLocation StatementLocation = null ;
292+ internal Func < TypedExpression , TypedExpression > UpdatedExpression ;
293+
294+ private readonly List < ( NonNullable < string > , QsLocation ) > UpdatedLocals = new List < ( NonNullable < string > , QsLocation ) > ( ) ;
295+ private readonly List < ( NonNullable < string > , QsLocation ) > UsedLocals = new List < ( NonNullable < string > , QsLocation ) > ( ) ;
296+
297+ internal TransformationState ( ) =>
298+ this . UpdatedExpression = new __OnTypedExpression__ < TransformationState > ( this , this . UpdatedLocal ) . Transform ; // FIXME: ENTIRELY NEW PARENT!
299+
300+ public ILookup < NonNullable < string > , QsLocation > ReassignedVariables =>
301+ this . UpdatedLocals . ToLookup ( var => var . Item1 , var => var . Item2 ) ;
302+
303+ public ILookup < NonNullable < string > , QsLocation > UsedLocalVariables =>
304+ this . UsedLocals . ToLookup ( var => var . Item1 , var => var . Item2 ) ;
287305
306+
307+ private Func < TypedExpression , TypedExpression > Add ( List < ( NonNullable < string > , QsLocation ) > accumulate ) => ( TypedExpression ex ) =>
308+ {
309+ if ( ex . Expression is QsExpressionKind . Identifier id &&
310+ id . Item1 is Identifier . LocalVariable var )
311+ {
312+ var range = ex . Range . IsValue ? ex . Range . Item : this . StatementLocation . Range ;
313+ accumulate . Add ( ( var . Item , new QsLocation ( this . StatementLocation . Offset , range ) ) ) ;
314+ }
315+ } ;
316+
317+ internal Func < TypedExpression , TypedExpression > UsedLocal => Add ( this . UsedLocals ) ;
318+ internal Func < TypedExpression , TypedExpression > UpdatedLocal => Add ( this . UpdatedLocals ) ;
288319 }
289320
321+
290322 public __AccumulateIdentifiers__ ( ) :
291323 base ( new TransformationState ( ) )
292324 { }
293- }
294325
295- /// <summary>
296- /// Generates a look-up for all used local variables and their location in any of the transformed scopes,
297- /// as well as one for all local variables reassigned in any of the transformed scopes and their locations.
298- /// Note that the location information is relative to the root node, i.e. the start position of the containing specialization declaration.
299- /// </summary>
300- public class AccumulateIdentifiers :
301- ScopeTransformation < AccumulateIdentifiers . VariableReassignments , OnTypedExpression < Core . ExpressionTypeTransformation > >
302- {
303- private QsLocation StatementLocation ;
304- private Func < TypedExpression , TypedExpression > UpdatedExpression ;
326+ public override Core . ExpressionTransformation < TransformationState > NewExpressionTransformation ( ) =>
327+ new __OnTypedExpression__ < TransformationState > ( this , this . InternalState . UsedLocal ) ;
305328
306- private List < ( NonNullable < string > , QsLocation ) > UpdatedLocals ;
307- private List < ( NonNullable < string > , QsLocation ) > UsedLocals ;
329+ public override Core . StatementKindTransformation < TransformationState > NewStatementKindTransformation ( ) =>
330+ new VariableReassignments ( this ) ;
308331
309- public ILookup < NonNullable < string > , QsLocation > ReassignedVariables =>
310- this . UpdatedLocals . ToLookup ( var => var . Item1 , var => var . Item2 ) ;
332+ public override StatementTransformation < TransformationState > NewStatementTransformation ( ) =>
333+ new AccumulateIdentifiers ( this ) ;
311334
312- public ILookup < NonNullable < string > , QsLocation > UsedLocalVariables =>
313- this . UsedLocals . ToLookup ( var => var . Item1 , var => var . Item2 ) ;
314335
336+ // helper classes
315337
316- public AccumulateIdentifiers ( ) :
317- base (
318- scope => new VariableReassignments ( scope as AccumulateIdentifiers ) ,
319- new OnTypedExpression < Core . ExpressionTypeTransformation > ( recur : true ) )
338+ public class AccumulateIdentifiers :
339+ StatementTransformation < TransformationState >
320340 {
321- this . UpdatedLocals = new List < ( NonNullable < string > , QsLocation ) > ( ) ;
322- this . UsedLocals = new List < ( NonNullable < string > , QsLocation ) > ( ) ;
323- this . _Expression . OnExpression = this . onLocal ( this . UsedLocals ) ;
324- this . UpdatedExpression = new OnTypedExpression < Core . ExpressionTypeTransformation > ( this . onLocal ( this . UpdatedLocals ) , recur : true ) . Transform ;
325- }
341+ public AccumulateIdentifiers ( QsSyntaxTreeTransformation < TransformationState > parent )
342+ : base ( parent )
343+ { }
326344
327- private Action < TypedExpression > onLocal ( List < ( NonNullable < string > , QsLocation ) > accumulate ) => ( TypedExpression ex ) =>
328- {
329- if ( ex . Expression is QsExpressionKind . Identifier id &&
330- id . Item1 is Identifier . LocalVariable var )
345+ public override QsStatement onStatement ( QsStatement stm )
331346 {
332- var range = ex . Range . IsValue ? ex . Range . Item : this . StatementLocation . Range ;
333- accumulate . Add ( ( var . Item , new QsLocation ( this . StatementLocation . Offset , range ) ) ) ;
347+ this . Transformation . InternalState . StatementLocation = stm . Location . IsNull ? null : stm . Location . Item ;
348+ this . StatementKind . Transform ( stm . Statement ) ;
349+ return stm ;
334350 }
335- } ;
336-
337- public override QsStatement onStatement ( QsStatement stm )
338- {
339- this . StatementLocation = stm . Location . IsNull ? null : stm . Location . Item ;
340- this . StatementKind . Transform ( stm . Statement ) ;
341- return stm ;
342351 }
343352
344-
345- // helper class
346-
347353 public class VariableReassignments :
348- StatementKindTransformation < AccumulateIdentifiers >
354+ Core . StatementKindTransformation < TransformationState >
349355 {
350- public VariableReassignments ( AccumulateIdentifiers scope )
351- : base ( scope )
356+ public VariableReassignments ( QsSyntaxTreeTransformation < TransformationState > parent )
357+ : base ( parent )
352358 { }
353359
354360 public override QsStatementKind onValueUpdate ( QsValueUpdate stm )
355361 {
356- this . _Scope . UpdatedExpression ( stm . Lhs ) ;
362+ this . Transformation . InternalState . UpdatedExpression ( stm . Lhs ) ;
357363 this . ExpressionTransformation ( stm . Rhs ) ;
358364 return QsStatementKind . NewQsValueUpdate ( stm ) ;
359365 }
@@ -456,21 +462,29 @@ public class OnTypedExpression<T> :
456462 ExpressionTransformation < ExpressionKindTransformation < OnTypedExpression < T > > , T >
457463 where T : Core . ExpressionTypeTransformation
458464 {
459- private readonly bool recur ;
460-
461- public OnTypedExpression ( Action < TypedExpression > onExpression = null , Func < OnTypedExpression < T > , T > typeTransformation = null , bool recur = false ) :
465+ public OnTypedExpression ( Action < TypedExpression > onExpression = null , Func < OnTypedExpression < T > , T > typeTransformation = null ) :
462466 base ( e => new ExpressionKindTransformation < OnTypedExpression < T > > ( e as OnTypedExpression < T > ) ,
463- e => typeTransformation ? . Invoke ( e as OnTypedExpression < T > ) )
464- {
467+ e => typeTransformation ? . Invoke ( e as OnTypedExpression < T > ) ) =>
465468 this . OnExpression = onExpression ;
466- this . recur = recur ;
467- }
468469
469470 public Action < TypedExpression > OnExpression ;
470471 public override TypedExpression Transform ( TypedExpression ex )
471472 {
472473 this . OnExpression ? . Invoke ( ex ) ;
473- return this . recur ? base . Transform ( ex ) : ex ;
474+ return base . Transform ( ex ) ;
474475 }
475476 }
477+
478+
479+ public class __OnTypedExpression__ < T > :
480+ Core . ExpressionTransformation < T >
481+ {
482+ public __OnTypedExpression__ ( QsSyntaxTreeTransformation < T > parent , Func < TypedExpression , TypedExpression > onExpression )
483+ : base ( parent ) =>
484+ this . OnExpression = onExpression ?? throw new ArgumentNullException ( nameof ( onExpression ) ) ;
485+
486+ public Func < TypedExpression , TypedExpression > OnExpression ;
487+ public override TypedExpression Transform ( TypedExpression ex ) =>
488+ this . OnExpression ( ex ) ;
489+ }
476490}
0 commit comments