@@ -359,6 +359,11 @@ module API {
359359 Location getLocation ( ) {
360360 result = this .getInducingNode ( ) .getLocation ( )
361361 or
362+ exists ( DataFlow:: ModuleNode mod |
363+ this = Impl:: MkModuleObject ( mod ) and
364+ result = mod .getLocation ( )
365+ )
366+ or
362367 // For nodes that do not have a meaningful location, `path` is the empty string and all other
363368 // parameters are zero.
364369 not exists ( this .getInducingNode ( ) ) and
@@ -601,7 +606,9 @@ module API {
601606 /** A use of an API member at the node `nd`. */
602607 MkUse ( DataFlow:: Node nd ) { isUse ( nd ) } or
603608 /** 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 )
605612
606613 private string resolveTopLevel ( ConstantReadAccess read ) {
607614 result = read .getModule ( ) .getQualifiedName ( ) and
@@ -684,7 +691,14 @@ module API {
684691 * Holds if `ref` is a use of node `nd`.
685692 */
686693 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+ }
688702
689703 /**
690704 * Holds if `rhs` is a RHS of node `nd`.
@@ -802,6 +816,14 @@ module API {
802816 trackUseNode ( use ) .flowsTo ( call .getReceiver ( ) )
803817 }
804818
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+
805827 /**
806828 * Holds if there is an edge from `pred` to `succ` in the API graph that is labeled with `lbl`.
807829 */
@@ -813,38 +835,35 @@ module API {
813835 useRoot ( lbl , ref )
814836 or
815837 exists ( DataFlow:: Node node , DataFlow:: Node src |
816- pred = MkUse ( src ) and
838+ use ( pred , src ) and
817839 trackUseNode ( src ) .flowsTo ( node ) and
818840 useStep ( lbl , node , ref )
819841 )
820842 or
821843 exists ( DataFlow:: Node callback |
822- pred = MkDef ( callback ) and
844+ def ( pred , callback ) and
823845 parameterStep ( lbl , trackDefNode ( callback ) , ref )
824846 )
825847 )
826848 or
827849 exists ( DataFlow:: Node predNode , DataFlow:: Node succNode |
828850 def ( pred , predNode ) and
829- def ( succ , succNode ) and
851+ succ = MkDef ( succNode ) and
830852 defStep ( lbl , trackDefNode ( predNode ) , succNode )
831853 )
832854 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
841860 lbl = Label:: subclass ( )
842861 )
843862 or
844863 exists ( DataFlow:: CallNode call |
845864 // from receiver to method call node
846865 exists ( DataFlow:: Node receiver |
847- pred = MkUse ( receiver ) and
866+ use ( pred , receiver ) and
848867 useNodeReachesReceiver ( receiver , call ) and
849868 lbl = Label:: method ( call .getMethodName ( ) ) and
850869 succ = MkMethodAccessNode ( call )
0 commit comments