Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(29)

Unified Diff: pkg/compiler/lib/src/cps_ir/cps_ir_builder_visitor.dart

Issue 846353002: Dart2dart: Support for-loop variables captured in loop body. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Rebase Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/compiler/lib/src/cps_ir/cps_ir_builder_visitor.dart
diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_builder_visitor.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_builder_visitor.dart
index b292b4e5a40a78195b4123c7a8cf337637b7011d..3b3305da68222ba79f038be7fbf9d9bec805148c 100644
--- a/pkg/compiler/lib/src/cps_ir/cps_ir_builder_visitor.dart
+++ b/pkg/compiler/lib/src/cps_ir/cps_ir_builder_visitor.dart
@@ -410,15 +410,12 @@ class IrBuilderVisitor extends ResolvedVisitor<ir.Primitive>
}
visitFor(ast.For node) {
- // TODO(asgerf): Handle closure variables declared in a for-loop.
- if (!isJavaScriptBackend && node.initializer is ast.VariableDefinitions) {
+ List<LocalElement> loopVariables = <LocalElement>[];
+ if (node.initializer is ast.VariableDefinitions) {
ast.VariableDefinitions definitions = node.initializer;
- for (ast.Node definition in definitions.definitions.nodes) {
- LocalElement element = elements[definition];
- DartIrBuilder dartIrBuilder = irBuilder;
- if (dartIrBuilder.isInClosureVariable(element)) {
- return giveup(definition, 'Closure variable in for loop initializer');
- }
+ for (ast.Node node in definitions.definitions.nodes) {
+ LocalElement loopVariable = elements[node];
+ loopVariables.add(loopVariable);
}
}
@@ -429,6 +426,7 @@ class IrBuilderVisitor extends ResolvedVisitor<ir.Primitive>
buildBody: subbuild(node.body),
buildUpdate: subbuildSequence(node.update),
closureScope: getClosureScope(node),
+ loopVariables: loopVariables,
target: target);
}
@@ -1045,12 +1043,6 @@ class IrBuilderVisitor extends ResolvedVisitor<ir.Primitive>
irBuilder.declareLocalFunction(element, inner);
}
- static final String ABORT_IRNODE_BUILDER = "IrNode builder aborted";
-
- dynamic giveup(ast.Node node, [String reason]) {
- throw ABORT_IRNODE_BUILDER;
- }
-
ir.ExecutableDefinition nullIfGiveup(ir.ExecutableDefinition action()) {
try {
return action();
@@ -1067,9 +1059,19 @@ class IrBuilderVisitor extends ResolvedVisitor<ir.Primitive>
}
}
-/// Classifies local variables and local functions as 'closure variables'.
-/// A closure variable is one that is accessed from an inner function nested
-/// one or more levels inside the one that declares it.
+final String ABORT_IRNODE_BUILDER = "IrNode builder aborted";
+
+dynamic giveup(ast.Node node, [String reason]) {
+ throw ABORT_IRNODE_BUILDER;
+}
+
+/// Classifies local variables and local functions as captured, if they
+/// are accessed from within a nested function.
+///
+/// This class is specific to the [DartIrBuilder], in that it gives up if it
+/// sees a feature that is currently unsupport by that builder. In particular,
+/// loop variables captured in a for-loop initializer, condition, or update
+/// expression are unsupported.
class DetectClosureVariables extends ast.Visitor
implements ClosureVariableInfo {
final TreeElements elements;
@@ -1089,6 +1091,25 @@ class DetectClosureVariables extends ast.Visitor
node.visitChildren(this);
}
+ visitFor(ast.For node) {
+ if (node.initializer != null) visit(node.initializer);
+ if (node.condition != null) visit(node.condition);
+ if (node.update != null) visit(node.update);
+
+ // Give up if a variable was captured outside of the loop body.
+ if (node.initializer is ast.VariableDefinitions) {
+ ast.VariableDefinitions definitions = node.initializer;
+ for (ast.Node node in definitions.definitions.nodes) {
+ LocalElement loopVariable = elements[node];
+ if (capturedVariables.contains(loopVariable)) {
+ return giveup(node, 'For-loop variable captured in loop header');
+ }
+ }
+ }
+
+ if (node.body != null) visit(node.body);
+ }
+
void handleSend(ast.Send node) {
Element element = elements[node];
if (Elements.isLocal(element) &&
« no previous file with comments | « pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698