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

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

Issue 2778213002: Use message.yaml in parser. (Closed)
Patch Set: Update subpackage relationships. Created 3 years, 8 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'
8 show
9 FastaCode,
10 FastaMessage,
11 codeAbstractNotSync,
12 codeAsciiControlCharacter,
13 codeAsyncAsIdentifier,
14 codeAwaitAsIdentifier,
15 codeAwaitForNotAsync,
16 codeAwaitNotAsync,
17 codeBuiltInIdentifierAsType,
18 codeBuiltInIdentifierInDeclaration,
19 codeEmptyNamedParameterList,
20 codeEmptyOptionalParameterList,
21 codeEncoding,
22 codeExpectedBlockToSkip,
23 codeExpectedBody,
24 codeExpectedButGot,
25 codeExpectedClassBody,
26 codeExpectedClassBodyToSkip,
27 codeExpectedDeclaration,
28 codeExpectedExpression,
29 codeExpectedFunctionBody,
30 codeExpectedIdentifier,
31 codeExpectedOpenParens,
32 codeExpectedString,
33 codeExpectedType,
34 codeExtraneousModifier,
35 codeExtraneousModifierReplace,
36 codeFactoryNotSync,
37 codeGeneratorReturnsValue,
38 codeInvalidAwaitFor,
39 codeInvalidInlineFunctionType,
40 codeInvalidSyncModifier,
41 codeInvalidVoid,
42 codeNonAsciiIdentifier,
43 codeNonAsciiWhitespace,
44 codeOnlyTry,
45 codePositionalParameterWithEquals,
46 codeRequiredParameterWithDefault,
47 codeSetterNotSync,
48 codeStackOverflow,
49 codeUnexpectedToken,
50 codeUnmatchedToken,
51 codeUnspecified,
52 codeUnsupportedPrefixPlus,
53 codeUnterminatedString,
54 codeYieldAsIdentifier,
55 codeYieldNotGenerator;
56
7 import '../scanner.dart' show ErrorToken; 57 import '../scanner.dart' show ErrorToken;
8 58
9 import '../scanner/recover.dart' show closeBraceFor, skipToEof; 59 import '../scanner/recover.dart' show closeBraceFor, skipToEof;
10 60
11 import '../scanner/keyword.dart' show Keyword; 61 import '../scanner/keyword.dart' show Keyword;
12 62
13 import '../scanner/precedence.dart' 63 import '../scanner/precedence.dart'
14 show 64 show
15 ASSIGNMENT_PRECEDENCE, 65 ASSIGNMENT_PRECEDENCE,
16 AS_INFO, 66 AS_INFO,
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
63 STRING_TOKEN; 113 STRING_TOKEN;
64 114
65 import '../scanner/characters.dart' show $CLOSE_CURLY_BRACKET; 115 import '../scanner/characters.dart' show $CLOSE_CURLY_BRACKET;
66 116
67 import '../util/link.dart' show Link; 117 import '../util/link.dart' show Link;
68 118
69 import 'async_modifier.dart' show AsyncModifier; 119 import 'async_modifier.dart' show AsyncModifier;
70 120
71 import 'listener.dart' show Listener; 121 import 'listener.dart' show Listener;
72 122
73 import 'error_kind.dart' show ErrorKind;
74
75 import 'identifier_context.dart' show IdentifierContext; 123 import 'identifier_context.dart' show IdentifierContext;
76 124
77 /// Returns true if [token] is the symbol or keyword [value]. 125 /// Returns true if [token] is the symbol or keyword [value].
78 bool optional(String value, Token token) { 126 bool optional(String value, Token token) {
79 return identical(value, token.stringValue); 127 return identical(value, token.stringValue);
80 } 128 }
81 129
82 class FormalParameterType { 130 class FormalParameterType {
83 final String type; 131 final String type;
84 const FormalParameterType(this.type); 132 const FormalParameterType(this.type);
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
125 /// As a consequence of this, one should not use `==` to compare strings in the 173 /// As a consequence of this, one should not use `==` to compare strings in the
126 /// parser. One should favor the methods [optional] and [expected] to recognize 174 /// parser. One should favor the methods [optional] and [expected] to recognize
127 /// keywords or identifiers. In some cases, it's possible to compare a token's 175 /// keywords or identifiers. In some cases, it's possible to compare a token's
128 /// `stringValue` using [identical], but normally [optional] will suffice. 176 /// `stringValue` using [identical], but normally [optional] will suffice.
129 /// 177 ///
130 /// Historically, we over-used identical, and when identical is used on other 178 /// Historically, we over-used identical, and when identical is used on other
131 /// objects than strings, it can often be replaced by `==`. 179 /// objects than strings, it can often be replaced by `==`.
132 class Parser { 180 class Parser {
133 final Listener listener; 181 final Listener listener;
134 182
183 Uri get uri => listener.uri;
184
135 bool mayParseFunctionExpressions = true; 185 bool mayParseFunctionExpressions = true;
136 186
137 /// Represents parser state: what asynchronous syntax is allowed in the 187 /// Represents parser state: what asynchronous syntax is allowed in the
138 /// function being currently parsed. In rare situations, this can be set by 188 /// function being currently parsed. In rare situations, this can be set by
139 /// external clients, for example, to parse an expression outside a function. 189 /// external clients, for example, to parse an expression outside a function.
140 AsyncModifier asyncState = AsyncModifier.Sync; 190 AsyncModifier asyncState = AsyncModifier.Sync;
141 191
142 Parser(this.listener); 192 Parser(this.listener);
143 193
144 bool get inGenerator { 194 bool get inGenerator {
(...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after
480 listener.handleNoFormalParameters(token); 530 listener.handleNoFormalParameters(token);
481 return token; 531 return token;
482 } 532 }
483 } 533 }
484 534
485 Token skipFormalParameters(Token token) { 535 Token skipFormalParameters(Token token) {
486 // TODO(ahe): Shouldn't this be `beginFormalParameters`? 536 // TODO(ahe): Shouldn't this be `beginFormalParameters`?
487 listener.beginOptionalFormalParameters(token); 537 listener.beginOptionalFormalParameters(token);
488 if (!optional('(', token)) { 538 if (!optional('(', token)) {
489 if (optional(';', token)) { 539 if (optional(';', token)) {
490 reportRecoverableError(token, ErrorKind.ExpectedOpenParens); 540 reportRecoverableErrorCode(token, codeExpectedOpenParens);
491 return token; 541 return token;
492 } 542 }
493 return reportUnrecoverableError( 543 return reportUnrecoverableErrorCodeWithString(
494 token, ErrorKind.ExpectedButGot, {"expected": "("})?.next; 544 token, codeExpectedButGot, "(")
545 .next;
495 } 546 }
496 BeginGroupToken beginGroupToken = token; 547 BeginGroupToken beginGroupToken = token;
497 Token endToken = beginGroupToken.endGroup; 548 Token endToken = beginGroupToken.endGroup;
498 listener.endFormalParameters(0, token, endToken); 549 listener.endFormalParameters(0, token, endToken);
499 return endToken.next; 550 return endToken.next;
500 } 551 }
501 552
502 /// Parses the formal parameter list of a function. 553 /// Parses the formal parameter list of a function.
503 /// 554 ///
504 /// If [inFunctionType] is true, then the names may be omitted (except for 555 /// If [inFunctionType] is true, then the names may be omitted (except for
(...skipping 13 matching lines...) Expand all
518 if (identical(value, '[')) { 569 if (identical(value, '[')) {
519 token = parseOptionalFormalParameters(token, false, 570 token = parseOptionalFormalParameters(token, false,
520 inFunctionType: inFunctionType); 571 inFunctionType: inFunctionType);
521 break; 572 break;
522 } else if (identical(value, '{')) { 573 } else if (identical(value, '{')) {
523 token = parseOptionalFormalParameters(token, true, 574 token = parseOptionalFormalParameters(token, true,
524 inFunctionType: inFunctionType); 575 inFunctionType: inFunctionType);
525 break; 576 break;
526 } else if (identical(value, '[]')) { 577 } else if (identical(value, '[]')) {
527 --parameterCount; 578 --parameterCount;
528 reportRecoverableError(token, ErrorKind.EmptyOptionalParameterList); 579 reportRecoverableErrorCode(token, codeEmptyOptionalParameterList);
529 token = token.next; 580 token = token.next;
530 break; 581 break;
531 } 582 }
532 token = parseFormalParameter(token, FormalParameterType.REQUIRED, 583 token = parseFormalParameter(token, FormalParameterType.REQUIRED,
533 inFunctionType: inFunctionType); 584 inFunctionType: inFunctionType);
534 } while (optional(',', token)); 585 } while (optional(',', token));
535 listener.endFormalParameters(parameterCount, begin, token); 586 listener.endFormalParameters(parameterCount, begin, token);
536 return expect(')', token); 587 return expect(')', token);
537 } 588 }
538 589
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
586 Token inlineFunctionTypeStart = token; 637 Token inlineFunctionTypeStart = token;
587 listener.beginFunctionTypedFormalParameter(token); 638 listener.beginFunctionTypedFormalParameter(token);
588 listener.handleNoTypeVariables(token); 639 listener.handleNoTypeVariables(token);
589 token = parseFormalParameters(token); 640 token = parseFormalParameters(token);
590 listener.endFunctionTypedFormalParameter( 641 listener.endFunctionTypedFormalParameter(
591 covariantKeyword, thisKeyword, kind); 642 covariantKeyword, thisKeyword, kind);
592 // Generalized function types don't allow inline function types. 643 // Generalized function types don't allow inline function types.
593 // The following isn't allowed: 644 // The following isn't allowed:
594 // int Function(int bar(String x)). 645 // int Function(int bar(String x)).
595 if (inFunctionType) { 646 if (inFunctionType) {
596 reportRecoverableError( 647 reportRecoverableErrorCode(
597 inlineFunctionTypeStart, ErrorKind.InvalidInlineFunctionType); 648 inlineFunctionTypeStart, codeInvalidInlineFunctionType);
598 } 649 }
599 } else if (optional('<', token)) { 650 } else if (optional('<', token)) {
600 Token inlineFunctionTypeStart = token; 651 Token inlineFunctionTypeStart = token;
601 listener.beginFunctionTypedFormalParameter(token); 652 listener.beginFunctionTypedFormalParameter(token);
602 token = parseTypeVariablesOpt(token); 653 token = parseTypeVariablesOpt(token);
603 token = parseFormalParameters(token); 654 token = parseFormalParameters(token);
604 listener.endFunctionTypedFormalParameter( 655 listener.endFunctionTypedFormalParameter(
605 covariantKeyword, thisKeyword, kind); 656 covariantKeyword, thisKeyword, kind);
606 // Generalized function types don't allow inline function types. 657 // Generalized function types don't allow inline function types.
607 // The following isn't allowed: 658 // The following isn't allowed:
608 // int Function(int bar(String x)). 659 // int Function(int bar(String x)).
609 if (inFunctionType) { 660 if (inFunctionType) {
610 reportRecoverableError( 661 reportRecoverableErrorCode(
611 inlineFunctionTypeStart, ErrorKind.InvalidInlineFunctionType); 662 inlineFunctionTypeStart, codeInvalidInlineFunctionType);
612 } 663 }
613 } 664 }
614 String value = token.stringValue; 665 String value = token.stringValue;
615 if ((identical('=', value)) || (identical(':', value))) { 666 if ((identical('=', value)) || (identical(':', value))) {
616 // TODO(ahe): Validate that these are only used for optional parameters. 667 // TODO(ahe): Validate that these are only used for optional parameters.
617 Token equal = token; 668 Token equal = token;
618 token = parseExpression(token.next); 669 token = parseExpression(token.next);
619 listener.handleValuedFormalParameter(equal, token); 670 listener.handleValuedFormalParameter(equal, token);
620 if (kind.isRequired) { 671 if (kind.isRequired) {
621 reportRecoverableError(equal, ErrorKind.RequiredParameterWithDefault); 672 reportRecoverableErrorCode(equal, codeRequiredParameterWithDefault);
622 } else if (kind.isPositional && identical(':', value)) { 673 } else if (kind.isPositional && identical(':', value)) {
623 reportRecoverableError(equal, ErrorKind.PositionalParameterWithEquals); 674 reportRecoverableErrorCode(equal, codePositionalParameterWithEquals);
624 } 675 }
625 } else { 676 } else {
626 listener.handleFormalParameterWithoutValue(token); 677 listener.handleFormalParameterWithoutValue(token);
627 } 678 }
628 listener.endFormalParameter(covariantKeyword, thisKeyword, nameToken, kind); 679 listener.endFormalParameter(covariantKeyword, thisKeyword, nameToken, kind);
629 return token; 680 return token;
630 } 681 }
631 682
632 Token parseOptionalFormalParameters(Token token, bool isNamed, 683 Token parseOptionalFormalParameters(Token token, bool isNamed,
633 {bool inFunctionType: false}) { 684 {bool inFunctionType: false}) {
634 Token begin = token; 685 Token begin = token;
635 listener.beginOptionalFormalParameters(begin); 686 listener.beginOptionalFormalParameters(begin);
636 assert((isNamed && optional('{', token)) || optional('[', token)); 687 assert((isNamed && optional('{', token)) || optional('[', token));
637 int parameterCount = 0; 688 int parameterCount = 0;
638 do { 689 do {
639 token = token.next; 690 token = token.next;
640 if (isNamed && optional('}', token)) { 691 if (isNamed && optional('}', token)) {
641 break; 692 break;
642 } else if (!isNamed && optional(']', token)) { 693 } else if (!isNamed && optional(']', token)) {
643 break; 694 break;
644 } 695 }
645 var type = 696 var type =
646 isNamed ? FormalParameterType.NAMED : FormalParameterType.POSITIONAL; 697 isNamed ? FormalParameterType.NAMED : FormalParameterType.POSITIONAL;
647 token = parseFormalParameter(token, type, inFunctionType: inFunctionType); 698 token = parseFormalParameter(token, type, inFunctionType: inFunctionType);
648 ++parameterCount; 699 ++parameterCount;
649 } while (optional(',', token)); 700 } while (optional(',', token));
650 if (parameterCount == 0) { 701 if (parameterCount == 0) {
651 reportRecoverableError( 702 reportRecoverableErrorCode(
652 token, 703 token,
653 isNamed 704 isNamed
654 ? ErrorKind.EmptyNamedParameterList 705 ? codeEmptyNamedParameterList
655 : ErrorKind.EmptyOptionalParameterList); 706 : codeEmptyOptionalParameterList);
656 } 707 }
657 listener.endOptionalFormalParameters(parameterCount, begin, token); 708 listener.endOptionalFormalParameters(parameterCount, begin, token);
658 if (isNamed) { 709 if (isNamed) {
659 return expect('}', token); 710 return expect('}', token);
660 } else { 711 } else {
661 return expect(']', token); 712 return expect(']', token);
662 } 713 }
663 } 714 }
664 715
665 Token parseTypeOpt(Token token) { 716 Token parseTypeOpt(Token token) {
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
784 Token parseQualifiedRest(Token token, IdentifierContext context) { 835 Token parseQualifiedRest(Token token, IdentifierContext context) {
785 assert(optional('.', token)); 836 assert(optional('.', token));
786 Token period = token; 837 Token period = token;
787 token = parseIdentifier(token.next, context); 838 token = parseIdentifier(token.next, context);
788 listener.handleQualified(period); 839 listener.handleQualified(period);
789 return token; 840 return token;
790 } 841 }
791 842
792 Token skipBlock(Token token) { 843 Token skipBlock(Token token) {
793 if (!optional('{', token)) { 844 if (!optional('{', token)) {
794 return reportUnrecoverableError(token, ErrorKind.ExpectedBlockToSkip) 845 return reportUnrecoverableErrorCode(token, codeExpectedBlockToSkip).next;
795 ?.next;
796 } 846 }
797 BeginGroupToken beginGroupToken = token; 847 BeginGroupToken beginGroupToken = token;
798 Token endGroup = beginGroupToken.endGroup; 848 Token endGroup = beginGroupToken.endGroup;
799 if (endGroup == null) { 849 if (endGroup == null || !identical(endGroup.kind, $CLOSE_CURLY_BRACKET)) {
800 return reportUnrecoverableError(beginGroupToken, ErrorKind.UnmatchedToken) 850 return reportUnmatchedToken(beginGroupToken).next;
801 ?.next;
802 } else if (!identical(endGroup.kind, $CLOSE_CURLY_BRACKET)) {
803 return reportUnrecoverableError(beginGroupToken, ErrorKind.UnmatchedToken)
804 ?.next;
805 } 851 }
806 return beginGroupToken.endGroup; 852 return beginGroupToken.endGroup;
807 } 853 }
808 854
809 Token parseEnum(Token token) { 855 Token parseEnum(Token token) {
810 listener.beginEnum(token); 856 listener.beginEnum(token);
811 Token enumKeyword = token; 857 Token enumKeyword = token;
812 token = parseIdentifier(token.next, IdentifierContext.enumDeclaration); 858 token = parseIdentifier(token.next, IdentifierContext.enumDeclaration);
813 token = expect('{', token); 859 token = expect('{', token);
814 int count = 0; 860 int count = 0;
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
903 } while (optional(',', token)); 949 } while (optional(',', token));
904 } 950 }
905 token = parseClassBody(token); 951 token = parseClassBody(token);
906 listener.endClassDeclaration(interfacesCount, begin, classKeyword, 952 listener.endClassDeclaration(interfacesCount, begin, classKeyword,
907 extendsKeyword, implementsKeyword, token); 953 extendsKeyword, implementsKeyword, token);
908 return token.next; 954 return token.next;
909 } 955 }
910 956
911 Token parseStringPart(Token token) { 957 Token parseStringPart(Token token) {
912 if (token.kind != STRING_TOKEN) { 958 if (token.kind != STRING_TOKEN) {
913 token = reportUnrecoverableError(token, ErrorKind.ExpectedString)?.next; 959 token =
960 reportUnrecoverableErrorCodeWithToken(token, codeExpectedString).next;
914 } 961 }
915 listener.handleStringPart(token); 962 listener.handleStringPart(token);
916 return token.next; 963 return token.next;
917 } 964 }
918 965
919 Token parseIdentifier(Token token, IdentifierContext context) { 966 Token parseIdentifier(Token token, IdentifierContext context) {
920 if (!token.isIdentifier()) { 967 if (!token.isIdentifier()) {
921 token = 968 token =
922 reportUnrecoverableError(token, ErrorKind.ExpectedIdentifier)?.next; 969 reportUnrecoverableErrorCodeWithToken(token, codeExpectedIdentifier)
970 .next;
923 } else if (token.isBuiltInIdentifier && 971 } else if (token.isBuiltInIdentifier &&
924 !context.isBuiltInIdentifierAllowed) { 972 !context.isBuiltInIdentifierAllowed) {
925 if (context.inDeclaration) { 973 if (context.inDeclaration) {
926 reportRecoverableError(token, ErrorKind.BuiltInIdentifierInDeclaration); 974 reportRecoverableErrorCodeWithToken(
975 token, codeBuiltInIdentifierInDeclaration);
927 } else if (!optional("dynamic", token)) { 976 } else if (!optional("dynamic", token)) {
928 reportRecoverableError(token, ErrorKind.BuiltInIdentifierAsType); 977 reportRecoverableErrorCodeWithToken(token, codeBuiltInIdentifierAsType);
929 } 978 }
930 } else if (!inPlainSync && token.isPseudo) { 979 } else if (!inPlainSync && token.isPseudo) {
931 if (optional('await', token)) { 980 if (optional('await', token)) {
932 reportRecoverableError(token, ErrorKind.AwaitAsIdentifier); 981 reportRecoverableErrorCode(token, codeAwaitAsIdentifier);
933 } else if (optional('yield', token)) { 982 } else if (optional('yield', token)) {
934 reportRecoverableError(token, ErrorKind.YieldAsIdentifier); 983 reportRecoverableErrorCode(token, codeYieldAsIdentifier);
935 } else if (optional('async', token)) { 984 } else if (optional('async', token)) {
936 reportRecoverableError(token, ErrorKind.AsyncAsIdentifier); 985 reportRecoverableErrorCode(token, codeAsyncAsIdentifier);
937 } 986 }
938 } 987 }
939 listener.handleIdentifier(token, context); 988 listener.handleIdentifier(token, context);
940 return token.next; 989 return token.next;
941 } 990 }
942 991
943 Token expect(String string, Token token) { 992 Token expect(String string, Token token) {
944 if (!identical(string, token.stringValue)) { 993 if (!identical(string, token.stringValue)) {
945 return reportUnrecoverableError( 994 return reportUnrecoverableErrorCodeWithString(
946 token, ErrorKind.ExpectedButGot, {"expected": string})?.next; 995 token, codeExpectedButGot, string)
996 .next;
947 } 997 }
948 return token.next; 998 return token.next;
949 } 999 }
950 1000
951 Token parseTypeVariable(Token token) { 1001 Token parseTypeVariable(Token token) {
952 listener.beginTypeVariable(token); 1002 listener.beginTypeVariable(token);
953 token = parseMetadataStar(token); 1003 token = parseMetadataStar(token);
954 token = parseIdentifier(token, IdentifierContext.typeVariableDeclaration); 1004 token = parseIdentifier(token, IdentifierContext.typeVariableDeclaration);
955 Token extendsOrSuper = null; 1005 Token extendsOrSuper = null;
956 if (optional('extends', token) || optional('super', token)) { 1006 if (optional('extends', token) || optional('super', token)) {
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
1003 } else if (identical(token.stringValue, 'void') && 1053 } else if (identical(token.stringValue, 'void') &&
1004 isGeneralizedFunctionType(token.next)) { 1054 isGeneralizedFunctionType(token.next)) {
1005 listener.handleVoidKeyword(token); 1055 listener.handleVoidKeyword(token);
1006 token = token.next; 1056 token = token.next;
1007 } else { 1057 } else {
1008 if (isValidTypeReference(token)) { 1058 if (isValidTypeReference(token)) {
1009 token = parseIdentifier(token, IdentifierContext.typeReference); 1059 token = parseIdentifier(token, IdentifierContext.typeReference);
1010 token = parseQualifiedRestOpt( 1060 token = parseQualifiedRestOpt(
1011 token, IdentifierContext.typeReferenceContinuation); 1061 token, IdentifierContext.typeReferenceContinuation);
1012 } else { 1062 } else {
1013 token = reportUnrecoverableError(token, ErrorKind.ExpectedType)?.next; 1063 token =
1064 reportUnrecoverableErrorCodeWithToken(token, codeExpectedType).next;
1014 listener.handleInvalidTypeReference(token); 1065 listener.handleInvalidTypeReference(token);
1015 } 1066 }
1016 token = parseTypeArgumentsOpt(token); 1067 token = parseTypeArgumentsOpt(token);
1017 listener.handleType(begin, token); 1068 listener.handleType(begin, token);
1018 } 1069 }
1019 1070
1020 // While we see a `Function(` treat the pushed type as return type. 1071 // While we see a `Function(` treat the pushed type as return type.
1021 // For example: `int Function() Function(int) Function(String x)`. 1072 // For example: `int Function() Function(int) Function(String x)`.
1022 while (isGeneralizedFunctionType(token)) { 1073 while (isGeneralizedFunctionType(token)) {
1023 token = parseFunctionType(token); 1074 token = parseFunctionType(token);
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
1079 handleNoStuff(token); 1130 handleNoStuff(token);
1080 return token; 1131 return token;
1081 } 1132 }
1082 1133
1083 Token parseTopLevelMember(Token token) { 1134 Token parseTopLevelMember(Token token) {
1084 Token start = token; 1135 Token start = token;
1085 listener.beginTopLevelMember(token); 1136 listener.beginTopLevelMember(token);
1086 1137
1087 Link<Token> identifiers = findMemberName(token); 1138 Link<Token> identifiers = findMemberName(token);
1088 if (identifiers.isEmpty) { 1139 if (identifiers.isEmpty) {
1089 return reportUnrecoverableError(start, ErrorKind.ExpectedDeclaration) 1140 return reportUnrecoverableErrorCodeWithToken(
1090 ?.next; 1141 start, codeExpectedDeclaration)
1142 .next;
1091 } 1143 }
1092 Token afterName = identifiers.head; 1144 Token afterName = identifiers.head;
1093 identifiers = identifiers.tail; 1145 identifiers = identifiers.tail;
1094 1146
1095 if (identifiers.isEmpty) { 1147 if (identifiers.isEmpty) {
1096 return reportUnrecoverableError(start, ErrorKind.ExpectedDeclaration) 1148 return reportUnrecoverableErrorCodeWithToken(
1097 ?.next; 1149 start, codeExpectedDeclaration)
1150 .next;
1098 } 1151 }
1099 Token name = identifiers.head; 1152 Token name = identifiers.head;
1100 identifiers = identifiers.tail; 1153 identifiers = identifiers.tail;
1101 Token getOrSet; 1154 Token getOrSet;
1102 if (!identifiers.isEmpty) { 1155 if (!identifiers.isEmpty) {
1103 String value = identifiers.head.stringValue; 1156 String value = identifiers.head.stringValue;
1104 if ((identical(value, 'get')) || (identical(value, 'set'))) { 1157 if ((identical(value, 'get')) || (identical(value, 'set'))) {
1105 getOrSet = identifiers.head; 1158 getOrSet = identifiers.head;
1106 identifiers = identifiers.tail; 1159 identifiers = identifiers.tail;
1107 } 1160 }
(...skipping 24 matching lines...) Expand all
1132 if (getOrSet != null) { 1185 if (getOrSet != null) {
1133 // If we found a "get" keyword, this must be an abstract 1186 // If we found a "get" keyword, this must be an abstract
1134 // getter. 1187 // getter.
1135 isField = (!identical(getOrSet.stringValue, 'get')); 1188 isField = (!identical(getOrSet.stringValue, 'get'));
1136 // TODO(ahe): This feels like a hack. 1189 // TODO(ahe): This feels like a hack.
1137 } else { 1190 } else {
1138 isField = true; 1191 isField = true;
1139 } 1192 }
1140 break; 1193 break;
1141 } else { 1194 } else {
1142 token = 1195 token = reportUnexpectedToken(token).next;
1143 reportUnrecoverableError(token, ErrorKind.UnexpectedToken)?.next;
1144 if (identical(token.kind, EOF_TOKEN)) return token; 1196 if (identical(token.kind, EOF_TOKEN)) return token;
1145 } 1197 }
1146 } 1198 }
1147 var modifiers = identifiers.reverse(); 1199 var modifiers = identifiers.reverse();
1148 return isField 1200 return isField
1149 ? parseFields(start, modifiers, type, getOrSet, name, true) 1201 ? parseFields(start, modifiers, type, getOrSet, name, true)
1150 : parseTopLevelMethod(start, modifiers, type, getOrSet, name); 1202 : parseTopLevelMethod(start, modifiers, type, getOrSet, name);
1151 } 1203 }
1152 1204
1153 bool isVarFinalOrConst(Token token) { 1205 bool isVarFinalOrConst(Token token) {
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
1200 } 1252 }
1201 } 1253 }
1202 bool hasTypeOrModifier = hasType; 1254 bool hasTypeOrModifier = hasType;
1203 if (varFinalOrConst != null) { 1255 if (varFinalOrConst != null) {
1204 parseModifier(varFinalOrConst); 1256 parseModifier(varFinalOrConst);
1205 modifierCount++; 1257 modifierCount++;
1206 hasTypeOrModifier = true; 1258 hasTypeOrModifier = true;
1207 modifierList.remove(varFinalOrConst); 1259 modifierList.remove(varFinalOrConst);
1208 } 1260 }
1209 listener.handleModifiers(modifierCount); 1261 listener.handleModifiers(modifierCount);
1210 var kind = hasTypeOrModifier
1211 ? ErrorKind.ExtraneousModifier
1212 : ErrorKind.ExtraneousModifierReplace;
1213 for (Token modifier in modifierList) { 1262 for (Token modifier in modifierList) {
1214 reportRecoverableError(modifier, kind, {'modifier': modifier}); 1263 reportRecoverableErrorCodeWithToken(
1264 modifier,
1265 hasTypeOrModifier
1266 ? codeExtraneousModifier
1267 : codeExtraneousModifierReplace);
1215 } 1268 }
1216 return null; 1269 return null;
1217 } 1270 }
1218 1271
1219 /// Removes the optional `covariant` token from the modifiers, if there 1272 /// Removes the optional `covariant` token from the modifiers, if there
1220 /// is no `static` in the list, and `covariant` is the first modifier. 1273 /// is no `static` in the list, and `covariant` is the first modifier.
1221 Link<Token> removeOptCovariantTokenIfNotStatic(Link<Token> modifiers) { 1274 Link<Token> removeOptCovariantTokenIfNotStatic(Link<Token> modifiers) {
1222 if (modifiers.isEmpty || 1275 if (modifiers.isEmpty ||
1223 !identical(modifiers.first.stringValue, 'covariant')) { 1276 !identical(modifiers.first.stringValue, 'covariant')) {
1224 return modifiers; 1277 return modifiers;
(...skipping 24 matching lines...) Expand all
1249 Token varFinalOrConst = 1302 Token varFinalOrConst =
1250 expectVarFinalOrConst(modifiers, hasType, !isTopLevel); 1303 expectVarFinalOrConst(modifiers, hasType, !isTopLevel);
1251 bool isVar = false; 1304 bool isVar = false;
1252 bool hasModifier = false; 1305 bool hasModifier = false;
1253 if (varFinalOrConst != null) { 1306 if (varFinalOrConst != null) {
1254 hasModifier = true; 1307 hasModifier = true;
1255 isVar = optional('var', varFinalOrConst); 1308 isVar = optional('var', varFinalOrConst);
1256 } 1309 }
1257 1310
1258 if (getOrSet != null) { 1311 if (getOrSet != null) {
1259 var kind = (hasModifier || hasType) 1312 reportRecoverableErrorCodeWithToken(
1260 ? ErrorKind.ExtraneousModifier 1313 getOrSet,
1261 : ErrorKind.ExtraneousModifierReplace; 1314 hasModifier || hasType
1262 reportRecoverableError(getOrSet, kind, {'modifier': getOrSet}); 1315 ? codeExtraneousModifier
1316 : codeExtraneousModifierReplace);
1263 } 1317 }
1264 1318
1265 if (!hasType) { 1319 if (!hasType) {
1266 listener.handleNoType(name); 1320 listener.handleNoType(name);
1267 } else if (optional('void', type) && 1321 } else if (optional('void', type) &&
1268 !isGeneralizedFunctionType(type.next)) { 1322 !isGeneralizedFunctionType(type.next)) {
1269 listener.handleNoType(name); 1323 listener.handleNoType(name);
1270 // TODO(ahe): This error is reported twice, second time is from 1324 // TODO(ahe): This error is reported twice, second time is from
1271 // [parseVariablesDeclarationMaybeSemicolon] via 1325 // [parseVariablesDeclarationMaybeSemicolon] via
1272 // [PartialFieldListElement.parseNode]. 1326 // [PartialFieldListElement.parseNode].
1273 reportRecoverableError(type, ErrorKind.InvalidVoid); 1327 reportRecoverableErrorCode(type, codeInvalidVoid);
1274 } else { 1328 } else {
1275 parseType(type); 1329 parseType(type);
1276 if (isVar) { 1330 if (isVar) {
1277 reportRecoverableError(modifiers.head, ErrorKind.ExtraneousModifier, 1331 reportRecoverableErrorCodeWithToken(
1278 {'modifier': modifiers.head}); 1332 modifiers.head, codeExtraneousModifier);
1279 } 1333 }
1280 } 1334 }
1281 1335
1282 IdentifierContext context = isTopLevel 1336 IdentifierContext context = isTopLevel
1283 ? IdentifierContext.topLevelVariableDeclaration 1337 ? IdentifierContext.topLevelVariableDeclaration
1284 : IdentifierContext.fieldDeclaration; 1338 : IdentifierContext.fieldDeclaration;
1285 Token token = parseIdentifier(name, context); 1339 Token token = parseIdentifier(name, context);
1286 1340
1287 int fieldCount = 1; 1341 int fieldCount = 1;
1288 token = parseFieldInitializerOpt(token); 1342 token = parseFieldInitializerOpt(token);
(...skipping 15 matching lines...) Expand all
1304 Token parseTopLevelMethod(Token start, Link<Token> modifiers, Token type, 1358 Token parseTopLevelMethod(Token start, Link<Token> modifiers, Token type,
1305 Token getOrSet, Token name) { 1359 Token getOrSet, Token name) {
1306 listener.beginTopLevelMethod(start, name); 1360 listener.beginTopLevelMethod(start, name);
1307 Token externalModifier; 1361 Token externalModifier;
1308 // TODO(johnniwinther): Move error reporting to resolution to give more 1362 // TODO(johnniwinther): Move error reporting to resolution to give more
1309 // specific error messages. 1363 // specific error messages.
1310 for (Token modifier in modifiers) { 1364 for (Token modifier in modifiers) {
1311 if (externalModifier == null && optional('external', modifier)) { 1365 if (externalModifier == null && optional('external', modifier)) {
1312 externalModifier = modifier; 1366 externalModifier = modifier;
1313 } else { 1367 } else {
1314 reportRecoverableError( 1368 reportRecoverableErrorCodeWithToken(modifier, codeExtraneousModifier);
1315 modifier, ErrorKind.ExtraneousModifier, {'modifier': modifier});
1316 } 1369 }
1317 } 1370 }
1318 if (externalModifier != null) { 1371 if (externalModifier != null) {
1319 parseModifier(externalModifier); 1372 parseModifier(externalModifier);
1320 listener.handleModifiers(1); 1373 listener.handleModifiers(1);
1321 } else { 1374 } else {
1322 listener.handleModifiers(0); 1375 listener.handleModifiers(0);
1323 } 1376 }
1324 1377
1325 if (type == null) { 1378 if (type == null) {
1326 listener.handleNoType(name); 1379 listener.handleNoType(name);
1327 } else { 1380 } else {
1328 parseReturnTypeOpt(type); 1381 parseReturnTypeOpt(type);
1329 } 1382 }
1330 Token token = 1383 Token token =
1331 parseIdentifier(name, IdentifierContext.topLevelFunctionDeclaration); 1384 parseIdentifier(name, IdentifierContext.topLevelFunctionDeclaration);
1332 1385
1333 if (getOrSet == null) { 1386 if (getOrSet == null) {
1334 token = parseTypeVariablesOpt(token); 1387 token = parseTypeVariablesOpt(token);
1335 } else { 1388 } else {
1336 listener.handleNoTypeVariables(token); 1389 listener.handleNoTypeVariables(token);
1337 } 1390 }
1338 token = parseFormalParametersOpt(token); 1391 token = parseFormalParametersOpt(token);
1339 AsyncModifier savedAsyncModifier = asyncState; 1392 AsyncModifier savedAsyncModifier = asyncState;
1340 Token asyncToken = token; 1393 Token asyncToken = token;
1341 token = parseAsyncModifier(token); 1394 token = parseAsyncModifier(token);
1342 if (getOrSet != null && !inPlainSync && optional("set", getOrSet)) { 1395 if (getOrSet != null && !inPlainSync && optional("set", getOrSet)) {
1343 reportRecoverableError(asyncToken, ErrorKind.SetterNotSync); 1396 reportRecoverableErrorCode(asyncToken, codeSetterNotSync);
1344 } 1397 }
1345 token = parseFunctionBody(token, false, externalModifier != null); 1398 token = parseFunctionBody(token, false, externalModifier != null);
1346 asyncState = savedAsyncModifier; 1399 asyncState = savedAsyncModifier;
1347 Token endToken = token; 1400 Token endToken = token;
1348 token = token.next; 1401 token = token.next;
1349 listener.endTopLevelMethod(start, getOrSet, endToken); 1402 listener.endTopLevelMethod(start, getOrSet, endToken);
1350 return token; 1403 return token;
1351 } 1404 }
1352 1405
1353 /// Looks ahead to find the name of a member. Returns a link of the modifiers, 1406 /// Looks ahead to find the name of a member. Returns a link of the modifiers,
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
1427 // type '.' ... 1480 // type '.' ...
1428 if (token.next.next.isIdentifier()) { 1481 if (token.next.next.isIdentifier()) {
1429 // type '.' identifier 1482 // type '.' identifier
1430 token = token.next.next; 1483 token = token.next.next;
1431 } 1484 }
1432 } 1485 }
1433 if (optional('<', token.next)) { 1486 if (optional('<', token.next)) {
1434 if (token.next is BeginGroupToken) { 1487 if (token.next is BeginGroupToken) {
1435 BeginGroupToken beginGroup = token.next; 1488 BeginGroupToken beginGroup = token.next;
1436 if (beginGroup.endGroup == null) { 1489 if (beginGroup.endGroup == null) {
1437 reportUnrecoverableError(beginGroup, ErrorKind.UnmatchedToken); 1490 token = reportUnmatchedToken(beginGroup).next;
1438 } else { 1491 } else {
1439 token = beginGroup.endGroup; 1492 token = beginGroup.endGroup;
1440 } 1493 }
1441 } 1494 }
1442 } 1495 }
1443 } 1496 }
1444 token = token.next; 1497 token = token.next;
1445 } 1498 }
1446 while (isGeneralizedFunctionType(token)) { 1499 while (isGeneralizedFunctionType(token)) {
1447 token = token.next; 1500 token = token.next;
1448 if (optional('<', token)) { 1501 if (optional('<', token)) {
1449 if (token is BeginGroupToken) { 1502 if (token is BeginGroupToken) {
1450 BeginGroupToken beginGroup = token; 1503 BeginGroupToken beginGroup = token;
1451 if (beginGroup.endGroup == null) { 1504 if (beginGroup.endGroup == null) {
1452 reportUnrecoverableError(beginGroup, ErrorKind.UnmatchedToken); 1505 token = reportUnmatchedToken(beginGroup).next;
1453 } else { 1506 } else {
1454 token = beginGroup.endGroup.next; 1507 token = beginGroup.endGroup.next;
1455 } 1508 }
1456 } 1509 }
1457 } 1510 }
1458 if (!optional('(', token)) { 1511 if (!optional('(', token)) {
1459 if (optional(';', token)) { 1512 if (optional(';', token)) {
1460 reportRecoverableError(token, ErrorKind.ExpectedOpenParens); 1513 reportRecoverableErrorCode(token, codeExpectedOpenParens);
1461 } 1514 }
1462 token = expect("(", token); 1515 token = expect("(", token);
1463 } 1516 }
1464 if (token is BeginGroupToken) { 1517 if (token is BeginGroupToken) {
1465 BeginGroupToken beginGroup = token; 1518 BeginGroupToken beginGroup = token;
1466 if (beginGroup.endGroup == null) { 1519 if (beginGroup.endGroup == null) {
1467 reportUnrecoverableError(beginGroup, ErrorKind.UnmatchedToken); 1520 token = reportUnmatchedToken(beginGroup).next;
1468 } else { 1521 } else {
1469 token = beginGroup.endGroup.next; 1522 token = beginGroup.endGroup.next;
1470 } 1523 }
1471 } 1524 }
1472 } 1525 }
1473 } 1526 }
1474 return listener.handleMemberName(const Link<Token>()); 1527 return listener.handleMemberName(const Link<Token>());
1475 } 1528 }
1476 1529
1477 Token parseFieldInitializerOpt(Token token) { 1530 Token parseFieldInitializerOpt(Token token) {
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
1523 } while (optional(',', token)); 1576 } while (optional(',', token));
1524 mayParseFunctionExpressions = old; 1577 mayParseFunctionExpressions = old;
1525 listener.endInitializers(count, begin, token); 1578 listener.endInitializers(count, begin, token);
1526 return token; 1579 return token;
1527 } 1580 }
1528 1581
1529 Token parseLiteralStringOrRecoverExpression(Token token) { 1582 Token parseLiteralStringOrRecoverExpression(Token token) {
1530 if (identical(token.kind, STRING_TOKEN)) { 1583 if (identical(token.kind, STRING_TOKEN)) {
1531 return parseLiteralString(token); 1584 return parseLiteralString(token);
1532 } else { 1585 } else {
1533 reportRecoverableError(token, ErrorKind.ExpectedString); 1586 reportRecoverableErrorCodeWithToken(token, codeExpectedString);
1534 return parseRecoverExpression(token); 1587 return parseRecoverExpression(token);
1535 } 1588 }
1536 } 1589 }
1537 1590
1538 Token expectSemicolon(Token token) { 1591 Token expectSemicolon(Token token) {
1539 return expect(';', token); 1592 return expect(';', token);
1540 } 1593 }
1541 1594
1542 bool isModifier(Token token) { 1595 bool isModifier(Token token) {
1543 final String value = token.stringValue; 1596 final String value = token.stringValue;
(...skipping 11 matching lines...) Expand all
1555 return token.next; 1608 return token.next;
1556 } 1609 }
1557 1610
1558 void parseModifierList(Link<Token> tokens) { 1611 void parseModifierList(Link<Token> tokens) {
1559 int count = 0; 1612 int count = 0;
1560 for (; !tokens.isEmpty; tokens = tokens.tail) { 1613 for (; !tokens.isEmpty; tokens = tokens.tail) {
1561 Token token = tokens.head; 1614 Token token = tokens.head;
1562 if (isModifier(token)) { 1615 if (isModifier(token)) {
1563 parseModifier(token); 1616 parseModifier(token);
1564 } else { 1617 } else {
1565 reportUnrecoverableError(token, ErrorKind.UnexpectedToken); 1618 reportUnexpectedToken(token);
1566 // Skip the remaining modifiers. 1619 // Skip the remaining modifiers.
1567 break; 1620 break;
1568 } 1621 }
1569 count++; 1622 count++;
1570 } 1623 }
1571 listener.handleModifiers(count); 1624 listener.handleModifiers(count);
1572 } 1625 }
1573 1626
1574 Token parseModifiers(Token token) { 1627 Token parseModifiers(Token token) {
1575 // TODO(ahe): The calling convention of this method probably needs to 1628 // TODO(ahe): The calling convention of this method probably needs to
1576 // change. For example, this is parsed as a local variable declaration: 1629 // change. For example, this is parsed as a local variable declaration:
1577 // `abstract foo;`. Ideally, this example should be handled as a local 1630 // `abstract foo;`. Ideally, this example should be handled as a local
1578 // variable having the type `abstract` (which should be reported as 1631 // variable having the type `abstract` (which should be reported as
1579 // `ErrorKind.BuiltInIdentifierAsType` by [parseIdentifier]). 1632 // `codeBuiltInIdentifierAsType` by [parseIdentifier]).
1580 int count = 0; 1633 int count = 0;
1581 while (identical(token.kind, KEYWORD_TOKEN)) { 1634 while (identical(token.kind, KEYWORD_TOKEN)) {
1582 if (!isModifier(token)) break; 1635 if (!isModifier(token)) break;
1583 token = parseModifier(token); 1636 token = parseModifier(token);
1584 count++; 1637 count++;
1585 } 1638 }
1586 listener.handleModifiers(count); 1639 listener.handleModifiers(count);
1587 return token; 1640 return token;
1588 } 1641 }
1589 1642
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
1679 /// If [token] is not the start of a type, null is returned. 1732 /// If [token] is not the start of a type, null is returned.
1680 Token peekAfterIfType(Token token) { 1733 Token peekAfterIfType(Token token) {
1681 if (!optional('void', token) && !token.isIdentifier()) { 1734 if (!optional('void', token) && !token.isIdentifier()) {
1682 return null; 1735 return null;
1683 } 1736 }
1684 return peekAfterType(token); 1737 return peekAfterType(token);
1685 } 1738 }
1686 1739
1687 Token skipClassBody(Token token) { 1740 Token skipClassBody(Token token) {
1688 if (!optional('{', token)) { 1741 if (!optional('{', token)) {
1689 return reportUnrecoverableError(token, ErrorKind.ExpectedClassBodyToSkip) 1742 return reportUnrecoverableErrorCodeWithToken(
1690 ?.next; 1743 token, codeExpectedClassBodyToSkip)
1744 .next;
1691 } 1745 }
1692 BeginGroupToken beginGroupToken = token; 1746 BeginGroupToken beginGroupToken = token;
1693 Token endGroup = beginGroupToken.endGroup; 1747 Token endGroup = beginGroupToken.endGroup;
1694 if (endGroup == null) { 1748 if (endGroup == null || !identical(endGroup.kind, $CLOSE_CURLY_BRACKET)) {
1695 return reportUnrecoverableError(beginGroupToken, ErrorKind.UnmatchedToken) 1749 return reportUnmatchedToken(beginGroupToken).next;
1696 ?.next;
1697 } else if (!identical(endGroup.kind, $CLOSE_CURLY_BRACKET)) {
1698 return reportUnrecoverableError(beginGroupToken, ErrorKind.UnmatchedToken)
1699 ?.next;
1700 } 1750 }
1701 return endGroup; 1751 return endGroup;
1702 } 1752 }
1703 1753
1704 Token parseClassBody(Token token) { 1754 Token parseClassBody(Token token) {
1705 Token begin = token; 1755 Token begin = token;
1706 listener.beginClassBody(token); 1756 listener.beginClassBody(token);
1707 if (!optional('{', token)) { 1757 if (!optional('{', token)) {
1708 token = 1758 token =
1709 reportUnrecoverableError(token, ErrorKind.ExpectedClassBody)?.next; 1759 reportUnrecoverableErrorCodeWithToken(token, codeExpectedClassBody)
1760 .next;
1710 } 1761 }
1711 token = token.next; 1762 token = token.next;
1712 int count = 0; 1763 int count = 0;
1713 while (notEofOrValue('}', token)) { 1764 while (notEofOrValue('}', token)) {
1714 token = parseMember(token); 1765 token = parseMember(token);
1715 ++count; 1766 ++count;
1716 } 1767 }
1717 expect('}', token); 1768 expect('}', token);
1718 listener.endClassBody(count, begin, token); 1769 listener.endClassBody(count, begin, token);
1719 return token; 1770 return token;
(...skipping 16 matching lines...) Expand all
1736 listener.beginMember(token); 1787 listener.beginMember(token);
1737 if (isFactoryDeclaration(token)) { 1788 if (isFactoryDeclaration(token)) {
1738 token = parseFactoryMethod(token); 1789 token = parseFactoryMethod(token);
1739 listener.endMember(); 1790 listener.endMember();
1740 assert(token != null); 1791 assert(token != null);
1741 return token; 1792 return token;
1742 } 1793 }
1743 1794
1744 Link<Token> identifiers = findMemberName(token); 1795 Link<Token> identifiers = findMemberName(token);
1745 if (identifiers.isEmpty) { 1796 if (identifiers.isEmpty) {
1746 return reportUnrecoverableError(start, ErrorKind.ExpectedDeclaration) 1797 return reportUnrecoverableErrorCodeWithToken(
1747 ?.next; 1798 start, codeExpectedDeclaration)
1799 .next;
1748 } 1800 }
1749 Token afterName = identifiers.head; 1801 Token afterName = identifiers.head;
1750 identifiers = identifiers.tail; 1802 identifiers = identifiers.tail;
1751 1803
1752 if (identifiers.isEmpty) { 1804 if (identifiers.isEmpty) {
1753 return reportUnrecoverableError(start, ErrorKind.ExpectedDeclaration) 1805 return reportUnrecoverableErrorCodeWithToken(
1754 ?.next; 1806 start, codeExpectedDeclaration)
1807 .next;
1755 } 1808 }
1756 Token name = identifiers.head; 1809 Token name = identifiers.head;
1757 identifiers = identifiers.tail; 1810 identifiers = identifiers.tail;
1758 if (!identifiers.isEmpty) { 1811 if (!identifiers.isEmpty) {
1759 if (optional('operator', identifiers.head)) { 1812 if (optional('operator', identifiers.head)) {
1760 name = identifiers.head; 1813 name = identifiers.head;
1761 identifiers = identifiers.tail; 1814 identifiers = identifiers.tail;
1762 } 1815 }
1763 } 1816 }
1764 Token getOrSet; 1817 Token getOrSet;
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1796 isField = !optional("get", getOrSet); 1849 isField = !optional("get", getOrSet);
1797 // TODO(ahe): This feels like a hack. 1850 // TODO(ahe): This feels like a hack.
1798 } else { 1851 } else {
1799 isField = true; 1852 isField = true;
1800 } 1853 }
1801 break; 1854 break;
1802 } else if ((identical(value, '=')) || (identical(value, ','))) { 1855 } else if ((identical(value, '=')) || (identical(value, ','))) {
1803 isField = true; 1856 isField = true;
1804 break; 1857 break;
1805 } else { 1858 } else {
1806 token = 1859 token = reportUnexpectedToken(token).next;
1807 reportUnrecoverableError(token, ErrorKind.UnexpectedToken)?.next;
1808 if (identical(token.kind, EOF_TOKEN)) { 1860 if (identical(token.kind, EOF_TOKEN)) {
1809 // TODO(ahe): This is a hack, see parseTopLevelMember. 1861 // TODO(ahe): This is a hack, see parseTopLevelMember.
1810 listener.endFields(1, null, start, token); 1862 listener.endFields(1, null, start, token);
1811 listener.endMember(); 1863 listener.endMember();
1812 return token; 1864 return token;
1813 } 1865 }
1814 } 1866 }
1815 } 1867 }
1816 1868
1817 var modifiers = identifiers.reverse(); 1869 var modifiers = identifiers.reverse();
(...skipping 12 matching lines...) Expand all
1830 Token constModifier; 1882 Token constModifier;
1831 int modifierCount = 0; 1883 int modifierCount = 0;
1832 int allowedModifierCount = 1; 1884 int allowedModifierCount = 1;
1833 // TODO(johnniwinther): Move error reporting to resolution to give more 1885 // TODO(johnniwinther): Move error reporting to resolution to give more
1834 // specific error messages. 1886 // specific error messages.
1835 for (Token modifier in modifiers) { 1887 for (Token modifier in modifiers) {
1836 if (externalModifier == null && optional('external', modifier)) { 1888 if (externalModifier == null && optional('external', modifier)) {
1837 modifierCount++; 1889 modifierCount++;
1838 externalModifier = modifier; 1890 externalModifier = modifier;
1839 if (modifierCount != allowedModifierCount) { 1891 if (modifierCount != allowedModifierCount) {
1840 reportRecoverableError( 1892 reportRecoverableErrorCodeWithToken(modifier, codeExtraneousModifier);
1841 modifier, ErrorKind.ExtraneousModifier, {'modifier': modifier});
1842 } 1893 }
1843 allowedModifierCount++; 1894 allowedModifierCount++;
1844 } else if (staticModifier == null && optional('static', modifier)) { 1895 } else if (staticModifier == null && optional('static', modifier)) {
1845 modifierCount++; 1896 modifierCount++;
1846 staticModifier = modifier; 1897 staticModifier = modifier;
1847 if (modifierCount != allowedModifierCount) { 1898 if (modifierCount != allowedModifierCount) {
1848 reportRecoverableError( 1899 reportRecoverableErrorCodeWithToken(modifier, codeExtraneousModifier);
1849 modifier, ErrorKind.ExtraneousModifier, {'modifier': modifier});
1850 } 1900 }
1851 } else if (constModifier == null && optional('const', modifier)) { 1901 } else if (constModifier == null && optional('const', modifier)) {
1852 modifierCount++; 1902 modifierCount++;
1853 constModifier = modifier; 1903 constModifier = modifier;
1854 if (modifierCount != allowedModifierCount) { 1904 if (modifierCount != allowedModifierCount) {
1855 reportRecoverableError( 1905 reportRecoverableErrorCodeWithToken(modifier, codeExtraneousModifier);
1856 modifier, ErrorKind.ExtraneousModifier, {'modifier': modifier});
1857 } 1906 }
1858 } else { 1907 } else {
1859 reportRecoverableError( 1908 reportRecoverableErrorCodeWithToken(modifier, codeExtraneousModifier);
1860 modifier, ErrorKind.ExtraneousModifier, {'modifier': modifier});
1861 } 1909 }
1862 } 1910 }
1863 if (getOrSet != null && constModifier != null) { 1911 if (getOrSet != null && constModifier != null) {
1864 reportRecoverableError(constModifier, ErrorKind.ExtraneousModifier, 1912 reportRecoverableErrorCodeWithToken(
1865 {'modifier': constModifier}); 1913 constModifier, codeExtraneousModifier);
1866 } 1914 }
1867 parseModifierList(modifiers); 1915 parseModifierList(modifiers);
1868 1916
1869 if (type == null) { 1917 if (type == null) {
1870 listener.handleNoType(name); 1918 listener.handleNoType(name);
1871 } else { 1919 } else {
1872 parseReturnTypeOpt(type); 1920 parseReturnTypeOpt(type);
1873 } 1921 }
1874 Token token; 1922 Token token;
1875 if (optional('operator', name)) { 1923 if (optional('operator', name)) {
1876 token = parseOperatorName(name); 1924 token = parseOperatorName(name);
1877 if (staticModifier != null) { 1925 if (staticModifier != null) {
1878 reportRecoverableError(staticModifier, ErrorKind.ExtraneousModifier, 1926 reportRecoverableErrorCodeWithToken(
1879 {'modifier': staticModifier}); 1927 staticModifier, codeExtraneousModifier);
1880 } 1928 }
1881 } else { 1929 } else {
1882 token = parseIdentifier(name, IdentifierContext.methodDeclaration); 1930 token = parseIdentifier(name, IdentifierContext.methodDeclaration);
1883 } 1931 }
1884 1932
1885 token = parseQualifiedRestOpt( 1933 token = parseQualifiedRestOpt(
1886 token, IdentifierContext.methodDeclarationContinuation); 1934 token, IdentifierContext.methodDeclarationContinuation);
1887 if (getOrSet == null) { 1935 if (getOrSet == null) {
1888 token = parseTypeVariablesOpt(token); 1936 token = parseTypeVariablesOpt(token);
1889 } else { 1937 } else {
1890 listener.handleNoTypeVariables(token); 1938 listener.handleNoTypeVariables(token);
1891 } 1939 }
1892 token = parseFormalParametersOpt(token); 1940 token = parseFormalParametersOpt(token);
1893 token = parseInitializersOpt(token); 1941 token = parseInitializersOpt(token);
1894 AsyncModifier savedAsyncModifier = asyncState; 1942 AsyncModifier savedAsyncModifier = asyncState;
1895 Token asyncToken = token; 1943 Token asyncToken = token;
1896 token = parseAsyncModifier(token); 1944 token = parseAsyncModifier(token);
1897 if (getOrSet != null && !inPlainSync && optional("set", getOrSet)) { 1945 if (getOrSet != null && !inPlainSync && optional("set", getOrSet)) {
1898 reportRecoverableError(asyncToken, ErrorKind.SetterNotSync); 1946 reportRecoverableErrorCode(asyncToken, codeSetterNotSync);
1899 } 1947 }
1900 if (optional('=', token)) { 1948 if (optional('=', token)) {
1901 token = parseRedirectingFactoryBody(token); 1949 token = parseRedirectingFactoryBody(token);
1902 } else { 1950 } else {
1903 token = parseFunctionBody( 1951 token = parseFunctionBody(
1904 token, false, staticModifier == null || externalModifier != null); 1952 token, false, staticModifier == null || externalModifier != null);
1905 } 1953 }
1906 asyncState = savedAsyncModifier; 1954 asyncState = savedAsyncModifier;
1907 listener.endMethod(getOrSet, start, token); 1955 listener.endMethod(getOrSet, start, token);
1908 return token.next; 1956 return token.next;
(...skipping 13 matching lines...) Expand all
1922 } 1970 }
1923 listener.handleModifiers(modifierCount); 1971 listener.handleModifiers(modifierCount);
1924 Token factoryKeyword = token; 1972 Token factoryKeyword = token;
1925 listener.beginFactoryMethod(factoryKeyword); 1973 listener.beginFactoryMethod(factoryKeyword);
1926 token = expect('factory', token); 1974 token = expect('factory', token);
1927 token = parseConstructorReference(token); 1975 token = parseConstructorReference(token);
1928 token = parseFormalParameters(token); 1976 token = parseFormalParameters(token);
1929 Token asyncToken = token; 1977 Token asyncToken = token;
1930 token = parseAsyncModifier(token); 1978 token = parseAsyncModifier(token);
1931 if (!inPlainSync) { 1979 if (!inPlainSync) {
1932 reportRecoverableError(asyncToken, ErrorKind.FactoryNotSync); 1980 reportRecoverableErrorCode(asyncToken, codeFactoryNotSync);
1933 } 1981 }
1934 if (optional('=', token)) { 1982 if (optional('=', token)) {
1935 token = parseRedirectingFactoryBody(token); 1983 token = parseRedirectingFactoryBody(token);
1936 } else { 1984 } else {
1937 token = parseFunctionBody(token, false, isExternal); 1985 token = parseFunctionBody(token, false, isExternal);
1938 } 1986 }
1939 listener.endFactoryMethod(start, factoryKeyword, token); 1987 listener.endFactoryMethod(start, factoryKeyword, token);
1940 return token.next; 1988 return token.next;
1941 } 1989 }
1942 1990
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
2074 listener.endRedirectingFactoryBody(equals, semicolon); 2122 listener.endRedirectingFactoryBody(equals, semicolon);
2075 return token; 2123 return token;
2076 } 2124 }
2077 2125
2078 Token skipFunctionBody(Token token, bool isExpression, bool allowAbstract) { 2126 Token skipFunctionBody(Token token, bool isExpression, bool allowAbstract) {
2079 assert(!isExpression); 2127 assert(!isExpression);
2080 token = skipAsyncModifier(token); 2128 token = skipAsyncModifier(token);
2081 String value = token.stringValue; 2129 String value = token.stringValue;
2082 if (identical(value, ';')) { 2130 if (identical(value, ';')) {
2083 if (!allowAbstract) { 2131 if (!allowAbstract) {
2084 reportRecoverableError(token, ErrorKind.ExpectedBody); 2132 reportRecoverableErrorCode(token, codeExpectedBody);
2085 } 2133 }
2086 listener.handleNoFunctionBody(token); 2134 listener.handleNoFunctionBody(token);
2087 } else { 2135 } else {
2088 if (identical(value, '=>')) { 2136 if (identical(value, '=>')) {
2089 token = parseExpression(token.next); 2137 token = parseExpression(token.next);
2090 expectSemicolon(token); 2138 expectSemicolon(token);
2091 listener.handleFunctionBodySkipped(token, true); 2139 listener.handleFunctionBodySkipped(token, true);
2092 } else if (identical(value, '=')) { 2140 } else if (identical(value, '=')) {
2093 reportRecoverableError(token, ErrorKind.ExpectedBody); 2141 reportRecoverableErrorCode(token, codeExpectedBody);
2094 token = parseExpression(token.next); 2142 token = parseExpression(token.next);
2095 expectSemicolon(token); 2143 expectSemicolon(token);
2096 listener.handleFunctionBodySkipped(token, true); 2144 listener.handleFunctionBodySkipped(token, true);
2097 } else { 2145 } else {
2098 token = skipBlock(token); 2146 token = skipBlock(token);
2099 listener.handleFunctionBodySkipped(token, false); 2147 listener.handleFunctionBodySkipped(token, false);
2100 } 2148 }
2101 } 2149 }
2102 return token; 2150 return token;
2103 } 2151 }
2104 2152
2105 Token parseFunctionBody(Token token, bool isExpression, bool allowAbstract) { 2153 Token parseFunctionBody(Token token, bool isExpression, bool allowAbstract) {
2106 if (optional(';', token)) { 2154 if (optional(';', token)) {
2107 if (!allowAbstract) { 2155 if (!allowAbstract) {
2108 reportRecoverableError(token, ErrorKind.ExpectedBody); 2156 reportRecoverableErrorCode(token, codeExpectedBody);
2109 } 2157 }
2110 listener.handleEmptyFunctionBody(token); 2158 listener.handleEmptyFunctionBody(token);
2111 return token; 2159 return token;
2112 } else if (optional('=>', token)) { 2160 } else if (optional('=>', token)) {
2113 Token begin = token; 2161 Token begin = token;
2114 token = parseExpression(token.next); 2162 token = parseExpression(token.next);
2115 if (!isExpression) { 2163 if (!isExpression) {
2116 expectSemicolon(token); 2164 expectSemicolon(token);
2117 listener.handleExpressionFunctionBody(begin, token); 2165 listener.handleExpressionFunctionBody(begin, token);
2118 } else { 2166 } else {
2119 listener.handleExpressionFunctionBody(begin, null); 2167 listener.handleExpressionFunctionBody(begin, null);
2120 } 2168 }
2121 return token; 2169 return token;
2122 } else if (optional('=', token)) { 2170 } else if (optional('=', token)) {
2123 Token begin = token; 2171 Token begin = token;
2124 // Recover from a bad factory method. 2172 // Recover from a bad factory method.
2125 reportRecoverableError(token, ErrorKind.ExpectedBody); 2173 reportRecoverableErrorCode(token, codeExpectedBody);
2126 token = parseExpression(token.next); 2174 token = parseExpression(token.next);
2127 if (!isExpression) { 2175 if (!isExpression) {
2128 expectSemicolon(token); 2176 expectSemicolon(token);
2129 listener.handleExpressionFunctionBody(begin, token); 2177 listener.handleExpressionFunctionBody(begin, token);
2130 } else { 2178 } else {
2131 listener.handleExpressionFunctionBody(begin, null); 2179 listener.handleExpressionFunctionBody(begin, null);
2132 } 2180 }
2133 return token; 2181 return token;
2134 } 2182 }
2135 Token begin = token; 2183 Token begin = token;
2136 int statementCount = 0; 2184 int statementCount = 0;
2137 if (!optional('{', token)) { 2185 if (!optional('{', token)) {
2138 token = 2186 token =
2139 reportUnrecoverableError(token, ErrorKind.ExpectedFunctionBody)?.next; 2187 reportUnrecoverableErrorCodeWithToken(token, codeExpectedFunctionBody)
2188 .next;
2140 listener.handleInvalidFunctionBody(token); 2189 listener.handleInvalidFunctionBody(token);
2141 return token; 2190 return token;
2142 } 2191 }
2143 2192
2144 listener.beginBlockFunctionBody(begin); 2193 listener.beginBlockFunctionBody(begin);
2145 token = token.next; 2194 token = token.next;
2146 while (notEofOrValue('}', token)) { 2195 while (notEofOrValue('}', token)) {
2147 token = parseStatement(token); 2196 token = parseStatement(token);
2148 ++statementCount; 2197 ++statementCount;
2149 } 2198 }
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
2187 asyncState = AsyncModifier.Async; 2236 asyncState = AsyncModifier.Async;
2188 } 2237 }
2189 } else if (optional('sync', token)) { 2238 } else if (optional('sync', token)) {
2190 async = token; 2239 async = token;
2191 token = token.next; 2240 token = token.next;
2192 if (optional('*', token)) { 2241 if (optional('*', token)) {
2193 asyncState = AsyncModifier.SyncStar; 2242 asyncState = AsyncModifier.SyncStar;
2194 star = token; 2243 star = token;
2195 token = token.next; 2244 token = token.next;
2196 } else { 2245 } else {
2197 reportRecoverableError(async, ErrorKind.InvalidSyncModifier); 2246 reportRecoverableErrorCode(async, codeInvalidSyncModifier);
2198 } 2247 }
2199 } 2248 }
2200 listener.handleAsyncModifier(async, star); 2249 listener.handleAsyncModifier(async, star);
2201 if (inGenerator && optional('=>', token)) { 2250 if (inGenerator && optional('=>', token)) {
2202 reportRecoverableError(token, ErrorKind.GeneratorReturnsValue); 2251 reportRecoverableErrorCode(token, codeGeneratorReturnsValue);
2203 } else if (!inPlainSync && optional(';', token)) { 2252 } else if (!inPlainSync && optional(';', token)) {
2204 reportRecoverableError(token, ErrorKind.AbstractNotSync); 2253 reportRecoverableErrorCode(token, codeAbstractNotSync);
2205 } 2254 }
2206 return token; 2255 return token;
2207 } 2256 }
2208 2257
2209 int statementDepth = 0; 2258 int statementDepth = 0;
2210 Token parseStatement(Token token) { 2259 Token parseStatement(Token token) {
2211 if (statementDepth++ > 500) { 2260 if (statementDepth++ > 500) {
2212 // This happens for degenerate programs, for example, a lot of nested 2261 // This happens for degenerate programs, for example, a lot of nested
2213 // if-statements. The language test deep_nesting2_negative_test, for 2262 // if-statements. The language test deep_nesting2_negative_test, for
2214 // example, provokes this. 2263 // example, provokes this.
2215 return reportUnrecoverableError(token, ErrorKind.StackOverflow)?.next; 2264 return reportUnrecoverableErrorCode(token, codeStackOverflow).next;
2216 } 2265 }
2217 Token result = parseStatementX(token); 2266 Token result = parseStatementX(token);
2218 statementDepth--; 2267 statementDepth--;
2219 return result; 2268 return result;
2220 } 2269 }
2221 2270
2222 Token parseStatementX(Token token) { 2271 Token parseStatementX(Token token) {
2223 final value = token.stringValue; 2272 final value = token.stringValue;
2224 if (identical(token.kind, IDENTIFIER_TOKEN)) { 2273 if (identical(token.kind, IDENTIFIER_TOKEN)) {
2225 return parseExpressionStatementOrDeclaration(token); 2274 return parseExpressionStatementOrDeclaration(token);
2226 } else if (identical(value, '{')) { 2275 } else if (identical(value, '{')) {
2227 return parseBlock(token); 2276 return parseBlock(token);
2228 } else if (identical(value, 'return')) { 2277 } else if (identical(value, 'return')) {
2229 return parseReturnStatement(token); 2278 return parseReturnStatement(token);
2230 } else if (identical(value, 'var') || identical(value, 'final')) { 2279 } else if (identical(value, 'var') || identical(value, 'final')) {
2231 return parseVariablesDeclaration(token); 2280 return parseVariablesDeclaration(token);
2232 } else if (identical(value, 'if')) { 2281 } else if (identical(value, 'if')) {
2233 return parseIfStatement(token); 2282 return parseIfStatement(token);
2234 } else if (identical(value, 'await') && optional('for', token.next)) { 2283 } else if (identical(value, 'await') && optional('for', token.next)) {
2235 if (!inAsync) { 2284 if (!inAsync) {
2236 reportRecoverableError(token, ErrorKind.AwaitForNotAsync); 2285 reportRecoverableErrorCode(token, codeAwaitForNotAsync);
2237 } 2286 }
2238 return parseForStatement(token, token.next); 2287 return parseForStatement(token, token.next);
2239 } else if (identical(value, 'for')) { 2288 } else if (identical(value, 'for')) {
2240 return parseForStatement(null, token); 2289 return parseForStatement(null, token);
2241 } else if (identical(value, 'rethrow')) { 2290 } else if (identical(value, 'rethrow')) {
2242 return parseRethrowStatement(token); 2291 return parseRethrowStatement(token);
2243 } else if (identical(value, 'throw') && optional(';', token.next)) { 2292 } else if (identical(value, 'throw') && optional(';', token.next)) {
2244 // TODO(kasperl): Stop dealing with throw here. 2293 // TODO(kasperl): Stop dealing with throw here.
2245 return parseRethrowStatement(token); 2294 return parseRethrowStatement(token);
2246 } else if (identical(value, 'void')) { 2295 } else if (identical(value, 'void')) {
(...skipping 17 matching lines...) Expand all
2264 } else if (identical(value, 'yield')) { 2313 } else if (identical(value, 'yield')) {
2265 switch (asyncState) { 2314 switch (asyncState) {
2266 case AsyncModifier.Sync: 2315 case AsyncModifier.Sync:
2267 return parseExpressionStatementOrDeclaration(token); 2316 return parseExpressionStatementOrDeclaration(token);
2268 2317
2269 case AsyncModifier.SyncStar: 2318 case AsyncModifier.SyncStar:
2270 case AsyncModifier.AsyncStar: 2319 case AsyncModifier.AsyncStar:
2271 return parseYieldStatement(token); 2320 return parseYieldStatement(token);
2272 2321
2273 case AsyncModifier.Async: 2322 case AsyncModifier.Async:
2274 reportRecoverableError(token, ErrorKind.YieldNotGenerator); 2323 reportRecoverableErrorCode(token, codeYieldNotGenerator);
2275 return parseYieldStatement(token); 2324 return parseYieldStatement(token);
2276 } 2325 }
2277 throw "Internal error: Unknown asyncState: '$asyncState'."; 2326 throw "Internal error: Unknown asyncState: '$asyncState'.";
2278 } else if (identical(value, 'const')) { 2327 } else if (identical(value, 'const')) {
2279 return parseExpressionStatementOrConstDeclaration(token); 2328 return parseExpressionStatementOrConstDeclaration(token);
2280 } else if (token.isIdentifier()) { 2329 } else if (token.isIdentifier()) {
2281 return parseExpressionStatementOrDeclaration(token); 2330 return parseExpressionStatementOrDeclaration(token);
2282 } else { 2331 } else {
2283 return parseExpressionStatement(token); 2332 return parseExpressionStatement(token);
2284 } 2333 }
(...skipping 17 matching lines...) Expand all
2302 Token parseReturnStatement(Token token) { 2351 Token parseReturnStatement(Token token) {
2303 Token begin = token; 2352 Token begin = token;
2304 listener.beginReturnStatement(begin); 2353 listener.beginReturnStatement(begin);
2305 assert(identical('return', token.stringValue)); 2354 assert(identical('return', token.stringValue));
2306 token = token.next; 2355 token = token.next;
2307 if (optional(';', token)) { 2356 if (optional(';', token)) {
2308 listener.endReturnStatement(false, begin, token); 2357 listener.endReturnStatement(false, begin, token);
2309 } else { 2358 } else {
2310 token = parseExpression(token); 2359 token = parseExpression(token);
2311 if (inGenerator) { 2360 if (inGenerator) {
2312 reportRecoverableError(begin.next, ErrorKind.GeneratorReturnsValue); 2361 reportRecoverableErrorCode(begin.next, codeGeneratorReturnsValue);
2313 } 2362 }
2314 listener.endReturnStatement(true, begin, token); 2363 listener.endReturnStatement(true, begin, token);
2315 } 2364 }
2316 return expectSemicolon(token); 2365 return expectSemicolon(token);
2317 } 2366 }
2318 2367
2319 Token peekIdentifierAfterType(Token token) { 2368 Token peekIdentifierAfterType(Token token) {
2320 Token peek = peekAfterType(token); 2369 Token peek = peekAfterType(token);
2321 if (peek != null && peek.isIdentifier()) { 2370 if (peek != null && peek.isIdentifier()) {
2322 // We are looking at "type identifier". 2371 // We are looking at "type identifier".
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after
2527 continue; 2576 continue;
2528 } 2577 }
2529 } 2578 }
2530 if (!mayParseFunctionExpressions && identical(value, '{')) { 2579 if (!mayParseFunctionExpressions && identical(value, '{')) {
2531 break; 2580 break;
2532 } 2581 }
2533 if (token is BeginGroupToken) { 2582 if (token is BeginGroupToken) {
2534 BeginGroupToken begin = token; 2583 BeginGroupToken begin = token;
2535 token = (begin.endGroup != null) ? begin.endGroup : token; 2584 token = (begin.endGroup != null) ? begin.endGroup : token;
2536 } else if (token is ErrorToken) { 2585 } else if (token is ErrorToken) {
2537 reportErrorToken(token, false)?.next; 2586 reportErrorToken(token, false).next;
2538 } 2587 }
2539 token = token.next; 2588 token = token.next;
2540 } 2589 }
2541 return token; 2590 return token;
2542 } 2591 }
2543 2592
2544 Token parseRecoverExpression(Token token) => parseExpression(token); 2593 Token parseRecoverExpression(Token token) => parseExpression(token);
2545 2594
2546 int expressionDepth = 0; 2595 int expressionDepth = 0;
2547 Token parseExpression(Token token) { 2596 Token parseExpression(Token token) {
2548 if (expressionDepth++ > 500) { 2597 if (expressionDepth++ > 500) {
2549 // This happens in degenerate programs, for example, with a lot of nested 2598 // This happens in degenerate programs, for example, with a lot of nested
2550 // list literals. This is provoked by, for examaple, the language test 2599 // list literals. This is provoked by, for examaple, the language test
2551 // deep_nesting1_negative_test. 2600 // deep_nesting1_negative_test.
2552 return reportUnrecoverableError(token, ErrorKind.StackOverflow)?.next; 2601 return reportUnrecoverableErrorCode(token, codeStackOverflow).next;
2553 } 2602 }
2554 listener.beginExpression(token); 2603 listener.beginExpression(token);
2555 Token result = optional('throw', token) 2604 Token result = optional('throw', token)
2556 ? parseThrowExpression(token, true) 2605 ? parseThrowExpression(token, true)
2557 : parsePrecedenceExpression(token, ASSIGNMENT_PRECEDENCE, true); 2606 : parsePrecedenceExpression(token, ASSIGNMENT_PRECEDENCE, true);
2558 expressionDepth--; 2607 expressionDepth--;
2559 return result; 2608 return result;
2560 } 2609 }
2561 2610
2562 Token parseExpressionWithoutCascade(Token token) { 2611 Token parseExpressionWithoutCascade(Token token) {
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
2610 token.next, IdentifierContext.expressionContinuation); 2659 token.next, IdentifierContext.expressionContinuation);
2611 listener.handleBinaryExpression(operator); 2660 listener.handleBinaryExpression(operator);
2612 } else if ((identical(info, OPEN_PAREN_INFO)) || 2661 } else if ((identical(info, OPEN_PAREN_INFO)) ||
2613 (identical(info, OPEN_SQUARE_BRACKET_INFO))) { 2662 (identical(info, OPEN_SQUARE_BRACKET_INFO))) {
2614 token = parseArgumentOrIndexStar(token); 2663 token = parseArgumentOrIndexStar(token);
2615 } else if ((identical(info, PLUS_PLUS_INFO)) || 2664 } else if ((identical(info, PLUS_PLUS_INFO)) ||
2616 (identical(info, MINUS_MINUS_INFO))) { 2665 (identical(info, MINUS_MINUS_INFO))) {
2617 listener.handleUnaryPostfixAssignmentExpression(token); 2666 listener.handleUnaryPostfixAssignmentExpression(token);
2618 token = token.next; 2667 token = token.next;
2619 } else { 2668 } else {
2620 token = reportUnrecoverableError(token, ErrorKind.UnexpectedToken) 2669 token = reportUnexpectedToken(token).next;
2621 ?.next;
2622 } 2670 }
2623 } else if (identical(info, IS_INFO)) { 2671 } else if (identical(info, IS_INFO)) {
2624 token = parseIsOperatorRest(token); 2672 token = parseIsOperatorRest(token);
2625 } else if (identical(info, AS_INFO)) { 2673 } else if (identical(info, AS_INFO)) {
2626 token = parseAsOperatorRest(token); 2674 token = parseAsOperatorRest(token);
2627 } else if (identical(info, QUESTION_INFO)) { 2675 } else if (identical(info, QUESTION_INFO)) {
2628 token = parseConditionalExpressionRest(token); 2676 token = parseConditionalExpressionRest(token);
2629 } else { 2677 } else {
2630 // Left associative, so we recurse at the next higher 2678 // Left associative, so we recurse at the next higher
2631 // precedence level. 2679 // precedence level.
(...skipping 19 matching lines...) Expand all
2651 listener.beginCascade(token); 2699 listener.beginCascade(token);
2652 assert(optional('..', token)); 2700 assert(optional('..', token));
2653 Token cascadeOperator = token; 2701 Token cascadeOperator = token;
2654 token = token.next; 2702 token = token.next;
2655 if (optional('[', token)) { 2703 if (optional('[', token)) {
2656 token = parseArgumentOrIndexStar(token); 2704 token = parseArgumentOrIndexStar(token);
2657 } else if (token.isIdentifier()) { 2705 } else if (token.isIdentifier()) {
2658 token = parseSend(token, IdentifierContext.expressionContinuation); 2706 token = parseSend(token, IdentifierContext.expressionContinuation);
2659 listener.handleBinaryExpression(cascadeOperator); 2707 listener.handleBinaryExpression(cascadeOperator);
2660 } else { 2708 } else {
2661 return reportUnrecoverableError(token, ErrorKind.UnexpectedToken)?.next; 2709 return reportUnexpectedToken(token).next;
2662 } 2710 }
2663 Token mark; 2711 Token mark;
2664 do { 2712 do {
2665 mark = token; 2713 mark = token;
2666 if (optional('.', token)) { 2714 if (optional('.', token)) {
2667 Token period = token; 2715 Token period = token;
2668 token = parseSend(token.next, IdentifierContext.expressionContinuation); 2716 token = parseSend(token.next, IdentifierContext.expressionContinuation);
2669 listener.handleBinaryExpression(period); 2717 listener.handleBinaryExpression(period);
2670 } 2718 }
2671 token = parseArgumentOrIndexStar(token); 2719 token = parseArgumentOrIndexStar(token);
(...skipping 12 matching lines...) Expand all
2684 String value = token.stringValue; 2732 String value = token.stringValue;
2685 // Prefix: 2733 // Prefix:
2686 if (optional('await', token)) { 2734 if (optional('await', token)) {
2687 if (inPlainSync) { 2735 if (inPlainSync) {
2688 return parsePrimary(token, IdentifierContext.expression); 2736 return parsePrimary(token, IdentifierContext.expression);
2689 } else { 2737 } else {
2690 return parseAwaitExpression(token, allowCascades); 2738 return parseAwaitExpression(token, allowCascades);
2691 } 2739 }
2692 } else if (identical(value, '+')) { 2740 } else if (identical(value, '+')) {
2693 // Dart no longer allows prefix-plus. 2741 // Dart no longer allows prefix-plus.
2694 reportRecoverableError(token, ErrorKind.UnsupportedPrefixPlus); 2742 reportRecoverableErrorCode(token, codeUnsupportedPrefixPlus);
2695 return parseUnaryExpression(token.next, allowCascades); 2743 return parseUnaryExpression(token.next, allowCascades);
2696 } else if ((identical(value, '!')) || 2744 } else if ((identical(value, '!')) ||
2697 (identical(value, '-')) || 2745 (identical(value, '-')) ||
2698 (identical(value, '~'))) { 2746 (identical(value, '~'))) {
2699 Token operator = token; 2747 Token operator = token;
2700 // Right associative, so we recurse at the same precedence 2748 // Right associative, so we recurse at the same precedence
2701 // level. 2749 // level.
2702 token = parsePrecedenceExpression( 2750 token = parsePrecedenceExpression(
2703 token.next, POSTFIX_PRECEDENCE, allowCascades); 2751 token.next, POSTFIX_PRECEDENCE, allowCascades);
2704 listener.handleUnaryPrefixExpression(operator); 2752 listener.handleUnaryPrefixExpression(operator);
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
2784 listener.handleNoTypeArguments(token); 2832 listener.handleNoTypeArguments(token);
2785 return parseLiteralMapSuffix(token, null); 2833 return parseLiteralMapSuffix(token, null);
2786 } else if (kind == LT_TOKEN) { 2834 } else if (kind == LT_TOKEN) {
2787 return parseLiteralListOrMapOrFunction(token, null); 2835 return parseLiteralListOrMapOrFunction(token, null);
2788 } else { 2836 } else {
2789 return expressionExpected(token); 2837 return expressionExpected(token);
2790 } 2838 }
2791 } 2839 }
2792 2840
2793 Token expressionExpected(Token token) { 2841 Token expressionExpected(Token token) {
2794 token = reportUnrecoverableError(token, ErrorKind.ExpectedExpression)?.next; 2842 token = reportUnrecoverableErrorCodeWithToken(token, codeExpectedExpression)
2843 .next;
2795 listener.handleInvalidExpression(token); 2844 listener.handleInvalidExpression(token);
2796 return token; 2845 return token;
2797 } 2846 }
2798 2847
2799 Token parseParenthesizedExpressionOrFunctionLiteral(Token token) { 2848 Token parseParenthesizedExpressionOrFunctionLiteral(Token token) {
2800 BeginGroupToken beginGroup = token; 2849 BeginGroupToken beginGroup = token;
2801 // TODO(eernst): Check for NPE as described in issue 26252. 2850 // TODO(eernst): Check for NPE as described in issue 26252.
2802 Token nextToken = beginGroup.endGroup.next; 2851 Token nextToken = beginGroup.endGroup.next;
2803 int kind = nextToken.kind; 2852 int kind = nextToken.kind;
2804 if (mayParseFunctionExpressions && 2853 if (mayParseFunctionExpressions &&
(...skipping 14 matching lines...) Expand all
2819 } 2868 }
2820 2869
2821 Token parseParenthesizedExpression(Token token) { 2870 Token parseParenthesizedExpression(Token token) {
2822 // We expect [begin] to be of type [BeginGroupToken], but we don't know for 2871 // We expect [begin] to be of type [BeginGroupToken], but we don't know for
2823 // sure until after calling expect. 2872 // sure until after calling expect.
2824 dynamic begin = token; 2873 dynamic begin = token;
2825 token = expect('(', token); 2874 token = expect('(', token);
2826 // [begin] is now known to have type [BeginGroupToken]. 2875 // [begin] is now known to have type [BeginGroupToken].
2827 token = parseExpression(token); 2876 token = parseExpression(token);
2828 if (!identical(begin.endGroup, token)) { 2877 if (!identical(begin.endGroup, token)) {
2829 reportUnrecoverableError(token, ErrorKind.UnexpectedToken)?.next; 2878 reportUnexpectedToken(token).next;
2830 token = begin.endGroup; 2879 token = begin.endGroup;
2831 } 2880 }
2832 listener.handleParenthesizedExpression(begin); 2881 listener.handleParenthesizedExpression(begin);
2833 return expect(')', token); 2882 return expect(')', token);
2834 } 2883 }
2835 2884
2836 Token parseThisExpression(Token token, IdentifierContext context) { 2885 Token parseThisExpression(Token token, IdentifierContext context) {
2837 Token beginToken = token; 2886 Token beginToken = token;
2838 listener.handleThisExpression(token, context); 2887 listener.handleThisExpression(token, context);
2839 token = token.next; 2888 token = token.next;
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
2923 Token nextToken = beginGroup.endGroup.next; 2972 Token nextToken = beginGroup.endGroup.next;
2924 int kind = nextToken.kind; 2973 int kind = nextToken.kind;
2925 if (identical(kind, FUNCTION_TOKEN) || 2974 if (identical(kind, FUNCTION_TOKEN) ||
2926 identical(kind, OPEN_CURLY_BRACKET_TOKEN) || 2975 identical(kind, OPEN_CURLY_BRACKET_TOKEN) ||
2927 (identical(kind, KEYWORD_TOKEN) && 2976 (identical(kind, KEYWORD_TOKEN) &&
2928 (optional('async', nextToken) || optional('sync', nextToken)))) { 2977 (optional('async', nextToken) || optional('sync', nextToken)))) {
2929 return parseUnnamedFunction(token); 2978 return parseUnnamedFunction(token);
2930 } 2979 }
2931 // Fall through. 2980 // Fall through.
2932 } 2981 }
2933 reportUnrecoverableError(token, ErrorKind.UnexpectedToken); 2982 return reportUnexpectedToken(token).next;
2934 return null;
2935 } 2983 }
2936 2984
2937 /// genericListLiteral | genericMapLiteral | genericFunctionLiteral. 2985 /// genericListLiteral | genericMapLiteral | genericFunctionLiteral.
2938 /// 2986 ///
2939 /// Where 2987 /// Where
2940 /// genericListLiteral ::= typeArguments '[' (expressionList ','?)? ']' 2988 /// genericListLiteral ::= typeArguments '[' (expressionList ','?)? ']'
2941 /// genericMapLiteral ::= 2989 /// genericMapLiteral ::=
2942 /// typeArguments '{' (mapLiteralEntry (',' mapLiteralEntry)* ','?)? '}' 2990 /// typeArguments '{' (mapLiteralEntry (',' mapLiteralEntry)* ','?)? '}'
2943 /// genericFunctionLiteral ::= 2991 /// genericFunctionLiteral ::=
2944 /// typeParameters formalParameterList functionBody 2992 /// typeParameters formalParameterList functionBody
2945 /// Provide token for [constKeyword] if preceded by 'const', null if not. 2993 /// Provide token for [constKeyword] if preceded by 'const', null if not.
2946 Token parseLiteralListOrMapOrFunction(Token token, Token constKeyword) { 2994 Token parseLiteralListOrMapOrFunction(Token token, Token constKeyword) {
2947 assert(optional('<', token)); 2995 assert(optional('<', token));
2948 BeginGroupToken begin = token; 2996 BeginGroupToken begin = token;
2949 if (constKeyword == null && 2997 if (constKeyword == null &&
2950 begin.endGroup != null && 2998 begin.endGroup != null &&
2951 identical(begin.endGroup.next.kind, OPEN_PAREN_TOKEN)) { 2999 identical(begin.endGroup.next.kind, OPEN_PAREN_TOKEN)) {
2952 token = parseTypeVariablesOpt(token); 3000 token = parseTypeVariablesOpt(token);
2953 return parseLiteralFunctionSuffix(token); 3001 return parseLiteralFunctionSuffix(token);
2954 } else { 3002 } else {
2955 token = parseTypeArgumentsOpt(token); 3003 token = parseTypeArgumentsOpt(token);
2956 if (optional('{', token)) { 3004 if (optional('{', token)) {
2957 return parseLiteralMapSuffix(token, constKeyword); 3005 return parseLiteralMapSuffix(token, constKeyword);
2958 } else if ((optional('[', token)) || (optional('[]', token))) { 3006 } else if ((optional('[', token)) || (optional('[]', token))) {
2959 return parseLiteralListSuffix(token, constKeyword); 3007 return parseLiteralListSuffix(token, constKeyword);
2960 } 3008 }
2961 reportUnrecoverableError(token, ErrorKind.UnexpectedToken); 3009 return reportUnexpectedToken(token).next;
2962 return null;
2963 } 3010 }
2964 } 3011 }
2965 3012
2966 Token parseMapLiteralEntry(Token token) { 3013 Token parseMapLiteralEntry(Token token) {
2967 listener.beginLiteralMapEntry(token); 3014 listener.beginLiteralMapEntry(token);
2968 // Assume the listener rejects non-string keys. 3015 // Assume the listener rejects non-string keys.
2969 token = parseExpression(token); 3016 token = parseExpression(token);
2970 Token colon = token; 3017 Token colon = token;
2971 token = expect(':', token); 3018 token = expect(':', token);
2972 token = parseExpression(token); 3019 token = parseExpression(token);
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
3008 } 3055 }
3009 } 3056 }
3010 return false; 3057 return false;
3011 } 3058 }
3012 3059
3013 Token parseRequiredArguments(Token token) { 3060 Token parseRequiredArguments(Token token) {
3014 if (optional('(', token)) { 3061 if (optional('(', token)) {
3015 token = parseArguments(token); 3062 token = parseArguments(token);
3016 } else { 3063 } else {
3017 listener.handleNoArguments(token); 3064 listener.handleNoArguments(token);
3018 token = reportUnrecoverableError(token, ErrorKind.UnexpectedToken)?.next; 3065 token = reportUnexpectedToken(token).next;
3019 } 3066 }
3020 return token; 3067 return token;
3021 } 3068 }
3022 3069
3023 Token parseNewExpression(Token token) { 3070 Token parseNewExpression(Token token) {
3024 Token newKeyword = token; 3071 Token newKeyword = token;
3025 token = expect('new', token); 3072 token = expect('new', token);
3026 listener.beginNewExpression(newKeyword); 3073 listener.beginNewExpression(newKeyword);
3027 token = parseConstructorReference(token); 3074 token = parseConstructorReference(token);
3028 token = parseRequiredArguments(token); 3075 token = parseRequiredArguments(token);
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after
3213 if (optional('!', token.next)) { 3260 if (optional('!', token.next)) {
3214 token = token.next; 3261 token = token.next;
3215 not = token; 3262 not = token;
3216 } 3263 }
3217 token = parseType(token.next); 3264 token = parseType(token.next);
3218 listener.handleIsOperator(operator, not, token); 3265 listener.handleIsOperator(operator, not, token);
3219 String value = token.stringValue; 3266 String value = token.stringValue;
3220 if (identical(value, 'is') || identical(value, 'as')) { 3267 if (identical(value, 'is') || identical(value, 'as')) {
3221 // The is- and as-operators cannot be chained, but they can take part of 3268 // The is- and as-operators cannot be chained, but they can take part of
3222 // expressions like: foo is Foo || foo is Bar. 3269 // expressions like: foo is Foo || foo is Bar.
3223 reportUnrecoverableError(token, ErrorKind.UnexpectedToken); 3270 reportUnexpectedToken(token);
3224 } 3271 }
3225 return token; 3272 return token;
3226 } 3273 }
3227 3274
3228 Token parseAsOperatorRest(Token token) { 3275 Token parseAsOperatorRest(Token token) {
3229 assert(optional('as', token)); 3276 assert(optional('as', token));
3230 Token operator = token; 3277 Token operator = token;
3231 token = parseType(token.next); 3278 token = parseType(token.next);
3232 listener.handleAsOperator(operator, token); 3279 listener.handleAsOperator(operator, token);
3233 String value = token.stringValue; 3280 String value = token.stringValue;
3234 if (identical(value, 'is') || identical(value, 'as')) { 3281 if (identical(value, 'is') || identical(value, 'as')) {
3235 // The is- and as-operators cannot be chained. 3282 // The is- and as-operators cannot be chained.
3236 reportUnrecoverableError(token, ErrorKind.UnexpectedToken); 3283 reportUnexpectedToken(token);
3237 } 3284 }
3238 return token; 3285 return token;
3239 } 3286 }
3240 3287
3241 Token parseVariablesDeclaration(Token token) { 3288 Token parseVariablesDeclaration(Token token) {
3242 return parseVariablesDeclarationMaybeSemicolon(token, true); 3289 return parseVariablesDeclarationMaybeSemicolon(token, true);
3243 } 3290 }
3244 3291
3245 Token parseVariablesDeclarationNoSemicolon(Token token) { 3292 Token parseVariablesDeclarationNoSemicolon(Token token) {
3246 // Only called when parsing a for loop, so this is for parsing locals. 3293 // Only called when parsing a for loop, so this is for parsing locals.
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
3301 Token forKeyword = token; 3348 Token forKeyword = token;
3302 listener.beginForStatement(forKeyword); 3349 listener.beginForStatement(forKeyword);
3303 token = expect('for', token); 3350 token = expect('for', token);
3304 Token leftParenthesis = token; 3351 Token leftParenthesis = token;
3305 token = expect('(', token); 3352 token = expect('(', token);
3306 token = parseVariablesDeclarationOrExpressionOpt(token); 3353 token = parseVariablesDeclarationOrExpressionOpt(token);
3307 if (optional('in', token)) { 3354 if (optional('in', token)) {
3308 return parseForInRest(awaitToken, forKeyword, leftParenthesis, token); 3355 return parseForInRest(awaitToken, forKeyword, leftParenthesis, token);
3309 } else { 3356 } else {
3310 if (awaitToken != null) { 3357 if (awaitToken != null) {
3311 reportRecoverableError(awaitToken, ErrorKind.InvalidAwaitFor); 3358 reportRecoverableErrorCode(awaitToken, codeInvalidAwaitFor);
3312 } 3359 }
3313 return parseForRest(forKeyword, leftParenthesis, token); 3360 return parseForRest(forKeyword, leftParenthesis, token);
3314 } 3361 }
3315 } 3362 }
3316 3363
3317 Token parseVariablesDeclarationOrExpressionOpt(Token token) { 3364 Token parseVariablesDeclarationOrExpressionOpt(Token token) {
3318 final String value = token.stringValue; 3365 final String value = token.stringValue;
3319 if (identical(value, ';')) { 3366 if (identical(value, ';')) {
3320 listener.handleNoExpression(token); 3367 listener.handleNoExpression(token);
3321 return token; 3368 return token;
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
3414 } 3461 }
3415 listener.endBlock(statementCount, begin, token); 3462 listener.endBlock(statementCount, begin, token);
3416 return expect('}', token); 3463 return expect('}', token);
3417 } 3464 }
3418 3465
3419 Token parseAwaitExpression(Token token, bool allowCascades) { 3466 Token parseAwaitExpression(Token token, bool allowCascades) {
3420 Token awaitToken = token; 3467 Token awaitToken = token;
3421 listener.beginAwaitExpression(awaitToken); 3468 listener.beginAwaitExpression(awaitToken);
3422 token = expect('await', token); 3469 token = expect('await', token);
3423 if (!inAsync) { 3470 if (!inAsync) {
3424 reportRecoverableError(awaitToken, ErrorKind.AwaitNotAsync); 3471 reportRecoverableErrorCode(awaitToken, codeAwaitNotAsync);
3425 } 3472 }
3426 token = parsePrecedenceExpression(token, POSTFIX_PRECEDENCE, allowCascades); 3473 token = parsePrecedenceExpression(token, POSTFIX_PRECEDENCE, allowCascades);
3427 listener.endAwaitExpression(awaitToken, token); 3474 listener.endAwaitExpression(awaitToken, token);
3428 return token; 3475 return token;
3429 } 3476 }
3430 3477
3431 Token parseThrowExpression(Token token, bool allowCascades) { 3478 Token parseThrowExpression(Token token, bool allowCascades) {
3432 Token throwToken = token; 3479 Token throwToken = token;
3433 listener.beginThrowExpression(throwToken); 3480 listener.beginThrowExpression(throwToken);
3434 token = expect('throw', token); 3481 token = expect('throw', token);
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
3482 value = token.stringValue; // while condition 3529 value = token.stringValue; // while condition
3483 } 3530 }
3484 3531
3485 Token finallyKeyword = null; 3532 Token finallyKeyword = null;
3486 if (optional('finally', token)) { 3533 if (optional('finally', token)) {
3487 finallyKeyword = token; 3534 finallyKeyword = token;
3488 token = parseBlock(token.next); 3535 token = parseBlock(token.next);
3489 listener.handleFinallyBlock(finallyKeyword); 3536 listener.handleFinallyBlock(finallyKeyword);
3490 } else { 3537 } else {
3491 if (catchCount == 0) { 3538 if (catchCount == 0) {
3492 reportRecoverableError(tryKeyword, ErrorKind.OnlyTry); 3539 reportRecoverableErrorCode(tryKeyword, codeOnlyTry);
3493 } 3540 }
3494 } 3541 }
3495 listener.endTryStatement(catchCount, tryKeyword, finallyKeyword); 3542 listener.endTryStatement(catchCount, tryKeyword, finallyKeyword);
3496 return token; 3543 return token;
3497 } 3544 }
3498 3545
3499 Token parseSwitchStatement(Token token) { 3546 Token parseSwitchStatement(Token token) {
3500 assert(optional('switch', token)); 3547 assert(optional('switch', token));
3501 Token switchKeyword = token; 3548 Token switchKeyword = token;
3502 listener.beginSwitchStatement(switchKeyword); 3549 listener.beginSwitchStatement(switchKeyword);
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
3561 Token caseKeyword = token; 3608 Token caseKeyword = token;
3562 token = parseExpression(token.next); 3609 token = parseExpression(token.next);
3563 Token colonToken = token; 3610 Token colonToken = token;
3564 token = expect(':', token); 3611 token = expect(':', token);
3565 listener.handleCaseMatch(caseKeyword, colonToken); 3612 listener.handleCaseMatch(caseKeyword, colonToken);
3566 expressionCount++; 3613 expressionCount++;
3567 peek = peekPastLabels(token); 3614 peek = peekPastLabels(token);
3568 } else { 3615 } else {
3569 if (expressionCount == 0) { 3616 if (expressionCount == 0) {
3570 // TODO(ahe): This is probably easy to recover from. 3617 // TODO(ahe): This is probably easy to recover from.
3571 reportUnrecoverableError( 3618 reportUnrecoverableErrorCodeWithString(
3572 token, ErrorKind.ExpectedButGot, {"expected": "case"}); 3619 token, codeExpectedButGot, "case");
3573 } 3620 }
3574 break; 3621 break;
3575 } 3622 }
3576 } 3623 }
3577 listener.beginSwitchCase(labelCount, expressionCount, begin); 3624 listener.beginSwitchCase(labelCount, expressionCount, begin);
3578 // Finally zero or more statements. 3625 // Finally zero or more statements.
3579 int statementCount = 0; 3626 int statementCount = 0;
3580 while (!identical(token.kind, EOF_TOKEN)) { 3627 while (!identical(token.kind, EOF_TOKEN)) {
3581 String value = peek.stringValue; 3628 String value = peek.stringValue;
3582 if ((identical(value, 'case')) || 3629 if ((identical(value, 'case')) ||
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
3643 return expectSemicolon(token); 3690 return expectSemicolon(token);
3644 } 3691 }
3645 3692
3646 Token parseEmptyStatement(Token token) { 3693 Token parseEmptyStatement(Token token) {
3647 listener.handleEmptyStatement(token); 3694 listener.handleEmptyStatement(token);
3648 return expectSemicolon(token); 3695 return expectSemicolon(token);
3649 } 3696 }
3650 3697
3651 /// Don't call this method. Should only be used as a last resort when there 3698 /// Don't call this method. Should only be used as a last resort when there
3652 /// is no feasible way to recover from a parser error. 3699 /// is no feasible way to recover from a parser error.
3653 Token reportUnrecoverableError(Token token, ErrorKind kind, [Map arguments]) { 3700 Token reportUnrecoverableError(Token token, FastaMessage format()) {
3654 Token next; 3701 Token next;
3655 if (token is ErrorToken) { 3702 if (token is ErrorToken) {
3656 next = reportErrorToken(token, false); 3703 next = reportErrorToken(token, false);
3657 } else { 3704 } else {
3658 arguments ??= {}; 3705 next = listener.handleUnrecoverableError(token, format());
3659 arguments.putIfAbsent("actual", () => token.lexeme);
3660 next = listener.handleUnrecoverableError(token, kind, arguments);
3661 } 3706 }
3662 return next ?? skipToEof(token); 3707 return next ?? skipToEof(token);
3663 } 3708 }
3664 3709
3665 void reportRecoverableError(Token token, ErrorKind kind, [Map arguments]) { 3710 void reportRecoverableError(Token token, FastaMessage format()) {
3666 if (token is ErrorToken) { 3711 if (token is ErrorToken) {
3667 reportErrorToken(token, true); 3712 reportErrorToken(token, true);
3668 } else { 3713 } else {
3669 arguments ??= {}; 3714 listener.handleRecoverableError(token, format());
3670 listener.handleRecoverableError(token, kind, arguments);
3671 } 3715 }
3672 } 3716 }
3673 3717
3674 Token reportErrorToken(ErrorToken token, bool isRecoverable) { 3718 Token reportErrorToken(ErrorToken token, bool isRecoverable) {
3675 ErrorKind kind = token.errorCode; 3719 FastaCode code = token.errorCode;
3676 Map arguments = const {}; 3720 FastaMessage message;
3677 switch (kind) { 3721 if (code == codeAsciiControlCharacter) {
3678 case ErrorKind.AsciiControlCharacter: 3722 message = codeAsciiControlCharacter.format(
3679 case ErrorKind.NonAsciiIdentifier: 3723 uri, token.charOffset, token.character);
3680 case ErrorKind.NonAsciiWhitespace: 3724 } else if (code == codeNonAsciiWhitespace) {
3681 case ErrorKind.Encoding: 3725 message =
3682 String hex = token.character.toRadixString(16); 3726 codeNonAsciiWhitespace.format(uri, token.charOffset, token.character);
3683 if (hex.length < 4) { 3727 } else if (code == codeEncoding) {
3684 String padding = "0000".substring(hex.length); 3728 message = codeEncoding.format(uri, token.charOffset);
3685 hex = "$padding$hex"; 3729 } else if (code == codeNonAsciiIdentifier) {
3686 } 3730 message = codeNonAsciiIdentifier.format(uri, token.charOffset,
3687 arguments = {'characterHex': hex}; 3731 new String.fromCharCodes([token.character]), token.character);
3688 break; 3732 } else if (code == codeUnterminatedString) {
3689 3733 message =
3690 case ErrorKind.UnterminatedString: 3734 codeUnterminatedString.format(uri, token.charOffset, token.start);
3691 arguments = {'quote': token.start}; 3735 } else if (code == codeUnmatchedToken) {
3692 break; 3736 Token begin = token.begin;
3693 3737 message = codeUnmatchedToken.format(
3694 case ErrorKind.UnmatchedToken: 3738 uri, token.charOffset, closeBraceFor(begin.lexeme), begin);
3695 String begin = token.begin.lexeme; 3739 } else if (code == codeUnspecified) {
3696 String end = closeBraceFor(begin); 3740 message =
3697 arguments = {'begin': begin, 'end': end}; 3741 codeUnspecified.format(uri, token.charOffset, token.assertionMessage);
3698 break; 3742 } else {
3699 3743 message = code.format(uri, token.charOffset);
3700 case ErrorKind.Unspecified:
3701 arguments = {"text": token.assertionMessage};
3702 break;
3703
3704 default:
3705 break;
3706 } 3744 }
3707 if (isRecoverable) { 3745 if (isRecoverable) {
3708 listener.handleRecoverableError(token, kind, arguments); 3746 listener.handleRecoverableError(token, message);
3709 return null; 3747 return null;
3710 } else { 3748 } else {
3711 return listener.handleUnrecoverableError(token, kind, arguments); 3749 Token next = listener.handleUnrecoverableError(token, message);
3750 return next ?? skipToEof(token);
3712 } 3751 }
3713 } 3752 }
3753
3754 Token reportUnmatchedToken(BeginGroupToken token) {
3755 return reportUnrecoverableError(
3756 token,
3757 () => codeUnmatchedToken.format(
3758 uri, token.charOffset, closeBraceFor(token.lexeme), token));
3759 }
3760
3761 Token reportUnexpectedToken(Token token) {
3762 return reportUnrecoverableError(
3763 token, () => codeUnexpectedToken.format(uri, token.charOffset, token));
3764 }
3765
3766 void reportRecoverableErrorCode(Token token, FastaCode<NoArgument> code) {
3767 reportRecoverableError(token, () => code.format(uri, token.charOffset));
3768 }
3769
3770 Token reportUnrecoverableErrorCode(Token token, FastaCode<NoArgument> code) {
3771 return reportUnrecoverableError(
3772 token, () => code.format(uri, token.charOffset));
3773 }
3774
3775 void reportRecoverableErrorCodeWithToken(
3776 Token token, FastaCode<TokenArgument> code) {
3777 reportRecoverableError(
3778 token, () => code.format(uri, token.charOffset, token));
3779 }
3780
3781 Token reportUnrecoverableErrorCodeWithToken(
3782 Token token, FastaCode<TokenArgument> code) {
3783 return reportUnrecoverableError(
3784 token, () => code.format(uri, token.charOffset, token));
3785 }
3786
3787 Token reportUnrecoverableErrorCodeWithString(
3788 Token token, FastaCode<StringArgument> code, String string) {
3789 return reportUnrecoverableError(
3790 token, () => code.format(uri, token.charOffset, string));
3791 }
3714 } 3792 }
3793
3794 typedef FastaMessage NoArgument(Uri uri, int charOffset);
3795
3796 typedef FastaMessage TokenArgument(Uri uri, int charOffset, Token token);
3797
3798 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/problems.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698