Chromium Code Reviews| 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..0f66b5aad1c6919fa940b4e9b164281dcf02f906 100644 |
| --- a/pkg/kernel/lib/transformations/closure/info.dart |
| +++ b/pkg/kernel/lib/transformations/closure/info.dart |
| @@ -25,11 +25,18 @@ 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; |
| + |
| + final Map<VariableDeclaration, int /*captured flags*/ > variables = |
|
Dmitry Stefantsov
2017/07/31 15:05:35
I think a more elaborate comment about the flags,
sjindel
2017/07/31 15:32:16
Done.
|
| + <VariableDeclaration, int>{}; |
| + |
| 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 +114,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); |
|
Dmitry Stefantsov
2017/07/31 15:05:35
To this point, we've already visited [typeParamete
sjindel
2017/07/31 15:32:16
Yes, but I wrote it this way so if a new field is
Dmitry Stefantsov
2017/08/01 09:36:13
I guess it's ok to leave it like this, but conside
|
| }); |
| endMember(); |
| } |
| @@ -181,14 +197,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] = variables[node.variable] | captureFlags; |
|
Dmitry Stefantsov
2017/07/31 15:05:35
How about using `|=` operation here and below?
sjindel
2017/07/31 15:32:16
Done.
|
| } |
| 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] = variables[node.variable] | captureFlags; |
| } |
| node.visitChildren(this); |
| } |