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 dd867f45f1d9d608b32efdb58bade9571a754a2b..cc72c9095377c840fb82d0d3e140fdbf1565d9eb 100644 |
--- a/pkg/kernel/lib/transformations/closure/info.dart |
+++ b/pkg/kernel/lib/transformations/closure/info.dart |
@@ -25,11 +25,24 @@ import '../../visitor.dart' show RecursiveVisitor; |
class ClosureInfo extends RecursiveVisitor { |
FunctionNode currentFunction; |
+ |
+ static const int OUTSIDE_INITIALIZER = 1; |
+ static const int INSIDE_INITIALIZER = 2; |
+ |
+ int captureFlags = OUTSIDE_INITIALIZER; |
+ |
+ // For function parameters, we need to distinquish the following states: |
+ // |
+ // - captured inside initializers, not used in body (INSIDE_INITIALIZER) |
+ // - only used in body (OUTSIDE_INITIALIZER) |
+ // - captured inside initializers and used in body (OUTSIDE_INITIALIZER | |
+ // INSIDE_INITIALIZER) |
+ // |
Dmitry Stefantsov
2017/08/01 09:36:14
Please, remove the empty comment line here.
sjindel
2017/08/01 14:58:25
Done.
|
+ final Map<VariableDeclaration, int> variables = <VariableDeclaration, int>{}; |
Dmitry Stefantsov
2017/08/01 09:36:14
How about adding helper functions to hide the inte
sjindel
2017/08/01 14:58:25
I would prefer the second approach over the first,
Dmitry Stefantsov
2017/08/03 09:28:26
I guess it depends on the definition of "significa
|
+ |
final Map<VariableDeclaration, FunctionNode> function = |
<VariableDeclaration, FunctionNode>{}; |
- final Set<VariableDeclaration> variables = new Set<VariableDeclaration>(); |
- |
/// Map from functions to set of type variables captured within them. |
final Map<FunctionNode, Set<TypeParameter>> typeVariables = |
<FunctionNode, Set<TypeParameter>>{}; |
@@ -107,8 +120,17 @@ class ClosureInfo extends RecursiveVisitor { |
visitList(node.annotations, this); |
node.name?.accept(this); |
- node.function?.accept(this); |
+ |
+ visitList(node.function.typeParameters, this); |
+ visitList(node.function.positionalParameters, this); |
+ visitList(node.function.namedParameters, this); |
+ |
+ assert(captureFlags == OUTSIDE_INITIALIZER); |
+ captureFlags = INSIDE_INITIALIZER; |
visitList(node.initializers, this); |
+ captureFlags = OUTSIDE_INITIALIZER; |
+ |
+ node.function.accept(this); |
}); |
endMember(); |
} |
@@ -181,14 +203,20 @@ class ClosureInfo extends RecursiveVisitor { |
visitVariableGet(VariableGet node) { |
if (function[node.variable] != currentFunction) { |
- variables.add(node.variable); |
+ variables.putIfAbsent(node.variable, () => 0); |
+ } |
+ if (variables.containsKey(node.variable)) { |
+ variables[node.variable] |= captureFlags; |
} |
node.visitChildren(this); |
} |
visitVariableSet(VariableSet node) { |
if (function[node.variable] != currentFunction) { |
- variables.add(node.variable); |
+ variables.putIfAbsent(node.variable, () => 0); |
+ } |
+ if (variables.containsKey(node.variable)) { |
+ variables[node.variable] |= captureFlags; |
} |
node.visitChildren(this); |
} |