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

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

Issue 2948383002: Remove peeking from parseTypedef and parseClassOrNamedMixinApplication. (Closed)
Patch Set: Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library fasta.parser.parser; 5 library fasta.parser.parser;
6 6
7 import '../fasta_codes.dart' 7 import '../fasta_codes.dart'
8 show 8 show
9 FastaCode, 9 FastaCode,
10 FastaMessage, 10 FastaMessage,
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
173 /// 173 ///
174 /// An assertion can legally occur as a statement. However, assertions are also 174 /// An assertion can legally occur as a statement. However, assertions are also
175 /// experimentally allowed in initializers. For improved error recovery, we 175 /// experimentally allowed in initializers. For improved error recovery, we
176 /// also attempt to parse asserts as expressions. 176 /// also attempt to parse asserts as expressions.
177 enum Assert { 177 enum Assert {
178 Expression, 178 Expression,
179 Initializer, 179 Initializer,
180 Statement, 180 Statement,
181 } 181 }
182 182
183 enum TypeContinuation {
Paul Berry 2017/06/24 14:16:26 It would be nice to have a comment explaining what
ahe 2017/06/26 10:14:00 I want to reserve that word for you :-)
184 Typedef,
185 }
186
183 /// An event generating parser of Dart programs. This parser expects all tokens 187 /// An event generating parser of Dart programs. This parser expects all tokens
184 /// in a linked list (aka a token stream). 188 /// in a linked list (aka a token stream).
185 /// 189 ///
186 /// The class [Scanner] is used to generate a token stream. See the file 190 /// The class [Scanner] is used to generate a token stream. See the file
187 /// [scanner.dart](../scanner.dart). 191 /// [scanner.dart](../scanner.dart).
188 /// 192 ///
189 /// Subclasses of the class [Listener] are used to listen to events. 193 /// Subclasses of the class [Listener] are used to listen to events.
190 /// 194 ///
191 /// Most methods of this class belong in one of three major categories: parse 195 /// Most methods of this class belong in one of three major categories: parse
192 /// methods, peek methods, and skip methods. Parse methods all have the prefix 196 /// methods, peek methods, and skip methods. Parse methods all have the prefix
(...skipping 415 matching lines...) Expand 10 before | Expand all | Expand 10 after
608 612
609 Token parseScript(Token token) { 613 Token parseScript(Token token) {
610 listener.handleScript(token); 614 listener.handleScript(token);
611 return token.next; 615 return token.next;
612 } 616 }
613 617
614 Token parseTypedef(Token token) { 618 Token parseTypedef(Token token) {
615 Token typedefKeyword = token; 619 Token typedefKeyword = token;
616 listener.beginFunctionTypeAlias(token); 620 listener.beginFunctionTypeAlias(token);
617 Token equals; 621 Token equals;
618 if (optional('=', peekAfterNominalType(token.next))) { 622 Token afterType = parseType(token.next,
623 isOptional: true, continuation: TypeContinuation.Typedef);
624 if (afterType == null) {
619 token = parseIdentifier(token.next, IdentifierContext.typedefDeclaration); 625 token = parseIdentifier(token.next, IdentifierContext.typedefDeclaration);
620 token = parseTypeVariablesOpt(token); 626 token = parseTypeVariablesOpt(token);
621 equals = token; 627 equals = token;
622 token = expect('=', token); 628 token = expect('=', token);
623 token = parseType(token); 629 token = parseType(token);
624 } else { 630 } else {
625 token = parseType(token.next, isOptional: true); 631 token = afterType;
626 token = parseIdentifier(token, IdentifierContext.typedefDeclaration); 632 token = parseIdentifier(token, IdentifierContext.typedefDeclaration);
627 token = parseTypeVariablesOpt(token); 633 token = parseTypeVariablesOpt(token);
628 token = parseFormalParameters(token, MemberKind.FunctionTypeAlias); 634 token = parseFormalParameters(token, MemberKind.FunctionTypeAlias);
629 } 635 }
630 listener.endFunctionTypeAlias(typedefKeyword, equals, token); 636 listener.endFunctionTypeAlias(typedefKeyword, equals, token);
631 return expect(';', token); 637 return expect(';', token);
632 } 638 }
633 639
634 Token parseMixinApplication(Token token) { 640 Token parseMixinApplication(Token token) {
635 listener.beginMixinApplication(token); 641 listener.beginMixinApplication(token);
(...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after
961 count++; 967 count++;
962 } 968 }
963 } 969 }
964 Token endBrace = token; 970 Token endBrace = token;
965 token = expect('}', token); 971 token = expect('}', token);
966 listener.endEnum(enumKeyword, endBrace, count); 972 listener.endEnum(enumKeyword, endBrace, count);
967 return token; 973 return token;
968 } 974 }
969 975
970 Token parseClassOrNamedMixinApplication(Token token) { 976 Token parseClassOrNamedMixinApplication(Token token) {
977 listener.beginClassOrNamedMixinApplication(token);
971 Token begin = token; 978 Token begin = token;
972 Token abstractKeyword; 979 if (optional('abstract', token)) {
980 token = parseModifier(token);
981 listener.handleModifiers(1);
982 } else {
983 listener.handleModifiers(0);
984 }
973 Token classKeyword = token; 985 Token classKeyword = token;
974 if (optional('abstract', token)) { 986 token = expect("class", token);
975 abstractKeyword = token; 987 Token name = token;
976 token = token.next; 988 token =
977 classKeyword = token; 989 parseIdentifier(name, IdentifierContext.classOrNamedMixinDeclaration);
978 } 990 token = parseTypeVariablesOpt(token);
979 assert(optional('class', classKeyword)); 991 if (optional('=', token)) {
980 int modifierCount = 0;
981 if (abstractKeyword != null) {
982 parseModifier(abstractKeyword);
983 modifierCount++;
984 }
985 listener.handleModifiers(modifierCount);
986 bool isMixinApplication = optional('=', peekAfterNominalType(token));
987 Token name = token.next;
988
989 if (isMixinApplication) {
990 token = parseIdentifier(name, IdentifierContext.namedMixinDeclaration);
991 listener.beginNamedMixinApplication(begin, name); 992 listener.beginNamedMixinApplication(begin, name);
992 } else {
993 token = parseIdentifier(name, IdentifierContext.classDeclaration);
994 listener.beginClassDeclaration(begin, name);
995 }
996
997 token = parseTypeVariablesOpt(token);
998
999 if (optional('=', token)) {
1000 Token equals = token; 993 Token equals = token;
1001 token = token.next; 994 token = token.next;
1002 return parseNamedMixinApplication( 995 return parseNamedMixinApplication(
1003 token, begin, classKeyword, name, equals); 996 token, begin, classKeyword, name, equals);
1004 } else { 997 } else {
998 listener.beginClassDeclaration(begin, name);
1005 return parseClass(token, begin, classKeyword, name); 999 return parseClass(token, begin, classKeyword, name);
1006 } 1000 }
1007 } 1001 }
1008 1002
1009 Token parseNamedMixinApplication( 1003 Token parseNamedMixinApplication(
1010 Token token, Token begin, Token classKeyword, Token name, Token equals) { 1004 Token token, Token begin, Token classKeyword, Token name, Token equals) {
1011 token = parseMixinApplication(token); 1005 token = parseMixinApplication(token);
1012 Token implementsKeyword = null; 1006 Token implementsKeyword = null;
1013 if (optional('implements', token)) { 1007 if (optional('implements', token)) {
1014 implementsKeyword = token; 1008 implementsKeyword = token;
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
1132 bool notEofOrValue(String value, Token token) { 1126 bool notEofOrValue(String value, Token token) {
1133 return !identical(token.kind, EOF_TOKEN) && 1127 return !identical(token.kind, EOF_TOKEN) &&
1134 !identical(value, token.stringValue); 1128 !identical(value, token.stringValue);
1135 } 1129 }
1136 1130
1137 bool isGeneralizedFunctionType(Token token) { 1131 bool isGeneralizedFunctionType(Token token) {
1138 return optional('Function', token) && 1132 return optional('Function', token) &&
1139 (optional('<', token.next) || optional('(', token.next)); 1133 (optional('<', token.next) || optional('(', token.next));
1140 } 1134 }
1141 1135
1142 Token parseType(Token token, {bool isOptional: false}) { 1136 Token parseType(Token token,
Paul Berry 2017/06/24 14:16:26 It would be nice to have a comment here explaining
ahe 2017/06/26 10:14:01 Done.
1137 {bool isOptional: false, TypeContinuation continuation}) {
1138 if (continuation != null) {
ahe 2017/06/24 10:10:31 A little bit of context here: My plan is to move
1139 switch (continuation) {
Paul Berry 2017/06/24 14:16:26 Nit: It seems odd to have a null check followed by
ahe 2017/06/26 10:14:00 Done.
1140 case TypeContinuation.Typedef:
1141 if (optional('=', peekAfterNominalType(token))) {
1142 return null; // This isn't a type, it's a new-style typedef.
1143 }
1144 break;
1145
1146 default:
1147 throw "Internal error: Unhandled continuation '$continuation'.";
1148 }
1149 }
1143 if (isOptional) { 1150 if (isOptional) {
1144 do { 1151 do {
1145 if (optional("void", token)) { 1152 if (optional("void", token)) {
1146 if (isGeneralizedFunctionType(token.next)) { 1153 if (isGeneralizedFunctionType(token.next)) {
1147 // This is a type, parse it. 1154 // This is a type, parse it.
1148 break; 1155 break;
1149 } else { 1156 } else {
1150 listener.handleVoidKeyword(token); 1157 listener.handleVoidKeyword(token);
1151 return token.next; 1158 return token.next;
1152 } 1159 }
(...skipping 2872 matching lines...) Expand 10 before | Expand all | Expand 10 after
4025 return reportUnrecoverableError( 4032 return reportUnrecoverableError(
4026 token, () => code.format(uri, token.charOffset, string)); 4033 token, () => code.format(uri, token.charOffset, string));
4027 } 4034 }
4028 } 4035 }
4029 4036
4030 typedef FastaMessage NoArgument(Uri uri, int charOffset); 4037 typedef FastaMessage NoArgument(Uri uri, int charOffset);
4031 4038
4032 typedef FastaMessage TokenArgument(Uri uri, int charOffset, Token token); 4039 typedef FastaMessage TokenArgument(Uri uri, int charOffset, Token token);
4033 4040
4034 typedef FastaMessage StringArgument(Uri uri, int charOffset, String string); 4041 typedef FastaMessage StringArgument(Uri uri, int charOffset, String string);
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698