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