| 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, MemberKind, optional; | 10 import '../parser/parser.dart' show FormalParameterType, MemberKind, optional; |
| (...skipping 632 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 643 } | 643 } |
| 644 } else if (arguments == null) { | 644 } else if (arguments == null) { |
| 645 push(receiver); | 645 push(receiver); |
| 646 } else { | 646 } else { |
| 647 push(finishSend(receiver, arguments, beginToken.charOffset)); | 647 push(finishSend(receiver, arguments, beginToken.charOffset)); |
| 648 } | 648 } |
| 649 } | 649 } |
| 650 | 650 |
| 651 @override | 651 @override |
| 652 finishSend(Object receiver, Arguments arguments, int charOffset) { | 652 finishSend(Object receiver, Arguments arguments, int charOffset) { |
| 653 bool isIdentical(Object receiver) { | |
| 654 return receiver is StaticAccessor && | |
| 655 receiver.readTarget == coreTypes.identicalProcedure; | |
| 656 } | |
| 657 | |
| 658 if (receiver is FastaAccessor) { | 653 if (receiver is FastaAccessor) { |
| 659 if (constantExpressionRequired && | |
| 660 !isIdentical(receiver) && | |
| 661 !receiver.isInitializer) { | |
| 662 addCompileTimeError(charOffset, "Not a constant expression."); | |
| 663 } | |
| 664 return receiver.doInvocation(charOffset, arguments); | 654 return receiver.doInvocation(charOffset, arguments); |
| 665 } else { | 655 } else { |
| 666 return buildMethodInvocation( | 656 return buildMethodInvocation( |
| 667 toValue(receiver), callName, arguments, charOffset); | 657 toValue(receiver), callName, arguments, charOffset); |
| 668 } | 658 } |
| 669 } | 659 } |
| 670 | 660 |
| 671 @override | 661 @override |
| 672 void beginCascade(Token token) { | 662 void beginCascade(Token token) { |
| 673 debugEvent("beginCascade"); | 663 debugEvent("beginCascade"); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 687 @override | 677 @override |
| 688 void endCascade() { | 678 void endCascade() { |
| 689 debugEvent("endCascade"); | 679 debugEvent("endCascade"); |
| 690 Expression expression = popForEffect(); | 680 Expression expression = popForEffect(); |
| 691 KernelCascadeExpression cascadeReceiver = pop(); | 681 KernelCascadeExpression cascadeReceiver = pop(); |
| 692 cascadeReceiver.finalize(expression); | 682 cascadeReceiver.finalize(expression); |
| 693 push(cascadeReceiver); | 683 push(cascadeReceiver); |
| 694 } | 684 } |
| 695 | 685 |
| 696 @override | 686 @override |
| 687 void beginCaseExpression(Token caseKeyword) { |
| 688 debugEvent("beginCaseExpression"); |
| 689 super.push(constantExpressionRequired); |
| 690 constantExpressionRequired = true; |
| 691 } |
| 692 |
| 693 @override |
| 694 void endCaseExpression(Token colon) { |
| 695 debugEvent("endCaseExpression"); |
| 696 Expression expression = popForValue(); |
| 697 constantExpressionRequired = pop(); |
| 698 super.push(expression); |
| 699 } |
| 700 |
| 701 @override |
| 697 void handleBinaryExpression(Token token) { | 702 void handleBinaryExpression(Token token) { |
| 698 debugEvent("BinaryExpression"); | 703 debugEvent("BinaryExpression"); |
| 699 if (optional(".", token) || optional("..", token)) { | 704 if (optional(".", token) || optional("..", token)) { |
| 700 return doDotOrCascadeExpression(token); | 705 return doDotOrCascadeExpression(token); |
| 701 } | 706 } |
| 702 if (optional("&&", token) || optional("||", token)) { | 707 if (optional("&&", token) || optional("||", token)) { |
| 703 return doLogicalExpression(token); | 708 return doLogicalExpression(token); |
| 704 } | 709 } |
| 705 if (optional("??", token)) return doIfNull(token); | 710 if (optional("??", token)) return doIfNull(token); |
| 706 if (optional("?.", token)) return doIfNotNull(token); | 711 if (optional("?.", token)) return doIfNotNull(token); |
| (...skipping 995 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1702 Identifier name = pop(); | 1707 Identifier name = pop(); |
| 1703 push(new InitializedIdentifier(name.token, initializer)); | 1708 push(new InitializedIdentifier(name.token, initializer)); |
| 1704 } | 1709 } |
| 1705 | 1710 |
| 1706 @override | 1711 @override |
| 1707 void handleFormalParameterWithoutValue(Token token) { | 1712 void handleFormalParameterWithoutValue(Token token) { |
| 1708 debugEvent("FormalParameterWithoutValue"); | 1713 debugEvent("FormalParameterWithoutValue"); |
| 1709 } | 1714 } |
| 1710 | 1715 |
| 1711 @override | 1716 @override |
| 1717 void beginFormalParameters(Token token, MemberKind kind) { |
| 1718 super.push(constantExpressionRequired); |
| 1719 constantExpressionRequired = false; |
| 1720 } |
| 1721 |
| 1722 @override |
| 1712 void endFormalParameters( | 1723 void endFormalParameters( |
| 1713 int count, Token beginToken, Token endToken, MemberKind kind) { | 1724 int count, Token beginToken, Token endToken, MemberKind kind) { |
| 1714 debugEvent("FormalParameters"); | 1725 debugEvent("FormalParameters"); |
| 1715 OptionalFormals optional; | 1726 OptionalFormals optional; |
| 1716 if (count > 0 && peek() is OptionalFormals) { | 1727 if (count > 0 && peek() is OptionalFormals) { |
| 1717 optional = pop(); | 1728 optional = pop(); |
| 1718 count--; | 1729 count--; |
| 1719 } | 1730 } |
| 1720 FormalParameters formals = new FormalParameters( | 1731 FormalParameters formals = new FormalParameters( |
| 1721 popList(count) ?? <VariableDeclaration>[], | 1732 popList(count) ?? <VariableDeclaration>[], |
| 1722 optional, | 1733 optional, |
| 1723 beginToken.charOffset); | 1734 beginToken.charOffset); |
| 1735 constantExpressionRequired = pop(); |
| 1724 push(formals); | 1736 push(formals); |
| 1725 if ((inCatchClause || functionNestingLevel != 0) && | 1737 if ((inCatchClause || functionNestingLevel != 0) && |
| 1726 kind != MemberKind.GeneralizedFunctionType) { | 1738 kind != MemberKind.GeneralizedFunctionType) { |
| 1727 enterLocalScope(formals.computeFormalParameterScope( | 1739 enterLocalScope(formals.computeFormalParameterScope( |
| 1728 scope, member ?? classBuilder ?? library, this)); | 1740 scope, member ?? classBuilder ?? library, this)); |
| 1729 } | 1741 } |
| 1730 } | 1742 } |
| 1731 | 1743 |
| 1732 @override | 1744 @override |
| 1733 void beginCatchClause(Token token) { | 1745 void beginCatchClause(Token token) { |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1827 } | 1839 } |
| 1828 if (receiver is ThisAccessor && receiver.isSuper) { | 1840 if (receiver is ThisAccessor && receiver.isSuper) { |
| 1829 push(toSuperMethodInvocation(buildMethodInvocation( | 1841 push(toSuperMethodInvocation(buildMethodInvocation( |
| 1830 new KernelThisExpression() | 1842 new KernelThisExpression() |
| 1831 ..fileOffset = offsetForToken(receiver.token), | 1843 ..fileOffset = offsetForToken(receiver.token), |
| 1832 new Name(operator), | 1844 new Name(operator), |
| 1833 new Arguments.empty(), | 1845 new Arguments.empty(), |
| 1834 token.charOffset))); | 1846 token.charOffset))); |
| 1835 } else { | 1847 } else { |
| 1836 push(buildMethodInvocation(toValue(receiver), new Name(operator), | 1848 push(buildMethodInvocation(toValue(receiver), new Name(operator), |
| 1837 new Arguments.empty(), token.charOffset)); | 1849 new Arguments.empty(), token.charOffset, |
| 1850 // This *could* be a constant expression, we can't know without |
| 1851 // evaluating [receiver]. |
| 1852 isConstantExpression: true)); |
| 1838 } | 1853 } |
| 1839 } | 1854 } |
| 1840 } | 1855 } |
| 1841 | 1856 |
| 1842 Name incrementOperator(Token token) { | 1857 Name incrementOperator(Token token) { |
| 1843 if (optional("++", token)) return plusName; | 1858 if (optional("++", token)) return plusName; |
| 1844 if (optional("--", token)) return minusName; | 1859 if (optional("--", token)) return minusName; |
| 1845 return internalError("Unknown increment operator: ${token.lexeme}"); | 1860 return internalError("Unknown increment operator: ${token.lexeme}"); |
| 1846 } | 1861 } |
| 1847 | 1862 |
| (...skipping 921 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2769 } | 2784 } |
| 2770 for (Expression argument in expressions.reversed) { | 2785 for (Expression argument in expressions.reversed) { |
| 2771 expression = new Let( | 2786 expression = new Let( |
| 2772 new VariableDeclaration.forValue(argument, isFinal: true), | 2787 new VariableDeclaration.forValue(argument, isFinal: true), |
| 2773 expression); | 2788 expression); |
| 2774 } | 2789 } |
| 2775 return expression; | 2790 return expression; |
| 2776 } | 2791 } |
| 2777 | 2792 |
| 2778 @override | 2793 @override |
| 2794 bool isIdentical(Member member) => member == coreTypes.identicalProcedure; |
| 2795 |
| 2796 @override |
| 2779 Expression buildMethodInvocation( | 2797 Expression buildMethodInvocation( |
| 2780 Expression receiver, Name name, Arguments arguments, int offset, | 2798 Expression receiver, Name name, Arguments arguments, int offset, |
| 2781 {bool isConstantExpression: false, bool isNullAware: false}) { | 2799 {bool isConstantExpression: false, bool isNullAware: false}) { |
| 2800 if (constantExpressionRequired && !isConstantExpression) { |
| 2801 return buildCompileTimeError("Not a constant expression.", offset); |
| 2802 } |
| 2782 if (isNullAware) { | 2803 if (isNullAware) { |
| 2783 VariableDeclaration variable = new VariableDeclaration.forValue(receiver); | 2804 VariableDeclaration variable = new VariableDeclaration.forValue(receiver); |
| 2784 return makeLet( | 2805 return makeLet( |
| 2785 variable, | 2806 variable, |
| 2786 new ConditionalExpression( | 2807 new ConditionalExpression( |
| 2787 buildIsNull(new VariableGet(variable)), | 2808 buildIsNull(new VariableGet(variable)), |
| 2788 new NullLiteral(), | 2809 new NullLiteral(), |
| 2789 new MethodInvocation(new VariableGet(variable), name, arguments) | 2810 new MethodInvocation(new VariableGet(variable), name, arguments) |
| 2790 ..fileOffset = offset, | 2811 ..fileOffset = offset, |
| 2791 const DynamicType())); | 2812 const DynamicType())); |
| (...skipping 477 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3269 if (starToken == null) { | 3290 if (starToken == null) { |
| 3270 return AsyncMarker.Async; | 3291 return AsyncMarker.Async; |
| 3271 } else { | 3292 } else { |
| 3272 assert(identical(starToken.stringValue, "*")); | 3293 assert(identical(starToken.stringValue, "*")); |
| 3273 return AsyncMarker.AsyncStar; | 3294 return AsyncMarker.AsyncStar; |
| 3274 } | 3295 } |
| 3275 } else { | 3296 } else { |
| 3276 return internalError("Unknown async modifier: $asyncToken"); | 3297 return internalError("Unknown async modifier: $asyncToken"); |
| 3277 } | 3298 } |
| 3278 } | 3299 } |
| OLD | NEW |