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

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: don't use the redirecting technique unless necessary. 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..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);
}

Powered by Google App Engine
This is Rietveld 408576698