@@ -188,7 +188,7 @@ module API {
188
188
/** A node corresponding to the use of an API component. */
189
189
class Use extends Node , Impl:: MkUse {
190
190
override string toString ( ) {
191
- exists ( string type | this = Impl :: MkUse ( _ ) and type = "Use " |
191
+ exists ( string type | type = "Use " |
192
192
result = type + getPath ( )
193
193
or
194
194
not exists ( this .getPath ( ) ) and result = type + "with no path"
@@ -239,20 +239,19 @@ module API {
239
239
/** The root of the API graph. */
240
240
MkRoot ( ) or
241
241
/** A use of an API member at the node `nd`. */
242
- MkUse ( DataFlow:: Node nd ) { use ( _ , _ , nd ) }
242
+ MkUse ( DataFlow:: Node nd ) { isUse ( nd ) }
243
243
244
244
private string resolveTopLevel ( ConstantReadAccess read ) {
245
245
TResolved ( result ) = resolveScopeExpr ( read ) and
246
246
not result .matches ( "%::%" )
247
247
}
248
248
249
249
/**
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.
252
252
*/
253
253
cached
254
- predicate use ( TApiNode base , string lbl , DataFlow:: Node ref ) {
255
- base = MkRoot ( ) and
254
+ predicate useRoot ( string lbl , DataFlow:: Node ref ) {
256
255
exists ( string name , ExprNodes:: ConstantAccessCfgNode access , ConstantReadAccess read |
257
256
access = ref .asExpr ( ) and
258
257
lbl = Label:: member ( read .getName ( ) ) and
@@ -264,7 +263,14 @@ module API {
264
263
not exists ( resolveTopLevel ( read ) ) and
265
264
not exists ( read .getScopeExpr ( ) )
266
265
)
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 ) {
268
274
exists ( ExprCfgNode node |
269
275
// First, we find a predecessor of the node `ref` that we want to determine. The predecessor
270
276
// 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 {
307
313
}
308
314
309
315
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 |
313
325
pred = trackUseNode ( src ) and
314
326
pred .flowsTo ( any ( DataFlow:: ExprNode n | n .getExprNode ( ) = node ) )
315
327
)
@@ -331,7 +343,7 @@ module API {
331
343
// recursive case, so instead we check it explicitly here.
332
344
src instanceof DataFlow:: LocalSourceNode and
333
345
t .start ( ) and
334
- use ( _ , src ) and
346
+ isUse ( src ) and
335
347
result = src
336
348
or
337
349
exists ( TypeTracker t2 | result = trackUseNode ( src , t2 ) .track ( t2 , t ) )
@@ -353,9 +365,14 @@ module API {
353
365
cached
354
366
predicate edge ( TApiNode pred , string lbl , TApiNode succ ) {
355
367
/* 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
+ )
359
376
)
360
377
}
361
378
0 commit comments