| Index: pkg/compiler/lib/src/closure.dart
|
| diff --git a/pkg/compiler/lib/src/closure.dart b/pkg/compiler/lib/src/closure.dart
|
| index 34ec80125996492d6f3a2132511344ed9a63040a..beeadde429bf40d02d36b01d15ea87c65a181cc9 100644
|
| --- a/pkg/compiler/lib/src/closure.dart
|
| +++ b/pkg/compiler/lib/src/closure.dart
|
| @@ -21,9 +21,18 @@ import "elements/visitor.dart" show ElementVisitor;
|
| import 'universe/universe.dart' show
|
| Universe;
|
|
|
| +class ClosureNamer {
|
| + String getClosureVariableName(String name, int id) {
|
| + return "${name}_$id";
|
| + }
|
| +
|
| + void forgetElement(Element element) {}
|
| +}
|
| +
|
| class ClosureTask extends CompilerTask {
|
| Map<Node, ClosureClassMap> closureMappingCache;
|
| - ClosureTask(Compiler compiler)
|
| + ClosureNamer namer;
|
| + ClosureTask(Compiler compiler, this.namer)
|
| : closureMappingCache = new Map<Node, ClosureClassMap>(),
|
| super(compiler);
|
|
|
| @@ -37,7 +46,7 @@ class ClosureTask extends CompilerTask {
|
| if (cached != null) return cached;
|
|
|
| ClosureTranslator translator =
|
| - new ClosureTranslator(compiler, elements, closureMappingCache);
|
| + new ClosureTranslator(compiler, elements, closureMappingCache, namer);
|
|
|
| // The translator will store the computed closure-mappings inside the
|
| // cache. One for given node and one for each nested closure.
|
| @@ -82,6 +91,7 @@ class ClosureTask extends CompilerTask {
|
| throw new SpannableAssertionFailure(
|
| closure, 'Not a closure: $closure (${closure.runtimeType}).');
|
| }
|
| + namer.forgetElement(cls);
|
| compiler.enqueuer.codegen.forgetElement(cls);
|
| }
|
| }
|
| @@ -449,25 +459,14 @@ class ClosureTranslator extends Visitor {
|
| // The closureData of the currentFunctionElement.
|
| ClosureClassMap closureData;
|
|
|
| + ClosureNamer namer;
|
| +
|
| bool insideClosure = false;
|
|
|
| ClosureTranslator(this.compiler,
|
| this.elements,
|
| - this.closureMappingCache);
|
| -
|
| - /// Generate a unique name for the [id]th closure variable, with proposed name
|
| - /// [name].
|
| - ///
|
| - /// The result is used as the name of [BoxFieldElement]s and
|
| - /// [ClosureFieldElement]s, and must therefore be unique to avoid breaking an
|
| - /// invariant in the element model (classes cannot declare multiple fields
|
| - /// with the same name).
|
| - ///
|
| - /// Also, the names should be distinct from real field names to prevent
|
| - /// clashes with selectors for those fields.
|
| - String getClosureVariableName(String name, int id) {
|
| - return "${outermostElement.name}_${name}_$id";
|
| - }
|
| + this.closureMappingCache,
|
| + this.namer);
|
|
|
| bool isCapturedVariable(Local element) {
|
| return _capturedVariableMapping.containsKey(element);
|
| @@ -570,7 +569,7 @@ class ClosureTranslator extends Visitor {
|
|
|
| for (Local capturedLocal in fieldCaptures.toList()..sort(compareLocals)) {
|
| int id = closureFieldCounter++;
|
| - String name = getClosureVariableName(capturedLocal.name, id);
|
| + String name = namer.getClosureVariableName(capturedLocal.name, id);
|
| addClosureField(capturedLocal, name);
|
| }
|
| closureClass.reverseBackendMembers();
|
| @@ -799,12 +798,12 @@ class ClosureTranslator extends Visitor {
|
| if (box == null) {
|
| // TODO(floitsch): construct better box names.
|
| String boxName =
|
| - getClosureVariableName('box', closureFieldCounter++);
|
| + namer.getClosureVariableName('box', closureFieldCounter++);
|
| box = new BoxLocal(boxName, executableContext);
|
| }
|
| String elementName = variable.name;
|
| String boxedName =
|
| - getClosureVariableName(elementName, boxedFieldCounter++);
|
| + namer.getClosureVariableName(elementName, boxedFieldCounter++);
|
| // TODO(kasperl): Should this be a FieldElement instead?
|
| BoxFieldElement boxed = new BoxFieldElement(boxedName, variable, box);
|
| // No need to rename the fields of a box, so we give them a native name
|
|
|