@@ -183,7 +183,26 @@ class CastExprTree extends StandardPostOrderTree instanceof CastExpr {
183183 override AstNode getChildNode ( int i ) { i = 0 and result = super .getExpr ( ) }
184184}
185185
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+ }
187206
188207class ContinueExprTree extends LeafTree , ContinueExpr {
189208 override predicate last ( AstNode last , Completion c ) { none ( ) }
@@ -203,7 +222,34 @@ class FieldExprTree extends StandardPostOrderTree instanceof FieldExpr {
203222 override AstNode getChildNode ( int i ) { i = 0 and result = super .getExpr ( ) }
204223}
205224
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+ }
207253
208254class IfExprTree extends PostOrderTree instanceof IfExpr {
209255 override predicate first ( AstNode node ) { first ( super .getCondition ( ) , node ) }
0 commit comments