@@ -27,6 +27,7 @@ module DataFlow {
27
27
private newtype TNode =
28
28
TValueNode ( AST:: ValueNode nd ) or
29
29
TSsaDefNode ( SsaDefinition d ) or
30
+ TCapturedVariableNode ( LocalVariable v ) { v .isCaptured ( ) } or
30
31
TPropNode ( @property p ) or
31
32
TRestPatternNode ( DestructuringPattern dp , Expr rest ) { rest = dp .getRest ( ) } or
32
33
TDestructuringPatternNode ( DestructuringPattern dp ) or
@@ -1221,6 +1222,29 @@ module DataFlow {
1221
1222
}
1222
1223
}
1223
1224
1225
+ /**
1226
+ * A data flow node representing a captured variable.
1227
+ */
1228
+ private class CapturedVariableNode extends Node , TCapturedVariableNode {
1229
+ LocalVariable variable ;
1230
+
1231
+ CapturedVariableNode ( ) { this = TCapturedVariableNode ( variable ) }
1232
+
1233
+ override BasicBlock getBasicBlock ( ) {
1234
+ result = variable .getDeclaringContainer ( ) .getStartBB ( )
1235
+ }
1236
+
1237
+ override predicate hasLocationInfo (
1238
+ string filepath , int startline , int startcolumn , int endline , int endcolumn
1239
+ ) {
1240
+ variable .getLocation ( ) .hasLocationInfo ( filepath , startline , startcolumn , endline , endcolumn )
1241
+ }
1242
+
1243
+ override string toString ( ) {
1244
+ result = variable .getName ( )
1245
+ }
1246
+ }
1247
+
1224
1248
/**
1225
1249
* Gets the data flow node corresponding to `nd`.
1226
1250
*
@@ -1434,19 +1458,23 @@ module DataFlow {
1434
1458
or
1435
1459
immediateFlowStep ( pred , succ )
1436
1460
or
1461
+ // From an assignment or implicit initialization of a captured variable to its flow-insensitive node.
1462
+ exists ( SsaDefinition predDef |
1463
+ pred = TSsaDefNode ( predDef ) and
1464
+ succ = TCapturedVariableNode ( predDef .getSourceVariable ( ) )
1465
+ |
1466
+ predDef instanceof SsaExplicitDefinition or
1467
+ predDef instanceof SsaImplicitInit
1468
+ )
1469
+ or
1470
+ // From a captured variable node to its flow-sensitive capture nodes
1471
+ exists ( SsaVariableCapture ssaCapture |
1472
+ pred = TCapturedVariableNode ( ssaCapture .getSourceVariable ( ) ) and
1473
+ succ = TSsaDefNode ( ssaCapture )
1474
+ )
1475
+ or
1437
1476
// Flow through implicit SSA nodes
1438
1477
exists ( SsaImplicitDefinition ssa | succ = TSsaDefNode ( ssa ) |
1439
- // from any explicit definition or implicit init of a captured variable into
1440
- // the capturing definition
1441
- exists ( SsaSourceVariable v , SsaDefinition predDef |
1442
- v = ssa .( SsaVariableCapture ) .getSourceVariable ( ) and
1443
- predDef .getSourceVariable ( ) = v and
1444
- pred = TSsaDefNode ( predDef )
1445
- |
1446
- predDef instanceof SsaExplicitDefinition or
1447
- predDef instanceof SsaImplicitInit
1448
- )
1449
- or
1450
1478
// from the inputs of phi and pi nodes into the node itself
1451
1479
pred = TSsaDefNode ( ssa .( SsaPseudoDefinition ) .getAnInput ( ) .getDefinition ( ) )
1452
1480
)
0 commit comments