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 |