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); |
} |