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

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

Issue 2944433002: Add tests for handling closures in LocalInitializers (Closed)
Patch Set: Merge in latest changes in master (e340ee517a) 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,
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
63 import '../../core_types.dart' show CoreTypes; 63 import '../../core_types.dart' show CoreTypes;
64 64
65 import '../../type_algebra.dart' show substitute; 65 import '../../type_algebra.dart' show substitute;
66 66
67 import 'clone_without_body.dart' show CloneWithoutBody; 67 import 'clone_without_body.dart' show CloneWithoutBody;
68 68
69 import 'context.dart' show Context, NoContext; 69 import 'context.dart' show Context, NoContext;
70 70
71 import 'info.dart' show ClosureInfo; 71 import 'info.dart' show ClosureInfo;
72 72
73 import 'rewriter.dart' show AstRewriter, BlockRewriter, InitializerRewriter; 73 import 'rewriter.dart'
74 show
75 AstRewriter,
76 BlockRewriter,
77 InitializerRewriter,
78 FieldInitializerRewriter,
79 LocalInitializerRewriter;
74 80
75 class ClosureConverter extends Transformer { 81 class ClosureConverter extends Transformer {
76 final CoreTypes coreTypes; 82 final CoreTypes coreTypes;
77 final Set<VariableDeclaration> capturedVariables; 83 final Set<VariableDeclaration> capturedVariables;
78 final Map<FunctionNode, Set<TypeParameter>> capturedTypeVariables; 84 final Map<FunctionNode, Set<TypeParameter>> capturedTypeVariables;
79 final Map<FunctionNode, VariableDeclaration> thisAccess; 85 final Map<FunctionNode, VariableDeclaration> thisAccess;
80 final Map<FunctionNode, String> localNames; 86 final Map<FunctionNode, String> localNames;
81 87
82 /// Records place-holders for cloning contexts. See [visitForStatement]. 88 /// Records place-holders for cloning contexts. See [visitForStatement].
83 final Set<InvalidExpression> contextClonePlaceHolders = 89 final Set<InvalidExpression> contextClonePlaceHolders =
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
188 newClassMembers.forEach(node.addMember); 194 newClassMembers.forEach(node.addMember);
189 newClassMembers.clear(); 195 newClassMembers.clear();
190 currentClass = null; 196 currentClass = null;
191 return node; 197 return node;
192 } 198 }
193 199
194 void extendContextWith(VariableDeclaration parameter) { 200 void extendContextWith(VariableDeclaration parameter) {
195 context.extend(parameter, new VariableGet(parameter)); 201 context.extend(parameter, new VariableGet(parameter));
196 } 202 }
197 203
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
198 TreeNode visitConstructor(Constructor node) { 229 TreeNode visitConstructor(Constructor node) {
199 assert(isEmptyContext); 230 assert(isEmptyContext);
200 currentMember = node; 231 currentMember = node;
201 // Transform initializers. 232 // Transform initializers.
202 for (Initializer initializer in node.initializers) { 233 for (Initializer initializer in node.initializers) {
203 if (initializer is FieldInitializer) { 234 if (initializer is FieldInitializer || initializer is LocalInitializer) {
204 // Create a rewriter and a context for the initializer expression. 235 // Create a rewriter and a context for the initializer expression.
205 rewriter = new InitializerRewriter(initializer.value); 236 InitializerRewriter initializerRewriter =
237 getRewriterForInitializer(initializer);
238 rewriter = initializerRewriter;
206 context = new NoContext(this); 239 context = new NoContext(this);
207 // Save the expression to visit it in the extended context, since the 240 // Save the expression to visit it in the extended context, since the
208 // rewriter will modify `initializer.value`. 241 // rewriter will modify `initializer.value` (for [FieldInitializer]) or
209 Expression initializerExpression = initializer.value; 242 // `initializer.variable.initializer` (for [LocalInitializer]).
243 Expression initializerExpression =
244 getInitializerExpression(initializer);
210 // Extend the context with all captured parameters of the constructor. 245 // Extend the context with all captured parameters of the constructor.
211 // TODO(karlklose): add a fine-grained analysis of captured parameters. 246 // TODO(karlklose): add a fine-grained analysis of captured parameters.
212 node.function.positionalParameters 247 node.function.positionalParameters
213 .where(capturedVariables.contains) 248 .where(capturedVariables.contains)
214 .forEach(extendContextWith); 249 .forEach(extendContextWith);
215 node.function.namedParameters 250 node.function.namedParameters
216 .where(capturedVariables.contains) 251 .where(capturedVariables.contains)
217 .forEach(extendContextWith); 252 .forEach(extendContextWith);
218 // Transform the initializer expression. 253 // Transform the initializer expression.
219 var parent = initializerExpression.parent; 254 var parent = initializerExpression.parent;
220 initializerExpression = initializerExpression.accept(this); 255 initializerExpression = initializerExpression.accept(this);
221 initializerExpression.parent = parent; 256 initializerExpression.parent = parent;
222 if (parent is Let) { 257 if (parent is Let) {
223 parent.body = initializerExpression; 258 parent.body = initializerExpression;
224 } else if (parent is FieldInitializer) { 259 } else if (parent is FieldInitializer) {
225 parent.value = initializerExpression; 260 parent.value = initializerExpression;
261 } else if (parent is LocalInitializer) {
262 parent.variable.initializer = initializerExpression;
226 } else { 263 } else {
227 throw "Found unexpected node '${node.runtimeType}, expected a 'Let' " 264 throw "Found unexpected node '${node.runtimeType}, expected a 'Let' "
228 "or a 'FieldInitializer'."; 265 ",a 'FieldInitializer', or a 'LocalInitializer'.";
229 } 266 }
230 } 267 }
231 } 268 }
232 rewriter = null; 269 rewriter = null;
233 // Transform constructor body. 270 // Transform constructor body.
234 FunctionNode function = node.function; 271 FunctionNode function = node.function;
235 if (function.body != null && function.body is! EmptyStatement) { 272 if (function.body != null && function.body is! EmptyStatement) {
236 setupContextForFunctionBody(function); 273 setupContextForFunctionBody(function);
237 VariableDeclaration self = thisAccess[currentMemberFunction]; 274 VariableDeclaration self = thisAccess[currentMemberFunction];
238 if (self != null) { 275 if (self != null) {
(...skipping 637 matching lines...) Expand 10 before | Expand all | Expand 10 after
876 newClassMembers.add(tearOffMethod); 913 newClassMembers.add(tearOffMethod);
877 914
878 resetContext(); 915 resetContext();
879 }); 916 });
880 } finally { 917 } finally {
881 currentMember = oldCurrentMember; 918 currentMember = oldCurrentMember;
882 currentMemberFunction = oldCurrentMemberFunction; 919 currentMemberFunction = oldCurrentMemberFunction;
883 } 920 }
884 } 921 }
885 } 922 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698