@@ -652,3 +652,121 @@ private module LiteralSynth {
652
652
}
653
653
}
654
654
}
655
+
656
+ /**
657
+ * Synthesize variable accesses for pipeline iterators inside a process block.
658
+ */
659
+ private module IteratorAccessSynth {
660
+ private class PipelineOrPipelineByPropertyNameIteratorVariable extends VariableSynth {
661
+ PipelineOrPipelineByPropertyNameIteratorVariable ( ) {
662
+ this instanceof PipelineIteratorVariable
663
+ or
664
+ this instanceof PipelineByPropertyNameIteratorVariable
665
+ }
666
+
667
+ string getPropertyName ( ) {
668
+ result = this .( PipelineByPropertyNameIteratorVariable ) .getPropertyName ( )
669
+ }
670
+
671
+ predicate isPipelineIterator ( ) { this instanceof PipelineIteratorVariable }
672
+ }
673
+
674
+ bindingset [ pb, v]
675
+ private string getAPipelineIteratorName (
676
+ Raw:: ProcessBlock pb , PipelineOrPipelineByPropertyNameIteratorVariable v
677
+ ) {
678
+ v .isPipelineIterator ( ) and
679
+ (
680
+ result = "_"
681
+ or
682
+ // or
683
+ // result = "psitem" // TODO: This is also an automatic variable
684
+ result = pb .getScriptBlock ( ) .getParamBlock ( ) .getPipelineParameter ( ) .getName ( ) .toLowerCase ( )
685
+ )
686
+ or
687
+ // TODO: We could join on something other than the string if we wanted (i.e., the raw parameter).
688
+ v .getPropertyName ( ) .toLowerCase ( ) = result and
689
+ result =
690
+ pb .getScriptBlock ( )
691
+ .getParamBlock ( )
692
+ .getAPipelineByPropertyNameParameter ( )
693
+ .getName ( )
694
+ .toLowerCase ( )
695
+ }
696
+
697
+ private class IteratorAccessSynth extends Synthesis {
698
+ private predicate expr ( Raw:: Ast rawParent , ChildIndex i , Raw:: VarAccess va , Child child ) {
699
+ rawParent .getChild ( toRawChildIndex ( i ) ) = va and
700
+ child = SynthChild ( VarAccessSynthKind ( this .varAccess ( va ) ) )
701
+ }
702
+
703
+ private predicate stmt ( Raw:: Ast rawParent , ChildIndex i , Raw:: CmdExpr cmdExpr , Child child ) {
704
+ rawParent .getChild ( toRawChildIndex ( i ) ) = cmdExpr and
705
+ not mustHaveExprChild ( rawParent , cmdExpr ) and
706
+ child = SynthChild ( ExprStmtKind ( ) )
707
+ }
708
+
709
+ private PipelineOrPipelineByPropertyNameIteratorVariable varAccess ( Raw:: VarAccess va ) {
710
+ exists ( Raw:: ProcessBlock pb |
711
+ pb = va .getParent + ( ) and
712
+ result = TVariableSynth ( pb , _) and
713
+ va .getUserPath ( ) .toLowerCase ( ) = getAPipelineIteratorName ( pb , result )
714
+ )
715
+ }
716
+
717
+ override predicate child ( Raw:: Ast parent , ChildIndex i , Child child ) {
718
+ this .expr ( parent , i , _, child )
719
+ or
720
+ this .stmt ( parent , i , _, child )
721
+ or
722
+ exists ( Raw:: ProcessBlock pb | parent = pb |
723
+ i = PipelineIteratorVar ( ) and
724
+ child = SynthChild ( VarSynthKind ( PipelineIteratorKind ( ) ) )
725
+ or
726
+ exists ( Raw:: Parameter p |
727
+ p = pb .getScriptBlock ( ) .getParamBlock ( ) .getAPipelineByPropertyNameParameter ( ) and
728
+ child = SynthChild ( VarSynthKind ( PipelineByPropertyNameIteratorKind ( p .getName ( ) ) ) ) and
729
+ i = PipelineByPropertyNameIteratorVar ( p )
730
+ )
731
+ )
732
+ }
733
+
734
+ override predicate exprStmtExpr ( ExprStmt e , Expr expr ) {
735
+ exists ( Raw:: Ast p , Raw:: VarAccess va , Raw:: CmdExpr cmdExpr , ChildIndex i1 , ChildIndex i2 |
736
+ this .stmt ( p , i1 , _, _) and
737
+ this .expr ( cmdExpr , i2 , va , _) and
738
+ e = TExprStmtSynth ( p , i1 ) and
739
+ expr = TVarAccessSynth ( cmdExpr , i2 , this .varAccess ( va ) )
740
+ )
741
+ }
742
+
743
+ final override Expr getResultAstImpl ( Raw:: Ast r ) {
744
+ exists ( Raw:: Ast parent , ChildIndex i | this .expr ( parent , i , r , _) |
745
+ result = TVarAccessSynth ( parent , i , this .varAccess ( r ) )
746
+ )
747
+ }
748
+
749
+ override predicate variableSynthName ( VariableSynth v , string name ) {
750
+ v = TVariableSynth ( _, PipelineIteratorVar ( ) ) and
751
+ name = "__pipeline_iterator"
752
+ or
753
+ exists ( Raw:: PipelineByPropertyNameParameter p |
754
+ v = TVariableSynth ( _, PipelineByPropertyNameIteratorVar ( p ) ) and
755
+ name = "__pipeline_iterator for " + p .getName ( )
756
+ )
757
+ }
758
+
759
+ final override Location getLocation ( Ast n ) {
760
+ exists ( Raw:: Ast parent , ChildIndex i , Raw:: CmdExpr cmdExpr |
761
+ this .stmt ( parent , i , cmdExpr , _) and
762
+ n = TExprStmtSynth ( parent , i ) and
763
+ result = cmdExpr .getLocation ( )
764
+ )
765
+ or
766
+ exists ( Raw:: Ast parent |
767
+ n = TVariableSynth ( parent , _) and
768
+ result = parent .getLocation ( )
769
+ )
770
+ }
771
+ }
772
+ }
0 commit comments