@@ -869,7 +869,9 @@ module DataFlowMake<LocationSig Location, InputSig<Location> Lang> {
869869
870870 private signature predicate collapseCandidateSig ( Node node , string toString ) ;
871871
872- private signature predicate stepSig ( InputPathNode node1 , InputPathNode node2 ) ;
872+ private signature predicate stepSig (
873+ InputPathNode node1 , InputPathNode node2 , string key , string val
874+ ) ;
873875
874876 private signature predicate subpathStepSig (
875877 InputPathNode arg , InputPathNode param , InputPathNode ret , InputPathNode out
@@ -887,22 +889,28 @@ module DataFlowMake<LocationSig Location, InputSig<Location> Lang> {
887889 * used to perform the opposite direction.
888890 */
889891 private module MakeDiscriminatorPass<
890- collapseCandidateSig / 2 collapseCandidate, stepSig / 2 step, subpathStepSig / 4 subpathStep>
892+ collapseCandidateSig / 2 collapseCandidate, stepSig / 4 step, subpathStepSig / 4 subpathStep>
891893 {
892894 /**
893- * Gets the number of `(node, toString)` pairs reachable in one step from `pathNode`.
895+ * Gets the number of `(key, val, node, toString)` tuples reachable in one step from `pathNode`.
896+ *
897+ * That is, two edges are counted as one if their target nodes are the same after projection, and the edges have the
898+ * same `(key, val)`.
894899 */
895900 private int getOutDegreeFromPathNode ( InputPathNode pathNode ) {
896- result = count ( Node node , string toString | step ( pathNode , getAPathNode ( node , toString ) ) )
901+ result =
902+ count ( Node node , string toString , string key , string val |
903+ step ( pathNode , getAPathNode ( node , toString ) , key , val )
904+ )
897905 }
898906
899907 /**
900- * Gets the number of `(node2, toString2)` pairs reachable in one step from path nodes corresponding to `(node, toString)`.
908+ * Gets the number of `(key, val, node2, toString2)` pairs reachable in one step from path nodes corresponding to `(node, toString)`.
901909 */
902910 private int getOutDegreeFromNode ( Node node , string toString ) {
903911 result =
904- strictcount ( Node node2 , string toString2 |
905- step ( getAPathNode ( node , toString ) , getAPathNode ( node2 , toString2 ) )
912+ strictcount ( Node node2 , string toString2 , string key , string val |
913+ step ( getAPathNode ( node , toString ) , getAPathNode ( node2 , toString2 ) , key , val )
906914 )
907915 }
908916
@@ -929,7 +937,7 @@ module DataFlowMake<LocationSig Location, InputSig<Location> Lang> {
929937
930938 /** Gets a successor of `node` including subpath flow-through. */
931939 InputPathNode stepEx ( InputPathNode node ) {
932- step ( node , result )
940+ step ( node , result , _ , _ )
933941 or
934942 subpathStep ( node , _, _, result ) // assuming the input is pruned properly, all subpaths have flow-through
935943 }
@@ -993,10 +1001,10 @@ module DataFlowMake<LocationSig Location, InputSig<Location> Lang> {
9931001 }
9941002
9951003 private module Pass1 =
996- MakeDiscriminatorPass< initialCandidate / 2 , Graph:: edges / 2 , Graph:: subpaths / 4 > ;
1004+ MakeDiscriminatorPass< initialCandidate / 2 , Graph:: edges / 4 , Graph:: subpaths / 4 > ;
9971005
998- private predicate edgesRev ( InputPathNode node1 , InputPathNode node2 ) {
999- Graph:: edges ( node2 , node1 )
1006+ private predicate edgesRev ( InputPathNode node1 , InputPathNode node2 , string key , string val ) {
1007+ Graph:: edges ( node2 , node1 , key , val )
10001008 }
10011009
10021010 private predicate subpathsRev (
@@ -1006,7 +1014,7 @@ module DataFlowMake<LocationSig Location, InputSig<Location> Lang> {
10061014 }
10071015
10081016 private module Pass2 =
1009- MakeDiscriminatorPass< Pass1:: discriminatedPair / 2 , edgesRev / 2 , subpathsRev / 4 > ;
1017+ MakeDiscriminatorPass< Pass1:: discriminatedPair / 2 , edgesRev / 4 , subpathsRev / 4 > ;
10101018
10111019 private newtype TPathNode =
10121020 TPreservedPathNode ( InputPathNode node ) { Pass2:: discriminatedPathNode ( node ) } or
@@ -1036,19 +1044,8 @@ module DataFlowMake<LocationSig Location, InputSig<Location> Lang> {
10361044 result = this .asPreservedNode ( ) .toString ( ) or this = TCollapsedPathNode ( _, result )
10371045 }
10381046
1039- /**
1040- * Holds if this element is at the specified location.
1041- * The location spans column `startcolumn` of line `startline` to
1042- * column `endcolumn` of line `endline` in file `filepath`.
1043- * For more information, see
1044- * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
1045- */
1046- predicate hasLocationInfo (
1047- string filepath , int startline , int startcolumn , int endline , int endcolumn
1048- ) {
1049- this .getAnOriginalPathNode ( )
1050- .hasLocationInfo ( filepath , startline , startcolumn , endline , endcolumn )
1051- }
1047+ /** Gets the location of this node. */
1048+ Location getLocation ( ) { result = this .getAnOriginalPathNode ( ) .getLocation ( ) }
10521049
10531050 /** Gets the corresponding data-flow node. */
10541051 Node getNode ( ) {
@@ -1066,8 +1063,8 @@ module DataFlowMake<LocationSig Location, InputSig<Location> Lang> {
10661063 Graph:: nodes ( node .getAnOriginalPathNode ( ) , key , val )
10671064 }
10681065
1069- query predicate edges ( PathNode node1 , PathNode node2 ) {
1070- Graph:: edges ( node1 .getAnOriginalPathNode ( ) , node2 .getAnOriginalPathNode ( ) )
1066+ query predicate edges ( PathNode node1 , PathNode node2 , string key , string val ) {
1067+ Graph:: edges ( node1 .getAnOriginalPathNode ( ) , node2 .getAnOriginalPathNode ( ) , key , val )
10711068 }
10721069
10731070 query predicate subpaths ( PathNode arg , PathNode par , PathNode ret , PathNode out ) {
0 commit comments