@@ -359,6 +359,11 @@ module API {
359
359
Location getLocation ( ) {
360
360
result = this .getInducingNode ( ) .getLocation ( )
361
361
or
362
+ exists ( DataFlow:: ModuleNode mod |
363
+ this = Impl:: MkModuleObject ( mod ) and
364
+ result = mod .getLocation ( )
365
+ )
366
+ or
362
367
// For nodes that do not have a meaningful location, `path` is the empty string and all other
363
368
// parameters are zero.
364
369
not exists ( this .getInducingNode ( ) ) and
@@ -601,7 +606,9 @@ module API {
601
606
/** A use of an API member at the node `nd`. */
602
607
MkUse ( DataFlow:: Node nd ) { isUse ( nd ) } or
603
608
/** A value that escapes into an external library at the node `nd` */
604
- MkDef ( DataFlow:: Node nd ) { isDef ( nd ) }
609
+ MkDef ( DataFlow:: Node nd ) { isDef ( nd ) } or
610
+ /** A module object seen as a use node. */
611
+ MkModuleObject ( DataFlow:: ModuleNode mod )
605
612
606
613
private string resolveTopLevel ( ConstantReadAccess read ) {
607
614
result = read .getModule ( ) .getQualifiedName ( ) and
@@ -684,7 +691,14 @@ module API {
684
691
* Holds if `ref` is a use of node `nd`.
685
692
*/
686
693
cached
687
- predicate use ( TApiNode nd , DataFlow:: Node ref ) { nd = MkUse ( ref ) }
694
+ predicate use ( TApiNode nd , DataFlow:: Node ref ) {
695
+ nd = MkUse ( ref )
696
+ or
697
+ exists ( DataFlow:: ModuleNode mod |
698
+ nd = MkModuleObject ( mod ) and
699
+ ref = mod .getAnImmediateReference ( )
700
+ )
701
+ }
688
702
689
703
/**
690
704
* Holds if `rhs` is a RHS of node `nd`.
@@ -802,6 +816,14 @@ module API {
802
816
trackUseNode ( use ) .flowsTo ( call .getReceiver ( ) )
803
817
}
804
818
819
+ /**
820
+ * Holds if `superclass` is the superclass of `mod`.
821
+ */
822
+ pragma [ nomagic]
823
+ private predicate superclassNode ( DataFlow:: ModuleNode mod , DataFlow:: Node superclass ) {
824
+ superclass .asExpr ( ) .getExpr ( ) = mod .getADeclaration ( ) .( ClassDeclaration ) .getSuperclassExpr ( )
825
+ }
826
+
805
827
/**
806
828
* Holds if there is an edge from `pred` to `succ` in the API graph that is labeled with `lbl`.
807
829
*/
@@ -813,38 +835,35 @@ module API {
813
835
useRoot ( lbl , ref )
814
836
or
815
837
exists ( DataFlow:: Node node , DataFlow:: Node src |
816
- pred = MkUse ( src ) and
838
+ use ( pred , src ) and
817
839
trackUseNode ( src ) .flowsTo ( node ) and
818
840
useStep ( lbl , node , ref )
819
841
)
820
842
or
821
843
exists ( DataFlow:: Node callback |
822
- pred = MkDef ( callback ) and
844
+ def ( pred , callback ) and
823
845
parameterStep ( lbl , trackDefNode ( callback ) , ref )
824
846
)
825
847
)
826
848
or
827
849
exists ( DataFlow:: Node predNode , DataFlow:: Node succNode |
828
850
def ( pred , predNode ) and
829
- def ( succ , succNode ) and
851
+ succ = MkDef ( succNode ) and
830
852
defStep ( lbl , trackDefNode ( predNode ) , succNode )
831
853
)
832
854
or
833
- // `pred` is a use of class A
834
- // `succ` is a use of class B
835
- // there exists a class declaration B < A
836
- exists ( ClassDeclaration c , DataFlow:: Node a , DataFlow:: Node b |
837
- use ( pred , a ) and
838
- use ( succ , b ) and
839
- b .asExpr ( ) .getExpr ( ) .( ConstantReadAccess ) .getAQualifiedName ( ) = c .getAQualifiedName ( ) and
840
- pragma [ only_bind_into ] ( c ) .getSuperclassExpr ( ) = a .asExpr ( ) .getExpr ( ) and
855
+ exists ( DataFlow:: Node predNode , DataFlow:: Node superclassNode , DataFlow:: ModuleNode mod |
856
+ use ( pred , predNode ) and
857
+ trackUseNode ( predNode ) .flowsTo ( superclassNode ) and
858
+ superclassNode ( mod , superclassNode ) and
859
+ succ = MkModuleObject ( mod ) and
841
860
lbl = Label:: subclass ( )
842
861
)
843
862
or
844
863
exists ( DataFlow:: CallNode call |
845
864
// from receiver to method call node
846
865
exists ( DataFlow:: Node receiver |
847
- pred = MkUse ( receiver ) and
866
+ use ( pred , receiver ) and
848
867
useNodeReachesReceiver ( receiver , call ) and
849
868
lbl = Label:: method ( call .getMethodName ( ) ) and
850
869
succ = MkMethodAccessNode ( call )
0 commit comments