Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(70)

Unified Diff: pkg/kernel/lib/transformations/closure/info.dart

Issue 2991853002: Fix duplicate context creation when closures appear in initializers. (Closed)
Patch Set: Review comments. Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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);
}

Powered by Google App Engine
This is Rietveld 408576698