@@ -320,6 +320,9 @@ newtype TDataFlowCallable =
320
320
// same to keep things easy to reason about (and therefore exclude things that do
321
321
// not have a definition)
322
322
exists ( func .getDefinition ( ) )
323
+ or
324
+ // ...scratch that, variable capture requires a callable
325
+ exists ( Comp c | c .getFunction ( ) = func )
323
326
} or
324
327
/** see QLDoc for `DataFlowModuleScope` for why we need this. */
325
328
TModule ( Module m ) or
@@ -1382,6 +1385,7 @@ private predicate sameEnclosingCallable(Node node1, Node node2) {
1382
1385
// =============================================================================
1383
1386
newtype TDataFlowCall =
1384
1387
TNormalCall ( CallNode call , Function target , CallType type ) { resolveCall ( call , target , type ) } or
1388
+ TComprehensionCall ( Comp c ) or
1385
1389
TPotentialLibraryCall ( CallNode call ) or
1386
1390
/** A synthesized call inside a summarized callable */
1387
1391
TSummaryCall (
@@ -1468,6 +1472,30 @@ class NormalCall extends ExtractedDataFlowCall, TNormalCall {
1468
1472
CallType getCallType ( ) { result = type }
1469
1473
}
1470
1474
1475
+ class ComprehensionCall extends ExtractedDataFlowCall , TComprehensionCall {
1476
+ Comp c ;
1477
+ Function target ;
1478
+
1479
+ ComprehensionCall ( ) {
1480
+ this = TComprehensionCall ( c ) and
1481
+ target = c .getFunction ( )
1482
+ }
1483
+
1484
+ Comp getComprehension ( ) { result = c }
1485
+
1486
+ override string toString ( ) { result = "comprehension call" }
1487
+
1488
+ override ControlFlowNode getNode ( ) { result .getNode ( ) = c }
1489
+
1490
+ override Scope getScope ( ) { result = c .getScope ( ) }
1491
+
1492
+ override DataFlowCallable getCallable ( ) { result .( DataFlowFunction ) .getScope ( ) = target }
1493
+
1494
+ override ArgumentNode getArgument ( ArgumentPosition apos ) { none ( ) }
1495
+
1496
+ override Location getLocation ( ) { result = c .getLocation ( ) }
1497
+ }
1498
+
1471
1499
/**
1472
1500
* A potential call to a summarized callable, a `LibraryCallable`.
1473
1501
*
@@ -1698,6 +1726,24 @@ class CapturedVariablesArgumentNode extends CfgNode, ArgumentNode {
1698
1726
}
1699
1727
}
1700
1728
1729
+ class ComprehensionCapturedVariablesArgumentNode extends CfgNode , ArgumentNode {
1730
+ Comp comp ;
1731
+
1732
+ ComprehensionCapturedVariablesArgumentNode ( ) {
1733
+ node .getNode ( ) = comp and
1734
+ exists ( Function target | target = comp .getFunction ( ) |
1735
+ target = any ( VariableCapture:: CapturedVariable v ) .getACapturingScope ( )
1736
+ )
1737
+ }
1738
+
1739
+ override string toString ( ) { result = "Capturing closure argument (comp)" }
1740
+
1741
+ override predicate argumentOf ( DataFlowCall call , ArgumentPosition pos ) {
1742
+ call .( ComprehensionCall ) .getComprehension ( ) = comp and
1743
+ pos .isLambdaSelf ( )
1744
+ }
1745
+ }
1746
+
1701
1747
/** Gets a viable run-time target for the call `call`. */
1702
1748
DataFlowCallable viableCallable ( DataFlowCall call ) {
1703
1749
call instanceof ExtractedDataFlowCall and
0 commit comments