| Index: pkg/kernel/lib/transformations/closure/info.dart
|
| diff --git a/pkg/kernel/lib/transformations/closure/info.dart b/pkg/kernel/lib/transformations/closure/info.dart
|
| index 50f280f32ed2a6f3dd29dd3e4095d885197e4418..6d0a2886ea3d53febd12e7643de6ca11ee92db6f 100644
|
| --- a/pkg/kernel/lib/transformations/closure/info.dart
|
| +++ b/pkg/kernel/lib/transformations/closure/info.dart
|
| @@ -26,18 +26,19 @@ import '../../visitor.dart' show RecursiveVisitor;
|
| class ClosureInfo extends RecursiveVisitor {
|
| FunctionNode currentFunction;
|
|
|
| - static const int OUTSIDE_INITIALIZER = 1;
|
| - static const int INSIDE_INITIALIZER = 2;
|
| + final Set<VariableDeclaration> variables = new Set<VariableDeclaration>();
|
|
|
| - int captureFlags = OUTSIDE_INITIALIZER;
|
| -
|
| - // For function parameters, we need to distinquish the following states:
|
| + // For captured constructor parameters, we need to distinquish the following
|
| + // states:
|
| //
|
| - // - captured inside initializers, not used in body (INSIDE_INITIALIZER)
|
| + // - only used inside initializers (INSIDE_INITIALIZER)
|
| // - only used in body (OUTSIDE_INITIALIZER)
|
| - // - captured inside initializers and used in body (OUTSIDE_INITIALIZER |
|
| - // INSIDE_INITIALIZER)
|
| - final Map<VariableDeclaration, int> variables = <VariableDeclaration, int>{};
|
| + // - used in body and initializers (OUTSIDE_INITIALIZER | INSIDE_INITIALIZER)
|
| + static const int OUTSIDE_INITIALIZER = 1;
|
| + static const int INSIDE_INITIALIZER = 2;
|
| + int captureFlags = OUTSIDE_INITIALIZER;
|
| + final Map<VariableDeclaration, int> parameterUses =
|
| + <VariableDeclaration, int>{};
|
|
|
| final Map<VariableDeclaration, FunctionNode> function =
|
| <VariableDeclaration, FunctionNode>{};
|
| @@ -129,6 +130,15 @@ class ClosureInfo extends RecursiveVisitor {
|
| visitList(node.initializers, this);
|
| captureFlags = OUTSIDE_INITIALIZER;
|
|
|
| + for (var decl in node.function.positionalParameters) {
|
| + var use = parameterUses[decl];
|
| + if (use == 0) parameterUses.remove(decl);
|
| + }
|
| + for (var decl in node.function.namedParameters) {
|
| + var use = parameterUses[decl];
|
| + if (use == 0) parameterUses.remove(decl);
|
| + }
|
| +
|
| node.function.accept(this);
|
| });
|
| endMember();
|
| @@ -202,20 +212,22 @@ class ClosureInfo extends RecursiveVisitor {
|
|
|
| visitVariableGet(VariableGet node) {
|
| if (function[node.variable] != currentFunction) {
|
| - variables.putIfAbsent(node.variable, () => 0);
|
| + variables.add(node.variable);
|
| }
|
| - if (variables.containsKey(node.variable)) {
|
| - variables[node.variable] |= captureFlags;
|
| + if (node.variable.parent.parent is Constructor) {
|
| + parameterUses.putIfAbsent(node.variable, () => 0);
|
| + parameterUses[node.variable] |= captureFlags;
|
| }
|
| node.visitChildren(this);
|
| }
|
|
|
| visitVariableSet(VariableSet node) {
|
| if (function[node.variable] != currentFunction) {
|
| - variables.putIfAbsent(node.variable, () => 0);
|
| + variables.add(node.variable);
|
| }
|
| - if (variables.containsKey(node.variable)) {
|
| - variables[node.variable] |= captureFlags;
|
| + if (node.variable.parent.parent is Constructor) {
|
| + parameterUses.putIfAbsent(node.variable, () => 0);
|
| + parameterUses[node.variable] |= captureFlags;
|
| }
|
| node.visitChildren(this);
|
| }
|
|
|