@@ -869,7 +869,9 @@ module DataFlowMake<LocationSig Location, InputSig<Location> Lang> {
869
869
870
870
private signature predicate collapseCandidateSig ( Node node , string toString ) ;
871
871
872
- private signature predicate stepSig ( InputPathNode node1 , InputPathNode node2 ) ;
872
+ private signature predicate stepSig (
873
+ InputPathNode node1 , InputPathNode node2 , string key , string val
874
+ ) ;
873
875
874
876
private signature predicate subpathStepSig (
875
877
InputPathNode arg , InputPathNode param , InputPathNode ret , InputPathNode out
@@ -887,22 +889,28 @@ module DataFlowMake<LocationSig Location, InputSig<Location> Lang> {
887
889
* used to perform the opposite direction.
888
890
*/
889
891
private module MakeDiscriminatorPass<
890
- collapseCandidateSig / 2 collapseCandidate, stepSig / 2 step, subpathStepSig / 4 subpathStep>
892
+ collapseCandidateSig / 2 collapseCandidate, stepSig / 4 step, subpathStepSig / 4 subpathStep>
891
893
{
892
894
/**
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)`.
894
899
*/
895
900
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
+ )
897
905
}
898
906
899
907
/**
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)`.
901
909
*/
902
910
private int getOutDegreeFromNode ( Node node , string toString ) {
903
911
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 )
906
914
)
907
915
}
908
916
@@ -929,7 +937,7 @@ module DataFlowMake<LocationSig Location, InputSig<Location> Lang> {
929
937
930
938
/** Gets a successor of `node` including subpath flow-through. */
931
939
InputPathNode stepEx ( InputPathNode node ) {
932
- step ( node , result )
940
+ step ( node , result , _ , _ )
933
941
or
934
942
subpathStep ( node , _, _, result ) // assuming the input is pruned properly, all subpaths have flow-through
935
943
}
@@ -993,10 +1001,10 @@ module DataFlowMake<LocationSig Location, InputSig<Location> Lang> {
993
1001
}
994
1002
995
1003
private module Pass1 =
996
- MakeDiscriminatorPass< initialCandidate / 2 , Graph:: edges / 2 , Graph:: subpaths / 4 > ;
1004
+ MakeDiscriminatorPass< initialCandidate / 2 , Graph:: edges / 4 , Graph:: subpaths / 4 > ;
997
1005
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 )
1000
1008
}
1001
1009
1002
1010
private predicate subpathsRev (
@@ -1006,7 +1014,7 @@ module DataFlowMake<LocationSig Location, InputSig<Location> Lang> {
1006
1014
}
1007
1015
1008
1016
private module Pass2 =
1009
- MakeDiscriminatorPass< Pass1:: discriminatedPair / 2 , edgesRev / 2 , subpathsRev / 4 > ;
1017
+ MakeDiscriminatorPass< Pass1:: discriminatedPair / 2 , edgesRev / 4 , subpathsRev / 4 > ;
1010
1018
1011
1019
private newtype TPathNode =
1012
1020
TPreservedPathNode ( InputPathNode node ) { Pass2:: discriminatedPathNode ( node ) } or
@@ -1036,19 +1044,8 @@ module DataFlowMake<LocationSig Location, InputSig<Location> Lang> {
1036
1044
result = this .asPreservedNode ( ) .toString ( ) or this = TCollapsedPathNode ( _, result )
1037
1045
}
1038
1046
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 ( ) }
1052
1049
1053
1050
/** Gets the corresponding data-flow node. */
1054
1051
Node getNode ( ) {
@@ -1066,8 +1063,8 @@ module DataFlowMake<LocationSig Location, InputSig<Location> Lang> {
1066
1063
Graph:: nodes ( node .getAnOriginalPathNode ( ) , key , val )
1067
1064
}
1068
1065
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 )
1071
1068
}
1072
1069
1073
1070
query predicate subpaths ( PathNode arg , PathNode par , PathNode ret , PathNode out ) {
0 commit comments