OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 } |
OLD | NEW |