@@ -27,6 +27,7 @@ module DataFlow {
2727 private newtype TNode =
2828 TValueNode ( AST:: ValueNode nd ) or
2929 TSsaDefNode ( SsaDefinition d ) or
30+ TCapturedVariableNode ( LocalVariable v ) { v .isCaptured ( ) } or
3031 TPropNode ( @property p ) or
3132 TRestPatternNode ( DestructuringPattern dp , Expr rest ) { rest = dp .getRest ( ) } or
3233 TDestructuringPatternNode ( DestructuringPattern dp ) or
@@ -1221,6 +1222,29 @@ module DataFlow {
12211222 }
12221223 }
12231224
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+
12241248 /**
12251249 * Gets the data flow node corresponding to `nd`.
12261250 *
@@ -1434,19 +1458,23 @@ module DataFlow {
14341458 or
14351459 immediateFlowStep ( pred , succ )
14361460 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
14371476 // Flow through implicit SSA nodes
14381477 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
14501478 // from the inputs of phi and pi nodes into the node itself
14511479 pred = TSsaDefNode ( ssa .( SsaPseudoDefinition ) .getAnInput ( ) .getDefinition ( ) )
14521480 )
0 commit comments