@@ -183,7 +183,26 @@ class CastExprTree extends StandardPostOrderTree instanceof CastExpr {
183
183
override AstNode getChildNode ( int i ) { i = 0 and result = super .getExpr ( ) }
184
184
}
185
185
186
- class ClosureExprTree extends LeafTree instanceof ClosureExpr { }
186
+ // Closures have their own CFG scope, so we need to make sure that their
187
+ // CFG is not mixed with the surrounding CFG. This is done by retrofitting
188
+ // `first`, `propagatesAbnormal`, and `succ` below.
189
+ class ClosureExprTree extends StandardPostOrderTree , ClosureExpr {
190
+ override predicate first ( AstNode first ) { first = this }
191
+
192
+ override predicate propagatesAbnormal ( AstNode child ) { none ( ) }
193
+
194
+ override AstNode getChildNode ( int i ) {
195
+ result = this .getParamList ( ) .getParam ( i )
196
+ or
197
+ i = this .getParamList ( ) .getNumberOfParams ( ) and
198
+ result = this .getBody ( )
199
+ }
200
+
201
+ override predicate succ ( AstNode pred , AstNode succ , Completion c ) {
202
+ super .succ ( pred , succ , c ) and
203
+ not succ = this
204
+ }
205
+ }
187
206
188
207
class ContinueExprTree extends LeafTree , ContinueExpr {
189
208
override predicate last ( AstNode last , Completion c ) { none ( ) }
@@ -203,7 +222,34 @@ class FieldExprTree extends StandardPostOrderTree instanceof FieldExpr {
203
222
override AstNode getChildNode ( int i ) { i = 0 and result = super .getExpr ( ) }
204
223
}
205
224
206
- class FunctionTree extends LeafTree instanceof Function { }
225
+ // Functions have their own CFG scope, so we need to make sure that their
226
+ // CFG is not mixed with the surrounding CFG in case of nested functions.
227
+ // This is done by retrofitting `last`, `propagatesAbnormal`, and `succ`
228
+ // below.
229
+ class FunctionTree extends StandardPreOrderTree , Function {
230
+ override predicate last ( AstNode last , Completion c ) {
231
+ last = this and
232
+ completionIsValidFor ( c , this )
233
+ }
234
+
235
+ override predicate propagatesAbnormal ( AstNode child ) { none ( ) }
236
+
237
+ override AstNode getChildNode ( int i ) {
238
+ result = this .getParamList ( ) .getParam ( i )
239
+ or
240
+ i = this .getParamList ( ) .getNumberOfParams ( ) and
241
+ result = this .getBody ( )
242
+ }
243
+
244
+ override predicate succ ( AstNode pred , AstNode succ , Completion c ) {
245
+ super .succ ( pred , succ , c ) and
246
+ not pred = this
247
+ }
248
+ }
249
+
250
+ class ParamTree extends StandardPostOrderTree , Param {
251
+ override AstNode getChildNode ( int i ) { i = 0 and result = this .getPat ( ) }
252
+ }
207
253
208
254
class IfExprTree extends PostOrderTree instanceof IfExpr {
209
255
override predicate first ( AstNode node ) { first ( super .getCondition ( ) , node ) }
0 commit comments