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

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

Issue 2965393002: Use FastaMessage instead of String. Part 1. (Closed)
Patch Set: Add type variable to Code. Created 3 years, 5 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' show FastaCode, FastaMessage; 7 import '../fasta_codes.dart' show Code, Message, Template;
8 8
9 import '../fasta_codes.dart' as fasta; 9 import '../fasta_codes.dart' as fasta;
10 10
11 import '../scanner.dart' show ErrorToken, Token; 11 import '../scanner.dart' show ErrorToken, Token;
12 12
13 import '../scanner/recover.dart' show closeBraceFor, skipToEof; 13 import '../scanner/recover.dart' show closeBraceFor, skipToEof;
14 14
15 import '../../scanner/token.dart' 15 import '../../scanner/token.dart'
16 show 16 show
17 ASSIGNMENT_PRECEDENCE, 17 ASSIGNMENT_PRECEDENCE,
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after
271 /// 271 ///
272 /// Both dart2js and the Dart VM have used the `native` keyword to mark methods 272 /// Both dart2js and the Dart VM have used the `native` keyword to mark methods
273 /// that couldn't be implemented in the Dart language and needed to be 273 /// that couldn't be implemented in the Dart language and needed to be
274 /// implemented in JavaScript or C++, respectively. An example of the syntax 274 /// implemented in JavaScript or C++, respectively. An example of the syntax
275 /// extension used by the Dart VM is: 275 /// extension used by the Dart VM is:
276 /// 276 ///
277 /// nativeFunction() native "NativeFunction"; 277 /// nativeFunction() native "NativeFunction";
278 /// 278 ///
279 /// When attempting to parse this function, the parser eventually calls 279 /// When attempting to parse this function, the parser eventually calls
280 /// [parseFunctionBody]. This method will report an unrecoverable error to the 280 /// [parseFunctionBody]. This method will report an unrecoverable error to the
281 /// listener with the code [fasta.codeExpectedFunctionBody]. The listener can 281 /// listener with the code [fasta.messageExpectedFunctionBody]. The listener can
282 /// then look at the error code and the token and use the methods in 282 /// then look at the error code and the token and use the methods in
283 /// [dart_vm_native.dart](dart_vm_native.dart) to parse the native syntax. 283 /// [dart_vm_native.dart](dart_vm_native.dart) to parse the native syntax.
284 /// 284 ///
285 /// #### Implementation of Diet Parsing 285 /// #### Implementation of Diet Parsing
286 /// 286 ///
287 /// We call it _diet_ _parsing_ when the parser skips parts of a file. Both 287 /// We call it _diet_ _parsing_ when the parser skips parts of a file. Both
288 /// dart2js and the Dart VM have been relying on this from early on as it allows 288 /// dart2js and the Dart VM have been relying on this from early on as it allows
289 /// them to more quickly compile small programs that use small parts of big 289 /// them to more quickly compile small programs that use small parts of big
290 /// libraries. It's also become an integrated part of how Fasta builds up 290 /// libraries. It's also become an integrated part of how Fasta builds up
291 /// outlines before starting to parse method bodies. 291 /// outlines before starting to parse method bodies.
(...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after
606 606
607 /// Parse `'@' qualified (‘.’ identifier)? (arguments)?` 607 /// Parse `'@' qualified (‘.’ identifier)? (arguments)?`
608 Token parseMetadata(Token token) { 608 Token parseMetadata(Token token) {
609 listener.beginMetadata(token); 609 listener.beginMetadata(token);
610 Token atToken = token; 610 Token atToken = token;
611 assert(optional('@', token)); 611 assert(optional('@', token));
612 token = parseIdentifier(token.next, IdentifierContext.metadataReference); 612 token = parseIdentifier(token.next, IdentifierContext.metadataReference);
613 token = 613 token =
614 parseQualifiedRestOpt(token, IdentifierContext.metadataContinuation); 614 parseQualifiedRestOpt(token, IdentifierContext.metadataContinuation);
615 if (optional("<", token)) { 615 if (optional("<", token)) {
616 reportRecoverableErrorCode(token, fasta.codeMetadataTypeArguments); 616 reportRecoverableError(token, fasta.messageMetadataTypeArguments);
617 } 617 }
618 token = parseTypeArgumentsOpt(token); 618 token = parseTypeArgumentsOpt(token);
619 Token period = null; 619 Token period = null;
620 if (optional('.', token)) { 620 if (optional('.', token)) {
621 period = token; 621 period = token;
622 token = parseIdentifier( 622 token = parseIdentifier(
623 token.next, IdentifierContext.metadataContinuationAfterTypeArguments); 623 token.next, IdentifierContext.metadataContinuationAfterTypeArguments);
624 } 624 }
625 token = parseArgumentsOpt(token); 625 token = parseArgumentsOpt(token);
626 listener.endMetadata(atToken, period, token); 626 listener.endMetadata(atToken, period, token);
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
671 listener.handleNoFormalParameters(token, kind); 671 listener.handleNoFormalParameters(token, kind);
672 return token; 672 return token;
673 } 673 }
674 } 674 }
675 675
676 Token skipFormalParameters(Token token, MemberKind kind) { 676 Token skipFormalParameters(Token token, MemberKind kind) {
677 // TODO(ahe): Shouldn't this be `beginFormalParameters`? 677 // TODO(ahe): Shouldn't this be `beginFormalParameters`?
678 listener.beginOptionalFormalParameters(token); 678 listener.beginOptionalFormalParameters(token);
679 if (!optional('(', token)) { 679 if (!optional('(', token)) {
680 if (optional(';', token)) { 680 if (optional(';', token)) {
681 reportRecoverableErrorCode(token, fasta.codeExpectedOpenParens); 681 reportRecoverableError(token, fasta.messageExpectedOpenParens);
682 return token; 682 return token;
683 } 683 }
684 return reportUnrecoverableErrorCodeWithString( 684 return reportUnrecoverableError(
685 token, fasta.codeExpectedButGot, "(") 685 token, fasta.templateExpectedButGot.withArguments("("))
686 .next; 686 .next;
687 } 687 }
688 BeginToken beginGroupToken = token; 688 BeginToken beginGroupToken = token;
689 Token endToken = beginGroupToken.endGroup; 689 Token endToken = beginGroupToken.endGroup;
690 listener.endFormalParameters(0, token, endToken, kind); 690 listener.endFormalParameters(0, token, endToken, kind);
691 return endToken.next; 691 return endToken.next;
692 } 692 }
693 693
694 /// Parses the formal parameter list of a function. 694 /// Parses the formal parameter list of a function.
695 /// 695 ///
(...skipping 12 matching lines...) Expand all
708 ++parameterCount; 708 ++parameterCount;
709 String value = token.stringValue; 709 String value = token.stringValue;
710 if (identical(value, '[')) { 710 if (identical(value, '[')) {
711 token = parseOptionalFormalParameters(token, false, kind); 711 token = parseOptionalFormalParameters(token, false, kind);
712 break; 712 break;
713 } else if (identical(value, '{')) { 713 } else if (identical(value, '{')) {
714 token = parseOptionalFormalParameters(token, true, kind); 714 token = parseOptionalFormalParameters(token, true, kind);
715 break; 715 break;
716 } else if (identical(value, '[]')) { 716 } else if (identical(value, '[]')) {
717 --parameterCount; 717 --parameterCount;
718 reportRecoverableErrorCode(token, fasta.codeEmptyOptionalParameterList); 718 reportRecoverableError(token, fasta.messageEmptyOptionalParameterList);
719 token = token.next; 719 token = token.next;
720 break; 720 break;
721 } 721 }
722 token = parseFormalParameter(token, FormalParameterType.REQUIRED, kind); 722 token = parseFormalParameter(token, FormalParameterType.REQUIRED, kind);
723 } while (optional(',', token)); 723 } while (optional(',', token));
724 listener.endFormalParameters(parameterCount, begin, token, kind); 724 listener.endFormalParameters(parameterCount, begin, token, kind);
725 return expect(')', token); 725 return expect(')', token);
726 } 726 }
727 727
728 Token parseFormalParameter( 728 Token parseFormalParameter(
(...skipping 16 matching lines...) Expand all
745 break; 745 break;
746 } else if (!isNamed && optional(']', token)) { 746 } else if (!isNamed && optional(']', token)) {
747 break; 747 break;
748 } 748 }
749 var type = 749 var type =
750 isNamed ? FormalParameterType.NAMED : FormalParameterType.POSITIONAL; 750 isNamed ? FormalParameterType.NAMED : FormalParameterType.POSITIONAL;
751 token = parseFormalParameter(token, type, kind); 751 token = parseFormalParameter(token, type, kind);
752 ++parameterCount; 752 ++parameterCount;
753 } while (optional(',', token)); 753 } while (optional(',', token));
754 if (parameterCount == 0) { 754 if (parameterCount == 0) {
755 reportRecoverableErrorCode( 755 reportRecoverableError(
756 token, 756 token,
757 isNamed 757 isNamed
758 ? fasta.codeEmptyNamedParameterList 758 ? fasta.messageEmptyNamedParameterList
759 : fasta.codeEmptyOptionalParameterList); 759 : fasta.messageEmptyOptionalParameterList);
760 } 760 }
761 listener.endOptionalFormalParameters(parameterCount, begin, token); 761 listener.endOptionalFormalParameters(parameterCount, begin, token);
762 if (isNamed) { 762 if (isNamed) {
763 return expect('}', token); 763 return expect('}', token);
764 } else { 764 } else {
765 return expect(']', token); 765 return expect(']', token);
766 } 766 }
767 } 767 }
768 768
769 bool isValidTypeReference(Token token) { 769 bool isValidTypeReference(Token token) {
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
878 Token parseQualifiedRest(Token token, IdentifierContext context) { 878 Token parseQualifiedRest(Token token, IdentifierContext context) {
879 assert(optional('.', token)); 879 assert(optional('.', token));
880 Token period = token; 880 Token period = token;
881 token = parseIdentifier(token.next, context); 881 token = parseIdentifier(token.next, context);
882 listener.handleQualified(period); 882 listener.handleQualified(period);
883 return token; 883 return token;
884 } 884 }
885 885
886 Token skipBlock(Token token) { 886 Token skipBlock(Token token) {
887 if (!optional('{', token)) { 887 if (!optional('{', token)) {
888 return reportUnrecoverableErrorCode(token, fasta.codeExpectedBlockToSkip) 888 return reportUnrecoverableError(token, fasta.messageExpectedBlockToSkip)
889 .next; 889 .next;
890 } 890 }
891 BeginToken beginGroupToken = token; 891 BeginToken beginGroupToken = token;
892 Token endGroup = beginGroupToken.endGroup; 892 Token endGroup = beginGroupToken.endGroup;
893 if (endGroup == null || !identical(endGroup.kind, $CLOSE_CURLY_BRACKET)) { 893 if (endGroup == null || !identical(endGroup.kind, $CLOSE_CURLY_BRACKET)) {
894 return reportUnmatchedToken(beginGroupToken).next; 894 return reportUnmatchedToken(beginGroupToken).next;
895 } 895 }
896 return beginGroupToken.endGroup; 896 return beginGroupToken.endGroup;
897 } 897 }
898 898
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
982 } 982 }
983 token = parseClassBody(token); 983 token = parseClassBody(token);
984 listener.endClassDeclaration(interfacesCount, begin, classKeyword, 984 listener.endClassDeclaration(interfacesCount, begin, classKeyword,
985 extendsKeyword, implementsKeyword, token); 985 extendsKeyword, implementsKeyword, token);
986 return token.next; 986 return token.next;
987 } 987 }
988 988
989 Token parseStringPart(Token token) { 989 Token parseStringPart(Token token) {
990 if (token.kind != STRING_TOKEN) { 990 if (token.kind != STRING_TOKEN) {
991 token = 991 token =
992 reportUnrecoverableErrorCodeWithToken(token, fasta.codeExpectedString) 992 reportUnrecoverableErrorWithToken(token, fasta.templateExpectedString)
993 .next; 993 .next;
994 } 994 }
995 listener.handleStringPart(token); 995 listener.handleStringPart(token);
996 return token.next; 996 return token.next;
997 } 997 }
998 998
999 Token parseIdentifier(Token token, IdentifierContext context) { 999 Token parseIdentifier(Token token, IdentifierContext context) {
1000 if (!token.isIdentifier) { 1000 if (!token.isIdentifier) {
1001 if (optional("void", token)) { 1001 if (optional("void", token)) {
1002 reportRecoverableErrorCode(token, fasta.codeInvalidVoid); 1002 reportRecoverableError(token, fasta.messageInvalidVoid);
1003 } else { 1003 } else {
1004 token = reportUnrecoverableErrorCodeWithToken( 1004 token = reportUnrecoverableErrorWithToken(
1005 token, fasta.codeExpectedIdentifier) 1005 token, fasta.templateExpectedIdentifier)
1006 .next; 1006 .next;
1007 } 1007 }
1008 } else if (token.type.isBuiltIn && !context.isBuiltInIdentifierAllowed) { 1008 } else if (token.type.isBuiltIn && !context.isBuiltInIdentifierAllowed) {
1009 if (context.inDeclaration) { 1009 if (context.inDeclaration) {
1010 reportRecoverableErrorCodeWithToken( 1010 reportRecoverableErrorWithToken(
1011 token, fasta.codeBuiltInIdentifierInDeclaration); 1011 token, fasta.templateBuiltInIdentifierInDeclaration);
1012 } else if (!optional("dynamic", token)) { 1012 } else if (!optional("dynamic", token)) {
1013 reportRecoverableErrorCodeWithToken( 1013 reportRecoverableErrorWithToken(
1014 token, fasta.codeBuiltInIdentifierAsType); 1014 token, fasta.templateBuiltInIdentifierAsType);
1015 } 1015 }
1016 } else if (!inPlainSync && token.type.isPseudo) { 1016 } else if (!inPlainSync && token.type.isPseudo) {
1017 if (optional('await', token)) { 1017 if (optional('await', token)) {
1018 reportRecoverableErrorCode(token, fasta.codeAwaitAsIdentifier); 1018 reportRecoverableError(token, fasta.messageAwaitAsIdentifier);
1019 } else if (optional('yield', token)) { 1019 } else if (optional('yield', token)) {
1020 reportRecoverableErrorCode(token, fasta.codeYieldAsIdentifier); 1020 reportRecoverableError(token, fasta.messageYieldAsIdentifier);
1021 } else if (optional('async', token)) { 1021 } else if (optional('async', token)) {
1022 reportRecoverableErrorCode(token, fasta.codeAsyncAsIdentifier); 1022 reportRecoverableError(token, fasta.messageAsyncAsIdentifier);
1023 } 1023 }
1024 } 1024 }
1025 listener.handleIdentifier(token, context); 1025 listener.handleIdentifier(token, context);
1026 return token.next; 1026 return token.next;
1027 } 1027 }
1028 1028
1029 Token expect(String string, Token token) { 1029 Token expect(String string, Token token) {
1030 if (!identical(string, token.stringValue)) { 1030 if (!identical(string, token.stringValue)) {
1031 return reportUnrecoverableErrorCodeWithString( 1031 return reportUnrecoverableError(
1032 token, fasta.codeExpectedButGot, string) 1032 token, fasta.templateExpectedButGot.withArguments(string))
1033 .next; 1033 .next;
1034 } 1034 }
1035 return token.next; 1035 return token.next;
1036 } 1036 }
1037 1037
1038 Token parseTypeVariable(Token token) { 1038 Token parseTypeVariable(Token token) {
1039 listener.beginTypeVariable(token); 1039 listener.beginTypeVariable(token);
1040 token = parseMetadataStar(token); 1040 token = parseMetadataStar(token);
1041 token = parseIdentifier(token, IdentifierContext.typeVariableDeclaration); 1041 token = parseIdentifier(token, IdentifierContext.typeVariableDeclaration);
1042 Token extendsOrSuper = null; 1042 Token extendsOrSuper = null;
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
1241 if (optional("<", token)) { 1241 if (optional("<", token)) {
1242 // Skip type parameters, they were parsed above. 1242 // Skip type parameters, they were parsed above.
1243 token = getClose(token).next; 1243 token = getClose(token).next;
1244 } 1244 }
1245 token = 1245 token =
1246 parseFormalParameters(token, MemberKind.GeneralizedFunctionType); 1246 parseFormalParameters(token, MemberKind.GeneralizedFunctionType);
1247 listener.endFunctionType(functionToken, token); 1247 listener.endFunctionType(functionToken, token);
1248 } 1248 }
1249 1249
1250 if (hasVar) { 1250 if (hasVar) {
1251 reportRecoverableErrorCode(begin, fasta.codeTypeAfterVar); 1251 reportRecoverableError(begin, fasta.messageTypeAfterVar);
1252 } 1252 }
1253 1253
1254 return token; 1254 return token;
1255 } 1255 }
1256 1256
1257 /// Returns true if [kind] is '=', ';', or ',', that is, if [kind] could be 1257 /// Returns true if [kind] is '=', ';', or ',', that is, if [kind] could be
1258 /// the end of a variable declaration. 1258 /// the end of a variable declaration.
1259 bool looksLikeVariableDeclarationEnd(int kind) { 1259 bool looksLikeVariableDeclarationEnd(int kind) {
1260 return EQ_TOKEN == kind || SEMICOLON_TOKEN == kind || COMMA_TOKEN == kind; 1260 return EQ_TOKEN == kind || SEMICOLON_TOKEN == kind || COMMA_TOKEN == kind;
1261 } 1261 }
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after
1453 nameToken = token; 1453 nameToken = token;
1454 nameContext = IdentifierContext.fieldInitializer; 1454 nameContext = IdentifierContext.fieldInitializer;
1455 token = token.next; 1455 token = token.next;
1456 } else if (!nameToken.isIdentifier) { 1456 } else if (!nameToken.isIdentifier) {
1457 untyped = true; 1457 untyped = true;
1458 nameToken = begin; 1458 nameToken = begin;
1459 token = nameToken.next; 1459 token = nameToken.next;
1460 } 1460 }
1461 if (isNamedParameter && nameToken.lexeme.startsWith("_")) { 1461 if (isNamedParameter && nameToken.lexeme.startsWith("_")) {
1462 // TODO(ahe): Move this to after commiting the type. 1462 // TODO(ahe): Move this to after commiting the type.
1463 reportRecoverableErrorCode( 1463 reportRecoverableError(nameToken, fasta.messagePrivateNamedParameter);
1464 nameToken, fasta.codePrivateNamedParameter);
1465 } 1464 }
1466 1465
1467 token = listener.injectGenericCommentTypeList(token); 1466 token = listener.injectGenericCommentTypeList(token);
1468 1467
1469 Token inlineFunctionTypeStart; 1468 Token inlineFunctionTypeStart;
1470 if (optional("<", token)) { 1469 if (optional("<", token)) {
1471 Token closer = getClose(token); 1470 Token closer = getClose(token);
1472 if (closer != null) { 1471 if (closer != null) {
1473 if (optional("(", closer.next)) { 1472 if (optional("(", closer.next)) {
1474 inlineFunctionTypeStart = token; 1473 inlineFunctionTypeStart = token;
(...skipping 20 matching lines...) Expand all
1495 listener.handleNoType(begin); 1494 listener.handleNoType(begin);
1496 } 1495 }
1497 token = 1496 token =
1498 parseFormalParameters(token, MemberKind.FunctionTypedParameter); 1497 parseFormalParameters(token, MemberKind.FunctionTypedParameter);
1499 listener.endFunctionTypedFormalParameter(); 1498 listener.endFunctionTypedFormalParameter();
1500 1499
1501 // Generalized function types don't allow inline function types. 1500 // Generalized function types don't allow inline function types.
1502 // The following isn't allowed: 1501 // The following isn't allowed:
1503 // int Function(int bar(String x)). 1502 // int Function(int bar(String x)).
1504 if (memberKind == MemberKind.GeneralizedFunctionType) { 1503 if (memberKind == MemberKind.GeneralizedFunctionType) {
1505 reportRecoverableErrorCode( 1504 reportRecoverableError(inlineFunctionTypeStart,
1506 inlineFunctionTypeStart, fasta.codeInvalidInlineFunctionType); 1505 fasta.messageInvalidInlineFunctionType);
1507 } 1506 }
1508 } else if (untyped) { 1507 } else if (untyped) {
1509 listener.handleNoType(begin); 1508 listener.handleNoType(begin);
1510 } else { 1509 } else {
1511 Token saved = token; 1510 Token saved = token;
1512 commitType(); 1511 commitType();
1513 token = saved; 1512 token = saved;
1514 } 1513 }
1515 1514
1516 if (nameContext != null) { 1515 if (nameContext != null) {
1517 parseIdentifier(nameToken, nameContext); 1516 parseIdentifier(nameToken, nameContext);
1518 } else { 1517 } else {
1519 listener.handleNoName(nameToken); 1518 listener.handleNoName(nameToken);
1520 } 1519 }
1521 1520
1522 String value = token.stringValue; 1521 String value = token.stringValue;
1523 if ((identical('=', value)) || (identical(':', value))) { 1522 if ((identical('=', value)) || (identical(':', value))) {
1524 Token equal = token; 1523 Token equal = token;
1525 token = parseExpression(token.next); 1524 token = parseExpression(token.next);
1526 listener.handleValuedFormalParameter(equal, token); 1525 listener.handleValuedFormalParameter(equal, token);
1527 if (parameterKind.isRequired) { 1526 if (parameterKind.isRequired) {
1528 reportRecoverableErrorCode( 1527 reportRecoverableError(
1529 equal, fasta.codeRequiredParameterWithDefault); 1528 equal, fasta.messageRequiredParameterWithDefault);
1530 } else if (parameterKind.isPositional && identical(':', value)) { 1529 } else if (parameterKind.isPositional && identical(':', value)) {
1531 reportRecoverableErrorCode( 1530 reportRecoverableError(
1532 equal, fasta.codePositionalParameterWithEquals); 1531 equal, fasta.messagePositionalParameterWithEquals);
1533 } else if (inFunctionType || 1532 } else if (inFunctionType ||
1534 memberKind == MemberKind.FunctionTypeAlias || 1533 memberKind == MemberKind.FunctionTypeAlias ||
1535 memberKind == MemberKind.FunctionTypedParameter) { 1534 memberKind == MemberKind.FunctionTypedParameter) {
1536 reportRecoverableErrorCode( 1535 reportRecoverableError(
1537 equal.next, fasta.codeFunctionTypeDefaultValue); 1536 equal.next, fasta.messageFunctionTypeDefaultValue);
1538 } 1537 }
1539 } else { 1538 } else {
1540 listener.handleFormalParameterWithoutValue(token); 1539 listener.handleFormalParameterWithoutValue(token);
1541 } 1540 }
1542 listener.endFormalParameter( 1541 listener.endFormalParameter(
1543 thisKeyword, nameToken, parameterKind, memberKind); 1542 thisKeyword, nameToken, parameterKind, memberKind);
1544 1543
1545 return token; 1544 return token;
1546 } 1545 }
1547 1546
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1590 handleNoStuff(token); 1589 handleNoStuff(token);
1591 return token; 1590 return token;
1592 } 1591 }
1593 1592
1594 Token parseTopLevelMember(Token token) { 1593 Token parseTopLevelMember(Token token) {
1595 Token start = token; 1594 Token start = token;
1596 listener.beginTopLevelMember(token); 1595 listener.beginTopLevelMember(token);
1597 1596
1598 Link<Token> identifiers = findMemberName(token); 1597 Link<Token> identifiers = findMemberName(token);
1599 if (identifiers.isEmpty) { 1598 if (identifiers.isEmpty) {
1600 return reportUnrecoverableErrorCodeWithToken( 1599 return reportUnrecoverableErrorWithToken(
1601 start, fasta.codeExpectedDeclaration) 1600 start, fasta.templateExpectedDeclaration)
1602 .next; 1601 .next;
1603 } 1602 }
1604 Token afterName = identifiers.head; 1603 Token afterName = identifiers.head;
1605 identifiers = identifiers.tail; 1604 identifiers = identifiers.tail;
1606 1605
1607 if (identifiers.isEmpty) { 1606 if (identifiers.isEmpty) {
1608 return reportUnrecoverableErrorCodeWithToken( 1607 return reportUnrecoverableErrorWithToken(
1609 start, fasta.codeExpectedDeclaration) 1608 start, fasta.templateExpectedDeclaration)
1610 .next; 1609 .next;
1611 } 1610 }
1612 Token name = identifiers.head; 1611 Token name = identifiers.head;
1613 identifiers = identifiers.tail; 1612 identifiers = identifiers.tail;
1614 Token getOrSet; 1613 Token getOrSet;
1615 if (!identifiers.isEmpty) { 1614 if (!identifiers.isEmpty) {
1616 String value = identifiers.head.stringValue; 1615 String value = identifiers.head.stringValue;
1617 if ((identical(value, 'get')) || (identical(value, 'set'))) { 1616 if ((identical(value, 'get')) || (identical(value, 'set'))) {
1618 getOrSet = identifiers.head; 1617 getOrSet = identifiers.head;
1619 identifiers = identifiers.tail; 1618 identifiers = identifiers.tail;
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
1671 optional("const", modifier)) { 1670 optional("const", modifier)) {
1672 varFinalOrConst = modifier; 1671 varFinalOrConst = modifier;
1673 break; 1672 break;
1674 } 1673 }
1675 } 1674 }
1676 Token token = parseModifiers(start, 1675 Token token = parseModifiers(start,
1677 isTopLevel ? MemberKind.TopLevelField : MemberKind.NonStaticField, 1676 isTopLevel ? MemberKind.TopLevelField : MemberKind.NonStaticField,
1678 isVarAllowed: true); 1677 isVarAllowed: true);
1679 1678
1680 if (token != name) { 1679 if (token != name) {
1681 reportRecoverableErrorCodeWithToken(token, fasta.codeExtraneousModifier); 1680 reportRecoverableErrorWithToken(token, fasta.templateExtraneousModifier);
1682 token = name; 1681 token = name;
1683 } 1682 }
1684 1683
1685 IdentifierContext context = isTopLevel 1684 IdentifierContext context = isTopLevel
1686 ? IdentifierContext.topLevelVariableDeclaration 1685 ? IdentifierContext.topLevelVariableDeclaration
1687 : IdentifierContext.fieldDeclaration; 1686 : IdentifierContext.fieldDeclaration;
1688 token = parseIdentifier(token, context); 1687 token = parseIdentifier(token, context);
1689 1688
1690 int fieldCount = 1; 1689 int fieldCount = 1;
1691 token = parseFieldInitializerOpt(token, name, varFinalOrConst, isTopLevel); 1690 token = parseFieldInitializerOpt(token, name, varFinalOrConst, isTopLevel);
(...skipping 17 matching lines...) Expand all
1709 Token parseTopLevelMethod(Token start, Link<Token> modifiers, Token type, 1708 Token parseTopLevelMethod(Token start, Link<Token> modifiers, Token type,
1710 Token getOrSet, Token name) { 1709 Token getOrSet, Token name) {
1711 listener.beginTopLevelMethod(start, name); 1710 listener.beginTopLevelMethod(start, name);
1712 Token externalModifier; 1711 Token externalModifier;
1713 // TODO(johnniwinther): Move error reporting to resolution to give more 1712 // TODO(johnniwinther): Move error reporting to resolution to give more
1714 // specific error messages. 1713 // specific error messages.
1715 for (Token modifier in modifiers) { 1714 for (Token modifier in modifiers) {
1716 if (externalModifier == null && optional('external', modifier)) { 1715 if (externalModifier == null && optional('external', modifier)) {
1717 externalModifier = modifier; 1716 externalModifier = modifier;
1718 } else { 1717 } else {
1719 reportRecoverableErrorCodeWithToken( 1718 reportRecoverableErrorWithToken(
1720 modifier, fasta.codeExtraneousModifier); 1719 modifier, fasta.templateExtraneousModifier);
1721 } 1720 }
1722 } 1721 }
1723 if (externalModifier != null) { 1722 if (externalModifier != null) {
1724 parseModifier(externalModifier); 1723 parseModifier(externalModifier);
1725 listener.handleModifiers(1); 1724 listener.handleModifiers(1);
1726 } else { 1725 } else {
1727 listener.handleModifiers(0); 1726 listener.handleModifiers(0);
1728 } 1727 }
1729 1728
1730 if (type == null) { 1729 if (type == null) {
(...skipping 10 matching lines...) Expand all
1741 } else { 1740 } else {
1742 isGetter = optional("get", getOrSet); 1741 isGetter = optional("get", getOrSet);
1743 listener.handleNoTypeVariables(token); 1742 listener.handleNoTypeVariables(token);
1744 } 1743 }
1745 checkFormals(isGetter, name, token); 1744 checkFormals(isGetter, name, token);
1746 token = parseFormalParametersOpt(token, MemberKind.TopLevelMethod); 1745 token = parseFormalParametersOpt(token, MemberKind.TopLevelMethod);
1747 AsyncModifier savedAsyncModifier = asyncState; 1746 AsyncModifier savedAsyncModifier = asyncState;
1748 Token asyncToken = token; 1747 Token asyncToken = token;
1749 token = parseAsyncModifier(token); 1748 token = parseAsyncModifier(token);
1750 if (getOrSet != null && !inPlainSync && optional("set", getOrSet)) { 1749 if (getOrSet != null && !inPlainSync && optional("set", getOrSet)) {
1751 reportRecoverableErrorCode(asyncToken, fasta.codeSetterNotSync); 1750 reportRecoverableError(asyncToken, fasta.messageSetterNotSync);
1752 } 1751 }
1753 token = parseFunctionBody(token, false, externalModifier != null); 1752 token = parseFunctionBody(token, false, externalModifier != null);
1754 asyncState = savedAsyncModifier; 1753 asyncState = savedAsyncModifier;
1755 Token endToken = token; 1754 Token endToken = token;
1756 token = token.next; 1755 token = token.next;
1757 listener.endTopLevelMethod(start, getOrSet, endToken); 1756 listener.endTopLevelMethod(start, getOrSet, endToken);
1758 return token; 1757 return token;
1759 } 1758 }
1760 1759
1761 void checkFormals(bool isGetter, Token name, Token token) { 1760 void checkFormals(bool isGetter, Token name, Token token) {
1762 if (optional("(", token)) { 1761 if (optional("(", token)) {
1763 if (isGetter) { 1762 if (isGetter) {
1764 reportRecoverableErrorCode(token, fasta.codeGetterWithFormals); 1763 reportRecoverableError(token, fasta.messageGetterWithFormals);
1765 } 1764 }
1766 } else if (!isGetter) { 1765 } else if (!isGetter) {
1767 reportRecoverableErrorCodeWithToken(name, fasta.codeNoFormals); 1766 reportRecoverableErrorWithToken(name, fasta.templateNoFormals);
1768 } 1767 }
1769 } 1768 }
1770 1769
1771 /// Looks ahead to find the name of a member. Returns a link of the modifiers, 1770 /// Looks ahead to find the name of a member. Returns a link of the modifiers,
1772 /// set/get, (operator) name, and either the start of the method body or the 1771 /// set/get, (operator) name, and either the start of the method body or the
1773 /// end of the declaration. 1772 /// end of the declaration.
1774 /// 1773 ///
1775 /// Examples: 1774 /// Examples:
1776 /// 1775 ///
1777 /// int get foo; 1776 /// int get foo;
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
1882 BeginToken beginGroup = token; 1881 BeginToken beginGroup = token;
1883 if (beginGroup.endGroup == null) { 1882 if (beginGroup.endGroup == null) {
1884 token = reportUnmatchedToken(beginGroup).next; 1883 token = reportUnmatchedToken(beginGroup).next;
1885 } else { 1884 } else {
1886 token = beginGroup.endGroup.next; 1885 token = beginGroup.endGroup.next;
1887 } 1886 }
1888 } 1887 }
1889 } 1888 }
1890 if (!optional('(', token)) { 1889 if (!optional('(', token)) {
1891 if (optional(';', token)) { 1890 if (optional(';', token)) {
1892 reportRecoverableErrorCode(token, fasta.codeExpectedOpenParens); 1891 reportRecoverableError(token, fasta.messageExpectedOpenParens);
1893 } 1892 }
1894 token = expect("(", token); 1893 token = expect("(", token);
1895 } 1894 }
1896 if (token is BeginToken) { 1895 if (token is BeginToken) {
1897 BeginToken beginGroup = token; 1896 BeginToken beginGroup = token;
1898 if (beginGroup.endGroup == null) { 1897 if (beginGroup.endGroup == null) {
1899 token = reportUnmatchedToken(beginGroup).next; 1898 token = reportUnmatchedToken(beginGroup).next;
1900 } else { 1899 } else {
1901 token = beginGroup.endGroup.next; 1900 token = beginGroup.endGroup.next;
1902 } 1901 }
1903 } 1902 }
1904 } 1903 }
1905 } 1904 }
1906 return listener.handleMemberName(const Link<Token>()); 1905 return listener.handleMemberName(const Link<Token>());
1907 } 1906 }
1908 1907
1909 Token parseFieldInitializerOpt( 1908 Token parseFieldInitializerOpt(
1910 Token token, Token name, Token varFinalOrConst, bool isTopLevel) { 1909 Token token, Token name, Token varFinalOrConst, bool isTopLevel) {
1911 if (optional('=', token)) { 1910 if (optional('=', token)) {
1912 Token assignment = token; 1911 Token assignment = token;
1913 listener.beginFieldInitializer(token); 1912 listener.beginFieldInitializer(token);
1914 token = parseExpression(token.next); 1913 token = parseExpression(token.next);
1915 listener.endFieldInitializer(assignment, token); 1914 listener.endFieldInitializer(assignment, token);
1916 } else { 1915 } else {
1917 if (varFinalOrConst != null) { 1916 if (varFinalOrConst != null) {
1918 if (optional("const", varFinalOrConst)) { 1917 if (optional("const", varFinalOrConst)) {
1919 reportRecoverableErrorCode( 1918 reportRecoverableError(
1920 name, fasta.codeConstFieldWithoutInitializer); 1919 name, fasta.messageConstFieldWithoutInitializer);
1921 } else if (isTopLevel && optional("final", varFinalOrConst)) { 1920 } else if (isTopLevel && optional("final", varFinalOrConst)) {
1922 reportRecoverableErrorCode( 1921 reportRecoverableError(
1923 name, fasta.codeFinalFieldWithoutInitializer); 1922 name, fasta.messageFinalFieldWithoutInitializer);
1924 } 1923 }
1925 } 1924 }
1926 listener.handleNoFieldInitializer(token); 1925 listener.handleNoFieldInitializer(token);
1927 } 1926 }
1928 return token; 1927 return token;
1929 } 1928 }
1930 1929
1931 Token parseVariableInitializerOpt(Token token) { 1930 Token parseVariableInitializerOpt(Token token) {
1932 if (optional('=', token)) { 1931 if (optional('=', token)) {
1933 Token assignment = token; 1932 Token assignment = token;
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1972 } else { 1971 } else {
1973 token = parseExpression(token); 1972 token = parseExpression(token);
1974 } 1973 }
1975 listener.endInitializer(token); 1974 listener.endInitializer(token);
1976 return token; 1975 return token;
1977 } 1976 }
1978 1977
1979 Token parseLiteralStringOrRecoverExpression(Token token) { 1978 Token parseLiteralStringOrRecoverExpression(Token token) {
1980 if (identical(token.kind, STRING_TOKEN)) { 1979 if (identical(token.kind, STRING_TOKEN)) {
1981 return parseLiteralString(token); 1980 return parseLiteralString(token);
1981 } else if (token is ErrorToken) {
1982 return reportErrorToken(token, false);
1982 } else { 1983 } else {
1983 reportRecoverableErrorCodeWithToken(token, fasta.codeExpectedString); 1984 reportRecoverableErrorWithToken(token, fasta.templateExpectedString);
1984 return parseRecoverExpression( 1985 return parseRecoverExpression(
1985 token, fasta.codeExpectedString.format(uri, token.charOffset, token)); 1986 token, fasta.templateExpectedString.withArguments(token));
1986 } 1987 }
1987 } 1988 }
1988 1989
1989 Token expectSemicolon(Token token) { 1990 Token expectSemicolon(Token token) {
1990 return expect(';', token); 1991 return expect(';', token);
1991 } 1992 }
1992 1993
1993 bool isModifier(Token token) => modifierOrder(token) < 127; 1994 bool isModifier(Token token) => modifierOrder(token) < 127;
1994 1995
1995 /// Provides a partial order on modifiers. 1996 /// Provides a partial order on modifiers.
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
2049 break; 2050 break;
2050 } 2051 }
2051 } 2052 }
2052 int order = modifierOrder(token); 2053 int order = modifierOrder(token);
2053 if (order < 3) { 2054 if (order < 3) {
2054 // `abstract` isn't parsed with this method. 2055 // `abstract` isn't parsed with this method.
2055 if (order > currentOrder) { 2056 if (order > currentOrder) {
2056 currentOrder = order; 2057 currentOrder = order;
2057 if (optional("var", token)) { 2058 if (optional("var", token)) {
2058 if (!isVarAllowed && parameterKind == null) { 2059 if (!isVarAllowed && parameterKind == null) {
2059 reportRecoverableErrorCodeWithToken( 2060 reportRecoverableErrorWithToken(
2060 token, fasta.codeExtraneousModifier); 2061 token, fasta.templateExtraneousModifier);
2061 } 2062 }
2062 switch (typeContinuation ?? TypeContinuation.Required) { 2063 switch (typeContinuation ?? TypeContinuation.Required) {
2063 case TypeContinuation.NormalFormalParameter: 2064 case TypeContinuation.NormalFormalParameter:
2064 typeContinuation = 2065 typeContinuation =
2065 TypeContinuation.NormalFormalParameterAfterVar; 2066 TypeContinuation.NormalFormalParameterAfterVar;
2066 break; 2067 break;
2067 2068
2068 case TypeContinuation.OptionalPositionalFormalParameter: 2069 case TypeContinuation.OptionalPositionalFormalParameter:
2069 typeContinuation = 2070 typeContinuation =
2070 TypeContinuation.OptionalPositionalFormalParameterAfterVar; 2071 TypeContinuation.OptionalPositionalFormalParameterAfterVar;
2071 break; 2072 break;
2072 2073
2073 case TypeContinuation.NamedFormalParameter: 2074 case TypeContinuation.NamedFormalParameter:
2074 typeContinuation = 2075 typeContinuation =
2075 TypeContinuation.NamedFormalParameterAfterVar; 2076 TypeContinuation.NamedFormalParameterAfterVar;
2076 break; 2077 break;
2077 2078
2078 default: 2079 default:
2079 typeContinuation = TypeContinuation.OptionalAfterVar; 2080 typeContinuation = TypeContinuation.OptionalAfterVar;
2080 break; 2081 break;
2081 } 2082 }
2082 } else if (optional("final", token)) { 2083 } else if (optional("final", token)) {
2083 if (!isVarAllowed && parameterKind == null) { 2084 if (!isVarAllowed && parameterKind == null) {
2084 reportRecoverableErrorCodeWithToken( 2085 reportRecoverableErrorWithToken(
2085 token, fasta.codeExtraneousModifier); 2086 token, fasta.templateExtraneousModifier);
2086 } 2087 }
2087 typeContinuation ??= TypeContinuation.Optional; 2088 typeContinuation ??= TypeContinuation.Optional;
2088 } else if (optional("const", token)) { 2089 } else if (optional("const", token)) {
2089 if (!isVarAllowed) { 2090 if (!isVarAllowed) {
2090 reportRecoverableErrorCodeWithToken( 2091 reportRecoverableErrorWithToken(
2091 token, fasta.codeExtraneousModifier); 2092 token, fasta.templateExtraneousModifier);
2092 } 2093 }
2093 typeContinuation ??= TypeContinuation.Optional; 2094 typeContinuation ??= TypeContinuation.Optional;
2094 } else if (optional("static", token)) { 2095 } else if (optional("static", token)) {
2095 if (parameterKind != null) { 2096 if (parameterKind != null) {
2096 reportRecoverableErrorCodeWithToken( 2097 reportRecoverableErrorWithToken(
2097 token, fasta.codeExtraneousModifier); 2098 token, fasta.templateExtraneousModifier);
2098 } else if (memberKind == MemberKind.NonStaticMethod) { 2099 } else if (memberKind == MemberKind.NonStaticMethod) {
2099 memberKind = MemberKind.StaticMethod; 2100 memberKind = MemberKind.StaticMethod;
2100 } else if (memberKind == MemberKind.NonStaticField) { 2101 } else if (memberKind == MemberKind.NonStaticField) {
2101 memberKind = MemberKind.StaticField; 2102 memberKind = MemberKind.StaticField;
2102 } else { 2103 } else {
2103 reportRecoverableErrorCodeWithToken( 2104 reportRecoverableErrorWithToken(
2104 token, fasta.codeExtraneousModifier); 2105 token, fasta.templateExtraneousModifier);
2105 token = token.next; 2106 token = token.next;
2106 continue; 2107 continue;
2107 } 2108 }
2108 } else if (optional("covariant", token)) { 2109 } else if (optional("covariant", token)) {
2109 switch (memberKind) { 2110 switch (memberKind) {
2110 case MemberKind.StaticField: 2111 case MemberKind.StaticField:
2111 case MemberKind.StaticMethod: 2112 case MemberKind.StaticMethod:
2112 case MemberKind.TopLevelField: 2113 case MemberKind.TopLevelField:
2113 case MemberKind.TopLevelMethod: 2114 case MemberKind.TopLevelMethod:
2114 reportRecoverableErrorCodeWithToken( 2115 reportRecoverableErrorWithToken(
2115 token, fasta.codeExtraneousModifier); 2116 token, fasta.templateExtraneousModifier);
2116 token = token.next; 2117 token = token.next;
2117 continue; 2118 continue;
2118 2119
2119 default: 2120 default:
2120 break; 2121 break;
2121 } 2122 }
2122 } else if (optional("external", token)) { 2123 } else if (optional("external", token)) {
2123 switch (memberKind) { 2124 switch (memberKind) {
2124 case MemberKind.Factory: 2125 case MemberKind.Factory:
2125 case MemberKind.NonStaticMethod: 2126 case MemberKind.NonStaticMethod:
2126 case MemberKind.StaticMethod: 2127 case MemberKind.StaticMethod:
2127 case MemberKind.TopLevelMethod: 2128 case MemberKind.TopLevelMethod:
2128 break; 2129 break;
2129 2130
2130 default: 2131 default:
2131 reportRecoverableErrorCodeWithToken( 2132 reportRecoverableErrorWithToken(
2132 token, fasta.codeExtraneousModifier); 2133 token, fasta.templateExtraneousModifier);
2133 token = token.next; 2134 token = token.next;
2134 continue; 2135 continue;
2135 } 2136 }
2136 } 2137 }
2137 token = parseModifier(token); 2138 token = parseModifier(token);
2138 count++; 2139 count++;
2139 } else { 2140 } else {
2140 reportRecoverableErrorCodeWithToken( 2141 reportRecoverableErrorWithToken(
2141 token, fasta.codeExtraneousModifier); 2142 token, fasta.templateExtraneousModifier);
2142 token = token.next; 2143 token = token.next;
2143 } 2144 }
2144 } else { 2145 } else {
2145 break; 2146 break;
2146 } 2147 }
2147 } 2148 }
2148 listener.handleModifiers(count); 2149 listener.handleModifiers(count);
2149 2150
2150 typeContinuation ??= 2151 typeContinuation ??=
2151 (isVarAllowed || memberKind == MemberKind.GeneralizedFunctionType) 2152 (isVarAllowed || memberKind == MemberKind.GeneralizedFunctionType)
2152 ? TypeContinuation.Required 2153 ? TypeContinuation.Required
2153 : TypeContinuation.Optional; 2154 : TypeContinuation.Optional;
2154 2155
2155 token = parseType(token, typeContinuation, null, memberKind); 2156 token = parseType(token, typeContinuation, null, memberKind);
2156 return token; 2157 return token;
2157 } 2158 }
2158 2159
2159 Token skipClassBody(Token token) { 2160 Token skipClassBody(Token token) {
2160 if (!optional('{', token)) { 2161 if (!optional('{', token)) {
2161 return reportUnrecoverableErrorCodeWithToken( 2162 return reportUnrecoverableErrorWithToken(
2162 token, fasta.codeExpectedClassBodyToSkip) 2163 token, fasta.templateExpectedClassBodyToSkip)
2163 .next; 2164 .next;
2164 } 2165 }
2165 BeginToken beginGroupToken = token; 2166 BeginToken beginGroupToken = token;
2166 Token endGroup = beginGroupToken.endGroup; 2167 Token endGroup = beginGroupToken.endGroup;
2167 if (endGroup == null || !identical(endGroup.kind, $CLOSE_CURLY_BRACKET)) { 2168 if (endGroup == null || !identical(endGroup.kind, $CLOSE_CURLY_BRACKET)) {
2168 return reportUnmatchedToken(beginGroupToken).next; 2169 return reportUnmatchedToken(beginGroupToken).next;
2169 } 2170 }
2170 return endGroup; 2171 return endGroup;
2171 } 2172 }
2172 2173
2173 Token parseClassBody(Token token) { 2174 Token parseClassBody(Token token) {
2174 Token begin = token; 2175 Token begin = token;
2175 listener.beginClassBody(token); 2176 listener.beginClassBody(token);
2176 if (!optional('{', token)) { 2177 if (!optional('{', token)) {
2177 token = reportUnrecoverableErrorCodeWithToken( 2178 token = reportUnrecoverableErrorWithToken(
2178 token, fasta.codeExpectedClassBody) 2179 token, fasta.templateExpectedClassBody)
2179 .next; 2180 .next;
2180 } 2181 }
2181 token = token.next; 2182 token = token.next;
2182 int count = 0; 2183 int count = 0;
2183 while (notEofOrValue('}', token)) { 2184 while (notEofOrValue('}', token)) {
2184 token = parseMember(token); 2185 token = parseMember(token);
2185 ++count; 2186 ++count;
2186 } 2187 }
2187 expect('}', token); 2188 expect('}', token);
2188 listener.endClassBody(count, begin, token); 2189 listener.endClassBody(count, begin, token);
(...skipping 17 matching lines...) Expand all
2206 listener.beginMember(token); 2207 listener.beginMember(token);
2207 if (isFactoryDeclaration(token)) { 2208 if (isFactoryDeclaration(token)) {
2208 token = parseFactoryMethod(token); 2209 token = parseFactoryMethod(token);
2209 listener.endMember(); 2210 listener.endMember();
2210 assert(token != null); 2211 assert(token != null);
2211 return token; 2212 return token;
2212 } 2213 }
2213 2214
2214 Link<Token> identifiers = findMemberName(token); 2215 Link<Token> identifiers = findMemberName(token);
2215 if (identifiers.isEmpty) { 2216 if (identifiers.isEmpty) {
2216 return reportUnrecoverableErrorCodeWithToken( 2217 return reportUnrecoverableErrorWithToken(
2217 start, fasta.codeExpectedDeclaration) 2218 start, fasta.templateExpectedDeclaration)
2218 .next; 2219 .next;
2219 } 2220 }
2220 Token afterName = identifiers.head; 2221 Token afterName = identifiers.head;
2221 identifiers = identifiers.tail; 2222 identifiers = identifiers.tail;
2222 2223
2223 if (identifiers.isEmpty) { 2224 if (identifiers.isEmpty) {
2224 return reportUnrecoverableErrorCodeWithToken( 2225 return reportUnrecoverableErrorWithToken(
2225 start, fasta.codeExpectedDeclaration) 2226 start, fasta.templateExpectedDeclaration)
2226 .next; 2227 .next;
2227 } 2228 }
2228 Token name = identifiers.head; 2229 Token name = identifiers.head;
2229 identifiers = identifiers.tail; 2230 identifiers = identifiers.tail;
2230 if (!identifiers.isEmpty) { 2231 if (!identifiers.isEmpty) {
2231 if (optional('operator', identifiers.head)) { 2232 if (optional('operator', identifiers.head)) {
2232 name = identifiers.head; 2233 name = identifiers.head;
2233 identifiers = identifiers.tail; 2234 identifiers = identifiers.tail;
2234 } 2235 }
2235 } 2236 }
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
2299 2300
2300 Token externalModifier; 2301 Token externalModifier;
2301 Token staticModifier; 2302 Token staticModifier;
2302 // TODO(ahe): Consider using [parseModifiers] instead. 2303 // TODO(ahe): Consider using [parseModifiers] instead.
2303 void parseModifierList(Link<Token> tokens) { 2304 void parseModifierList(Link<Token> tokens) {
2304 int count = 0; 2305 int count = 0;
2305 int currentOrder = -1; 2306 int currentOrder = -1;
2306 for (; !tokens.isEmpty; tokens = tokens.tail) { 2307 for (; !tokens.isEmpty; tokens = tokens.tail) {
2307 Token token = tokens.head; 2308 Token token = tokens.head;
2308 if (optional("abstract", token)) { 2309 if (optional("abstract", token)) {
2309 reportRecoverableErrorCodeWithToken( 2310 reportRecoverableErrorWithToken(
2310 token, fasta.codeExtraneousModifier); 2311 token, fasta.templateExtraneousModifier);
2311 continue; 2312 continue;
2312 } 2313 }
2313 int order = modifierOrder(token); 2314 int order = modifierOrder(token);
2314 if (order < 127) { 2315 if (order < 127) {
2315 if (order > currentOrder) { 2316 if (order > currentOrder) {
2316 currentOrder = order; 2317 currentOrder = order;
2317 if (optional("var", token)) { 2318 if (optional("var", token)) {
2318 reportRecoverableErrorCodeWithToken( 2319 reportRecoverableErrorWithToken(
2319 token, fasta.codeExtraneousModifier); 2320 token, fasta.templateExtraneousModifier);
2320 } else if (optional("const", token)) { 2321 } else if (optional("const", token)) {
2321 if (getOrSet != null) { 2322 if (getOrSet != null) {
2322 reportRecoverableErrorCodeWithToken( 2323 reportRecoverableErrorWithToken(
2323 token, fasta.codeExtraneousModifier); 2324 token, fasta.templateExtraneousModifier);
2324 continue; 2325 continue;
2325 } 2326 }
2326 } else if (optional("external", token)) { 2327 } else if (optional("external", token)) {
2327 externalModifier = token; 2328 externalModifier = token;
2328 } else if (optional("static", token)) { 2329 } else if (optional("static", token)) {
2329 staticModifier = token; 2330 staticModifier = token;
2330 } else if (optional("covariant", token)) { 2331 } else if (optional("covariant", token)) {
2331 if (staticModifier != null || 2332 if (staticModifier != null ||
2332 getOrSet == null || 2333 getOrSet == null ||
2333 optional("get", getOrSet)) { 2334 optional("get", getOrSet)) {
2334 reportRecoverableErrorCodeWithToken( 2335 reportRecoverableErrorWithToken(
2335 token, fasta.codeExtraneousModifier); 2336 token, fasta.templateExtraneousModifier);
2336 continue; 2337 continue;
2337 } 2338 }
2338 } 2339 }
2339 } else { 2340 } else {
2340 reportRecoverableErrorCodeWithToken( 2341 reportRecoverableErrorWithToken(
2341 token, fasta.codeExtraneousModifier); 2342 token, fasta.templateExtraneousModifier);
2342 continue; 2343 continue;
2343 } 2344 }
2344 } else { 2345 } else {
2345 reportUnexpectedToken(token); 2346 reportUnexpectedToken(token);
2346 break; // Skip the remaining modifiers. 2347 break; // Skip the remaining modifiers.
2347 } 2348 }
2348 parseModifier(token); 2349 parseModifier(token);
2349 count++; 2350 count++;
2350 } 2351 }
2351 listener.handleModifiers(count); 2352 listener.handleModifiers(count);
2352 } 2353 }
2353 2354
2354 parseModifierList(modifiers); 2355 parseModifierList(modifiers);
2355 2356
2356 if (type == null) { 2357 if (type == null) {
2357 listener.handleNoType(name); 2358 listener.handleNoType(name);
2358 } else { 2359 } else {
2359 parseType(type, TypeContinuation.Optional); 2360 parseType(type, TypeContinuation.Optional);
2360 } 2361 }
2361 Token token; 2362 Token token;
2362 if (optional('operator', name)) { 2363 if (optional('operator', name)) {
2363 token = parseOperatorName(name); 2364 token = parseOperatorName(name);
2364 if (staticModifier != null) { 2365 if (staticModifier != null) {
2365 reportRecoverableErrorCodeWithToken( 2366 reportRecoverableErrorWithToken(
2366 staticModifier, fasta.codeExtraneousModifier); 2367 staticModifier, fasta.templateExtraneousModifier);
2367 } 2368 }
2368 } else { 2369 } else {
2369 token = parseIdentifier(name, IdentifierContext.methodDeclaration); 2370 token = parseIdentifier(name, IdentifierContext.methodDeclaration);
2370 } 2371 }
2371 2372
2372 token = parseQualifiedRestOpt( 2373 token = parseQualifiedRestOpt(
2373 token, IdentifierContext.methodDeclarationContinuation); 2374 token, IdentifierContext.methodDeclarationContinuation);
2374 bool isGetter = false; 2375 bool isGetter = false;
2375 if (getOrSet == null) { 2376 if (getOrSet == null) {
2376 token = parseTypeVariablesOpt(token); 2377 token = parseTypeVariablesOpt(token);
2377 } else { 2378 } else {
2378 isGetter = optional("get", getOrSet); 2379 isGetter = optional("get", getOrSet);
2379 listener.handleNoTypeVariables(token); 2380 listener.handleNoTypeVariables(token);
2380 } 2381 }
2381 checkFormals(isGetter, name, token); 2382 checkFormals(isGetter, name, token);
2382 token = parseFormalParametersOpt( 2383 token = parseFormalParametersOpt(
2383 token, 2384 token,
2384 staticModifier != null 2385 staticModifier != null
2385 ? MemberKind.StaticMethod 2386 ? MemberKind.StaticMethod
2386 : MemberKind.NonStaticMethod); 2387 : MemberKind.NonStaticMethod);
2387 token = parseInitializersOpt(token); 2388 token = parseInitializersOpt(token);
2388 AsyncModifier savedAsyncModifier = asyncState; 2389 AsyncModifier savedAsyncModifier = asyncState;
2389 Token asyncToken = token; 2390 Token asyncToken = token;
2390 token = parseAsyncModifier(token); 2391 token = parseAsyncModifier(token);
2391 if (getOrSet != null && !inPlainSync && optional("set", getOrSet)) { 2392 if (getOrSet != null && !inPlainSync && optional("set", getOrSet)) {
2392 reportRecoverableErrorCode(asyncToken, fasta.codeSetterNotSync); 2393 reportRecoverableError(asyncToken, fasta.messageSetterNotSync);
2393 } 2394 }
2394 if (optional('=', token)) { 2395 if (optional('=', token)) {
2395 token = parseRedirectingFactoryBody(token); 2396 token = parseRedirectingFactoryBody(token);
2396 } else { 2397 } else {
2397 token = parseFunctionBody( 2398 token = parseFunctionBody(
2398 token, false, staticModifier == null || externalModifier != null); 2399 token, false, staticModifier == null || externalModifier != null);
2399 } 2400 }
2400 asyncState = savedAsyncModifier; 2401 asyncState = savedAsyncModifier;
2401 listener.endMethod(getOrSet, start, token); 2402 listener.endMethod(getOrSet, start, token);
2402 return token.next; 2403 return token.next;
(...skipping 13 matching lines...) Expand all
2416 } 2417 }
2417 listener.handleModifiers(modifierCount); 2418 listener.handleModifiers(modifierCount);
2418 Token factoryKeyword = token; 2419 Token factoryKeyword = token;
2419 listener.beginFactoryMethod(factoryKeyword); 2420 listener.beginFactoryMethod(factoryKeyword);
2420 token = expect('factory', token); 2421 token = expect('factory', token);
2421 token = parseConstructorReference(token); 2422 token = parseConstructorReference(token);
2422 token = parseFormalParameters(token, MemberKind.Factory); 2423 token = parseFormalParameters(token, MemberKind.Factory);
2423 Token asyncToken = token; 2424 Token asyncToken = token;
2424 token = parseAsyncModifier(token); 2425 token = parseAsyncModifier(token);
2425 if (!inPlainSync) { 2426 if (!inPlainSync) {
2426 reportRecoverableErrorCode(asyncToken, fasta.codeFactoryNotSync); 2427 reportRecoverableError(asyncToken, fasta.messageFactoryNotSync);
2427 } 2428 }
2428 if (optional('=', token)) { 2429 if (optional('=', token)) {
2429 token = parseRedirectingFactoryBody(token); 2430 token = parseRedirectingFactoryBody(token);
2430 } else { 2431 } else {
2431 token = parseFunctionBody(token, false, isExternal); 2432 token = parseFunctionBody(token, false, isExternal);
2432 } 2433 }
2433 listener.endFactoryMethod(start, factoryKeyword, token); 2434 listener.endFactoryMethod(start, factoryKeyword, token);
2434 return token.next; 2435 return token.next;
2435 } 2436 }
2436 2437
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
2536 listener.endRedirectingFactoryBody(equals, semicolon); 2537 listener.endRedirectingFactoryBody(equals, semicolon);
2537 return token; 2538 return token;
2538 } 2539 }
2539 2540
2540 Token skipFunctionBody(Token token, bool isExpression, bool allowAbstract) { 2541 Token skipFunctionBody(Token token, bool isExpression, bool allowAbstract) {
2541 assert(!isExpression); 2542 assert(!isExpression);
2542 token = skipAsyncModifier(token); 2543 token = skipAsyncModifier(token);
2543 String value = token.stringValue; 2544 String value = token.stringValue;
2544 if (identical(value, ';')) { 2545 if (identical(value, ';')) {
2545 if (!allowAbstract) { 2546 if (!allowAbstract) {
2546 reportRecoverableErrorCode(token, fasta.codeExpectedBody); 2547 reportRecoverableError(token, fasta.messageExpectedBody);
2547 } 2548 }
2548 listener.handleNoFunctionBody(token); 2549 listener.handleNoFunctionBody(token);
2549 } else { 2550 } else {
2550 if (identical(value, '=>')) { 2551 if (identical(value, '=>')) {
2551 token = parseExpression(token.next); 2552 token = parseExpression(token.next);
2552 expectSemicolon(token); 2553 expectSemicolon(token);
2553 listener.handleFunctionBodySkipped(token, true); 2554 listener.handleFunctionBodySkipped(token, true);
2554 } else if (identical(value, '=')) { 2555 } else if (identical(value, '=')) {
2555 reportRecoverableErrorCode(token, fasta.codeExpectedBody); 2556 reportRecoverableError(token, fasta.messageExpectedBody);
2556 token = parseExpression(token.next); 2557 token = parseExpression(token.next);
2557 expectSemicolon(token); 2558 expectSemicolon(token);
2558 listener.handleFunctionBodySkipped(token, true); 2559 listener.handleFunctionBodySkipped(token, true);
2559 } else { 2560 } else {
2560 token = skipBlock(token); 2561 token = skipBlock(token);
2561 listener.handleFunctionBodySkipped(token, false); 2562 listener.handleFunctionBodySkipped(token, false);
2562 } 2563 }
2563 } 2564 }
2564 return token; 2565 return token;
2565 } 2566 }
2566 2567
2567 Token parseFunctionBody(Token token, bool isExpression, bool allowAbstract) { 2568 Token parseFunctionBody(Token token, bool isExpression, bool allowAbstract) {
2568 if (optional(';', token)) { 2569 if (optional(';', token)) {
2569 if (!allowAbstract) { 2570 if (!allowAbstract) {
2570 reportRecoverableErrorCode(token, fasta.codeExpectedBody); 2571 reportRecoverableError(token, fasta.messageExpectedBody);
2571 } 2572 }
2572 listener.handleEmptyFunctionBody(token); 2573 listener.handleEmptyFunctionBody(token);
2573 return token; 2574 return token;
2574 } else if (optional('=>', token)) { 2575 } else if (optional('=>', token)) {
2575 Token begin = token; 2576 Token begin = token;
2576 token = parseExpression(token.next); 2577 token = parseExpression(token.next);
2577 if (!isExpression) { 2578 if (!isExpression) {
2578 expectSemicolon(token); 2579 expectSemicolon(token);
2579 listener.handleExpressionFunctionBody(begin, token); 2580 listener.handleExpressionFunctionBody(begin, token);
2580 } else { 2581 } else {
2581 listener.handleExpressionFunctionBody(begin, null); 2582 listener.handleExpressionFunctionBody(begin, null);
2582 } 2583 }
2583 return token; 2584 return token;
2584 } else if (optional('=', token)) { 2585 } else if (optional('=', token)) {
2585 Token begin = token; 2586 Token begin = token;
2586 // Recover from a bad factory method. 2587 // Recover from a bad factory method.
2587 reportRecoverableErrorCode(token, fasta.codeExpectedBody); 2588 reportRecoverableError(token, fasta.messageExpectedBody);
2588 token = parseExpression(token.next); 2589 token = parseExpression(token.next);
2589 if (!isExpression) { 2590 if (!isExpression) {
2590 expectSemicolon(token); 2591 expectSemicolon(token);
2591 listener.handleExpressionFunctionBody(begin, token); 2592 listener.handleExpressionFunctionBody(begin, token);
2592 } else { 2593 } else {
2593 listener.handleExpressionFunctionBody(begin, null); 2594 listener.handleExpressionFunctionBody(begin, null);
2594 } 2595 }
2595 return token; 2596 return token;
2596 } 2597 }
2597 Token begin = token; 2598 Token begin = token;
2598 int statementCount = 0; 2599 int statementCount = 0;
2599 if (!optional('{', token)) { 2600 if (!optional('{', token)) {
2600 token = reportUnrecoverableErrorCodeWithToken( 2601 token = reportUnrecoverableErrorWithToken(
2601 token, fasta.codeExpectedFunctionBody) 2602 token, fasta.templateExpectedFunctionBody)
2602 .next; 2603 .next;
2603 listener.handleInvalidFunctionBody(token); 2604 listener.handleInvalidFunctionBody(token);
2604 return token; 2605 return token;
2605 } 2606 }
2606 2607
2607 listener.beginBlockFunctionBody(begin); 2608 listener.beginBlockFunctionBody(begin);
2608 token = token.next; 2609 token = token.next;
2609 while (notEofOrValue('}', token)) { 2610 while (notEofOrValue('}', token)) {
2610 token = parseStatement(token); 2611 token = parseStatement(token);
2611 ++statementCount; 2612 ++statementCount;
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
2650 asyncState = AsyncModifier.Async; 2651 asyncState = AsyncModifier.Async;
2651 } 2652 }
2652 } else if (optional('sync', token)) { 2653 } else if (optional('sync', token)) {
2653 async = token; 2654 async = token;
2654 token = token.next; 2655 token = token.next;
2655 if (optional('*', token)) { 2656 if (optional('*', token)) {
2656 asyncState = AsyncModifier.SyncStar; 2657 asyncState = AsyncModifier.SyncStar;
2657 star = token; 2658 star = token;
2658 token = token.next; 2659 token = token.next;
2659 } else { 2660 } else {
2660 reportRecoverableErrorCode(async, fasta.codeInvalidSyncModifier); 2661 reportRecoverableError(async, fasta.messageInvalidSyncModifier);
2661 } 2662 }
2662 } 2663 }
2663 listener.handleAsyncModifier(async, star); 2664 listener.handleAsyncModifier(async, star);
2664 if (inGenerator && optional('=>', token)) { 2665 if (inGenerator && optional('=>', token)) {
2665 reportRecoverableErrorCode(token, fasta.codeGeneratorReturnsValue); 2666 reportRecoverableError(token, fasta.messageGeneratorReturnsValue);
2666 } else if (!inPlainSync && optional(';', token)) { 2667 } else if (!inPlainSync && optional(';', token)) {
2667 reportRecoverableErrorCode(token, fasta.codeAbstractNotSync); 2668 reportRecoverableError(token, fasta.messageAbstractNotSync);
2668 } 2669 }
2669 return token; 2670 return token;
2670 } 2671 }
2671 2672
2672 int statementDepth = 0; 2673 int statementDepth = 0;
2673 Token parseStatement(Token token) { 2674 Token parseStatement(Token token) {
2674 if (statementDepth++ > 500) { 2675 if (statementDepth++ > 500) {
2675 // This happens for degenerate programs, for example, a lot of nested 2676 // This happens for degenerate programs, for example, a lot of nested
2676 // if-statements. The language test deep_nesting2_negative_test, for 2677 // if-statements. The language test deep_nesting2_negative_test, for
2677 // example, provokes this. 2678 // example, provokes this.
2678 return reportUnrecoverableErrorCode(token, fasta.codeStackOverflow).next; 2679 return reportUnrecoverableError(token, fasta.messageStackOverflow).next;
2679 } 2680 }
2680 Token result = parseStatementX(token); 2681 Token result = parseStatementX(token);
2681 statementDepth--; 2682 statementDepth--;
2682 return result; 2683 return result;
2683 } 2684 }
2684 2685
2685 Token parseStatementX(Token token) { 2686 Token parseStatementX(Token token) {
2686 final value = token.stringValue; 2687 final value = token.stringValue;
2687 if (identical(token.kind, IDENTIFIER_TOKEN)) { 2688 if (identical(token.kind, IDENTIFIER_TOKEN)) {
2688 return parseExpressionStatementOrDeclaration(token); 2689 return parseExpressionStatementOrDeclaration(token);
2689 } else if (identical(value, '{')) { 2690 } else if (identical(value, '{')) {
2690 return parseBlock(token); 2691 return parseBlock(token);
2691 } else if (identical(value, 'return')) { 2692 } else if (identical(value, 'return')) {
2692 return parseReturnStatement(token); 2693 return parseReturnStatement(token);
2693 } else if (identical(value, 'var') || identical(value, 'final')) { 2694 } else if (identical(value, 'var') || identical(value, 'final')) {
2694 return parseVariablesDeclaration(token); 2695 return parseVariablesDeclaration(token);
2695 } else if (identical(value, 'if')) { 2696 } else if (identical(value, 'if')) {
2696 return parseIfStatement(token); 2697 return parseIfStatement(token);
2697 } else if (identical(value, 'await') && optional('for', token.next)) { 2698 } else if (identical(value, 'await') && optional('for', token.next)) {
2698 if (!inAsync) { 2699 if (!inAsync) {
2699 reportRecoverableErrorCode(token, fasta.codeAwaitForNotAsync); 2700 reportRecoverableError(token, fasta.messageAwaitForNotAsync);
2700 } 2701 }
2701 return parseForStatement(token, token.next); 2702 return parseForStatement(token, token.next);
2702 } else if (identical(value, 'for')) { 2703 } else if (identical(value, 'for')) {
2703 return parseForStatement(null, token); 2704 return parseForStatement(null, token);
2704 } else if (identical(value, 'rethrow')) { 2705 } else if (identical(value, 'rethrow')) {
2705 return parseRethrowStatement(token); 2706 return parseRethrowStatement(token);
2706 } else if (identical(value, 'throw') && optional(';', token.next)) { 2707 } else if (identical(value, 'throw') && optional(';', token.next)) {
2707 // TODO(kasperl): Stop dealing with throw here. 2708 // TODO(kasperl): Stop dealing with throw here.
2708 return parseRethrowStatement(token); 2709 return parseRethrowStatement(token);
2709 } else if (identical(value, 'void')) { 2710 } else if (identical(value, 'void')) {
(...skipping 17 matching lines...) Expand all
2727 } else if (identical(value, 'yield')) { 2728 } else if (identical(value, 'yield')) {
2728 switch (asyncState) { 2729 switch (asyncState) {
2729 case AsyncModifier.Sync: 2730 case AsyncModifier.Sync:
2730 return parseExpressionStatementOrDeclaration(token); 2731 return parseExpressionStatementOrDeclaration(token);
2731 2732
2732 case AsyncModifier.SyncStar: 2733 case AsyncModifier.SyncStar:
2733 case AsyncModifier.AsyncStar: 2734 case AsyncModifier.AsyncStar:
2734 return parseYieldStatement(token); 2735 return parseYieldStatement(token);
2735 2736
2736 case AsyncModifier.Async: 2737 case AsyncModifier.Async:
2737 reportRecoverableErrorCode(token, fasta.codeYieldNotGenerator); 2738 reportRecoverableError(token, fasta.messageYieldNotGenerator);
2738 return parseYieldStatement(token); 2739 return parseYieldStatement(token);
2739 } 2740 }
2740 throw "Internal error: Unknown asyncState: '$asyncState'."; 2741 throw "Internal error: Unknown asyncState: '$asyncState'.";
2741 } else if (identical(value, 'const')) { 2742 } else if (identical(value, 'const')) {
2742 return parseExpressionStatementOrConstDeclaration(token); 2743 return parseExpressionStatementOrConstDeclaration(token);
2743 } else if (token.isIdentifier) { 2744 } else if (token.isIdentifier) {
2744 return parseExpressionStatementOrDeclaration(token); 2745 return parseExpressionStatementOrDeclaration(token);
2745 } else if (identical(value, '@')) { 2746 } else if (identical(value, '@')) {
2746 return parseVariablesDeclaration(token); 2747 return parseVariablesDeclaration(token);
2747 } else { 2748 } else {
(...skipping 19 matching lines...) Expand all
2767 Token parseReturnStatement(Token token) { 2768 Token parseReturnStatement(Token token) {
2768 Token begin = token; 2769 Token begin = token;
2769 listener.beginReturnStatement(begin); 2770 listener.beginReturnStatement(begin);
2770 assert(identical('return', token.stringValue)); 2771 assert(identical('return', token.stringValue));
2771 token = token.next; 2772 token = token.next;
2772 if (optional(';', token)) { 2773 if (optional(';', token)) {
2773 listener.endReturnStatement(false, begin, token); 2774 listener.endReturnStatement(false, begin, token);
2774 } else { 2775 } else {
2775 token = parseExpression(token); 2776 token = parseExpression(token);
2776 if (inGenerator) { 2777 if (inGenerator) {
2777 reportRecoverableErrorCode(begin.next, fasta.codeGeneratorReturnsValue); 2778 reportRecoverableError(begin.next, fasta.messageGeneratorReturnsValue);
2778 } 2779 }
2779 listener.endReturnStatement(true, begin, token); 2780 listener.endReturnStatement(true, begin, token);
2780 } 2781 }
2781 return expectSemicolon(token); 2782 return expectSemicolon(token);
2782 } 2783 }
2783 2784
2784 Token parseExpressionStatementOrDeclaration(Token token) { 2785 Token parseExpressionStatementOrDeclaration(Token token) {
2785 return parseType(token, TypeContinuation.ExpressionStatementOrDeclaration); 2786 return parseType(token, TypeContinuation.ExpressionStatementOrDeclaration);
2786 } 2787 }
2787 2788
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
2880 BeginToken begin = token; 2881 BeginToken begin = token;
2881 token = (begin.endGroup != null) ? begin.endGroup : token; 2882 token = (begin.endGroup != null) ? begin.endGroup : token;
2882 } else if (token is ErrorToken) { 2883 } else if (token is ErrorToken) {
2883 reportErrorToken(token, false).next; 2884 reportErrorToken(token, false).next;
2884 } 2885 }
2885 token = token.next; 2886 token = token.next;
2886 } 2887 }
2887 return token; 2888 return token;
2888 } 2889 }
2889 2890
2890 Token parseRecoverExpression(Token token, FastaMessage message) => 2891 Token parseRecoverExpression(Token token, Message message) {
2891 parseExpression(token); 2892 return parseExpression(token);
2893 }
2892 2894
2893 int expressionDepth = 0; 2895 int expressionDepth = 0;
2894 Token parseExpression(Token token) { 2896 Token parseExpression(Token token) {
2895 if (expressionDepth++ > 500) { 2897 if (expressionDepth++ > 500) {
2896 // This happens in degenerate programs, for example, with a lot of nested 2898 // This happens in degenerate programs, for example, with a lot of nested
2897 // list literals. This is provoked by, for examaple, the language test 2899 // list literals. This is provoked by, for examaple, the language test
2898 // deep_nesting1_negative_test. 2900 // deep_nesting1_negative_test.
2899 return reportUnrecoverableErrorCode(token, fasta.codeStackOverflow).next; 2901 return reportUnrecoverableError(token, fasta.messageStackOverflow).next;
2900 } 2902 }
2901 listener.beginExpression(token); 2903 listener.beginExpression(token);
2902 Token result = optional('throw', token) 2904 Token result = optional('throw', token)
2903 ? parseThrowExpression(token, true) 2905 ? parseThrowExpression(token, true)
2904 : parsePrecedenceExpression(token, ASSIGNMENT_PRECEDENCE, true); 2906 : parsePrecedenceExpression(token, ASSIGNMENT_PRECEDENCE, true);
2905 expressionDepth--; 2907 expressionDepth--;
2906 return result; 2908 return result;
2907 } 2909 }
2908 2910
2909 Token parseExpressionWithoutCascade(Token token) { 2911 Token parseExpressionWithoutCascade(Token token) {
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
3030 String value = token.stringValue; 3032 String value = token.stringValue;
3031 // Prefix: 3033 // Prefix:
3032 if (optional('await', token)) { 3034 if (optional('await', token)) {
3033 if (inPlainSync) { 3035 if (inPlainSync) {
3034 return parsePrimary(token, IdentifierContext.expression); 3036 return parsePrimary(token, IdentifierContext.expression);
3035 } else { 3037 } else {
3036 return parseAwaitExpression(token, allowCascades); 3038 return parseAwaitExpression(token, allowCascades);
3037 } 3039 }
3038 } else if (identical(value, '+')) { 3040 } else if (identical(value, '+')) {
3039 // Dart no longer allows prefix-plus. 3041 // Dart no longer allows prefix-plus.
3040 reportRecoverableErrorCode(token, fasta.codeUnsupportedPrefixPlus); 3042 reportRecoverableError(token, fasta.messageUnsupportedPrefixPlus);
3041 return parseUnaryExpression(token.next, allowCascades); 3043 return parseUnaryExpression(token.next, allowCascades);
3042 } else if ((identical(value, '!')) || 3044 } else if ((identical(value, '!')) ||
3043 (identical(value, '-')) || 3045 (identical(value, '-')) ||
3044 (identical(value, '~'))) { 3046 (identical(value, '~'))) {
3045 Token operator = token; 3047 Token operator = token;
3046 // Right associative, so we recurse at the same precedence 3048 // Right associative, so we recurse at the same precedence
3047 // level. 3049 // level.
3048 token = parsePrecedenceExpression( 3050 token = parsePrecedenceExpression(
3049 token.next, POSTFIX_PRECEDENCE, allowCascades); 3051 token.next, POSTFIX_PRECEDENCE, allowCascades);
3050 listener.handleUnaryPrefixExpression(operator); 3052 listener.handleUnaryPrefixExpression(operator);
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
3133 listener.handleNoTypeArguments(token); 3135 listener.handleNoTypeArguments(token);
3134 return parseLiteralMapSuffix(token, null); 3136 return parseLiteralMapSuffix(token, null);
3135 } else if (kind == LT_TOKEN) { 3137 } else if (kind == LT_TOKEN) {
3136 return parseLiteralListOrMapOrFunction(token, null); 3138 return parseLiteralListOrMapOrFunction(token, null);
3137 } else { 3139 } else {
3138 return expressionExpected(token); 3140 return expressionExpected(token);
3139 } 3141 }
3140 } 3142 }
3141 3143
3142 Token expressionExpected(Token token) { 3144 Token expressionExpected(Token token) {
3143 token = reportUnrecoverableErrorCodeWithToken( 3145 token = reportUnrecoverableErrorWithToken(
3144 token, fasta.codeExpectedExpression) 3146 token, fasta.templateExpectedExpression)
3145 .next; 3147 .next;
3146 listener.handleInvalidExpression(token); 3148 listener.handleInvalidExpression(token);
3147 return token; 3149 return token;
3148 } 3150 }
3149 3151
3150 Token parseParenthesizedExpressionOrFunctionLiteral(Token token) { 3152 Token parseParenthesizedExpressionOrFunctionLiteral(Token token) {
3151 BeginToken beginGroup = token; 3153 BeginToken beginGroup = token;
3152 Token nextToken = beginGroup.endGroup.next; 3154 Token nextToken = beginGroup.endGroup.next;
3153 int kind = nextToken.kind; 3155 int kind = nextToken.kind;
3154 if (mayParseFunctionExpressions && 3156 if (mayParseFunctionExpressions &&
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
3199 Token parseSuperExpression(Token token, IdentifierContext context) { 3201 Token parseSuperExpression(Token token, IdentifierContext context) {
3200 Token beginToken = token; 3202 Token beginToken = token;
3201 listener.handleSuperExpression(token, context); 3203 listener.handleSuperExpression(token, context);
3202 token = token.next; 3204 token = token.next;
3203 if (optional('(', token)) { 3205 if (optional('(', token)) {
3204 // Super constructor. 3206 // Super constructor.
3205 listener.handleNoTypeArguments(token); 3207 listener.handleNoTypeArguments(token);
3206 token = parseArguments(token); 3208 token = parseArguments(token);
3207 listener.endSend(beginToken, token); 3209 listener.endSend(beginToken, token);
3208 } else if (optional("?.", token)) { 3210 } else if (optional("?.", token)) {
3209 reportRecoverableErrorCode(token, fasta.codeSuperNullAware); 3211 reportRecoverableError(token, fasta.messageSuperNullAware);
3210 } 3212 }
3211 return token; 3213 return token;
3212 } 3214 }
3213 3215
3214 /// '[' (expressionList ','?)? ']'. 3216 /// '[' (expressionList ','?)? ']'.
3215 /// 3217 ///
3216 /// Provide [constKeyword] if preceded by 'const', null if not. 3218 /// Provide [constKeyword] if preceded by 'const', null if not.
3217 /// This is a suffix parser because it is assumed that type arguments have 3219 /// This is a suffix parser because it is assumed that type arguments have
3218 /// been parsed, or `listener.handleNoTypeArguments(..)` has been executed. 3220 /// been parsed, or `listener.handleNoTypeArguments(..)` has been executed.
3219 Token parseLiteralListSuffix(Token token, Token constKeyword) { 3221 Token parseLiteralListSuffix(Token token, Token constKeyword) {
(...skipping 455 matching lines...) Expand 10 before | Expand all | Expand 10 after
3675 Token forKeyword = token; 3677 Token forKeyword = token;
3676 listener.beginForStatement(forKeyword); 3678 listener.beginForStatement(forKeyword);
3677 token = expect('for', token); 3679 token = expect('for', token);
3678 Token leftParenthesis = token; 3680 Token leftParenthesis = token;
3679 token = expect('(', token); 3681 token = expect('(', token);
3680 token = parseVariablesDeclarationOrExpressionOpt(token); 3682 token = parseVariablesDeclarationOrExpressionOpt(token);
3681 if (optional('in', token)) { 3683 if (optional('in', token)) {
3682 return parseForInRest(awaitToken, forKeyword, leftParenthesis, token); 3684 return parseForInRest(awaitToken, forKeyword, leftParenthesis, token);
3683 } else { 3685 } else {
3684 if (awaitToken != null) { 3686 if (awaitToken != null) {
3685 reportRecoverableErrorCode(awaitToken, fasta.codeInvalidAwaitFor); 3687 reportRecoverableError(awaitToken, fasta.messageInvalidAwaitFor);
3686 } 3688 }
3687 return parseForRest(forKeyword, leftParenthesis, token); 3689 return parseForRest(forKeyword, leftParenthesis, token);
3688 } 3690 }
3689 } 3691 }
3690 3692
3691 Token parseVariablesDeclarationOrExpressionOpt(Token token) { 3693 Token parseVariablesDeclarationOrExpressionOpt(Token token) {
3692 final String value = token.stringValue; 3694 final String value = token.stringValue;
3693 if (identical(value, ';')) { 3695 if (identical(value, ';')) {
3694 listener.handleNoExpression(token); 3696 listener.handleNoExpression(token);
3695 return token; 3697 return token;
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
3781 } 3783 }
3782 listener.endBlock(statementCount, begin, token); 3784 listener.endBlock(statementCount, begin, token);
3783 return expect('}', token); 3785 return expect('}', token);
3784 } 3786 }
3785 3787
3786 Token parseAwaitExpression(Token token, bool allowCascades) { 3788 Token parseAwaitExpression(Token token, bool allowCascades) {
3787 Token awaitToken = token; 3789 Token awaitToken = token;
3788 listener.beginAwaitExpression(awaitToken); 3790 listener.beginAwaitExpression(awaitToken);
3789 token = expect('await', token); 3791 token = expect('await', token);
3790 if (!inAsync) { 3792 if (!inAsync) {
3791 reportRecoverableErrorCode(awaitToken, fasta.codeAwaitNotAsync); 3793 reportRecoverableError(awaitToken, fasta.messageAwaitNotAsync);
3792 } 3794 }
3793 token = parsePrecedenceExpression(token, POSTFIX_PRECEDENCE, allowCascades); 3795 token = parsePrecedenceExpression(token, POSTFIX_PRECEDENCE, allowCascades);
3794 listener.endAwaitExpression(awaitToken, token); 3796 listener.endAwaitExpression(awaitToken, token);
3795 return token; 3797 return token;
3796 } 3798 }
3797 3799
3798 Token parseThrowExpression(Token token, bool allowCascades) { 3800 Token parseThrowExpression(Token token, bool allowCascades) {
3799 Token throwToken = token; 3801 Token throwToken = token;
3800 listener.beginThrowExpression(throwToken); 3802 listener.beginThrowExpression(throwToken);
3801 token = expect('throw', token); 3803 token = expect('throw', token);
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
3840 if (identical(value, 'catch')) { 3842 if (identical(value, 'catch')) {
3841 catchKeyword = token; 3843 catchKeyword = token;
3842 Token openParens = catchKeyword.next; 3844 Token openParens = catchKeyword.next;
3843 Token exceptionName = openParens.next; 3845 Token exceptionName = openParens.next;
3844 Token commaOrCloseParens = exceptionName.next; 3846 Token commaOrCloseParens = exceptionName.next;
3845 Token traceName = commaOrCloseParens.next; 3847 Token traceName = commaOrCloseParens.next;
3846 Token closeParens = traceName.next; 3848 Token closeParens = traceName.next;
3847 if (!optional("(", openParens)) { 3849 if (!optional("(", openParens)) {
3848 // Handled below by parseFormalParameters. 3850 // Handled below by parseFormalParameters.
3849 } else if (!exceptionName.isIdentifier) { 3851 } else if (!exceptionName.isIdentifier) {
3850 reportRecoverableErrorCode(exceptionName, fasta.codeCatchSyntax); 3852 reportRecoverableError(exceptionName, fasta.messageCatchSyntax);
3851 } else if (optional(")", commaOrCloseParens)) { 3853 } else if (optional(")", commaOrCloseParens)) {
3852 // OK: `catch (identifier)`. 3854 // OK: `catch (identifier)`.
3853 } else if (!optional(",", commaOrCloseParens)) { 3855 } else if (!optional(",", commaOrCloseParens)) {
3854 reportRecoverableErrorCode(exceptionName, fasta.codeCatchSyntax); 3856 reportRecoverableError(exceptionName, fasta.messageCatchSyntax);
3855 } else if (!traceName.isIdentifier) { 3857 } else if (!traceName.isIdentifier) {
3856 reportRecoverableErrorCode(exceptionName, fasta.codeCatchSyntax); 3858 reportRecoverableError(exceptionName, fasta.messageCatchSyntax);
3857 } else if (!optional(")", closeParens)) { 3859 } else if (!optional(")", closeParens)) {
3858 reportRecoverableErrorCode(exceptionName, fasta.codeCatchSyntax); 3860 reportRecoverableError(exceptionName, fasta.messageCatchSyntax);
3859 } 3861 }
3860 token = parseFormalParameters(token.next, MemberKind.Catch); 3862 token = parseFormalParameters(token.next, MemberKind.Catch);
3861 } 3863 }
3862 listener.endCatchClause(token); 3864 listener.endCatchClause(token);
3863 token = parseBlock(token); 3865 token = parseBlock(token);
3864 ++catchCount; 3866 ++catchCount;
3865 listener.handleCatchBlock(onKeyword, catchKeyword); 3867 listener.handleCatchBlock(onKeyword, catchKeyword);
3866 value = token.stringValue; // while condition 3868 value = token.stringValue; // while condition
3867 } 3869 }
3868 3870
3869 Token finallyKeyword = null; 3871 Token finallyKeyword = null;
3870 if (optional('finally', token)) { 3872 if (optional('finally', token)) {
3871 finallyKeyword = token; 3873 finallyKeyword = token;
3872 token = parseBlock(token.next); 3874 token = parseBlock(token.next);
3873 listener.handleFinallyBlock(finallyKeyword); 3875 listener.handleFinallyBlock(finallyKeyword);
3874 } else { 3876 } else {
3875 if (catchCount == 0) { 3877 if (catchCount == 0) {
3876 reportRecoverableErrorCode(tryKeyword, fasta.codeOnlyTry); 3878 reportRecoverableError(tryKeyword, fasta.messageOnlyTry);
3877 } 3879 }
3878 } 3880 }
3879 listener.endTryStatement(catchCount, tryKeyword, finallyKeyword); 3881 listener.endTryStatement(catchCount, tryKeyword, finallyKeyword);
3880 return token; 3882 return token;
3881 } 3883 }
3882 3884
3883 Token parseSwitchStatement(Token token) { 3885 Token parseSwitchStatement(Token token) {
3884 assert(optional('switch', token)); 3886 assert(optional('switch', token));
3885 Token switchKeyword = token; 3887 Token switchKeyword = token;
3886 listener.beginSwitchStatement(switchKeyword); 3888 listener.beginSwitchStatement(switchKeyword);
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
3947 token = parseExpression(token.next); 3949 token = parseExpression(token.next);
3948 listener.endCaseExpression(token); 3950 listener.endCaseExpression(token);
3949 Token colonToken = token; 3951 Token colonToken = token;
3950 token = expect(':', token); 3952 token = expect(':', token);
3951 listener.handleCaseMatch(caseKeyword, colonToken); 3953 listener.handleCaseMatch(caseKeyword, colonToken);
3952 expressionCount++; 3954 expressionCount++;
3953 peek = peekPastLabels(token); 3955 peek = peekPastLabels(token);
3954 } else { 3956 } else {
3955 if (expressionCount == 0) { 3957 if (expressionCount == 0) {
3956 // TODO(ahe): This is probably easy to recover from. 3958 // TODO(ahe): This is probably easy to recover from.
3957 reportUnrecoverableErrorCodeWithString( 3959 reportUnrecoverableError(
3958 token, fasta.codeExpectedButGot, "case"); 3960 token, fasta.templateExpectedButGot.withArguments("case"));
3959 } 3961 }
3960 break; 3962 break;
3961 } 3963 }
3962 } 3964 }
3963 listener.beginSwitchCase(labelCount, expressionCount, begin); 3965 listener.beginSwitchCase(labelCount, expressionCount, begin);
3964 // Finally zero or more statements. 3966 // Finally zero or more statements.
3965 int statementCount = 0; 3967 int statementCount = 0;
3966 while (!identical(token.kind, EOF_TOKEN)) { 3968 while (!identical(token.kind, EOF_TOKEN)) {
3967 String value = peek.stringValue; 3969 String value = peek.stringValue;
3968 if ((identical(value, 'case')) || 3970 if ((identical(value, 'case')) ||
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
4008 commaToken = token; 4010 commaToken = token;
4009 token = token.next; 4011 token = token.next;
4010 token = parseExpression(token); 4012 token = parseExpression(token);
4011 } 4013 }
4012 if (optional(',', token)) { 4014 if (optional(',', token)) {
4013 Token firstExtra = token.next; 4015 Token firstExtra = token.next;
4014 while (optional(',', token)) { 4016 while (optional(',', token)) {
4015 token = token.next; 4017 token = token.next;
4016 Token begin = token; 4018 Token begin = token;
4017 token = parseExpression(token); 4019 token = parseExpression(token);
4018 listener.handleExtraneousExpression(begin, 4020 listener.handleExtraneousExpression(
4019 fasta.codeAssertExtraneousArgument.format(uri, token.charOffset)); 4021 begin, fasta.messageAssertExtraneousArgument);
4020 } 4022 }
4021 reportRecoverableErrorCode( 4023 reportRecoverableError(firstExtra, fasta.messageAssertExtraneousArgument);
4022 firstExtra, fasta.codeAssertExtraneousArgument);
4023 } 4024 }
4024 Token rightParenthesis = token; 4025 Token rightParenthesis = token;
4025 token = expect(')', token); 4026 token = expect(')', token);
4026 mayParseFunctionExpressions = old; 4027 mayParseFunctionExpressions = old;
4027 listener.endAssert(assertKeyword, kind, leftParenthesis, commaToken, 4028 listener.endAssert(assertKeyword, kind, leftParenthesis, commaToken,
4028 rightParenthesis, token); 4029 rightParenthesis, token);
4029 if (kind == Assert.Expression) { 4030 if (kind == Assert.Expression) {
4030 reportRecoverableErrorCode(assertKeyword, fasta.codeAssertAsExpression); 4031 reportRecoverableError(assertKeyword, fasta.messageAssertAsExpression);
4031 } 4032 }
4032 return token; 4033 return token;
4033 } 4034 }
4034 4035
4035 Token parseAssertStatement(Token token) { 4036 Token parseAssertStatement(Token token) {
4036 token = parseAssert(token, Assert.Statement); 4037 token = parseAssert(token, Assert.Statement);
4037 return expectSemicolon(token); 4038 return expectSemicolon(token);
4038 } 4039 }
4039 4040
4040 Token parseContinueStatement(Token token) { 4041 Token parseContinueStatement(Token token) {
4041 assert(optional('continue', token)); 4042 assert(optional('continue', token));
4042 Token continueKeyword = token; 4043 Token continueKeyword = token;
4043 token = token.next; 4044 token = token.next;
4044 bool hasTarget = false; 4045 bool hasTarget = false;
4045 if (token.isIdentifier) { 4046 if (token.isIdentifier) {
4046 token = parseIdentifier(token, IdentifierContext.labelReference); 4047 token = parseIdentifier(token, IdentifierContext.labelReference);
4047 hasTarget = true; 4048 hasTarget = true;
4048 } 4049 }
4049 listener.handleContinueStatement(hasTarget, continueKeyword, token); 4050 listener.handleContinueStatement(hasTarget, continueKeyword, token);
4050 return expectSemicolon(token); 4051 return expectSemicolon(token);
4051 } 4052 }
4052 4053
4053 Token parseEmptyStatement(Token token) { 4054 Token parseEmptyStatement(Token token) {
4054 listener.handleEmptyStatement(token); 4055 listener.handleEmptyStatement(token);
4055 return expectSemicolon(token); 4056 return expectSemicolon(token);
4056 } 4057 }
4057 4058
4058 /// Don't call this method. Should only be used as a last resort when there 4059 /// Don't call this method. Should only be used as a last resort when there
4059 /// is no feasible way to recover from a parser error. 4060 /// is no feasible way to recover from a parser error.
4060 Token reportUnrecoverableError(Token token, FastaMessage format()) { 4061 Token reportUnrecoverableError(Token token, Message message) {
4061 Token next; 4062 Token next;
4062 if (token is ErrorToken) { 4063 if (token is ErrorToken) {
4063 next = reportErrorToken(token, false); 4064 next = reportErrorToken(token, false);
4064 } else { 4065 } else {
4065 next = listener.handleUnrecoverableError(token, format()); 4066 next = listener.handleUnrecoverableError(token, message);
4066 } 4067 }
4067 return next ?? skipToEof(token); 4068 return next ?? skipToEof(token);
4068 } 4069 }
4069 4070
4070 void reportRecoverableError(Token token, FastaMessage format()) { 4071 void reportRecoverableError(Token token, Message message) {
4071 if (token is ErrorToken) { 4072 if (token is ErrorToken) {
4072 reportErrorToken(token, true); 4073 reportErrorToken(token, true);
4073 } else { 4074 } else {
4074 listener.handleRecoverableError(token, format()); 4075 listener.handleRecoverableError(token, message);
4076 }
4077 }
4078
4079 Token reportUnrecoverableErrorWithToken(
4080 Token token, Template<_MessageWithArgument<Token>> template) {
4081 Token next;
4082 if (token is ErrorToken) {
4083 next = reportErrorToken(token, false);
4084 } else {
4085 next = listener.handleUnrecoverableError(
4086 token, template.withArguments(token));
4087 }
4088 return next ?? skipToEof(token);
4089 }
4090
4091 void reportRecoverableErrorWithToken(
4092 Token token, Template<_MessageWithArgument<Token>> template) {
4093 if (token is ErrorToken) {
4094 reportErrorToken(token, true);
4095 } else {
4096 listener.handleRecoverableError(token, template.withArguments(token));
4075 } 4097 }
4076 } 4098 }
4077 4099
4078 Token reportErrorToken(ErrorToken token, bool isRecoverable) { 4100 Token reportErrorToken(ErrorToken token, bool isRecoverable) {
4079 FastaCode code = token.errorCode; 4101 Code code = token.errorCode;
4080 FastaMessage message; 4102 Message message;
4081 if (code == fasta.codeAsciiControlCharacter) { 4103 if (code == fasta.codeAsciiControlCharacter) {
4082 message = fasta.codeAsciiControlCharacter 4104 message =
4083 .format(uri, token.charOffset, token.character); 4105 fasta.templateAsciiControlCharacter.withArguments(token.character);
4084 } else if (code == fasta.codeNonAsciiWhitespace) { 4106 } else if (code == fasta.codeNonAsciiWhitespace) {
4085 message = fasta.codeNonAsciiWhitespace 4107 message = fasta.templateNonAsciiWhitespace.withArguments(token.character);
4086 .format(uri, token.charOffset, token.character);
4087 } else if (code == fasta.codeEncoding) { 4108 } else if (code == fasta.codeEncoding) {
4088 message = fasta.codeEncoding.format(uri, token.charOffset); 4109 message = fasta.messageEncoding;
4089 } else if (code == fasta.codeNonAsciiIdentifier) { 4110 } else if (code == fasta.codeNonAsciiIdentifier) {
4090 message = fasta.codeNonAsciiIdentifier.format(uri, token.charOffset, 4111 message = fasta.templateNonAsciiIdentifier.withArguments(
4091 new String.fromCharCodes([token.character]), token.character); 4112 new String.fromCharCodes([token.character]), token.character);
4092 } else if (code == fasta.codeUnterminatedString) { 4113 } else if (code == fasta.codeUnterminatedString) {
4093 message = fasta.codeUnterminatedString 4114 message = fasta.templateUnterminatedString.withArguments(token.start);
4094 .format(uri, token.charOffset, token.start);
4095 } else if (code == fasta.codeUnmatchedToken) { 4115 } else if (code == fasta.codeUnmatchedToken) {
4096 Token begin = token.begin; 4116 Token begin = token.begin;
4097 message = fasta.codeUnmatchedToken 4117 message = fasta.templateUnmatchedToken
4098 .format(uri, token.charOffset, closeBraceFor(begin.lexeme), begin); 4118 .withArguments(closeBraceFor(begin.lexeme), begin);
4099 } else if (code == fasta.codeUnspecified) { 4119 } else if (code == fasta.codeUnspecified) {
4100 message = fasta.codeUnspecified 4120 message = fasta.templateUnspecified.withArguments(token.assertionMessage);
4101 .format(uri, token.charOffset, token.assertionMessage);
4102 } else { 4121 } else {
4103 message = code.format(uri, token.charOffset); 4122 message = code as Message;
4104 } 4123 }
4105 if (isRecoverable) { 4124 if (isRecoverable) {
4106 listener.handleRecoverableError(token, message); 4125 listener.handleRecoverableError(token, message);
4107 return null; 4126 return null;
4108 } else { 4127 } else {
4109 Token next = listener.handleUnrecoverableError(token, message); 4128 Token next = listener.handleUnrecoverableError(token, message);
4110 return next ?? skipToEof(token); 4129 return next ?? skipToEof(token);
4111 } 4130 }
4112 } 4131 }
4113 4132
4114 Token reportUnmatchedToken(BeginToken token) { 4133 Token reportUnmatchedToken(BeginToken token) {
4115 return reportUnrecoverableError( 4134 return reportUnrecoverableError(
4116 token, 4135 token,
4117 () => fasta.codeUnmatchedToken 4136 fasta.templateUnmatchedToken
4118 .format(uri, token.charOffset, closeBraceFor(token.lexeme), token)); 4137 .withArguments(closeBraceFor(token.lexeme), token));
4119 } 4138 }
4120 4139
4121 Token reportUnexpectedToken(Token token) { 4140 Token reportUnexpectedToken(Token token) {
4122 return reportUnrecoverableError(token, 4141 return reportUnrecoverableErrorWithToken(
4123 () => fasta.codeUnexpectedToken.format(uri, token.charOffset, token)); 4142 token, fasta.templateUnexpectedToken);
4124 }
4125
4126 void reportRecoverableErrorCode(Token token, FastaCode<NoArgument> code) {
4127 reportRecoverableError(token, () => code.format(uri, token.charOffset));
4128 }
4129
4130 Token reportUnrecoverableErrorCode(Token token, FastaCode<NoArgument> code) {
4131 return reportUnrecoverableError(
4132 token, () => code.format(uri, token.charOffset));
4133 }
4134
4135 void reportRecoverableErrorCodeWithToken(
4136 Token token, FastaCode<TokenArgument> code) {
4137 reportRecoverableError(
4138 token, () => code.format(uri, token.charOffset, token));
4139 }
4140
4141 Token reportUnrecoverableErrorCodeWithToken(
4142 Token token, FastaCode<TokenArgument> code) {
4143 return reportUnrecoverableError(
4144 token, () => code.format(uri, token.charOffset, token));
4145 }
4146
4147 Token reportUnrecoverableErrorCodeWithString(
4148 Token token, FastaCode<StringArgument> code, String string) {
4149 return reportUnrecoverableError(
4150 token, () => code.format(uri, token.charOffset, string));
4151 } 4143 }
4152 } 4144 }
4153 4145
4154 typedef FastaMessage NoArgument(Uri uri, int charOffset); 4146 // TODO(ahe): Remove when analyzer supports generalized function syntax.
4155 4147 typedef _MessageWithArgument<T> = Message Function(T);
4156 typedef FastaMessage TokenArgument(Uri uri, int charOffset, Token token);
4157
4158 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/scanner/error_token.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698