@@ -76,17 +76,16 @@ module SsaFlow {
7676 or
7777 result .( Impl:: ExprNode ) .getExpr ( ) = n .asStmt ( )
7878 or
79- result .( Impl:: ExprNode ) .getExpr ( ) = n .( ProcessNode ) .getProcessBlock ( )
79+ result .( Impl:: ExprNode ) .getExpr ( ) =
80+ [ n .( ProcessNode ) .getProcessBlock ( ) , n .( ProcessPropertyByNameNode ) .getProcessBlock ( ) ]
8081 or
8182 result .( Impl:: ExprPostUpdateNode ) .getExpr ( ) = n .( PostUpdateNode ) .getPreUpdateNode ( ) .asExpr ( )
8283 or
8384 n = toParameterNode ( result .( Impl:: ParameterNode ) .getParameter ( ) )
8485 }
8586
8687 predicate localFlowStep ( SsaImpl:: DefinitionExt def , Node nodeFrom , Node nodeTo , boolean isUseStep ) {
87- Impl:: localFlowStep ( def , asNode ( nodeFrom ) , asNode ( nodeTo ) , isUseStep ) and
88- // Flow out of property name parameter nodes are covered by `readStep`.
89- not nodeFrom instanceof PipelineByPropertyNameParameter
88+ Impl:: localFlowStep ( def , asNode ( nodeFrom ) , asNode ( nodeTo ) , isUseStep )
9089 }
9190
9291 predicate localMustFlowStep ( SsaImpl:: DefinitionExt def , Node nodeFrom , Node nodeTo ) {
@@ -146,6 +145,12 @@ module VariableCapture {
146145 // TODO
147146}
148147
148+ private predicate isProcessPropertyByNameNode (
149+ PipelineByPropertyNameIteratorVariable iter , ProcessBlock pb
150+ ) {
151+ pb .getEnclosingScope ( ) = iter .getDeclaringScope ( )
152+ }
153+
149154/** A collection of cached types and predicates to be evaluated in the same stage. */
150155cached
151156private module Cached {
@@ -172,7 +177,10 @@ private module Cached {
172177 TPreReturnNodeImpl ( CfgNodes:: AstCfgNode n , Boolean isArray ) { isMultiReturned ( n ) } or
173178 TImplicitWrapNode ( CfgNodes:: AstCfgNode n , Boolean shouldWrap ) { isMultiReturned ( n ) } or
174179 TReturnNodeImpl ( CfgScope scope ) or
175- TProcessNode ( ProcessBlock process )
180+ TProcessNode ( ProcessBlock process ) or
181+ TProcessPropertyByNameNode ( PipelineByPropertyNameIteratorVariable iter ) {
182+ isProcessPropertyByNameNode ( iter , _)
183+ }
176184
177185 cached
178186 Location getLocation ( NodeImpl n ) { result = n .getLocationImpl ( ) }
@@ -501,8 +509,8 @@ private module ParameterNodes {
501509 override string toStringImpl ( ) { result = parameter .toString ( ) }
502510 }
503511
504- class PipelineByPropertyNameParameter extends NormalParameterNode {
505- PipelineByPropertyNameParameter ( ) { this .getParameter ( ) .isPipelineByPropertyName ( ) }
512+ class PipelineByPropertyNameParameterNode extends NormalParameterNode {
513+ PipelineByPropertyNameParameterNode ( ) { this .getParameter ( ) .isPipelineByPropertyName ( ) }
506514
507515 string getPropretyName ( ) { result = this .getParameter ( ) .getName ( ) }
508516 }
@@ -753,15 +761,30 @@ predicate readStep(Node node1, ContentSet c, Node node2) {
753761 )
754762 or
755763 c .isAnyElement ( ) and
756- exists ( SsaImpl:: DefinitionExt def |
757- node1 .( ProcessNode ) .getIteratorVariable ( ) = def .getSourceVariable ( ) and
764+ exists ( SsaImpl:: DefinitionExt def , ProcessNode processNode , LocalScopeVariable iterator |
765+ processNode = node1 and iterator = def .getSourceVariable ( )
766+ |
767+ processNode .getIteratorVariable ( ) = iterator and
768+ SsaImpl:: firstRead ( def , node2 .asExpr ( ) )
769+ or
770+ processNode .getPropertyNameIteratorVariable ( ) = iterator and
771+ node2 = TProcessPropertyByNameNode ( def .getSourceVariable ( ) )
772+ )
773+ or
774+ exists (
775+ Content:: KnownElementContent ec , PipelineByPropertyNameParameter p , SsaImpl:: DefinitionExt def
776+ |
777+ c .isSingleton ( ec ) and
778+ p .getIteratorVariable ( ) = node1 .( ProcessPropertyByNameNode ) .getVariable ( ) and
779+ p .getName ( ) = ec .getIndex ( ) .asString ( ) and
780+ def .getSourceVariable ( ) = p .getIteratorVariable ( ) and
758781 SsaImpl:: firstRead ( def , node2 .asExpr ( ) )
759782 )
760783 or
761784 exists ( Content:: KnownElementContent ec , SsaImpl:: DefinitionExt def |
762785 c .isSingleton ( ec ) and
763- node1 .( PipelineByPropertyNameParameter ) .getPropretyName ( ) = ec .getIndex ( ) .asString ( ) and
764- def .getSourceVariable ( ) = node1 .( PipelineByPropertyNameParameter ) .getParameter ( ) and
786+ node1 .( PipelineByPropertyNameParameterNode ) .getPropretyName ( ) = ec .getIndex ( ) .asString ( ) and
787+ def .getSourceVariable ( ) = node1 .( PipelineByPropertyNameParameterNode ) .getParameter ( ) and
765788 SsaImpl:: firstRead ( def , node2 .asExpr ( ) )
766789 )
767790}
@@ -792,11 +815,6 @@ predicate expectsContent(Node n, ContentSet c) {
792815 or
793816 n instanceof ProcessNode and
794817 c .isAnyElement ( )
795- or
796- exists ( Content:: KnownElementContent ec |
797- ec .getIndex ( ) .asString ( ) = n .( PipelineByPropertyNameParameter ) .getPropretyName ( ) and
798- c .isSingleton ( ec )
799- )
800818}
801819
802820class DataFlowType extends TDataFlowType {
@@ -925,15 +943,39 @@ private class ProcessNode extends TProcessNode, NodeImpl {
925943
926944 override Location getLocationImpl ( ) { result = process .getLocation ( ) }
927945
928- override string toStringImpl ( ) { result = process .toString ( ) }
946+ override string toStringImpl ( ) { result = "process node for " + process .toString ( ) }
929947
930948 override predicate nodeIsHidden ( ) { any ( ) }
931949
932950 PipelineIteratorVariable getIteratorVariable ( ) { result .getProcessBlock ( ) = process }
933951
952+ PipelineByPropertyNameIteratorVariable getPropertyNameIteratorVariable ( ) {
953+ result .getProcessBlock ( ) = process
954+ }
955+
934956 CfgNodes:: ProcessBlockCfgNode getProcessBlock ( ) { result .getAstNode ( ) = process }
935957}
936958
959+ private class ProcessPropertyByNameNode extends TProcessPropertyByNameNode , NodeImpl {
960+ private PipelineByPropertyNameIteratorVariable iter ;
961+
962+ ProcessPropertyByNameNode ( ) { this = TProcessPropertyByNameNode ( iter ) }
963+
964+ PipelineByPropertyNameIteratorVariable getVariable ( ) { result = iter }
965+
966+ override CfgScope getCfgScope ( ) { result = iter .getDeclaringScope ( ) }
967+
968+ override Location getLocationImpl ( ) { result = iter .getLocation ( ) }
969+
970+ override string toStringImpl ( ) { result = "process node for " + iter .toString ( ) }
971+
972+ override predicate nodeIsHidden ( ) { any ( ) }
973+
974+ CfgNodes:: ProcessBlockCfgNode getProcessBlock ( ) {
975+ isProcessPropertyByNameNode ( iter , result .getAstNode ( ) )
976+ }
977+ }
978+
937979/** A node that performs a type cast. */
938980class CastNode extends Node {
939981 CastNode ( ) { none ( ) }
0 commit comments