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 fasta.body_builder; | 5 library fasta.body_builder; |
6 | 6 |
7 import '../fasta_codes.dart' | 7 import '../fasta_codes.dart' |
8 show FastaMessage, codeExpectedButGot, codeExpectedFunctionBody; | 8 show FastaMessage, codeExpectedButGot, codeExpectedFunctionBody; |
9 | 9 |
10 import '../parser/parser.dart' show FormalParameterType, optional; | 10 import '../parser/parser.dart' show FormalParameterType, optional; |
(...skipping 603 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
614 | 614 |
615 if (receiver is FastaAccessor) { | 615 if (receiver is FastaAccessor) { |
616 if (constantExpressionRequired && | 616 if (constantExpressionRequired && |
617 !isIdentical(receiver) && | 617 !isIdentical(receiver) && |
618 !receiver.isInitializer) { | 618 !receiver.isInitializer) { |
619 addCompileTimeError(charOffset, "Not a constant expression."); | 619 addCompileTimeError(charOffset, "Not a constant expression."); |
620 } | 620 } |
621 return receiver.doInvocation(charOffset, arguments); | 621 return receiver.doInvocation(charOffset, arguments); |
622 } else { | 622 } else { |
623 return buildMethodInvocation( | 623 return buildMethodInvocation( |
624 toValue(receiver), callName, arguments, charOffset); | 624 astFactory, toValue(receiver), callName, arguments, charOffset); |
625 } | 625 } |
626 } | 626 } |
627 | 627 |
628 @override | 628 @override |
629 void beginCascade(Token token) { | 629 void beginCascade(Token token) { |
630 debugEvent("beginCascade"); | 630 debugEvent("beginCascade"); |
631 Expression expression = popForValue(); | 631 Expression expression = popForValue(); |
632 if (expression is CascadeReceiver) { | 632 if (expression is CascadeReceiver) { |
633 push(expression); | 633 push(expression); |
634 push(new VariableAccessor(this, token, expression.variable)); | 634 push(new VariableAccessor(this, token, expression.variable)); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
677 bool negate = false; | 677 bool negate = false; |
678 String operator = token.stringValue; | 678 String operator = token.stringValue; |
679 if (identical("!=", operator)) { | 679 if (identical("!=", operator)) { |
680 operator = "=="; | 680 operator = "=="; |
681 negate = true; | 681 negate = true; |
682 } | 682 } |
683 if (!isBinaryOperator(operator) && !isMinusOperator(operator)) { | 683 if (!isBinaryOperator(operator) && !isMinusOperator(operator)) { |
684 return buildCompileTimeError( | 684 return buildCompileTimeError( |
685 "Not an operator: '$operator'.", token.charOffset); | 685 "Not an operator: '$operator'.", token.charOffset); |
686 } else { | 686 } else { |
687 Expression result = | 687 Expression result = makeBinary(astFactory, a, new Name(operator), null, b, |
688 makeBinary(a, new Name(operator), null, b, offset: token.charOffset); | 688 offset: token.charOffset); |
689 if (isSuper) { | 689 if (isSuper) { |
690 result = toSuperMethodInvocation(result); | 690 result = toSuperMethodInvocation(result); |
691 } | 691 } |
692 return negate ? astFactory.not(null, result) : result; | 692 return negate ? astFactory.not(null, result) : result; |
693 } | 693 } |
694 } | 694 } |
695 | 695 |
696 void doLogicalExpression(Token token) { | 696 void doLogicalExpression(Token token) { |
697 Expression argument = popForValue(); | 697 Expression argument = popForValue(); |
698 Expression receiver = popForValue(); | 698 Expression receiver = popForValue(); |
699 push(astFactory.logicalExpression(receiver, token.stringValue, argument)); | 699 push(astFactory.logicalExpression(receiver, token.stringValue, argument)); |
700 } | 700 } |
701 | 701 |
702 /// Handle `a ?? b`. | 702 /// Handle `a ?? b`. |
703 void doIfNull(Token token) { | 703 void doIfNull(Token token) { |
704 Expression b = popForValue(); | 704 Expression b = popForValue(); |
705 Expression a = popForValue(); | 705 Expression a = popForValue(); |
706 VariableDeclaration variable = new VariableDeclaration.forValue(a); | 706 VariableDeclaration variable = new VariableDeclaration.forValue(a); |
707 push(makeLet( | 707 push(makeLet( |
708 variable, | 708 variable, |
709 new ConditionalExpression(buildIsNull(new VariableGet(variable)), b, | 709 new ConditionalExpression( |
710 new VariableGet(variable), const DynamicType()))); | 710 buildIsNull(astFactory, new VariableGet(variable)), |
| 711 b, |
| 712 new VariableGet(variable), |
| 713 const DynamicType()))); |
711 } | 714 } |
712 | 715 |
713 /// Handle `a?.b(...)`. | 716 /// Handle `a?.b(...)`. |
714 void doIfNotNull(Token token) { | 717 void doIfNotNull(Token token) { |
715 IncompleteSend send = pop(); | 718 IncompleteSend send = pop(); |
716 push(send.withReceiver(pop(), isNullAware: true)); | 719 push(send.withReceiver(pop(), isNullAware: true)); |
717 } | 720 } |
718 | 721 |
719 void doDotOrCascadeExpression(Token token) { | 722 void doDotOrCascadeExpression(Token token) { |
720 // TODO(ahe): Handle null-aware. | 723 // TODO(ahe): Handle null-aware. |
(...skipping 23 matching lines...) Expand all Loading... |
744 if (isNoSuchMethod) { | 747 if (isNoSuchMethod) { |
745 return throwNoSuchMethodError( | 748 return throwNoSuchMethodError( |
746 node.name.name, node.arguments, node.fileOffset, | 749 node.name.name, node.arguments, node.fileOffset, |
747 isSuper: true); | 750 isSuper: true); |
748 } | 751 } |
749 // TODO(ahe): Use [DirectPropertyGet] when possible. | 752 // TODO(ahe): Use [DirectPropertyGet] when possible. |
750 Expression receiver = | 753 Expression receiver = |
751 astFactory.directPropertyGet(new ThisExpression(), target); | 754 astFactory.directPropertyGet(new ThisExpression(), target); |
752 receiver = astFactory.superPropertyGet(node.name, target); | 755 receiver = astFactory.superPropertyGet(node.name, target); |
753 return buildMethodInvocation( | 756 return buildMethodInvocation( |
754 receiver, callName, node.arguments, node.fileOffset); | 757 astFactory, receiver, callName, node.arguments, node.fileOffset); |
755 } | 758 } |
756 | 759 |
757 bool areArgumentsCompatible(FunctionNode function, Arguments arguments) { | 760 bool areArgumentsCompatible(FunctionNode function, Arguments arguments) { |
758 // TODO(ahe): Implement this. | 761 // TODO(ahe): Implement this. |
759 return true; | 762 return true; |
760 } | 763 } |
761 | 764 |
762 @override | 765 @override |
763 Expression throwNoSuchMethodError( | 766 Expression throwNoSuchMethodError( |
764 String name, Arguments arguments, int charOffset, | 767 String name, Arguments arguments, int charOffset, |
(...skipping 971 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1736 var receiver = pop(); | 1739 var receiver = pop(); |
1737 if (optional("!", token)) { | 1740 if (optional("!", token)) { |
1738 push(astFactory.not(token, toValue(receiver))); | 1741 push(astFactory.not(token, toValue(receiver))); |
1739 } else { | 1742 } else { |
1740 String operator = token.stringValue; | 1743 String operator = token.stringValue; |
1741 if (optional("-", token)) { | 1744 if (optional("-", token)) { |
1742 operator = "unary-"; | 1745 operator = "unary-"; |
1743 } | 1746 } |
1744 if (receiver is ThisAccessor && receiver.isSuper) { | 1747 if (receiver is ThisAccessor && receiver.isSuper) { |
1745 push(toSuperMethodInvocation(buildMethodInvocation( | 1748 push(toSuperMethodInvocation(buildMethodInvocation( |
| 1749 astFactory, |
1746 astFactory.thisExpression(receiver.token), | 1750 astFactory.thisExpression(receiver.token), |
1747 new Name(operator), | 1751 new Name(operator), |
1748 new Arguments.empty(), | 1752 new Arguments.empty(), |
1749 token.charOffset))); | 1753 token.charOffset))); |
1750 } else { | 1754 } else { |
1751 push(buildMethodInvocation(toValue(receiver), new Name(operator), | 1755 push(buildMethodInvocation(astFactory, toValue(receiver), |
1752 new Arguments.empty(), token.charOffset)); | 1756 new Name(operator), new Arguments.empty(), token.charOffset)); |
1753 } | 1757 } |
1754 } | 1758 } |
1755 } | 1759 } |
1756 | 1760 |
1757 Name incrementOperator(Token token) { | 1761 Name incrementOperator(Token token) { |
1758 if (optional("++", token)) return plusName; | 1762 if (optional("++", token)) return plusName; |
1759 if (optional("--", token)) return minusName; | 1763 if (optional("--", token)) return minusName; |
1760 return internalError("Unknown increment operator: ${token.lexeme}"); | 1764 return internalError("Unknown increment operator: ${token.lexeme}"); |
1761 } | 1765 } |
1762 | 1766 |
(...skipping 1364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3127 } else if (node is PrefixBuilder) { | 3131 } else if (node is PrefixBuilder) { |
3128 return node.name; | 3132 return node.name; |
3129 } else if (node is ThisAccessor) { | 3133 } else if (node is ThisAccessor) { |
3130 return node.isSuper ? "super" : "this"; | 3134 return node.isSuper ? "super" : "this"; |
3131 } else if (node is FastaAccessor) { | 3135 } else if (node is FastaAccessor) { |
3132 return node.plainNameForRead; | 3136 return node.plainNameForRead; |
3133 } else { | 3137 } else { |
3134 return internalError("Unhandled: ${node.runtimeType}"); | 3138 return internalError("Unhandled: ${node.runtimeType}"); |
3135 } | 3139 } |
3136 } | 3140 } |
OLD | NEW |