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

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

Issue 2978063002: Move parser helper classes to own files and clean them up. (Closed)
Patch Set: Don't use problems.dart in parser. Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library fasta.parser.parser; 5 library fasta.parser.parser;
6 6
7 import '../fasta_codes.dart' show Code, Message, Template; 7 import '../fasta_codes.dart' show Code, Message, Template;
8 8
9 import '../fasta_codes.dart' as fasta; 9 import '../fasta_codes.dart' as fasta;
10 10
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
45 PERIOD_TOKEN, 45 PERIOD_TOKEN,
46 SEMICOLON_TOKEN, 46 SEMICOLON_TOKEN,
47 STRING_INTERPOLATION_IDENTIFIER_TOKEN, 47 STRING_INTERPOLATION_IDENTIFIER_TOKEN,
48 STRING_INTERPOLATION_TOKEN, 48 STRING_INTERPOLATION_TOKEN,
49 STRING_TOKEN; 49 STRING_TOKEN;
50 50
51 import '../scanner/characters.dart' show $CLOSE_CURLY_BRACKET; 51 import '../scanner/characters.dart' show $CLOSE_CURLY_BRACKET;
52 52
53 import '../util/link.dart' show Link; 53 import '../util/link.dart' show Link;
54 54
55 import 'assert.dart' show Assert;
56
55 import 'async_modifier.dart' show AsyncModifier; 57 import 'async_modifier.dart' show AsyncModifier;
56 58
59 import 'formal_parameter_kind.dart'
60 show
61 FormalParameterKind,
62 isMandatoryFormalParameterKind,
63 isOptionalPositionalFormalParameterKind;
64
65 import 'identifier_context.dart' show IdentifierContext;
66
57 import 'listener.dart' show Listener; 67 import 'listener.dart' show Listener;
58 68
59 import 'identifier_context.dart' show IdentifierContext; 69 import 'member_kind.dart' show MemberKind;
60 70
61 /// Returns true if [token] is the symbol or keyword [value]. 71 import 'type_continuation.dart'
62 bool optional(String value, Token token) { 72 show TypeContinuation, typeContiunationFromFormalParameterKind;
63 return identical(value, token.stringValue);
64 }
65 73
66 // TODO(ahe): Convert this to an enum. 74 import 'util.dart' show optional;
67 class FormalParameterType {
68 final String type;
69
70 final TypeContinuation typeContinuation;
71
72 const FormalParameterType(this.type, this.typeContinuation);
73
74 bool get isRequired => this == REQUIRED;
75
76 bool get isPositional => this == POSITIONAL;
77
78 bool get isNamed => this == NAMED;
79
80 static final REQUIRED = const FormalParameterType(
81 'required', TypeContinuation.NormalFormalParameter);
82
83 static final POSITIONAL = const FormalParameterType(
84 'positional', TypeContinuation.OptionalPositionalFormalParameter);
85
86 static final NAMED =
87 const FormalParameterType('named', TypeContinuation.NamedFormalParameter);
88 }
89
90 enum MemberKind {
91 /// A catch block, not a real member.
92 Catch,
93
94 /// A factory
95 Factory,
96
97 /// Old-style typedef.
98 FunctionTypeAlias,
99
100 /// Old-style function-typed parameter, not a real member.
101 FunctionTypedParameter,
102
103 /// A generalized function type, not a real member.
104 GeneralizedFunctionType,
105
106 /// A local function.
107 Local,
108
109 /// A non-static method in a class (including constructors).
110 NonStaticMethod,
111
112 /// A static method in a class.
113 StaticMethod,
114
115 /// A top-level method.
116 TopLevelMethod,
117
118 /// An instance field in a class.
119 NonStaticField,
120
121 /// A static field in a class.
122 StaticField,
123
124 /// A top-level field.
125 TopLevelField,
126 }
127
128 /// Syntactic forms of `assert`.
129 ///
130 /// An assertion can legally occur as a statement. However, assertions are also
131 /// experimentally allowed in initializers. For improved error recovery, we
132 /// also attempt to parse asserts as expressions.
133 enum Assert {
134 Expression,
135 Initializer,
136 Statement,
137 }
138
139 /// Indication of how the parser should continue after (attempting) to parse a
140 /// type.
141 ///
142 /// Depending on the continuation, the parser may not parse a type at all.
143 enum TypeContinuation {
144 /// Indicates that a type is unconditionally expected.
145 Required,
146
147 /// Indicates that a type may follow. If the following matches one of these
148 /// productions, it is parsed as a type:
149 ///
150 /// - `'void'`
151 /// - `'Function' ( '(' | '<' )`
152 /// - `identifier ('.' identifier)? ('<' ... '>')? identifer`
153 ///
154 /// Otherwise, do nothing.
155 Optional,
156
157 /// Same as [Optional], but we have seen `var`.
158 OptionalAfterVar,
159
160 /// Indicates that the keyword `typedef` has just been seen, and the parser
161 /// should parse the following as a type unless it is followed by `=`.
162 Typedef,
163
164 /// Indicates that what follows is either a local declaration or an
165 /// expression.
166 ExpressionStatementOrDeclaration,
167
168 /// Indicates that the keyword `const` has just been seen, and what follows
169 /// may be a local variable declaration or an expression.
170 ExpressionStatementOrConstDeclaration,
171
172 /// Indicates that the parser is parsing an expression and has just seen an
173 /// identifier.
174 SendOrFunctionLiteral,
175
176 /// Indicates that the parser has just parsed `for '('` and is looking to
177 /// parse a variable declaration or expression.
178 VariablesDeclarationOrExpression,
179
180 /// Indicates that an optional type followed by a normal formal parameter is
181 /// expected.
182 NormalFormalParameter,
183
184 /// Indicates that an optional type followed by an optional positional formal
185 /// parameter is expected.
186 OptionalPositionalFormalParameter,
187
188 /// Indicates that an optional type followed by a named formal parameter is
189 /// expected.
190 NamedFormalParameter,
191
192 /// Same as [NormalFormalParameter], but we have seen `var`.
193 NormalFormalParameterAfterVar,
194
195 /// Same as [OptionalPositionalFormalParameter], but we have seen `var`.
196 OptionalPositionalFormalParameterAfterVar,
197
198 /// Same as [NamedFormalParameter], but we have seen `var`.
199 NamedFormalParameterAfterVar,
200 }
201 75
202 /// An event generating parser of Dart programs. This parser expects all tokens 76 /// An event generating parser of Dart programs. This parser expects all tokens
203 /// in a linked list (aka a token stream). 77 /// in a linked list (aka a token stream).
204 /// 78 ///
205 /// The class [Scanner] is used to generate a token stream. See the file 79 /// The class [Scanner] is used to generate a token stream. See the file
206 /// [scanner.dart](../scanner.dart). 80 /// [scanner.dart](../scanner.dart).
207 /// 81 ///
208 /// Subclasses of the class [Listener] are used to listen to events. 82 /// Subclasses of the class [Listener] are used to listen to events.
209 /// 83 ///
210 /// Most methods of this class belong in one of three major categories: parse 84 /// Most methods of this class belong in one of three major categories: parse
(...skipping 501 matching lines...) Expand 10 before | Expand all | Expand 10 after
712 break; 586 break;
713 } else if (identical(value, '{')) { 587 } else if (identical(value, '{')) {
714 token = parseOptionalFormalParameters(token, true, kind); 588 token = parseOptionalFormalParameters(token, true, kind);
715 break; 589 break;
716 } else if (identical(value, '[]')) { 590 } else if (identical(value, '[]')) {
717 --parameterCount; 591 --parameterCount;
718 reportRecoverableError(token, fasta.messageEmptyOptionalParameterList); 592 reportRecoverableError(token, fasta.messageEmptyOptionalParameterList);
719 token = token.next; 593 token = token.next;
720 break; 594 break;
721 } 595 }
722 token = parseFormalParameter(token, FormalParameterType.REQUIRED, kind); 596 token = parseFormalParameter(token, FormalParameterKind.mandatory, kind);
723 } while (optional(',', token)); 597 } while (optional(',', token));
724 listener.endFormalParameters(parameterCount, begin, token, kind); 598 listener.endFormalParameters(parameterCount, begin, token, kind);
725 return expect(')', token); 599 return expect(')', token);
726 } 600 }
727 601
728 Token parseFormalParameter( 602 Token parseFormalParameter(
729 Token token, FormalParameterType parameterKind, MemberKind memberKind) { 603 Token token, FormalParameterKind parameterKind, MemberKind memberKind) {
730 token = parseMetadataStar(token, forParameter: true); 604 token = parseMetadataStar(token, forParameter: true);
731 listener.beginFormalParameter(token, memberKind); 605 listener.beginFormalParameter(token, memberKind);
732 token = parseModifiers(token, memberKind, parameterKind: parameterKind); 606 token = parseModifiers(token, memberKind, parameterKind: parameterKind);
733 return token; 607 return token;
734 } 608 }
735 609
736 Token parseOptionalFormalParameters( 610 Token parseOptionalFormalParameters(
737 Token token, bool isNamed, MemberKind kind) { 611 Token token, bool isNamed, MemberKind kind) {
738 Token begin = token; 612 Token begin = token;
739 listener.beginOptionalFormalParameters(begin); 613 listener.beginOptionalFormalParameters(begin);
740 assert((isNamed && optional('{', token)) || optional('[', token)); 614 assert((isNamed && optional('{', token)) || optional('[', token));
741 int parameterCount = 0; 615 int parameterCount = 0;
742 do { 616 do {
743 token = token.next; 617 token = token.next;
744 if (isNamed && optional('}', token)) { 618 if (isNamed && optional('}', token)) {
745 break; 619 break;
746 } else if (!isNamed && optional(']', token)) { 620 } else if (!isNamed && optional(']', token)) {
747 break; 621 break;
748 } 622 }
749 var type = 623 var type = isNamed
750 isNamed ? FormalParameterType.NAMED : FormalParameterType.POSITIONAL; 624 ? FormalParameterKind.optionalNamed
625 : FormalParameterKind.optionalPositional;
751 token = parseFormalParameter(token, type, kind); 626 token = parseFormalParameter(token, type, kind);
752 ++parameterCount; 627 ++parameterCount;
753 } while (optional(',', token)); 628 } while (optional(',', token));
754 if (parameterCount == 0) { 629 if (parameterCount == 0) {
755 reportRecoverableError( 630 reportRecoverableError(
756 token, 631 token,
757 isNamed 632 isNamed
758 ? fasta.messageEmptyNamedParameterList 633 ? fasta.messageEmptyNamedParameterList
759 : fasta.messageEmptyOptionalParameterList); 634 : fasta.messageEmptyOptionalParameterList);
760 } 635 }
(...skipping 500 matching lines...) Expand 10 before | Expand all | Expand 10 after
1261 } 1136 }
1262 1137
1263 /// Returns true if [token] could be the start of a function body. 1138 /// Returns true if [token] could be the start of a function body.
1264 bool looksLikeFunctionBody(Token token) { 1139 bool looksLikeFunctionBody(Token token) {
1265 return optional('{', token) || 1140 return optional('{', token) ||
1266 optional('=>', token) || 1141 optional('=>', token) ||
1267 optional('async', token) || 1142 optional('async', token) ||
1268 optional('sync', token); 1143 optional('sync', token);
1269 } 1144 }
1270 1145
1271 FormalParameterType parameterKind; 1146 FormalParameterKind parameterKind;
1272 switch (continuation) { 1147 switch (continuation) {
1273 case TypeContinuation.Required: 1148 case TypeContinuation.Required:
1274 return commitType(); 1149 return commitType();
1275 1150
1276 optional: 1151 optional:
1277 case TypeContinuation.Optional: 1152 case TypeContinuation.Optional:
1278 if (looksLikeType) { 1153 if (looksLikeType) {
1279 if (functionTypes > 0) { 1154 if (functionTypes > 0) {
1280 return commitType(); // Parse function type. 1155 return commitType(); // Parse function type.
1281 } 1156 }
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
1400 token.isIdentifier && 1275 token.isIdentifier &&
1401 isOneOf4(token.next, '=', ';', ',', 'in')) { 1276 isOneOf4(token.next, '=', ';', ',', 'in')) {
1402 // TODO(ahe): Generate type events and call 1277 // TODO(ahe): Generate type events and call
1403 // parseVariablesDeclarationNoSemicolonRest instead. 1278 // parseVariablesDeclarationNoSemicolonRest instead.
1404 return parseVariablesDeclarationNoSemicolon(begin); 1279 return parseVariablesDeclarationNoSemicolon(begin);
1405 } 1280 }
1406 return parseExpression(begin); 1281 return parseExpression(begin);
1407 1282
1408 case TypeContinuation.NormalFormalParameter: 1283 case TypeContinuation.NormalFormalParameter:
1409 case TypeContinuation.NormalFormalParameterAfterVar: 1284 case TypeContinuation.NormalFormalParameterAfterVar:
1410 parameterKind = FormalParameterType.REQUIRED; 1285 parameterKind = FormalParameterKind.mandatory;
1411 hasVar = continuation == TypeContinuation.NormalFormalParameterAfterVar; 1286 hasVar = continuation == TypeContinuation.NormalFormalParameterAfterVar;
1412 continue handleParameters; 1287 continue handleParameters;
1413 1288
1414 case TypeContinuation.OptionalPositionalFormalParameter: 1289 case TypeContinuation.OptionalPositionalFormalParameter:
1415 case TypeContinuation.OptionalPositionalFormalParameterAfterVar: 1290 case TypeContinuation.OptionalPositionalFormalParameterAfterVar:
1416 parameterKind = FormalParameterType.POSITIONAL; 1291 parameterKind = FormalParameterKind.optionalPositional;
1417 hasVar = continuation == 1292 hasVar = continuation ==
1418 TypeContinuation.OptionalPositionalFormalParameterAfterVar; 1293 TypeContinuation.OptionalPositionalFormalParameterAfterVar;
1419 continue handleParameters; 1294 continue handleParameters;
1420 1295
1421 case TypeContinuation.NamedFormalParameterAfterVar: 1296 case TypeContinuation.NamedFormalParameterAfterVar:
1422 hasVar = true; 1297 hasVar = true;
1423 continue handleParameters; 1298 continue handleParameters;
1424 1299
1425 handleParameters: 1300 handleParameters:
1426 case TypeContinuation.NamedFormalParameter: 1301 case TypeContinuation.NamedFormalParameter:
1427 parameterKind ??= FormalParameterType.NAMED; 1302 parameterKind ??= FormalParameterKind.optionalNamed;
1428 bool inFunctionType = memberKind == MemberKind.GeneralizedFunctionType; 1303 bool inFunctionType = memberKind == MemberKind.GeneralizedFunctionType;
1429 bool isNamedParameter = parameterKind == FormalParameterType.NAMED; 1304 bool isNamedParameter =
1305 parameterKind == FormalParameterKind.optionalNamed;
1430 1306
1431 bool untyped = false; 1307 bool untyped = false;
1432 if (!looksLikeType || optional("this", begin)) { 1308 if (!looksLikeType || optional("this", begin)) {
1433 untyped = true; 1309 untyped = true;
1434 token = begin; 1310 token = begin;
1435 } 1311 }
1436 1312
1437 Token thisKeyword; 1313 Token thisKeyword;
1438 Token nameToken = token; 1314 Token nameToken = token;
1439 IdentifierContext nameContext = 1315 IdentifierContext nameContext =
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
1516 parseIdentifier(nameToken, nameContext); 1392 parseIdentifier(nameToken, nameContext);
1517 } else { 1393 } else {
1518 listener.handleNoName(nameToken); 1394 listener.handleNoName(nameToken);
1519 } 1395 }
1520 1396
1521 String value = token.stringValue; 1397 String value = token.stringValue;
1522 if ((identical('=', value)) || (identical(':', value))) { 1398 if ((identical('=', value)) || (identical(':', value))) {
1523 Token equal = token; 1399 Token equal = token;
1524 token = parseExpression(token.next); 1400 token = parseExpression(token.next);
1525 listener.handleValuedFormalParameter(equal, token); 1401 listener.handleValuedFormalParameter(equal, token);
1526 if (parameterKind.isRequired) { 1402 if (isMandatoryFormalParameterKind(parameterKind)) {
1527 reportRecoverableError( 1403 reportRecoverableError(
1528 equal, fasta.messageRequiredParameterWithDefault); 1404 equal, fasta.messageRequiredParameterWithDefault);
1529 } else if (parameterKind.isPositional && identical(':', value)) { 1405 } else if (isOptionalPositionalFormalParameterKind(parameterKind) &&
1406 identical(':', value)) {
1530 reportRecoverableError( 1407 reportRecoverableError(
1531 equal, fasta.messagePositionalParameterWithEquals); 1408 equal, fasta.messagePositionalParameterWithEquals);
1532 } else if (inFunctionType || 1409 } else if (inFunctionType ||
1533 memberKind == MemberKind.FunctionTypeAlias || 1410 memberKind == MemberKind.FunctionTypeAlias ||
1534 memberKind == MemberKind.FunctionTypedParameter) { 1411 memberKind == MemberKind.FunctionTypedParameter) {
1535 reportRecoverableError( 1412 reportRecoverableError(
1536 equal.next, fasta.messageFunctionTypeDefaultValue); 1413 equal.next, fasta.messageFunctionTypeDefaultValue);
1537 } 1414 }
1538 } else { 1415 } else {
1539 listener.handleFormalParameterWithoutValue(token); 1416 listener.handleFormalParameterWithoutValue(token);
(...skipping 484 matching lines...) Expand 10 before | Expand all | Expand 10 after
2024 } 1901 }
2025 1902
2026 /// This method is used in most locations where modifiers can occur. However, 1903 /// This method is used in most locations where modifiers can occur. However,
2027 /// it isn't used when parsing a class or when parsing the modifiers of a 1904 /// it isn't used when parsing a class or when parsing the modifiers of a
2028 /// member function (non-local), but is used when parsing their formal 1905 /// member function (non-local), but is used when parsing their formal
2029 /// parameters. 1906 /// parameters.
2030 /// 1907 ///
2031 /// When parsing the formal parameters of any function, [parameterKind] is 1908 /// When parsing the formal parameters of any function, [parameterKind] is
2032 /// non-null. 1909 /// non-null.
2033 Token parseModifiers(Token token, MemberKind memberKind, 1910 Token parseModifiers(Token token, MemberKind memberKind,
2034 {FormalParameterType parameterKind, bool isVarAllowed: false}) { 1911 {FormalParameterKind parameterKind, bool isVarAllowed: false}) {
2035 int count = 0; 1912 int count = 0;
2036 1913
2037 int currentOrder = -1; 1914 int currentOrder = -1;
2038 TypeContinuation typeContinuation = parameterKind?.typeContinuation; 1915 TypeContinuation typeContinuation =
1916 typeContiunationFromFormalParameterKind(parameterKind);
2039 1917
2040 while (token.kind == KEYWORD_TOKEN) { 1918 while (token.kind == KEYWORD_TOKEN) {
2041 if (token.type.isPseudo) { 1919 if (token.type.isPseudo) {
2042 // A pseudo keyword is never a modifier. 1920 // A pseudo keyword is never a modifier.
2043 break; 1921 break;
2044 } 1922 }
2045 if (token.type.isBuiltIn) { 1923 if (token.type.isBuiltIn) {
2046 // A built-in identifier can only be a modifier as long as it is 1924 // A built-in identifier can only be a modifier as long as it is
2047 // followed by another modifier or an identifier. Otherwise, it is the 1925 // followed by another modifier or an identifier. Otherwise, it is the
2048 // identifier. 1926 // identifier.
(...skipping 2086 matching lines...) Expand 10 before | Expand all | Expand 10 after
4135 } 4013 }
4136 4014
4137 Token reportUnexpectedToken(Token token) { 4015 Token reportUnexpectedToken(Token token) {
4138 return reportUnrecoverableErrorWithToken( 4016 return reportUnrecoverableErrorWithToken(
4139 token, fasta.templateUnexpectedToken); 4017 token, fasta.templateUnexpectedToken);
4140 } 4018 }
4141 } 4019 }
4142 4020
4143 // TODO(ahe): Remove when analyzer supports generalized function syntax. 4021 // TODO(ahe): Remove when analyzer supports generalized function syntax.
4144 typedef _MessageWithArgument<T> = Message Function(T); 4022 typedef _MessageWithArgument<T> = Message Function(T);
OLDNEW
« no previous file with comments | « pkg/front_end/lib/src/fasta/parser/native_support.dart ('k') | pkg/front_end/lib/src/fasta/parser/parser_error.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698