Chromium Code Reviews| 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 |