@@ -148,39 +148,13 @@ signature module AstSig<LocationSig Location> {
148148
149149 /** A for-loop that iterates over the elements of a collection. */
150150 class ForeachStmt extends LoopStmt {
151- /**
152- * Gets the variable declaration of this `foreach` loop, if any.
153- *
154- * A `foreach` loop that binds more than one variable per iteration (for
155- * example when destructuring is used, as in `for k, v := range m` in Go, or
156- * `for (a, b) in ...` in Rust/Python/Swift) should instead opt in to the
157- * synthesized per-iteration element node (see `foreachHasElementNode`) and
158- * destructure that element into its variables, in which case this predicate
159- * need not have a result.
160- */
151+ /** Gets the variable declaration of this `foreach` loop. */
161152 Expr getVariable ( ) ;
162153
163154 /** Gets the collection expression of this `foreach` loop. */
164155 Expr getCollection ( ) ;
165156 }
166157
167- /**
168- * Holds if `foreach` has a synthesized per-iteration "element" node, that is,
169- * an additional control flow node representing the element produced by each
170- * iteration of the loop.
171- *
172- * When this holds, the shared library routes control flow from the loop
173- * header (and from the non-empty collection) into the element node, but the
174- * language is then responsible for wiring control flow out of the element
175- * node and on to the loop body (typically destructuring the element into the
176- * loop variables). In this mode the shared `getVariable` routing is not used.
177- *
178- * This is useful for languages whose loop variables are bound by extracting
179- * components from an implicit "current element" value (as opposed to being
180- * evaluated as ordinary target expressions).
181- */
182- default predicate foreachHasElementNode ( ForeachStmt foreach ) { none ( ) }
183-
184158 /**
185159 * A `break` statement.
186160 *
@@ -723,8 +697,6 @@ module Make0<LocationSig Location, AstSig<Location> Ast> {
723697
724698 private string patternMatchTrueTag ( ) { result = "[MatchTrue]" }
725699
726- private string foreachElementTag ( ) { result = "[ForeachElement]" }
727-
728700 /**
729701 * Holds if an additional node tagged with `tag` should be created for
730702 * `n`. Edges targeting such nodes are labeled with `t` and therefore `t`
@@ -744,10 +716,6 @@ module Make0<LocationSig Location, AstSig<Location> Ast> {
744716 tag = loopHeaderTag ( ) and
745717 t instanceof DirectSuccessor
746718 or
747- foreachHasElementNode ( n ) and
748- tag = foreachElementTag ( ) and
749- t instanceof DirectSuccessor
750- or
751719 n instanceof PatternMatchExpr and
752720 tag = patternMatchTrueTag ( ) and
753721 t .( BooleanSuccessor ) .getValue ( ) = true
@@ -1817,21 +1785,7 @@ module Make0<LocationSig Location, AstSig<Location> Ast> {
18171785 n2 .isAfter ( loopstmt )
18181786 )
18191787 or
1820- exists ( ForeachStmt foreachstmt , PreControlFlowNode iterentry |
1821- // `iterentry` is where each iteration begins, after the loop header
1822- // (or after the collection is found to be non-empty): the element
1823- // node if the language opts in, otherwise the loop variable, or the
1824- // body directly if there is no variable.
1825- foreachHasElementNode ( foreachstmt ) and
1826- iterentry .isAdditional ( foreachstmt , foreachElementTag ( ) )
1827- or
1828- not foreachHasElementNode ( foreachstmt ) and
1829- (
1830- iterentry .isBefore ( foreachstmt .getVariable ( ) )
1831- or
1832- not exists ( foreachstmt .getVariable ( ) ) and iterentry .isBefore ( foreachstmt .getBody ( ) )
1833- )
1834- |
1788+ exists ( ForeachStmt foreachstmt |
18351789 n1 .isBefore ( foreachstmt ) and
18361790 n2 .isBefore ( foreachstmt .getCollection ( ) )
18371791 or
@@ -1845,14 +1799,8 @@ module Make0<LocationSig Location, AstSig<Location> Ast> {
18451799 or
18461800 n1 .isAfterValue ( foreachstmt .getCollection ( ) ,
18471801 any ( EmptinessSuccessor t | t .getValue ( ) = false ) ) and
1848- n2 = iterentry
1802+ n2 . isBefore ( foreachstmt . getVariable ( ) )
18491803 or
1850- n1 .isAdditional ( foreachstmt , loopHeaderTag ( ) ) and
1851- n2 = iterentry
1852- or
1853- // After the loop variable, enter the body. When the language opts in
1854- // to the element node, it is instead responsible for wiring the
1855- // element node through to the body itself.
18561804 n1 .isAfter ( foreachstmt .getVariable ( ) ) and
18571805 n2 .isBefore ( foreachstmt .getBody ( ) )
18581806 or
@@ -1865,6 +1813,9 @@ module Make0<LocationSig Location, AstSig<Location> Ast> {
18651813 or
18661814 not exists ( getLoopElse ( foreachstmt ) ) and n2 .isAfter ( foreachstmt )
18671815 )
1816+ or
1817+ n1 .isAdditional ( foreachstmt , loopHeaderTag ( ) ) and
1818+ n2 .isBefore ( foreachstmt .getVariable ( ) )
18681819 )
18691820 or
18701821 exists ( ForStmt forstmt , PreControlFlowNode condentry |
0 commit comments