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

Side by Side Diff: pkg/kernel/lib/transformations/closure/converter.dart

Issue 2981603002: Convert closures in all initializers, and share the context between them. (Closed)
Patch Set: Fix unnecessary context bug. 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 unified diff | Download patch
OLDNEW
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library kernel.transformations.closure.converter; 5 library kernel.transformations.closure.converter;
6 6
7 import '../../ast.dart' 7 import '../../ast.dart'
8 show 8 show
9 Arguments, 9 Arguments,
10 Block, 10 Block,
11 Catch, 11 Catch,
12 Class, 12 Class,
13 ClosureCreation, 13 ClosureCreation,
14 Constructor, 14 Constructor,
15 DartType, 15 DartType,
16 DynamicType, 16 DynamicType,
17 EmptyStatement, 17 EmptyStatement,
18 Expression, 18 Expression,
19 ExpressionStatement, 19 ExpressionStatement,
20 Field, 20 Field,
21 FieldInitializer,
22 ForInStatement, 21 ForInStatement,
23 ForStatement, 22 ForStatement,
24 FunctionDeclaration, 23 FunctionDeclaration,
25 FunctionExpression, 24 FunctionExpression,
26 FunctionNode, 25 FunctionNode,
27 FunctionType, 26 FunctionType,
28 Initializer,
29 InterfaceType, 27 InterfaceType,
30 InvalidExpression, 28 InvalidExpression,
31 InvocationExpression, 29 InvocationExpression,
32 Let, 30 // Let,
Dmitry Stefantsov 2017/07/13 07:19:53 If this import is not longer needed, it should be
sjindel 2017/07/13 11:34:04 Done.
33 Library, 31 Library,
34 LocalInitializer, 32 LocalInitializer,
35 Member, 33 Member,
36 MethodInvocation, 34 MethodInvocation,
37 Name, 35 Name,
38 NamedExpression, 36 NamedExpression,
39 NamedType, 37 NamedType,
40 NullLiteral, 38 NullLiteral,
41 Procedure, 39 Procedure,
42 ProcedureKind, 40 ProcedureKind,
(...skipping 20 matching lines...) Expand all
63 import '../../core_types.dart' show CoreTypes; 61 import '../../core_types.dart' show CoreTypes;
64 62
65 import '../../type_algebra.dart' show substitute; 63 import '../../type_algebra.dart' show substitute;
66 64
67 import 'clone_without_body.dart' show CloneWithoutBody; 65 import 'clone_without_body.dart' show CloneWithoutBody;
68 66
69 import 'context.dart' show Context, NoContext; 67 import 'context.dart' show Context, NoContext;
70 68
71 import 'info.dart' show ClosureInfo; 69 import 'info.dart' show ClosureInfo;
72 70
73 import 'rewriter.dart' 71 import 'rewriter.dart' show AstRewriter, BlockRewriter, InitializerListRewriter;
74 show
75 AstRewriter,
76 BlockRewriter,
77 InitializerRewriter,
78 FieldInitializerRewriter,
79 LocalInitializerRewriter;
80 72
81 class ClosureConverter extends Transformer { 73 class ClosureConverter extends Transformer {
82 final CoreTypes coreTypes; 74 final CoreTypes coreTypes;
83 final Set<VariableDeclaration> capturedVariables; 75 final Set<VariableDeclaration> capturedVariables;
84 final Map<FunctionNode, Set<TypeParameter>> capturedTypeVariables; 76 final Map<FunctionNode, Set<TypeParameter>> capturedTypeVariables;
85 final Map<FunctionNode, VariableDeclaration> thisAccess; 77 final Map<FunctionNode, VariableDeclaration> thisAccess;
86 final Map<FunctionNode, String> localNames; 78 final Map<FunctionNode, String> localNames;
87 79
88 /// Records place-holders for cloning contexts. See [visitForStatement]. 80 /// Records place-holders for cloning contexts. See [visitForStatement].
89 final Set<InvalidExpression> contextClonePlaceHolders = 81 final Set<InvalidExpression> contextClonePlaceHolders =
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
194 newClassMembers.forEach(node.addMember); 186 newClassMembers.forEach(node.addMember);
195 newClassMembers.clear(); 187 newClassMembers.clear();
196 currentClass = null; 188 currentClass = null;
197 return node; 189 return node;
198 } 190 }
199 191
200 void extendContextWith(VariableDeclaration parameter) { 192 void extendContextWith(VariableDeclaration parameter) {
201 context.extend(parameter, new VariableGet(parameter)); 193 context.extend(parameter, new VariableGet(parameter));
202 } 194 }
203 195
204 static InitializerRewriter getRewriterForInitializer(
205 Initializer initializer) {
206 if (initializer is FieldInitializer) {
207 return new FieldInitializerRewriter(initializer.value);
208 }
209 if (initializer is LocalInitializer) {
210 return new LocalInitializerRewriter(initializer.variable.initializer);
211 }
212 throw "Trying to extract an initializer expression from "
213 "${initializer.runtimeType}, but only FieldInitializer and "
214 "LocalInitializer are supported.";
215 }
216
217 static Expression getInitializerExpression(Initializer initializer) {
218 if (initializer is FieldInitializer) {
219 return initializer.value;
220 }
221 if (initializer is LocalInitializer) {
222 return initializer.variable.initializer;
223 }
224 throw "Trying to get initializing expressino from "
225 "${initializer.runtimeType}, but only Field Initializer and "
226 "LocalInitializer are supported.";
227 }
228
229 TreeNode visitConstructor(Constructor node) { 196 TreeNode visitConstructor(Constructor node) {
230 assert(isEmptyContext); 197 assert(isEmptyContext);
231 currentMember = node; 198 currentMember = node;
199
232 // Transform initializers. 200 // Transform initializers.
233 for (Initializer initializer in node.initializers) { 201 if (node.initializers.length > 0) {
234 if (initializer is FieldInitializer || initializer is LocalInitializer) { 202 var initRewriter = new InitializerListRewriter(node);
235 // Create a rewriter and a context for the initializer expression. 203 rewriter = initRewriter;
236 InitializerRewriter initializerRewriter = 204 context = new NoContext(this);
237 getRewriterForInitializer(initializer); 205
238 rewriter = initializerRewriter; 206 // TODO(karlklose): add a fine-grained analysis of captured parameters.
239 context = new NoContext(this); 207 node.function.positionalParameters
240 // Save the expression to visit it in the extended context, since the 208 .where(capturedVariables.contains)
241 // rewriter will modify `initializer.value` (for [FieldInitializer]) or 209 .forEach(extendContextWith);
242 // `initializer.variable.initializer` (for [LocalInitializer]). 210 node.function.namedParameters
243 Expression initializerExpression = 211 .where(capturedVariables.contains)
244 getInitializerExpression(initializer); 212 .forEach(extendContextWith);
245 // Extend the context with all captured parameters of the constructor. 213
246 // TODO(karlklose): add a fine-grained analysis of captured parameters. 214 transformList(node.initializers, this, node);
247 node.function.positionalParameters 215 node.initializers.insertAll(0, initRewriter.prefix);
248 .where(capturedVariables.contains) 216 context = rewriter = null;
249 .forEach(extendContextWith);
250 node.function.namedParameters
251 .where(capturedVariables.contains)
252 .forEach(extendContextWith);
253 // Transform the initializer expression.
254 var parent = initializerExpression.parent;
255 initializerExpression = initializerExpression.accept(this);
256 initializerExpression.parent = parent;
257 if (parent is Let) {
258 parent.body = initializerExpression;
259 } else if (parent is FieldInitializer) {
260 parent.value = initializerExpression;
261 } else if (parent is LocalInitializer) {
262 parent.variable.initializer = initializerExpression;
263 } else {
264 throw "Found unexpected node '${node.runtimeType}, expected a 'Let' "
265 ",a 'FieldInitializer', or a 'LocalInitializer'.";
266 }
267 }
268 } 217 }
269 rewriter = null; 218
270 // Transform constructor body. 219 // Transform constructor body.
271 FunctionNode function = node.function; 220 FunctionNode function = node.function;
272 if (function.body != null && function.body is! EmptyStatement) { 221 if (function.body != null && function.body is! EmptyStatement) {
273 setupContextForFunctionBody(function); 222 setupContextForFunctionBody(function);
274 VariableDeclaration self = thisAccess[currentMemberFunction]; 223 VariableDeclaration self = thisAccess[currentMemberFunction];
275 if (self != null) { 224 if (self != null) {
276 context.extend(self, new ThisExpression()); 225 context.extend(self, new ThisExpression());
277 } 226 }
278 node.function.accept(this); 227 node.function.accept(this);
279 resetContext(); 228 resetContext();
(...skipping 633 matching lines...) Expand 10 before | Expand all | Expand 10 after
913 newClassMembers.add(tearOffMethod); 862 newClassMembers.add(tearOffMethod);
914 863
915 resetContext(); 864 resetContext();
916 }); 865 });
917 } finally { 866 } finally {
918 currentMember = oldCurrentMember; 867 currentMember = oldCurrentMember;
919 currentMemberFunction = oldCurrentMemberFunction; 868 currentMemberFunction = oldCurrentMemberFunction;
920 } 869 }
921 } 870 }
922 } 871 }
OLDNEW
« no previous file with comments | « no previous file | pkg/kernel/lib/transformations/closure/info.dart » ('j') | pkg/kernel/lib/transformations/closure/info.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698