| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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.parser.parser; | 5 library fasta.parser.parser; |
| 6 | 6 |
| 7 import '../fasta_codes.dart' | 7 import '../fasta_codes.dart' |
| 8 show | 8 show |
| 9 FastaCode, | 9 FastaCode, |
| 10 FastaMessage, | 10 FastaMessage, |
| 11 codeAbstractNotSync, | 11 codeAbstractNotSync, |
| 12 codeAsciiControlCharacter, | 12 codeAsciiControlCharacter, |
| 13 codeAssertAsExpression, |
| 14 codeAssertExtraneousArgument, |
| 13 codeAsyncAsIdentifier, | 15 codeAsyncAsIdentifier, |
| 14 codeAwaitAsIdentifier, | 16 codeAwaitAsIdentifier, |
| 15 codeAwaitForNotAsync, | 17 codeAwaitForNotAsync, |
| 16 codeAwaitNotAsync, | 18 codeAwaitNotAsync, |
| 17 codeBuiltInIdentifierAsType, | 19 codeBuiltInIdentifierAsType, |
| 18 codeBuiltInIdentifierInDeclaration, | 20 codeBuiltInIdentifierInDeclaration, |
| 19 codeEmptyNamedParameterList, | 21 codeEmptyNamedParameterList, |
| 20 codeEmptyOptionalParameterList, | 22 codeEmptyOptionalParameterList, |
| 21 codeEncoding, | 23 codeEncoding, |
| 22 codeExpectedBlockToSkip, | 24 codeExpectedBlockToSkip, |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 151 /// An instance field in a class. | 153 /// An instance field in a class. |
| 152 NonStaticField, | 154 NonStaticField, |
| 153 | 155 |
| 154 /// A static field in a class. | 156 /// A static field in a class. |
| 155 StaticField, | 157 StaticField, |
| 156 | 158 |
| 157 /// A top-level field. | 159 /// A top-level field. |
| 158 TopLevelField, | 160 TopLevelField, |
| 159 } | 161 } |
| 160 | 162 |
| 163 /// Syntactic forms of `assert`. |
| 164 /// |
| 165 /// An assertion can legally occur as a statement. However, assertions are also |
| 166 /// experimentally allowed in initializers. For improved error recovery, we |
| 167 /// also attempt to parse asserts as expressions. |
| 168 enum Assert { |
| 169 Expression, |
| 170 Initializer, |
| 171 Statement, |
| 172 } |
| 173 |
| 161 /// An event generating parser of Dart programs. This parser expects all tokens | 174 /// An event generating parser of Dart programs. This parser expects all tokens |
| 162 /// in a linked list (aka a token stream). | 175 /// in a linked list (aka a token stream). |
| 163 /// | 176 /// |
| 164 /// The class [Scanner] is used to generate a token stream. See the file | 177 /// The class [Scanner] is used to generate a token stream. See the file |
| 165 /// [scanner.dart](../scanner.dart). | 178 /// [scanner.dart](../scanner.dart). |
| 166 /// | 179 /// |
| 167 /// Subclasses of the class [Listener] are used to listen to events. | 180 /// Subclasses of the class [Listener] are used to listen to events. |
| 168 /// | 181 /// |
| 169 /// Most methods of this class belong in one of three major categories: parse | 182 /// Most methods of this class belong in one of three major categories: parse |
| 170 /// methods, peek methods, and skip methods. Parse methods all have the prefix | 183 /// methods, peek methods, and skip methods. Parse methods all have the prefix |
| (...skipping 1383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1554 } | 1567 } |
| 1555 | 1568 |
| 1556 Token parseInitializers(Token token) { | 1569 Token parseInitializers(Token token) { |
| 1557 Token begin = token; | 1570 Token begin = token; |
| 1558 listener.beginInitializers(begin); | 1571 listener.beginInitializers(begin); |
| 1559 expect(':', token); | 1572 expect(':', token); |
| 1560 int count = 0; | 1573 int count = 0; |
| 1561 bool old = mayParseFunctionExpressions; | 1574 bool old = mayParseFunctionExpressions; |
| 1562 mayParseFunctionExpressions = false; | 1575 mayParseFunctionExpressions = false; |
| 1563 do { | 1576 do { |
| 1564 token = token.next; | 1577 token = parseInitializer(token.next); |
| 1565 listener.beginInitializer(token); | |
| 1566 token = parseExpression(token); | |
| 1567 listener.endInitializer(token); | |
| 1568 ++count; | 1578 ++count; |
| 1569 } while (optional(',', token)); | 1579 } while (optional(',', token)); |
| 1570 mayParseFunctionExpressions = old; | 1580 mayParseFunctionExpressions = old; |
| 1571 listener.endInitializers(count, begin, token); | 1581 listener.endInitializers(count, begin, token); |
| 1572 return token; | 1582 return token; |
| 1573 } | 1583 } |
| 1574 | 1584 |
| 1585 Token parseInitializer(Token token) { |
| 1586 listener.beginInitializer(token); |
| 1587 if (optional('assert', token)) { |
| 1588 token = parseAssert(token, Assert.Initializer); |
| 1589 } else { |
| 1590 token = parseExpression(token); |
| 1591 } |
| 1592 listener.endInitializer(token); |
| 1593 return token; |
| 1594 } |
| 1595 |
| 1575 Token parseLiteralStringOrRecoverExpression(Token token) { | 1596 Token parseLiteralStringOrRecoverExpression(Token token) { |
| 1576 if (identical(token.kind, STRING_TOKEN)) { | 1597 if (identical(token.kind, STRING_TOKEN)) { |
| 1577 return parseLiteralString(token); | 1598 return parseLiteralString(token); |
| 1578 } else { | 1599 } else { |
| 1579 reportRecoverableErrorCodeWithToken(token, codeExpectedString); | 1600 reportRecoverableErrorCodeWithToken(token, codeExpectedString); |
| 1580 return parseRecoverExpression(token); | 1601 return parseRecoverExpression( |
| 1602 token, codeExpectedString.format(uri, token.charOffset, token)); |
| 1581 } | 1603 } |
| 1582 } | 1604 } |
| 1583 | 1605 |
| 1584 Token expectSemicolon(Token token) { | 1606 Token expectSemicolon(Token token) { |
| 1585 return expect(';', token); | 1607 return expect(';', token); |
| 1586 } | 1608 } |
| 1587 | 1609 |
| 1588 bool isModifier(Token token) => modifierOrder(token) < 127; | 1610 bool isModifier(Token token) => modifierOrder(token) < 127; |
| 1589 | 1611 |
| 1590 /// Provides a partial order on modifiers. | 1612 /// Provides a partial order on modifiers. |
| (...skipping 1088 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2679 BeginToken begin = token; | 2701 BeginToken begin = token; |
| 2680 token = (begin.endGroup != null) ? begin.endGroup : token; | 2702 token = (begin.endGroup != null) ? begin.endGroup : token; |
| 2681 } else if (token is ErrorToken) { | 2703 } else if (token is ErrorToken) { |
| 2682 reportErrorToken(token, false).next; | 2704 reportErrorToken(token, false).next; |
| 2683 } | 2705 } |
| 2684 token = token.next; | 2706 token = token.next; |
| 2685 } | 2707 } |
| 2686 return token; | 2708 return token; |
| 2687 } | 2709 } |
| 2688 | 2710 |
| 2689 Token parseRecoverExpression(Token token) => parseExpression(token); | 2711 Token parseRecoverExpression(Token token, FastaMessage message) => |
| 2712 parseExpression(token); |
| 2690 | 2713 |
| 2691 int expressionDepth = 0; | 2714 int expressionDepth = 0; |
| 2692 Token parseExpression(Token token) { | 2715 Token parseExpression(Token token) { |
| 2693 if (expressionDepth++ > 500) { | 2716 if (expressionDepth++ > 500) { |
| 2694 // This happens in degenerate programs, for example, with a lot of nested | 2717 // This happens in degenerate programs, for example, with a lot of nested |
| 2695 // list literals. This is provoked by, for examaple, the language test | 2718 // list literals. This is provoked by, for examaple, the language test |
| 2696 // deep_nesting1_negative_test. | 2719 // deep_nesting1_negative_test. |
| 2697 return reportUnrecoverableErrorCode(token, codeStackOverflow).next; | 2720 return reportUnrecoverableErrorCode(token, codeStackOverflow).next; |
| 2698 } | 2721 } |
| 2699 listener.beginExpression(token); | 2722 listener.beginExpression(token); |
| (...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2908 return parseSuperExpression(token, context); | 2931 return parseSuperExpression(token, context); |
| 2909 } else if (identical(value, "new")) { | 2932 } else if (identical(value, "new")) { |
| 2910 return parseNewExpression(token); | 2933 return parseNewExpression(token); |
| 2911 } else if (identical(value, "const")) { | 2934 } else if (identical(value, "const")) { |
| 2912 return parseConstExpression(token); | 2935 return parseConstExpression(token); |
| 2913 } else if (identical(value, "void")) { | 2936 } else if (identical(value, "void")) { |
| 2914 return parseFunctionExpression(token); | 2937 return parseFunctionExpression(token); |
| 2915 } else if (!inPlainSync && | 2938 } else if (!inPlainSync && |
| 2916 (identical(value, "yield") || identical(value, "async"))) { | 2939 (identical(value, "yield") || identical(value, "async"))) { |
| 2917 return expressionExpected(token); | 2940 return expressionExpected(token); |
| 2941 } else if (identical(value, "assert")) { |
| 2942 return parseAssert(token, Assert.Expression); |
| 2918 } else if (token.isIdentifier) { | 2943 } else if (token.isIdentifier) { |
| 2919 return parseSendOrFunctionLiteral(token, context); | 2944 return parseSendOrFunctionLiteral(token, context); |
| 2920 } else { | 2945 } else { |
| 2921 return expressionExpected(token); | 2946 return expressionExpected(token); |
| 2922 } | 2947 } |
| 2923 } else if (kind == OPEN_PAREN_TOKEN) { | 2948 } else if (kind == OPEN_PAREN_TOKEN) { |
| 2924 return parseParenthesizedExpressionOrFunctionLiteral(token); | 2949 return parseParenthesizedExpressionOrFunctionLiteral(token); |
| 2925 } else if (kind == OPEN_SQUARE_BRACKET_TOKEN || optional('[]', token)) { | 2950 } else if (kind == OPEN_SQUARE_BRACKET_TOKEN || optional('[]', token)) { |
| 2926 listener.handleNoTypeArguments(token); | 2951 listener.handleNoTypeArguments(token); |
| 2927 return parseLiteralListSuffix(token, null); | 2952 return parseLiteralListSuffix(token, null); |
| (...skipping 838 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3766 token = token.next; | 3791 token = token.next; |
| 3767 bool hasTarget = false; | 3792 bool hasTarget = false; |
| 3768 if (token.isIdentifier) { | 3793 if (token.isIdentifier) { |
| 3769 token = parseIdentifier(token, IdentifierContext.labelReference); | 3794 token = parseIdentifier(token, IdentifierContext.labelReference); |
| 3770 hasTarget = true; | 3795 hasTarget = true; |
| 3771 } | 3796 } |
| 3772 listener.handleBreakStatement(hasTarget, breakKeyword, token); | 3797 listener.handleBreakStatement(hasTarget, breakKeyword, token); |
| 3773 return expectSemicolon(token); | 3798 return expectSemicolon(token); |
| 3774 } | 3799 } |
| 3775 | 3800 |
| 3776 Token parseAssertStatement(Token token) { | 3801 Token parseAssert(Token token, Assert kind) { |
| 3802 listener.beginAssert(token, kind); |
| 3777 Token assertKeyword = token; | 3803 Token assertKeyword = token; |
| 3778 Token commaToken = null; | 3804 Token commaToken = null; |
| 3779 token = expect('assert', token); | 3805 token = expect('assert', token); |
| 3780 Token leftParenthesis = token; | 3806 Token leftParenthesis = token; |
| 3781 token = expect('(', token); | 3807 token = expect('(', token); |
| 3782 bool old = mayParseFunctionExpressions; | 3808 bool old = mayParseFunctionExpressions; |
| 3783 mayParseFunctionExpressions = true; | 3809 mayParseFunctionExpressions = true; |
| 3784 token = parseExpression(token); | 3810 token = parseExpression(token); |
| 3785 if (optional(',', token)) { | 3811 if (optional(',', token)) { |
| 3786 commaToken = token; | 3812 commaToken = token; |
| 3787 token = token.next; | 3813 token = token.next; |
| 3788 token = parseExpression(token); | 3814 token = parseExpression(token); |
| 3789 } | 3815 } |
| 3816 if (optional(',', token)) { |
| 3817 Token firstExtra = token.next; |
| 3818 while (optional(',', token)) { |
| 3819 token = token.next; |
| 3820 Token begin = token; |
| 3821 token = parseExpression(token); |
| 3822 listener.handleExtraneousExpression( |
| 3823 begin, codeAssertExtraneousArgument.format(uri, token.charOffset)); |
| 3824 } |
| 3825 reportRecoverableErrorCode(firstExtra, codeAssertExtraneousArgument); |
| 3826 } |
| 3790 Token rightParenthesis = token; | 3827 Token rightParenthesis = token; |
| 3791 token = expect(')', token); | 3828 token = expect(')', token); |
| 3792 mayParseFunctionExpressions = old; | 3829 mayParseFunctionExpressions = old; |
| 3793 listener.handleAssertStatement( | 3830 listener.endAssert(assertKeyword, kind, leftParenthesis, commaToken, |
| 3794 assertKeyword, leftParenthesis, commaToken, rightParenthesis, token); | 3831 rightParenthesis, token); |
| 3832 if (kind == Assert.Expression) { |
| 3833 reportRecoverableErrorCode(assertKeyword, codeAssertAsExpression); |
| 3834 } |
| 3835 return token; |
| 3836 } |
| 3837 |
| 3838 Token parseAssertStatement(Token token) { |
| 3839 token = parseAssert(token, Assert.Statement); |
| 3795 return expectSemicolon(token); | 3840 return expectSemicolon(token); |
| 3796 } | 3841 } |
| 3797 | 3842 |
| 3798 Token parseContinueStatement(Token token) { | 3843 Token parseContinueStatement(Token token) { |
| 3799 assert(optional('continue', token)); | 3844 assert(optional('continue', token)); |
| 3800 Token continueKeyword = token; | 3845 Token continueKeyword = token; |
| 3801 token = token.next; | 3846 token = token.next; |
| 3802 bool hasTarget = false; | 3847 bool hasTarget = false; |
| 3803 if (token.isIdentifier) { | 3848 if (token.isIdentifier) { |
| 3804 token = parseIdentifier(token, IdentifierContext.labelReference); | 3849 token = parseIdentifier(token, IdentifierContext.labelReference); |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3907 return reportUnrecoverableError( | 3952 return reportUnrecoverableError( |
| 3908 token, () => code.format(uri, token.charOffset, string)); | 3953 token, () => code.format(uri, token.charOffset, string)); |
| 3909 } | 3954 } |
| 3910 } | 3955 } |
| 3911 | 3956 |
| 3912 typedef FastaMessage NoArgument(Uri uri, int charOffset); | 3957 typedef FastaMessage NoArgument(Uri uri, int charOffset); |
| 3913 | 3958 |
| 3914 typedef FastaMessage TokenArgument(Uri uri, int charOffset, Token token); | 3959 typedef FastaMessage TokenArgument(Uri uri, int charOffset, Token token); |
| 3915 | 3960 |
| 3916 typedef FastaMessage StringArgument(Uri uri, int charOffset, String string); | 3961 typedef FastaMessage StringArgument(Uri uri, int charOffset, String string); |
| OLD | NEW |