@@ -188,7 +188,7 @@ module API {
188188 /** A node corresponding to the use of an API component. */
189189 class Use extends Node , Impl:: MkUse {
190190 override string toString ( ) {
191- exists ( string type | this = Impl :: MkUse ( _ ) and type = "Use " |
191+ exists ( string type | type = "Use " |
192192 result = type + getPath ( )
193193 or
194194 not exists ( this .getPath ( ) ) and result = type + "with no path"
@@ -239,20 +239,19 @@ module API {
239239 /** The root of the API graph. */
240240 MkRoot ( ) or
241241 /** A use of an API member at the node `nd`. */
242- MkUse ( DataFlow:: Node nd ) { use ( _ , _ , nd ) }
242+ MkUse ( DataFlow:: Node nd ) { isUse ( nd ) }
243243
244244 private string resolveTopLevel ( ConstantReadAccess read ) {
245245 TResolved ( result ) = resolveScopeExpr ( read ) and
246246 not result .matches ( "%::%" )
247247 }
248248
249249 /**
250- * Holds if `ref` is a use of a node that should have an incoming edge from `base` labeled
251- * `lbl` in the API graph.
250+ * Holds if `ref` is a use of a node that should have an incoming edge from the root
251+ * node labeled `lbl` in the API graph.
252252 */
253253 cached
254- predicate use ( TApiNode base , string lbl , DataFlow:: Node ref ) {
255- base = MkRoot ( ) and
254+ predicate useRoot ( string lbl , DataFlow:: Node ref ) {
256255 exists ( string name , ExprNodes:: ConstantAccessCfgNode access , ConstantReadAccess read |
257256 access = ref .asExpr ( ) and
258257 lbl = Label:: member ( read .getName ( ) ) and
@@ -264,7 +263,14 @@ module API {
264263 not exists ( resolveTopLevel ( read ) ) and
265264 not exists ( read .getScopeExpr ( ) )
266265 )
267- or
266+ }
267+
268+ /**
269+ * Holds if `ref` is a use of a node that should have an incoming edge from use node
270+ * `base` labeled `lbl` in the API graph.
271+ */
272+ cached
273+ predicate useUse ( DataFlow:: LocalSourceNode base , string lbl , DataFlow:: Node ref ) {
268274 exists ( ExprCfgNode node |
269275 // First, we find a predecessor of the node `ref` that we want to determine. The predecessor
270276 // is any node that is a type-tracked use of a data flow node (`src`), which is itself a
@@ -307,9 +313,15 @@ module API {
307313 }
308314
309315 pragma [ nomagic]
310- private predicate useExpr ( ExprCfgNode node , TApiNode base ) {
311- exists ( DataFlow:: LocalSourceNode src , DataFlow:: LocalSourceNode pred |
312- use ( base , src ) and
316+ private predicate isUse ( DataFlow:: Node nd ) {
317+ useRoot ( _, nd )
318+ or
319+ useUse ( _, _, nd )
320+ }
321+
322+ pragma [ nomagic]
323+ private predicate useExpr ( ExprCfgNode node , DataFlow:: LocalSourceNode src ) {
324+ exists ( DataFlow:: LocalSourceNode pred |
313325 pred = trackUseNode ( src ) and
314326 pred .flowsTo ( any ( DataFlow:: ExprNode n | n .getExprNode ( ) = node ) )
315327 )
@@ -331,7 +343,7 @@ module API {
331343 // recursive case, so instead we check it explicitly here.
332344 src instanceof DataFlow:: LocalSourceNode and
333345 t .start ( ) and
334- use ( _ , src ) and
346+ isUse ( src ) and
335347 result = src
336348 or
337349 exists ( TypeTracker t2 | result = trackUseNode ( src , t2 ) .track ( t2 , t ) )
@@ -353,9 +365,14 @@ module API {
353365 cached
354366 predicate edge ( TApiNode pred , string lbl , TApiNode succ ) {
355367 /* Every node that is a use of an API component is itself added to the API graph. */
356- exists ( DataFlow:: LocalSourceNode ref |
357- use ( pred , lbl , ref ) and
358- succ = MkUse ( ref )
368+ exists ( DataFlow:: LocalSourceNode ref | succ = MkUse ( ref ) |
369+ pred = MkRoot ( ) and
370+ useRoot ( lbl , ref )
371+ or
372+ exists ( DataFlow:: Node nd |
373+ pred = MkUse ( nd ) and
374+ useUse ( nd , lbl , ref )
375+ )
359376 )
360377 }
361378
0 commit comments