Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(578)

Side by Side Diff: pkg/front_end/lib/src/fasta/parser/parser.dart

Issue 2899043006: cleanup fasta token classes (Closed)
Patch Set: Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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,
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
54 codeYieldAsIdentifier, 54 codeYieldAsIdentifier,
55 codeYieldNotGenerator; 55 codeYieldNotGenerator;
56 56
57 import '../scanner.dart' show ErrorToken, Token; 57 import '../scanner.dart' show ErrorToken, Token;
58 58
59 import '../scanner/recover.dart' show closeBraceFor, skipToEof; 59 import '../scanner/recover.dart' show closeBraceFor, skipToEof;
60 60
61 import '../../scanner/token.dart' 61 import '../../scanner/token.dart'
62 show 62 show
63 ASSIGNMENT_PRECEDENCE, 63 ASSIGNMENT_PRECEDENCE,
64 BeginToken,
64 CASCADE_PRECEDENCE, 65 CASCADE_PRECEDENCE,
65 EQUALITY_PRECEDENCE, 66 EQUALITY_PRECEDENCE,
66 POSTFIX_PRECEDENCE, 67 POSTFIX_PRECEDENCE,
67 RELATIONAL_PRECEDENCE, 68 RELATIONAL_PRECEDENCE,
68 TokenType; 69 TokenType;
69 70
70 import '../scanner/token.dart' 71 import '../scanner/token.dart' show isUserDefinableOperator;
71 show BeginGroupToken, SymbolToken, isUserDefinableOperator;
72 72
73 import '../scanner/token_constants.dart' 73 import '../scanner/token_constants.dart'
74 show 74 show
75 COMMA_TOKEN, 75 COMMA_TOKEN,
76 DOUBLE_TOKEN, 76 DOUBLE_TOKEN,
77 EOF_TOKEN, 77 EOF_TOKEN,
78 EQ_TOKEN, 78 EQ_TOKEN,
79 FUNCTION_TOKEN, 79 FUNCTION_TOKEN,
80 GT_TOKEN, 80 GT_TOKEN,
81 GT_GT_TOKEN, 81 GT_GT_TOKEN,
(...skipping 561 matching lines...) Expand 10 before | Expand all | Expand 10 after
643 listener.beginOptionalFormalParameters(token); 643 listener.beginOptionalFormalParameters(token);
644 if (!optional('(', token)) { 644 if (!optional('(', token)) {
645 if (optional(';', token)) { 645 if (optional(';', token)) {
646 reportRecoverableErrorCode(token, codeExpectedOpenParens); 646 reportRecoverableErrorCode(token, codeExpectedOpenParens);
647 return token; 647 return token;
648 } 648 }
649 return reportUnrecoverableErrorCodeWithString( 649 return reportUnrecoverableErrorCodeWithString(
650 token, codeExpectedButGot, "(") 650 token, codeExpectedButGot, "(")
651 .next; 651 .next;
652 } 652 }
653 BeginGroupToken beginGroupToken = token; 653 BeginToken beginGroupToken = token;
654 Token endToken = beginGroupToken.endGroup; 654 Token endToken = beginGroupToken.endGroup;
655 listener.endFormalParameters(0, token, endToken, kind); 655 listener.endFormalParameters(0, token, endToken, kind);
656 return endToken.next; 656 return endToken.next;
657 } 657 }
658 658
659 /// Parses the formal parameter list of a function. 659 /// Parses the formal parameter list of a function.
660 /// 660 ///
661 /// If `kind == MemberKind.GeneralizedFunctionType`, then names may be 661 /// If `kind == MemberKind.GeneralizedFunctionType`, then names may be
662 /// omitted (except for named arguments). Otherwise, types may be omitted. 662 /// omitted (except for named arguments). Otherwise, types may be omitted.
663 Token parseFormalParameters(Token token, MemberKind kind) { 663 Token parseFormalParameters(Token token, MemberKind kind) {
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
835 bool isValidMethodTypeArguments(Token token) { 835 bool isValidMethodTypeArguments(Token token) {
836 return tryParseMethodTypeArguments(token) != null; 836 return tryParseMethodTypeArguments(token) != null;
837 } 837 }
838 838
839 /// Returns token after match if [token] matches '<' type (',' type)* '>' '(', 839 /// Returns token after match if [token] matches '<' type (',' type)* '>' '(',
840 /// and otherwise returns null. Does not produce listener events. With respect 840 /// and otherwise returns null. Does not produce listener events. With respect
841 /// to the final '(', please see the description of 841 /// to the final '(', please see the description of
842 /// [isValidMethodTypeArguments]. 842 /// [isValidMethodTypeArguments].
843 Token tryParseMethodTypeArguments(Token token) { 843 Token tryParseMethodTypeArguments(Token token) {
844 if (!identical(token.kind, LT_TOKEN)) return null; 844 if (!identical(token.kind, LT_TOKEN)) return null;
845 BeginGroupToken beginToken = token; 845 BeginToken beginToken = token;
846 Token endToken = beginToken.endGroup; 846 Token endToken = beginToken.endGroup;
847 if (endToken == null || !identical(endToken.next.kind, OPEN_PAREN_TOKEN)) { 847 if (endToken == null || !identical(endToken.next.kind, OPEN_PAREN_TOKEN)) {
848 return null; 848 return null;
849 } 849 }
850 token = tryParseType(token.next); 850 token = tryParseType(token.next);
851 while (token != null && identical(token.kind, COMMA_TOKEN)) { 851 while (token != null && identical(token.kind, COMMA_TOKEN)) {
852 token = tryParseType(token.next); 852 token = tryParseType(token.next);
853 } 853 }
854 if (token == null || !identical(token.kind, GT_TOKEN)) return null; 854 if (token == null || !identical(token.kind, GT_TOKEN)) return null;
855 return token.next; 855 return token.next;
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
890 token = tryParseType(token.next); 890 token = tryParseType(token.next);
891 while (token != null && identical(token.kind, COMMA_TOKEN)) { 891 while (token != null && identical(token.kind, COMMA_TOKEN)) {
892 token = tryParseType(token.next); 892 token = tryParseType(token.next);
893 } 893 }
894 if (token == null) return null; 894 if (token == null) return null;
895 if (identical(token.kind, GT_TOKEN)) return token.next; 895 if (identical(token.kind, GT_TOKEN)) return token.next;
896 if (!identical(token.kind, GT_GT_TOKEN)) return null; 896 if (!identical(token.kind, GT_GT_TOKEN)) return null;
897 // [token] is '>>' of which the final '>' that we are parsing is the first 897 // [token] is '>>' of which the final '>' that we are parsing is the first
898 // character. In order to keep the parsing process on track we must return 898 // character. In order to keep the parsing process on track we must return
899 // a synthetic '>' corresponding to the second character of that '>>'. 899 // a synthetic '>' corresponding to the second character of that '>>'.
900 Token syntheticToken = new SymbolToken(TokenType.GT, token.charOffset + 1); 900 Token syntheticToken = new Token(TokenType.GT, token.charOffset + 1);
901 syntheticToken.next = token.next; 901 syntheticToken.next = token.next;
902 return syntheticToken; 902 return syntheticToken;
903 } 903 }
904 904
905 Token parseQualified(Token token, IdentifierContext context, 905 Token parseQualified(Token token, IdentifierContext context,
906 IdentifierContext continuationContext) { 906 IdentifierContext continuationContext) {
907 token = parseIdentifier(token, context); 907 token = parseIdentifier(token, context);
908 while (optional('.', token)) { 908 while (optional('.', token)) {
909 token = parseQualifiedRest(token, continuationContext); 909 token = parseQualifiedRest(token, continuationContext);
910 } 910 }
(...skipping 14 matching lines...) Expand all
925 Token period = token; 925 Token period = token;
926 token = parseIdentifier(token.next, context); 926 token = parseIdentifier(token.next, context);
927 listener.handleQualified(period); 927 listener.handleQualified(period);
928 return token; 928 return token;
929 } 929 }
930 930
931 Token skipBlock(Token token) { 931 Token skipBlock(Token token) {
932 if (!optional('{', token)) { 932 if (!optional('{', token)) {
933 return reportUnrecoverableErrorCode(token, codeExpectedBlockToSkip).next; 933 return reportUnrecoverableErrorCode(token, codeExpectedBlockToSkip).next;
934 } 934 }
935 BeginGroupToken beginGroupToken = token; 935 BeginToken beginGroupToken = token;
936 Token endGroup = beginGroupToken.endGroup; 936 Token endGroup = beginGroupToken.endGroup;
937 if (endGroup == null || !identical(endGroup.kind, $CLOSE_CURLY_BRACKET)) { 937 if (endGroup == null || !identical(endGroup.kind, $CLOSE_CURLY_BRACKET)) {
938 return reportUnmatchedToken(beginGroupToken).next; 938 return reportUnmatchedToken(beginGroupToken).next;
939 } 939 }
940 return beginGroupToken.endGroup; 940 return beginGroupToken.endGroup;
941 } 941 }
942 942
943 Token parseEnum(Token token) { 943 Token parseEnum(Token token) {
944 listener.beginEnum(token); 944 listener.beginEnum(token);
945 Token enumKeyword = token; 945 Token enumKeyword = token;
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after
1212 if (optional('<', token)) { 1212 if (optional('<', token)) {
1213 Token begin = token; 1213 Token begin = token;
1214 beginStuff(begin); 1214 beginStuff(begin);
1215 int count = 0; 1215 int count = 0;
1216 do { 1216 do {
1217 token = stuffParser(token.next); 1217 token = stuffParser(token.next);
1218 ++count; 1218 ++count;
1219 } while (optional(',', token)); 1219 } while (optional(',', token));
1220 Token next = token.next; 1220 Token next = token.next;
1221 if (identical(token.stringValue, '>>')) { 1221 if (identical(token.stringValue, '>>')) {
1222 token = new SymbolToken(TokenType.GT, token.charOffset); 1222 token = new Token(TokenType.GT, token.charOffset);
1223 token.next = new SymbolToken(TokenType.GT, token.charOffset + 1); 1223 token.next = new Token(TokenType.GT, token.charOffset + 1);
1224 token.next.next = next; 1224 token.next.next = next;
1225 } 1225 }
1226 endStuff(count, begin, token); 1226 endStuff(count, begin, token);
1227 return expect('>', token); 1227 return expect('>', token);
1228 } 1228 }
1229 handleNoStuff(token); 1229 handleNoStuff(token);
1230 return token; 1230 return token;
1231 } 1231 }
1232 1232
1233 Token parseTopLevelMember(Token token) { 1233 Token parseTopLevelMember(Token token) {
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after
1458 Token type = token; 1458 Token type = token;
1459 // type ... 1459 // type ...
1460 if (optional('.', token.next)) { 1460 if (optional('.', token.next)) {
1461 // type '.' ... 1461 // type '.' ...
1462 if (token.next.next.isIdentifier) { 1462 if (token.next.next.isIdentifier) {
1463 // type '.' identifier 1463 // type '.' identifier
1464 token = token.next.next; 1464 token = token.next.next;
1465 } 1465 }
1466 } 1466 }
1467 if (optional('<', token.next)) { 1467 if (optional('<', token.next)) {
1468 if (token.next is BeginGroupToken) { 1468 if (token.next is BeginToken) {
1469 BeginGroupToken beginGroup = token.next; 1469 BeginToken beginGroup = token.next;
1470 if (beginGroup.endGroup == null) { 1470 if (beginGroup.endGroup == null) {
1471 token = reportUnmatchedToken(beginGroup).next; 1471 token = reportUnmatchedToken(beginGroup).next;
1472 } else { 1472 } else {
1473 token = beginGroup.endGroup; 1473 token = beginGroup.endGroup;
1474 } 1474 }
1475 } 1475 }
1476 } 1476 }
1477 // If the next token after a type has a type substitution comment 1477 // If the next token after a type has a type substitution comment
1478 // /*=T*/, then the previous type tokens and the reference to them 1478 // /*=T*/, then the previous type tokens and the reference to them
1479 // from the link should be replaced. 1479 // from the link should be replaced.
1480 { 1480 {
1481 Token newType = listener.replaceTokenWithGenericCommentTypeAssign( 1481 Token newType = listener.replaceTokenWithGenericCommentTypeAssign(
1482 type, token.next); 1482 type, token.next);
1483 if (!identical(newType, type)) { 1483 if (!identical(newType, type)) {
1484 identifiers = identifiers.tail; 1484 identifiers = identifiers.tail;
1485 token = newType; 1485 token = newType;
1486 continue; 1486 continue;
1487 } 1487 }
1488 } 1488 }
1489 } 1489 }
1490 token = token.next; 1490 token = token.next;
1491 } 1491 }
1492 while (isGeneralizedFunctionType(token)) { 1492 while (isGeneralizedFunctionType(token)) {
1493 token = token.next; 1493 token = token.next;
1494 if (optional('<', token)) { 1494 if (optional('<', token)) {
1495 if (token is BeginGroupToken) { 1495 if (token is BeginToken) {
1496 BeginGroupToken beginGroup = token; 1496 BeginToken beginGroup = token;
1497 if (beginGroup.endGroup == null) { 1497 if (beginGroup.endGroup == null) {
1498 token = reportUnmatchedToken(beginGroup).next; 1498 token = reportUnmatchedToken(beginGroup).next;
1499 } else { 1499 } else {
1500 token = beginGroup.endGroup.next; 1500 token = beginGroup.endGroup.next;
1501 } 1501 }
1502 } 1502 }
1503 } 1503 }
1504 if (!optional('(', token)) { 1504 if (!optional('(', token)) {
1505 if (optional(';', token)) { 1505 if (optional(';', token)) {
1506 reportRecoverableErrorCode(token, codeExpectedOpenParens); 1506 reportRecoverableErrorCode(token, codeExpectedOpenParens);
1507 } 1507 }
1508 token = expect("(", token); 1508 token = expect("(", token);
1509 } 1509 }
1510 if (token is BeginGroupToken) { 1510 if (token is BeginToken) {
1511 BeginGroupToken beginGroup = token; 1511 BeginToken beginGroup = token;
1512 if (beginGroup.endGroup == null) { 1512 if (beginGroup.endGroup == null) {
1513 token = reportUnmatchedToken(beginGroup).next; 1513 token = reportUnmatchedToken(beginGroup).next;
1514 } else { 1514 } else {
1515 token = beginGroup.endGroup.next; 1515 token = beginGroup.endGroup.next;
1516 } 1516 }
1517 } 1517 }
1518 } 1518 }
1519 } 1519 }
1520 return listener.handleMemberName(const Link<Token>()); 1520 return listener.handleMemberName(const Link<Token>());
1521 } 1521 }
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after
1765 if (identical(peek.kind, PERIOD_TOKEN)) { 1765 if (identical(peek.kind, PERIOD_TOKEN)) {
1766 if (peek.next.isIdentifier) { 1766 if (peek.next.isIdentifier) {
1767 // Look past a library prefix. 1767 // Look past a library prefix.
1768 peek = peek.next.next; 1768 peek = peek.next.next;
1769 } 1769 }
1770 } 1770 }
1771 // We are looking at "qualified ...". 1771 // We are looking at "qualified ...".
1772 if (identical(peek.kind, LT_TOKEN)) { 1772 if (identical(peek.kind, LT_TOKEN)) {
1773 // Possibly generic type. 1773 // Possibly generic type.
1774 // We are looking at "qualified '<'". 1774 // We are looking at "qualified '<'".
1775 BeginGroupToken beginGroupToken = peek; 1775 BeginToken beginGroupToken = peek;
1776 Token gtToken = beginGroupToken.endGroup; 1776 Token gtToken = beginGroupToken.endGroup;
1777 if (gtToken != null) { 1777 if (gtToken != null) {
1778 // We are looking at "qualified '<' ... '>' ...". 1778 // We are looking at "qualified '<' ... '>' ...".
1779 peek = gtToken.next; 1779 peek = gtToken.next;
1780 } 1780 }
1781 } 1781 }
1782 return peek; 1782 return peek;
1783 } 1783 }
1784 1784
1785 /// Returns the first token after the function type starting at [token]. 1785 /// Returns the first token after the function type starting at [token].
(...skipping 14 matching lines...) Expand all
1800 /// pointed to the first `(`, then the returned token points to the second 1800 /// pointed to the first `(`, then the returned token points to the second
1801 /// `Function` token. 1801 /// `Function` token.
1802 Token peekAfterFunctionType(Token token) { 1802 Token peekAfterFunctionType(Token token) {
1803 // Possible inputs are: 1803 // Possible inputs are:
1804 // ( ... ) 1804 // ( ... )
1805 // < ... >( ... ) 1805 // < ... >( ... )
1806 1806
1807 Token peek = token; 1807 Token peek = token;
1808 // If there is a generic argument to the function, skip over that one first. 1808 // If there is a generic argument to the function, skip over that one first.
1809 if (identical(peek.kind, LT_TOKEN)) { 1809 if (identical(peek.kind, LT_TOKEN)) {
1810 BeginGroupToken beginGroupToken = peek; 1810 BeginToken beginGroupToken = peek;
1811 Token closeToken = beginGroupToken.endGroup; 1811 Token closeToken = beginGroupToken.endGroup;
1812 if (closeToken != null) { 1812 if (closeToken != null) {
1813 peek = closeToken.next; 1813 peek = closeToken.next;
1814 } 1814 }
1815 } 1815 }
1816 1816
1817 // Now we just need to skip over the formals. 1817 // Now we just need to skip over the formals.
1818 expect('(', peek); 1818 expect('(', peek);
1819 1819
1820 BeginGroupToken beginGroupToken = peek; 1820 BeginToken beginGroupToken = peek;
1821 Token closeToken = beginGroupToken.endGroup; 1821 Token closeToken = beginGroupToken.endGroup;
1822 if (closeToken != null) { 1822 if (closeToken != null) {
1823 peek = closeToken.next; 1823 peek = closeToken.next;
1824 } 1824 }
1825 1825
1826 return peek; 1826 return peek;
1827 } 1827 }
1828 1828
1829 /// If [token] is the start of a type, returns the token after that type. 1829 /// If [token] is the start of a type, returns the token after that type.
1830 /// If [token] is not the start of a type, null is returned. 1830 /// If [token] is not the start of a type, null is returned.
1831 Token peekAfterIfType(Token token) { 1831 Token peekAfterIfType(Token token) {
1832 if (!optional('void', token) && !token.isIdentifier) { 1832 if (!optional('void', token) && !token.isIdentifier) {
1833 return null; 1833 return null;
1834 } 1834 }
1835 return peekAfterType(token); 1835 return peekAfterType(token);
1836 } 1836 }
1837 1837
1838 Token skipClassBody(Token token) { 1838 Token skipClassBody(Token token) {
1839 if (!optional('{', token)) { 1839 if (!optional('{', token)) {
1840 return reportUnrecoverableErrorCodeWithToken( 1840 return reportUnrecoverableErrorCodeWithToken(
1841 token, codeExpectedClassBodyToSkip) 1841 token, codeExpectedClassBodyToSkip)
1842 .next; 1842 .next;
1843 } 1843 }
1844 BeginGroupToken beginGroupToken = token; 1844 BeginToken beginGroupToken = token;
1845 Token endGroup = beginGroupToken.endGroup; 1845 Token endGroup = beginGroupToken.endGroup;
1846 if (endGroup == null || !identical(endGroup.kind, $CLOSE_CURLY_BRACKET)) { 1846 if (endGroup == null || !identical(endGroup.kind, $CLOSE_CURLY_BRACKET)) {
1847 return reportUnmatchedToken(beginGroupToken).next; 1847 return reportUnmatchedToken(beginGroupToken).next;
1848 } 1848 }
1849 return endGroup; 1849 return endGroup;
1850 } 1850 }
1851 1851
1852 Token parseClassBody(Token token) { 1852 Token parseClassBody(Token token) {
1853 Token begin = token; 1853 Token begin = token;
1854 listener.beginClassBody(token); 1854 listener.beginClassBody(token);
(...skipping 638 matching lines...) Expand 10 before | Expand all | Expand 10 after
2493 2493
2494 Token afterId = identifier.next; 2494 Token afterId = identifier.next;
2495 int afterIdKind = afterId.kind; 2495 int afterIdKind = afterId.kind;
2496 if (identical(afterIdKind, EQ_TOKEN) || 2496 if (identical(afterIdKind, EQ_TOKEN) ||
2497 identical(afterIdKind, SEMICOLON_TOKEN) || 2497 identical(afterIdKind, SEMICOLON_TOKEN) ||
2498 identical(afterIdKind, COMMA_TOKEN)) { 2498 identical(afterIdKind, COMMA_TOKEN)) {
2499 // We are looking at "type identifier" followed by '=', ';', ','. 2499 // We are looking at "type identifier" followed by '=', ';', ','.
2500 return parseVariablesDeclaration(token); 2500 return parseVariablesDeclaration(token);
2501 } else if (identical(afterIdKind, OPEN_PAREN_TOKEN)) { 2501 } else if (identical(afterIdKind, OPEN_PAREN_TOKEN)) {
2502 // We are looking at "type identifier '('". 2502 // We are looking at "type identifier '('".
2503 BeginGroupToken beginParen = afterId; 2503 BeginToken beginParen = afterId;
2504 Token endParen = beginParen.endGroup; 2504 Token endParen = beginParen.endGroup;
2505 // TODO(eernst): Check for NPE as described in issue 26252. 2505 // TODO(eernst): Check for NPE as described in issue 26252.
2506 Token afterParens = endParen.next; 2506 Token afterParens = endParen.next;
2507 if (optional('{', afterParens) || 2507 if (optional('{', afterParens) ||
2508 optional('=>', afterParens) || 2508 optional('=>', afterParens) ||
2509 optional('async', afterParens) || 2509 optional('async', afterParens) ||
2510 optional('sync', afterParens)) { 2510 optional('sync', afterParens)) {
2511 // We are looking at "type identifier '(' ... ')'" followed 2511 // We are looking at "type identifier '(' ... ')'" followed
2512 // by '{', '=>', 'async', or 'sync'. 2512 // by '{', '=>', 'async', or 'sync'.
2513 return parseFunctionDeclaration(token); 2513 return parseFunctionDeclaration(token);
2514 } 2514 }
2515 } else if (identical(afterIdKind, LT_TOKEN)) { 2515 } else if (identical(afterIdKind, LT_TOKEN)) {
2516 // We are looking at "type identifier '<'". 2516 // We are looking at "type identifier '<'".
2517 BeginGroupToken beginAngle = afterId; 2517 BeginToken beginAngle = afterId;
2518 Token endAngle = beginAngle.endGroup; 2518 Token endAngle = beginAngle.endGroup;
2519 if (endAngle != null && 2519 if (endAngle != null &&
2520 identical(endAngle.next.kind, OPEN_PAREN_TOKEN)) { 2520 identical(endAngle.next.kind, OPEN_PAREN_TOKEN)) {
2521 BeginGroupToken beginParen = endAngle.next; 2521 BeginToken beginParen = endAngle.next;
2522 Token endParen = beginParen.endGroup; 2522 Token endParen = beginParen.endGroup;
2523 if (endParen != null) { 2523 if (endParen != null) {
2524 Token afterParens = endParen.next; 2524 Token afterParens = endParen.next;
2525 if (optional('{', afterParens) || 2525 if (optional('{', afterParens) ||
2526 optional('=>', afterParens) || 2526 optional('=>', afterParens) ||
2527 optional('async', afterParens) || 2527 optional('async', afterParens) ||
2528 optional('sync', afterParens)) { 2528 optional('sync', afterParens)) {
2529 // We are looking at "type identifier '<' ... '>' '(' ... ')'" 2529 // We are looking at "type identifier '<' ... '>' '(' ... ')'"
2530 // followed by '{', '=>', 'async', or 'sync'. 2530 // followed by '{', '=>', 'async', or 'sync'.
2531 return parseFunctionDeclaration(token); 2531 return parseFunctionDeclaration(token);
2532 } 2532 }
2533 } 2533 }
2534 } 2534 }
2535 } 2535 }
2536 // Fall-through to expression statement. 2536 // Fall-through to expression statement.
2537 } else { 2537 } else {
2538 if (optional(':', token.next)) { 2538 if (optional(':', token.next)) {
2539 return parseLabeledStatement(token); 2539 return parseLabeledStatement(token);
2540 } else if (optional('(', token.next)) { 2540 } else if (optional('(', token.next)) {
2541 BeginGroupToken begin = token.next; 2541 BeginToken begin = token.next;
2542 // TODO(eernst): Check for NPE as described in issue 26252. 2542 // TODO(eernst): Check for NPE as described in issue 26252.
2543 String afterParens = begin.endGroup.next.stringValue; 2543 String afterParens = begin.endGroup.next.stringValue;
2544 if (identical(afterParens, '{') || 2544 if (identical(afterParens, '{') ||
2545 identical(afterParens, '=>') || 2545 identical(afterParens, '=>') ||
2546 identical(afterParens, 'async') || 2546 identical(afterParens, 'async') ||
2547 identical(afterParens, 'sync')) { 2547 identical(afterParens, 'sync')) {
2548 return parseFunctionDeclaration(token); 2548 return parseFunctionDeclaration(token);
2549 } 2549 }
2550 } else if (optional('<', token.next)) { 2550 } else if (optional('<', token.next)) {
2551 BeginGroupToken beginAngle = token.next; 2551 BeginToken beginAngle = token.next;
2552 Token endAngle = beginAngle.endGroup; 2552 Token endAngle = beginAngle.endGroup;
2553 if (endAngle != null && 2553 if (endAngle != null &&
2554 identical(endAngle.next.kind, OPEN_PAREN_TOKEN)) { 2554 identical(endAngle.next.kind, OPEN_PAREN_TOKEN)) {
2555 BeginGroupToken beginParen = endAngle.next; 2555 BeginToken beginParen = endAngle.next;
2556 Token endParen = beginParen.endGroup; 2556 Token endParen = beginParen.endGroup;
2557 if (endParen != null) { 2557 if (endParen != null) {
2558 String afterParens = endParen.next.stringValue; 2558 String afterParens = endParen.next.stringValue;
2559 if (identical(afterParens, '{') || 2559 if (identical(afterParens, '{') ||
2560 identical(afterParens, '=>') || 2560 identical(afterParens, '=>') ||
2561 identical(afterParens, 'async') || 2561 identical(afterParens, 'async') ||
2562 identical(afterParens, 'sync')) { 2562 identical(afterParens, 'sync')) {
2563 return parseFunctionDeclaration(token); 2563 return parseFunctionDeclaration(token);
2564 } 2564 }
2565 } 2565 }
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
2642 token = token.next; 2642 token = token.next;
2643 nextValue = token.next.stringValue; 2643 nextValue = token.next.stringValue;
2644 } 2644 }
2645 if (identical(nextValue, '{')) { 2645 if (identical(nextValue, '{')) {
2646 // Handle cases like this: 2646 // Handle cases like this:
2647 // class Foo { 2647 // class Foo {
2648 // var map; 2648 // var map;
2649 // Foo() : map = {}; 2649 // Foo() : map = {};
2650 // Foo.x() : map = true ? {} : {}; 2650 // Foo.x() : map = true ? {} : {};
2651 // } 2651 // }
2652 BeginGroupToken begin = token.next; 2652 BeginToken begin = token.next;
2653 token = (begin.endGroup != null) ? begin.endGroup : token; 2653 token = (begin.endGroup != null) ? begin.endGroup : token;
2654 token = token.next; 2654 token = token.next;
2655 continue; 2655 continue;
2656 } 2656 }
2657 if (identical(nextValue, '<')) { 2657 if (identical(nextValue, '<')) {
2658 // Handle cases like this: 2658 // Handle cases like this:
2659 // class Foo { 2659 // class Foo {
2660 // var map; 2660 // var map;
2661 // Foo() : map = <String, Foo>{}; 2661 // Foo() : map = <String, Foo>{};
2662 // Foo.x() : map = true ? <String, Foo>{} : <String, Foo>{}; 2662 // Foo.x() : map = true ? <String, Foo>{} : <String, Foo>{};
2663 // } 2663 // }
2664 BeginGroupToken begin = token.next; 2664 BeginToken begin = token.next;
2665 token = (begin.endGroup != null) ? begin.endGroup : token; 2665 token = (begin.endGroup != null) ? begin.endGroup : token;
2666 token = token.next; 2666 token = token.next;
2667 if (identical(token.stringValue, '{')) { 2667 if (identical(token.stringValue, '{')) {
2668 begin = token; 2668 begin = token;
2669 token = (begin.endGroup != null) ? begin.endGroup : token; 2669 token = (begin.endGroup != null) ? begin.endGroup : token;
2670 token = token.next; 2670 token = token.next;
2671 } 2671 }
2672 continue; 2672 continue;
2673 } 2673 }
2674 } 2674 }
2675 if (!mayParseFunctionExpressions && identical(value, '{')) { 2675 if (!mayParseFunctionExpressions && identical(value, '{')) {
2676 break; 2676 break;
2677 } 2677 }
2678 if (token is BeginGroupToken) { 2678 if (token is BeginToken) {
2679 BeginGroupToken begin = token; 2679 BeginToken begin = token;
2680 token = (begin.endGroup != null) ? begin.endGroup : token; 2680 token = (begin.endGroup != null) ? begin.endGroup : token;
2681 } else if (token is ErrorToken) { 2681 } else if (token is ErrorToken) {
2682 reportErrorToken(token, false).next; 2682 reportErrorToken(token, false).next;
2683 } 2683 }
2684 token = token.next; 2684 token = token.next;
2685 } 2685 }
2686 return token; 2686 return token;
2687 } 2687 }
2688 2688
2689 Token parseRecoverExpression(Token token) => parseExpression(token); 2689 Token parseRecoverExpression(Token token) => parseExpression(token);
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after
2936 } 2936 }
2937 2937
2938 Token expressionExpected(Token token) { 2938 Token expressionExpected(Token token) {
2939 token = reportUnrecoverableErrorCodeWithToken(token, codeExpectedExpression) 2939 token = reportUnrecoverableErrorCodeWithToken(token, codeExpectedExpression)
2940 .next; 2940 .next;
2941 listener.handleInvalidExpression(token); 2941 listener.handleInvalidExpression(token);
2942 return token; 2942 return token;
2943 } 2943 }
2944 2944
2945 Token parseParenthesizedExpressionOrFunctionLiteral(Token token) { 2945 Token parseParenthesizedExpressionOrFunctionLiteral(Token token) {
2946 BeginGroupToken beginGroup = token; 2946 BeginToken beginGroup = token;
2947 // TODO(eernst): Check for NPE as described in issue 26252. 2947 // TODO(eernst): Check for NPE as described in issue 26252.
2948 Token nextToken = beginGroup.endGroup.next; 2948 Token nextToken = beginGroup.endGroup.next;
2949 int kind = nextToken.kind; 2949 int kind = nextToken.kind;
2950 if (mayParseFunctionExpressions && 2950 if (mayParseFunctionExpressions &&
2951 (identical(kind, FUNCTION_TOKEN) || 2951 (identical(kind, FUNCTION_TOKEN) ||
2952 identical(kind, OPEN_CURLY_BRACKET_TOKEN) || 2952 identical(kind, OPEN_CURLY_BRACKET_TOKEN) ||
2953 (identical(kind, KEYWORD_TOKEN) && 2953 (identical(kind, KEYWORD_TOKEN) &&
2954 (optional('async', nextToken) || 2954 (optional('async', nextToken) ||
2955 optional('sync', nextToken))))) { 2955 optional('sync', nextToken))))) {
2956 listener.handleNoTypeVariables(token); 2956 listener.handleNoTypeVariables(token);
2957 return parseUnnamedFunction(token); 2957 return parseUnnamedFunction(token);
2958 } else { 2958 } else {
2959 bool old = mayParseFunctionExpressions; 2959 bool old = mayParseFunctionExpressions;
2960 mayParseFunctionExpressions = true; 2960 mayParseFunctionExpressions = true;
2961 token = parseParenthesizedExpression(token); 2961 token = parseParenthesizedExpression(token);
2962 mayParseFunctionExpressions = old; 2962 mayParseFunctionExpressions = old;
2963 return token; 2963 return token;
2964 } 2964 }
2965 } 2965 }
2966 2966
2967 Token parseParenthesizedExpression(Token token) { 2967 Token parseParenthesizedExpression(Token token) {
2968 // We expect [begin] to be of type [BeginGroupToken], but we don't know for 2968 // We expect [begin] to be of type [BeginToken], but we don't know for
2969 // sure until after calling expect. 2969 // sure until after calling expect.
2970 dynamic begin = token; 2970 dynamic begin = token;
2971 token = expect('(', token); 2971 token = expect('(', token);
2972 // [begin] is now known to have type [BeginGroupToken]. 2972 // [begin] is now known to have type [BeginToken].
2973 token = parseExpression(token); 2973 token = parseExpression(token);
2974 if (!identical(begin.endGroup, token)) { 2974 if (!identical(begin.endGroup, token)) {
2975 reportUnexpectedToken(token).next; 2975 reportUnexpectedToken(token).next;
2976 token = begin.endGroup; 2976 token = begin.endGroup;
2977 } 2977 }
2978 listener.handleParenthesizedExpression(begin); 2978 listener.handleParenthesizedExpression(begin);
2979 return expect(')', token); 2979 return expect(')', token);
2980 } 2980 }
2981 2981
2982 Token parseThisExpression(Token token, IdentifierContext context) { 2982 Token parseThisExpression(Token token, IdentifierContext context) {
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
3057 listener.handleLiteralMap(count, beginToken, constKeyword, token); 3057 listener.handleLiteralMap(count, beginToken, constKeyword, token);
3058 return expect('}', token); 3058 return expect('}', token);
3059 } 3059 }
3060 3060
3061 /// formalParameterList functionBody. 3061 /// formalParameterList functionBody.
3062 /// 3062 ///
3063 /// This is a suffix parser because it is assumed that type arguments have 3063 /// This is a suffix parser because it is assumed that type arguments have
3064 /// been parsed, or `listener.handleNoTypeArguments(..)` has been executed. 3064 /// been parsed, or `listener.handleNoTypeArguments(..)` has been executed.
3065 Token parseLiteralFunctionSuffix(Token token) { 3065 Token parseLiteralFunctionSuffix(Token token) {
3066 assert(optional('(', token)); 3066 assert(optional('(', token));
3067 BeginGroupToken beginGroup = token; 3067 BeginToken beginGroup = token;
3068 if (beginGroup.endGroup != null) { 3068 if (beginGroup.endGroup != null) {
3069 Token nextToken = beginGroup.endGroup.next; 3069 Token nextToken = beginGroup.endGroup.next;
3070 int kind = nextToken.kind; 3070 int kind = nextToken.kind;
3071 if (identical(kind, FUNCTION_TOKEN) || 3071 if (identical(kind, FUNCTION_TOKEN) ||
3072 identical(kind, OPEN_CURLY_BRACKET_TOKEN) || 3072 identical(kind, OPEN_CURLY_BRACKET_TOKEN) ||
3073 (identical(kind, KEYWORD_TOKEN) && 3073 (identical(kind, KEYWORD_TOKEN) &&
3074 (optional('async', nextToken) || optional('sync', nextToken)))) { 3074 (optional('async', nextToken) || optional('sync', nextToken)))) {
3075 return parseUnnamedFunction(token); 3075 return parseUnnamedFunction(token);
3076 } 3076 }
3077 // Fall through. 3077 // Fall through.
3078 } 3078 }
3079 return reportUnexpectedToken(token).next; 3079 return reportUnexpectedToken(token).next;
3080 } 3080 }
3081 3081
3082 /// genericListLiteral | genericMapLiteral | genericFunctionLiteral. 3082 /// genericListLiteral | genericMapLiteral | genericFunctionLiteral.
3083 /// 3083 ///
3084 /// Where 3084 /// Where
3085 /// genericListLiteral ::= typeArguments '[' (expressionList ','?)? ']' 3085 /// genericListLiteral ::= typeArguments '[' (expressionList ','?)? ']'
3086 /// genericMapLiteral ::= 3086 /// genericMapLiteral ::=
3087 /// typeArguments '{' (mapLiteralEntry (',' mapLiteralEntry)* ','?)? '}' 3087 /// typeArguments '{' (mapLiteralEntry (',' mapLiteralEntry)* ','?)? '}'
3088 /// genericFunctionLiteral ::= 3088 /// genericFunctionLiteral ::=
3089 /// typeParameters formalParameterList functionBody 3089 /// typeParameters formalParameterList functionBody
3090 /// Provide token for [constKeyword] if preceded by 'const', null if not. 3090 /// Provide token for [constKeyword] if preceded by 'const', null if not.
3091 Token parseLiteralListOrMapOrFunction(Token token, Token constKeyword) { 3091 Token parseLiteralListOrMapOrFunction(Token token, Token constKeyword) {
3092 assert(optional('<', token)); 3092 assert(optional('<', token));
3093 BeginGroupToken begin = token; 3093 BeginToken begin = token;
3094 if (constKeyword == null && 3094 if (constKeyword == null &&
3095 begin.endGroup != null && 3095 begin.endGroup != null &&
3096 identical(begin.endGroup.next.kind, OPEN_PAREN_TOKEN)) { 3096 identical(begin.endGroup.next.kind, OPEN_PAREN_TOKEN)) {
3097 token = parseTypeVariablesOpt(token); 3097 token = parseTypeVariablesOpt(token);
3098 return parseLiteralFunctionSuffix(token); 3098 return parseLiteralFunctionSuffix(token);
3099 } else { 3099 } else {
3100 token = parseTypeArgumentsOpt(token); 3100 token = parseTypeArgumentsOpt(token);
3101 if (optional('{', token)) { 3101 if (optional('{', token)) {
3102 return parseLiteralMapSuffix(token, constKeyword); 3102 return parseLiteralMapSuffix(token, constKeyword);
3103 } else if ((optional('[', token)) || (optional('[]', token))) { 3103 } else if ((optional('[', token)) || (optional('[]', token))) {
(...skipping 25 matching lines...) Expand all
3129 return parseFunctionExpression(token); 3129 return parseFunctionExpression(token);
3130 } else if (isFunctionDeclaration(token.next)) { 3130 } else if (isFunctionDeclaration(token.next)) {
3131 return parseFunctionExpression(token); 3131 return parseFunctionExpression(token);
3132 } else { 3132 } else {
3133 return parseSend(token, context); 3133 return parseSend(token, context);
3134 } 3134 }
3135 } 3135 }
3136 3136
3137 bool isFunctionDeclaration(Token token) { 3137 bool isFunctionDeclaration(Token token) {
3138 if (optional('<', token)) { 3138 if (optional('<', token)) {
3139 BeginGroupToken begin = token; 3139 BeginToken begin = token;
3140 if (begin.endGroup == null) return false; 3140 if (begin.endGroup == null) return false;
3141 token = begin.endGroup.next; 3141 token = begin.endGroup.next;
3142 } 3142 }
3143 if (optional('(', token)) { 3143 if (optional('(', token)) {
3144 BeginGroupToken begin = token; 3144 BeginToken begin = token;
3145 // TODO(eernst): Check for NPE as described in issue 26252. 3145 // TODO(eernst): Check for NPE as described in issue 26252.
3146 String afterParens = begin.endGroup.next.stringValue; 3146 String afterParens = begin.endGroup.next.stringValue;
3147 if (identical(afterParens, '{') || 3147 if (identical(afterParens, '{') ||
3148 identical(afterParens, '=>') || 3148 identical(afterParens, '=>') ||
3149 identical(afterParens, 'async') || 3149 identical(afterParens, 'async') ||
3150 identical(afterParens, 'sync')) { 3150 identical(afterParens, 'sync')) {
3151 return true; 3151 return true;
3152 } 3152 }
3153 } 3153 }
3154 return false; 3154 return false;
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
3307 listener.handleNoTypeArguments(token); 3307 listener.handleNoTypeArguments(token);
3308 } 3308 }
3309 token = parseArgumentsOpt(token); 3309 token = parseArgumentsOpt(token);
3310 listener.endSend(beginToken, token); 3310 listener.endSend(beginToken, token);
3311 return token; 3311 return token;
3312 } 3312 }
3313 3313
3314 Token skipArgumentsOpt(Token token) { 3314 Token skipArgumentsOpt(Token token) {
3315 listener.handleNoArguments(token); 3315 listener.handleNoArguments(token);
3316 if (optional('(', token)) { 3316 if (optional('(', token)) {
3317 BeginGroupToken begin = token; 3317 BeginToken begin = token;
3318 return begin.endGroup.next; 3318 return begin.endGroup.next;
3319 } else { 3319 } else {
3320 return token; 3320 return token;
3321 } 3321 }
3322 } 3322 }
3323 3323
3324 Token parseArgumentsOpt(Token token) { 3324 Token parseArgumentsOpt(Token token) {
3325 if (!optional('(', token)) { 3325 if (!optional('(', token)) {
3326 listener.handleNoArguments(token); 3326 listener.handleNoArguments(token);
3327 return token; 3327 return token;
(...skipping 534 matching lines...) Expand 10 before | Expand all | Expand 10 after
3862 } 3862 }
3863 if (isRecoverable) { 3863 if (isRecoverable) {
3864 listener.handleRecoverableError(token, message); 3864 listener.handleRecoverableError(token, message);
3865 return null; 3865 return null;
3866 } else { 3866 } else {
3867 Token next = listener.handleUnrecoverableError(token, message); 3867 Token next = listener.handleUnrecoverableError(token, message);
3868 return next ?? skipToEof(token); 3868 return next ?? skipToEof(token);
3869 } 3869 }
3870 } 3870 }
3871 3871
3872 Token reportUnmatchedToken(BeginGroupToken token) { 3872 Token reportUnmatchedToken(BeginToken token) {
3873 return reportUnrecoverableError( 3873 return reportUnrecoverableError(
3874 token, 3874 token,
3875 () => codeUnmatchedToken.format( 3875 () => codeUnmatchedToken.format(
3876 uri, token.charOffset, closeBraceFor(token.lexeme), token)); 3876 uri, token.charOffset, closeBraceFor(token.lexeme), token));
3877 } 3877 }
3878 3878
3879 Token reportUnexpectedToken(Token token) { 3879 Token reportUnexpectedToken(Token token) {
3880 return reportUnrecoverableError( 3880 return reportUnrecoverableError(
3881 token, () => codeUnexpectedToken.format(uri, token.charOffset, token)); 3881 token, () => codeUnexpectedToken.format(uri, token.charOffset, token));
3882 } 3882 }
(...skipping 24 matching lines...) Expand all
3907 return reportUnrecoverableError( 3907 return reportUnrecoverableError(
3908 token, () => code.format(uri, token.charOffset, string)); 3908 token, () => code.format(uri, token.charOffset, string));
3909 } 3909 }
3910 } 3910 }
3911 3911
3912 typedef FastaMessage NoArgument(Uri uri, int charOffset); 3912 typedef FastaMessage NoArgument(Uri uri, int charOffset);
3913 3913
3914 typedef FastaMessage TokenArgument(Uri uri, int charOffset, Token token); 3914 typedef FastaMessage TokenArgument(Uri uri, int charOffset, Token token);
3915 3915
3916 typedef FastaMessage StringArgument(Uri uri, int charOffset, String string); 3916 typedef FastaMessage StringArgument(Uri uri, int charOffset, String string);
OLDNEW
« no previous file with comments | « pkg/front_end/lib/src/fasta/parser/listener.dart ('k') | pkg/front_end/lib/src/fasta/parser/token_stream_rewriter.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698