@@ -1342,11 +1342,15 @@ class LibraryCodeNode extends Node, TLibraryCodeNode {
1342
1342
Node getPredecessor ( AccessPath ap ) {
1343
1343
ap = sourceAp and
1344
1344
(
1345
+ // The source is either an argument or a qualifier, for example
1346
+ // `s` in `int.Parse(s)`
1345
1347
exists ( LibraryFlow:: LibrarySourceConfiguration x , Call call |
1346
1348
callCfn = call .getAControlFlowNode ( ) and
1347
1349
x .hasExprPath ( source .getSource ( call ) , result .( ExprNode ) .getControlFlowNode ( ) , _, callCfn )
1348
1350
)
1349
1351
or
1352
+ // The source is the output of a supplied delegate argument, for
1353
+ // example the output of `Foo` in `new Lazy(Foo)`
1350
1354
exists ( DataFlowCall call , int pos |
1351
1355
pos = source .( CallableFlowSourceDelegateArg ) .getArgumentIndex ( ) and
1352
1356
result .( ImplicitDelegateOutNode ) .isArgumentOf ( call , pos ) and
@@ -1366,15 +1370,19 @@ class LibraryCodeNode extends Node, TLibraryCodeNode {
1366
1370
callCfn = call .getAControlFlowNode ( ) and
1367
1371
x .hasExprPath ( _, callCfn , sink .getSink ( call ) , e .getControlFlowNode ( ) )
1368
1372
|
1373
+ // The sink is an ordinary return value, for example `int.Parse(s)`
1369
1374
sink instanceof CallableFlowSinkReturn and
1370
1375
result = e
1371
1376
or
1377
+ // The sink is a qualifier, for example `list` in `list.Add(x)`
1372
1378
sink instanceof CallableFlowSinkQualifier and
1373
1379
if sinkAp = AccessPath:: empty ( )
1374
1380
then result = e
1375
1381
else result .( ExprPostUpdateNode ) .getPreUpdateNode ( ) = e
1376
1382
)
1377
1383
or
1384
+ // The sink is an `out`/`ref` argument, for example `out i` in
1385
+ // `int.TryParse(s, out i)`
1378
1386
exists ( LibraryFlow:: LibrarySinkConfiguration x , OutRefReturnKind k |
1379
1387
result =
1380
1388
any ( ParamOutNode out |
@@ -1384,13 +1392,22 @@ class LibraryCodeNode extends Node, TLibraryCodeNode {
1384
1392
)
1385
1393
)
1386
1394
or
1387
- exists ( DataFlowCall call , ImplicitDelegateDataFlowCall dcall , int i , int j |
1395
+ // The sink is a parameter of a supplied delegate argument, for example
1396
+ // the parameter of `Foo` in `list.Select(Foo)`.
1397
+ //
1398
+ // This is implemented using a node that represents the implicit argument
1399
+ // (`ImplicitDelegateArgumentNode`) of the implicit call
1400
+ // (`ImplicitDelegateDataFlowCall`) to `Foo`.
1401
+ exists (
1402
+ DataFlowCall call , ImplicitDelegateDataFlowCall dcall , int delegateIndex , int parameterIndex
1403
+ |
1388
1404
sink =
1389
1405
any ( CallableFlowSinkDelegateArg s |
1390
- i = s .getDelegateIndex ( ) and j = s .getDelegateParameterIndex ( )
1406
+ delegateIndex = s .getDelegateIndex ( ) and
1407
+ parameterIndex = s .getDelegateParameterIndex ( )
1391
1408
) and
1392
- result = TImplicitDelegateArgumentNode ( dcall .getControlFlowNode ( ) , _, j ) and
1393
- dcall .isArgumentOf ( call , i ) and
1409
+ result = TImplicitDelegateArgumentNode ( dcall .getControlFlowNode ( ) , _, parameterIndex ) and
1410
+ dcall .isArgumentOf ( call , delegateIndex ) and
1394
1411
callCfn = call .getControlFlowNode ( )
1395
1412
)
1396
1413
)
0 commit comments