Index: pkg/compiler/lib/src/closure.dart |
diff --git a/pkg/compiler/lib/src/closure.dart b/pkg/compiler/lib/src/closure.dart |
index 44fcc597ac039edf58f5376b60500ac5a9568348..bd7a1a6205a6b658c9fdbcd22c62b1467c0159cc 100644 |
--- a/pkg/compiler/lib/src/closure.dart |
+++ b/pkg/compiler/lib/src/closure.dart |
@@ -100,9 +100,6 @@ class ScopeInfo { |
/// True if [variable] has been mutated and is also used in another scope. |
bool isBoxed(Local variable) => false; |
- |
- /// True if this scope declares any variables that need to be boxed. |
- bool get hasBoxedVariables => false; |
} |
/// Class representing the usage of a scope that has been captured in the |
@@ -141,6 +138,27 @@ class ClosureScope extends ScopeInfo { |
/// each iteration, by boxing the iteration variable[s]. |
class LoopClosureScope extends ClosureScope { |
const LoopClosureScope(); |
+ |
+ /// True if this loop scope declares in the first part of the loop |
+ /// `for (<here>;...;...)` any variables that need to be boxed. |
+ bool get hasBoxedLoopVariables => false; |
+ |
+ /// The set of iteration variables (or variables declared in the for loop |
+ /// expression (`for (<here>; ... ; ...)`) that need to be boxed to snapshot |
+ /// their value. These variables are also included in the set of |
+ /// `forEachBoxedVariable` method. The distinction between these two sets is |
+ /// in this example: |
+ /// |
+ /// run(f) => f(); |
+ /// var a; |
+ /// for (int i = 0; i < 3; i++) { |
+ /// var b = 3; |
+ /// a = () => b = i; |
+ /// } |
+ /// |
+ /// `i` would be a part of the boxedLoopVariables AND boxedVariables, but b |
+ /// would only be a part of boxedVariables. |
+ List<Local> get boxedLoopVariables => const <Local>[]; |
} |
/// Class that describes the actual mechanics of how the converted, rewritten |
@@ -647,18 +665,10 @@ class ClosureScopeImpl implements ClosureScope, LoopClosureScope { |
bool get requiresContextBox => capturedVariables.keys.isNotEmpty; |
void forEachBoxedVariable(f(Local local, FieldEntity field)) { |
- if (capturedVariables.isNotEmpty) { |
- capturedVariables.forEach(f); |
- } else { |
- for (Local l in boxedLoopVariables) { |
- // The boxes for loop variables are constructed on-demand per-iteration |
- // in the locals handler. |
- f(l, null); |
- } |
- } |
+ capturedVariables.forEach(f); |
} |
- bool get hasBoxedVariables => !capturedVariables.isEmpty; |
+ bool get hasBoxedLoopVariables => boxedLoopVariables.isNotEmpty; |
bool isBoxed(Local variable) { |
return capturedVariables.containsKey(variable); |
@@ -746,9 +756,6 @@ class ClosureClassMap implements ClosureRepresentationInfo { |
ClosureClassMap(this.closureEntity, this.closureClassEntity, this.callMethod, |
this.thisLocal); |
- bool get hasBoxedVariables => |
- throw new UnsupportedError("ClosureClassMap.hasBoxedVariables"); |
- |
List<Local> get createdFieldEntities { |
List<Local> fields = <Local>[]; |
if (closureClassEntity == null) return const <Local>[]; |