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, |
| (...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 223 parent.body = initializerExpression; | 223 parent.body = initializerExpression; |
| 224 } else if (parent is FieldInitializer) { | 224 } else if (parent is FieldInitializer) { |
| 225 parent.value = initializerExpression; | 225 parent.value = initializerExpression; |
| 226 } else { | 226 } else { |
| 227 throw "Found unexpected node '${node.runtimeType}, expected a 'Let' " | 227 throw "Found unexpected node '${node.runtimeType}, expected a 'Let' " |
| 228 "or a 'FieldInitializer'."; | 228 "or a 'FieldInitializer'."; |
| 229 } | 229 } |
| 230 } | 230 } |
| 231 } | 231 } |
| 232 rewriter = null; | 232 rewriter = null; |
| 233 context = null; | |
| 233 // Transform constructor body. | 234 // Transform constructor body. |
| 234 FunctionNode function = node.function; | 235 FunctionNode function = node.function; |
| 235 if (function.body != null && function.body is! EmptyStatement) { | 236 if (function.body != null && function.body is! EmptyStatement) { |
| 236 setupContextForFunctionBody(function); | 237 setupContextForFunctionBody(function); |
| 237 VariableDeclaration self = thisAccess[currentMemberFunction]; | 238 VariableDeclaration self = thisAccess[currentMemberFunction]; |
| 238 if (self != null) { | 239 if (self != null) { |
| 239 context.extend(self, new ThisExpression()); | 240 context.extend(self, new ThisExpression()); |
| 240 } | 241 } |
| 241 node.function.accept(this); | 242 node.function.accept(this); |
| 242 resetContext(); | 243 resetContext(); |
| (...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 476 .forEach(extendContextWith); | 477 .forEach(extendContextWith); |
| 477 assert(node.body != null); | 478 assert(node.body != null); |
| 478 node.body = node.body.accept(this); | 479 node.body = node.body.accept(this); |
| 479 node.body.parent = node; | 480 node.body.parent = node; |
| 480 return node; | 481 return node; |
| 481 } | 482 } |
| 482 | 483 |
| 483 TreeNode visitBlock(Block node) { | 484 TreeNode visitBlock(Block node) { |
| 484 return saveContext(() { | 485 return saveContext(() { |
| 485 BlockRewriter blockRewriter = rewriter = rewriter.forNestedBlock(node); | 486 BlockRewriter blockRewriter = rewriter = rewriter.forNestedBlock(node); |
| 486 blockRewriter.transformStatements(node, this); | 487 blockRewriter.transformStatements(this); |
| 487 return node; | 488 return node; |
| 488 }); | 489 }); |
| 489 } | 490 } |
| 490 | 491 |
| 491 TreeNode visitVariableDeclaration(VariableDeclaration node) { | 492 TreeNode visitVariableDeclaration(VariableDeclaration node) { |
| 492 node.transformChildren(this); | 493 node.transformChildren(this); |
| 493 | 494 |
| 494 if (!capturedVariables.contains(node)) return node; | 495 if (!capturedVariables.contains(node)) return node; |
| 495 if (node.initializer == null && node.parent is FunctionNode) { | 496 if (node.initializer == null && node.parent is FunctionNode) { |
| 496 // If the variable is a function parameter and doesn't have an | 497 // If the variable is a function parameter and doesn't have an |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 620 return super.visitForInStatement(node); | 621 return super.visitForInStatement(node); |
| 621 } | 622 } |
| 622 | 623 |
| 623 TreeNode visitThisExpression(ThisExpression node) { | 624 TreeNode visitThisExpression(ThisExpression node) { |
| 624 return isOuterMostContext | 625 return isOuterMostContext |
| 625 ? node | 626 ? node |
| 626 : context.lookup(thisAccess[currentMemberFunction]); | 627 : context.lookup(thisAccess[currentMemberFunction]); |
| 627 } | 628 } |
| 628 | 629 |
| 629 TreeNode visitStaticGet(StaticGet node) { | 630 TreeNode visitStaticGet(StaticGet node) { |
| 630 Member target = node.target; | 631 // TODO(dmitryas): Add support for tear-offs. When added, uncomment this. |
|
kustermann
2017/06/20 12:13:13
Consider filing an issue about kernel-based closur
Dmitry Stefantsov
2017/06/22 14:12:51
Good idea! I was thinking about doing it, but the
| |
| 631 if (target is Procedure && target.kind == ProcedureKind.Method) { | 632 // |
| 632 VariableDeclaration contextVariable = new VariableDeclaration( | 633 // Member target = node.target; |
| 633 "#contextParameter", | 634 // if (target is Procedure && target.kind == ProcedureKind.Method) { |
| 634 type: const VectorType()); | 635 // VariableDeclaration contextVariable = new VariableDeclaration( |
| 635 Expression expression = getTearOffExpression( | 636 // "#contextParameter", |
| 636 null, node.target, contextVariable, new NullLiteral()); | 637 // type: const VectorType()); |
| 637 expression.transformChildren(this); | 638 // Expression expression = getTearOffExpression( |
| 638 return expression; | 639 // null, node.target, contextVariable, new NullLiteral()); |
| 639 } | 640 // expression.transformChildren(this); |
| 641 // return expression; | |
| 642 // } | |
| 640 return super.visitStaticGet(node); | 643 return super.visitStaticGet(node); |
| 641 } | 644 } |
| 642 | 645 |
| 643 TreeNode visitPropertyGet(PropertyGet node) { | 646 TreeNode visitPropertyGet(PropertyGet node) { |
| 644 Name tearOffName = tearOffGetterNames[node.name]; | 647 Name tearOffName = tearOffGetterNames[node.name]; |
| 645 if (tearOffName != null) { | 648 if (tearOffName != null) { |
| 646 MethodInvocation replacement = new MethodInvocation( | 649 PropertyGet replacement = new PropertyGet(node.receiver, tearOffName); |
| 647 node.receiver, tearOffName, new Arguments(<Expression>[])); | 650 return super.visitPropertyGet(replacement); |
| 648 return super.visitMethodInvocation(replacement); | |
| 649 } | 651 } |
| 650 return super.visitPropertyGet(node); | 652 return super.visitPropertyGet(node); |
| 651 } | 653 } |
| 652 | 654 |
| 653 TreeNode visitCatch(Catch node) { | 655 TreeNode visitCatch(Catch node) { |
| 654 VariableDeclaration exception = node.exception; | 656 VariableDeclaration exception = node.exception; |
| 655 VariableDeclaration stackTrace = node.stackTrace; | 657 VariableDeclaration stackTrace = node.stackTrace; |
| 656 if (stackTrace != null && capturedVariables.contains(stackTrace)) { | 658 if (stackTrace != null && capturedVariables.contains(stackTrace)) { |
| 657 Block block = node.body = ensureBlock(node.body); | 659 Block block = node.body = ensureBlock(node.body); |
| 658 block.parent = node; | 660 block.parent = node; |
| (...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 864 "#contextParameter", | 866 "#contextParameter", |
| 865 type: const VectorType()); | 867 type: const VectorType()); |
| 866 Context parent = context; | 868 Context parent = context; |
| 867 context = context.toNestedContext( | 869 context = context.toNestedContext( |
| 868 new VariableAccessor(contextVariable, null, TreeNode.noOffset)); | 870 new VariableAccessor(contextVariable, null, TreeNode.noOffset)); |
| 869 | 871 |
| 870 body.addStatement(new ReturnStatement(getTearOffExpression( | 872 body.addStatement(new ReturnStatement(getTearOffExpression( |
| 871 self, procedure, contextVariable, parent.expression))); | 873 self, procedure, contextVariable, parent.expression))); |
| 872 | 874 |
| 873 Procedure tearOffMethod = new Procedure( | 875 Procedure tearOffMethod = new Procedure( |
| 874 name, ProcedureKind.Method, tearOffMethodFunction, | 876 name, ProcedureKind.Getter, tearOffMethodFunction, |
| 875 fileUri: currentFileUri); | 877 fileUri: currentFileUri); |
| 876 newClassMembers.add(tearOffMethod); | 878 newClassMembers.add(tearOffMethod); |
| 877 | 879 |
| 878 resetContext(); | 880 resetContext(); |
| 879 }); | 881 }); |
| 880 } finally { | 882 } finally { |
| 881 currentMember = oldCurrentMember; | 883 currentMember = oldCurrentMember; |
| 882 currentMemberFunction = oldCurrentMemberFunction; | 884 currentMemberFunction = oldCurrentMemberFunction; |
| 883 } | 885 } |
| 884 } | 886 } |
| 885 } | 887 } |
| OLD | NEW |