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

Side by Side Diff: pkg/front_end/lib/src/scanner/token.dart

Issue 3007943002: gracefully recover from extraneous top level modifiers (Closed)
Patch Set: address comments Created 3 years, 3 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) 2016, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2016, 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 /** 5 /**
6 * Defines the tokens that are produced by the scanner, used by the parser, and 6 * Defines the tokens that are produced by the scanner, used by the parser, and
7 * referenced from the [AST structure](ast.dart). 7 * referenced from the [AST structure](ast.dart).
8 */ 8 */
9 import 'dart:collection'; 9 import 'dart:collection';
10 10
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
131 } 131 }
132 } 132 }
133 133
134 /** 134 /**
135 * The keywords in the Dart programming language. 135 * The keywords in the Dart programming language.
136 * 136 *
137 * Clients may not extend, implement or mix-in this class. 137 * Clients may not extend, implement or mix-in this class.
138 */ 138 */
139 class Keyword extends TokenType { 139 class Keyword extends TokenType {
140 static const Keyword ABSTRACT = 140 static const Keyword ABSTRACT =
141 const Keyword("abstract", "ABSTRACT", isBuiltIn: true); 141 const Keyword("abstract", "ABSTRACT", isBuiltIn: true, isModifier: true);
142 142
143 static const Keyword AS = const Keyword("as", "AS", 143 static const Keyword AS = const Keyword("as", "AS",
144 precedence: RELATIONAL_PRECEDENCE, isBuiltIn: true); 144 precedence: RELATIONAL_PRECEDENCE, isBuiltIn: true);
145 145
146 static const Keyword ASSERT = const Keyword("assert", "ASSERT"); 146 static const Keyword ASSERT = const Keyword("assert", "ASSERT");
147 147
148 static const Keyword ASYNC = const Keyword("async", "ASYNC", isPseudo: true); 148 static const Keyword ASYNC = const Keyword("async", "ASYNC", isPseudo: true);
149 149
150 static const Keyword AWAIT = const Keyword("await", "AWAIT", isPseudo: true); 150 static const Keyword AWAIT = const Keyword("await", "AWAIT", isPseudo: true);
151 151
152 static const Keyword BREAK = const Keyword("break", "BREAK"); 152 static const Keyword BREAK = const Keyword("break", "BREAK");
153 153
154 static const Keyword CASE = const Keyword("case", "CASE"); 154 static const Keyword CASE = const Keyword("case", "CASE");
155 155
156 static const Keyword CATCH = const Keyword("catch", "CATCH"); 156 static const Keyword CATCH = const Keyword("catch", "CATCH");
157 157
158 static const Keyword CLASS = const Keyword("class", "CLASS"); 158 static const Keyword CLASS =
159 const Keyword("class", "CLASS", isTopLevelKeyword: true);
159 160
160 static const Keyword CONST = const Keyword("const", "CONST"); 161 static const Keyword CONST =
162 const Keyword("const", "CONST", isModifier: true);
161 163
162 static const Keyword CONTINUE = const Keyword("continue", "CONTINUE"); 164 static const Keyword CONTINUE = const Keyword("continue", "CONTINUE");
163 165
164 static const Keyword COVARIANT = 166 static const Keyword COVARIANT =
165 const Keyword("covariant", "COVARIANT", isBuiltIn: true); 167 const Keyword("covariant", "COVARIANT", isBuiltIn: true);
166 168
167 static const Keyword DEFAULT = const Keyword("default", "DEFAULT"); 169 static const Keyword DEFAULT = const Keyword("default", "DEFAULT");
168 170
169 static const Keyword DEFERRED = 171 static const Keyword DEFERRED =
170 const Keyword("deferred", "DEFERRED", isBuiltIn: true); 172 const Keyword("deferred", "DEFERRED", isBuiltIn: true);
171 173
172 static const Keyword DO = const Keyword("do", "DO"); 174 static const Keyword DO = const Keyword("do", "DO");
173 175
174 static const Keyword DYNAMIC = 176 static const Keyword DYNAMIC =
175 const Keyword("dynamic", "DYNAMIC", isBuiltIn: true); 177 const Keyword("dynamic", "DYNAMIC", isBuiltIn: true);
176 178
177 static const Keyword ELSE = const Keyword("else", "ELSE"); 179 static const Keyword ELSE = const Keyword("else", "ELSE");
178 180
179 static const Keyword ENUM = const Keyword("enum", "ENUM"); 181 static const Keyword ENUM =
182 const Keyword("enum", "ENUM", isTopLevelKeyword: true);
180 183
181 static const Keyword EXPORT = 184 static const Keyword EXPORT = const Keyword("export", "EXPORT",
182 const Keyword("export", "EXPORT", isBuiltIn: true); 185 isBuiltIn: true, isTopLevelKeyword: true);
183 186
184 static const Keyword EXTENDS = const Keyword("extends", "EXTENDS"); 187 static const Keyword EXTENDS = const Keyword("extends", "EXTENDS");
185 188
186 static const Keyword EXTERNAL = 189 static const Keyword EXTERNAL =
187 const Keyword("external", "EXTERNAL", isBuiltIn: true); 190 const Keyword("external", "EXTERNAL", isBuiltIn: true);
188 191
189 static const Keyword FACTORY = 192 static const Keyword FACTORY =
190 const Keyword("factory", "FACTORY", isBuiltIn: true); 193 const Keyword("factory", "FACTORY", isBuiltIn: true);
191 194
192 static const Keyword FALSE = const Keyword("false", "FALSE"); 195 static const Keyword FALSE = const Keyword("false", "FALSE");
193 196
194 static const Keyword FINAL = const Keyword("final", "FINAL"); 197 static const Keyword FINAL =
198 const Keyword("final", "FINAL", isModifier: true);
195 199
196 static const Keyword FINALLY = const Keyword("finally", "FINALLY"); 200 static const Keyword FINALLY = const Keyword("finally", "FINALLY");
197 201
198 static const Keyword FOR = const Keyword("for", "FOR"); 202 static const Keyword FOR = const Keyword("for", "FOR");
199 203
200 static const Keyword FUNCTION = 204 static const Keyword FUNCTION =
201 const Keyword("Function", "FUNCTION", isPseudo: true); 205 const Keyword("Function", "FUNCTION", isPseudo: true);
202 206
203 static const Keyword GET = const Keyword("get", "GET", isBuiltIn: true); 207 static const Keyword GET = const Keyword("get", "GET", isBuiltIn: true);
204 208
205 static const Keyword HIDE = const Keyword("hide", "HIDE", isPseudo: true); 209 static const Keyword HIDE = const Keyword("hide", "HIDE", isPseudo: true);
206 210
207 static const Keyword IF = const Keyword("if", "IF"); 211 static const Keyword IF = const Keyword("if", "IF");
208 212
209 static const Keyword IMPLEMENTS = 213 static const Keyword IMPLEMENTS =
210 const Keyword("implements", "IMPLEMENTS", isBuiltIn: true); 214 const Keyword("implements", "IMPLEMENTS", isBuiltIn: true);
211 215
212 static const Keyword IMPORT = 216 static const Keyword IMPORT = const Keyword("import", "IMPORT",
213 const Keyword("import", "IMPORT", isBuiltIn: true); 217 isBuiltIn: true, isTopLevelKeyword: true);
214 218
215 static const Keyword IN = const Keyword("in", "IN"); 219 static const Keyword IN = const Keyword("in", "IN");
216 220
217 static const Keyword IS = 221 static const Keyword IS =
218 const Keyword("is", "IS", precedence: RELATIONAL_PRECEDENCE); 222 const Keyword("is", "IS", precedence: RELATIONAL_PRECEDENCE);
219 223
220 static const Keyword LIBRARY = 224 static const Keyword LIBRARY = const Keyword("library", "LIBRARY",
221 const Keyword("library", "LIBRARY", isBuiltIn: true); 225 isBuiltIn: true, isTopLevelKeyword: true);
222 226
223 static const Keyword NATIVE = 227 static const Keyword NATIVE =
224 const Keyword("native", "NATIVE", isPseudo: true); 228 const Keyword("native", "NATIVE", isPseudo: true);
225 229
226 static const Keyword NEW = const Keyword("new", "NEW"); 230 static const Keyword NEW = const Keyword("new", "NEW");
227 231
228 static const Keyword NULL = const Keyword("null", "NULL"); 232 static const Keyword NULL = const Keyword("null", "NULL");
229 233
230 static const Keyword OF = const Keyword("of", "OF", isPseudo: true); 234 static const Keyword OF = const Keyword("of", "OF", isPseudo: true);
231 235
232 static const Keyword ON = const Keyword("on", "ON", isPseudo: true); 236 static const Keyword ON = const Keyword("on", "ON", isPseudo: true);
233 237
234 static const Keyword OPERATOR = 238 static const Keyword OPERATOR =
235 const Keyword("operator", "OPERATOR", isBuiltIn: true); 239 const Keyword("operator", "OPERATOR", isBuiltIn: true);
236 240
237 static const Keyword PART = const Keyword("part", "PART", isBuiltIn: true); 241 static const Keyword PART =
242 const Keyword("part", "PART", isBuiltIn: true, isTopLevelKeyword: true);
238 243
239 static const Keyword PATCH = const Keyword("patch", "PATCH", isPseudo: true); 244 static const Keyword PATCH = const Keyword("patch", "PATCH", isPseudo: true);
240 245
241 static const Keyword RETHROW = const Keyword("rethrow", "RETHROW"); 246 static const Keyword RETHROW = const Keyword("rethrow", "RETHROW");
242 247
243 static const Keyword RETURN = const Keyword("return", "RETURN"); 248 static const Keyword RETURN = const Keyword("return", "RETURN");
244 249
245 static const Keyword SET = const Keyword("set", "SET", isBuiltIn: true); 250 static const Keyword SET = const Keyword("set", "SET", isBuiltIn: true);
246 251
247 static const Keyword SHOW = const Keyword("show", "SHOW", isPseudo: true); 252 static const Keyword SHOW = const Keyword("show", "SHOW", isPseudo: true);
248 253
249 static const Keyword SOURCE = 254 static const Keyword SOURCE =
250 const Keyword("source", "SOURCE", isPseudo: true); 255 const Keyword("source", "SOURCE", isPseudo: true);
251 256
252 static const Keyword STATIC = 257 static const Keyword STATIC =
253 const Keyword("static", "STATIC", isBuiltIn: true); 258 const Keyword("static", "STATIC", isBuiltIn: true, isModifier: true);
254 259
255 static const Keyword SUPER = const Keyword("super", "SUPER"); 260 static const Keyword SUPER = const Keyword("super", "SUPER");
256 261
257 static const Keyword SWITCH = const Keyword("switch", "SWITCH"); 262 static const Keyword SWITCH = const Keyword("switch", "SWITCH");
258 263
259 static const Keyword SYNC = const Keyword("sync", "SYNC", isPseudo: true); 264 static const Keyword SYNC = const Keyword("sync", "SYNC", isPseudo: true);
260 265
261 static const Keyword THIS = const Keyword("this", "THIS"); 266 static const Keyword THIS = const Keyword("this", "THIS");
262 267
263 static const Keyword THROW = const Keyword("throw", "THROW"); 268 static const Keyword THROW = const Keyword("throw", "THROW");
264 269
265 static const Keyword TRUE = const Keyword("true", "TRUE"); 270 static const Keyword TRUE = const Keyword("true", "TRUE");
266 271
267 static const Keyword TRY = const Keyword("try", "TRY"); 272 static const Keyword TRY = const Keyword("try", "TRY");
268 273
269 static const Keyword TYPEDEF = 274 static const Keyword TYPEDEF = const Keyword("typedef", "TYPEDEF",
270 const Keyword("typedef", "TYPEDEF", isBuiltIn: true); 275 isBuiltIn: true, isTopLevelKeyword: true);
271 276
272 static const Keyword VAR = const Keyword("var", "VAR"); 277 static const Keyword VAR = const Keyword("var", "VAR");
273 278
274 static const Keyword VOID = const Keyword("void", "VOID"); 279 static const Keyword VOID = const Keyword("void", "VOID");
275 280
276 static const Keyword WHILE = const Keyword("while", "WHILE"); 281 static const Keyword WHILE = const Keyword("while", "WHILE");
277 282
278 static const Keyword WITH = const Keyword("with", "WITH"); 283 static const Keyword WITH = const Keyword("with", "WITH");
279 284
280 static const Keyword YIELD = const Keyword("yield", "YIELD", isPseudo: true); 285 static const Keyword YIELD = const Keyword("yield", "YIELD", isPseudo: true);
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
356 final bool isBuiltIn; 361 final bool isBuiltIn;
357 362
358 @override 363 @override
359 final bool isPseudo; 364 final bool isPseudo;
360 365
361 /** 366 /**
362 * Initialize a newly created keyword. 367 * Initialize a newly created keyword.
363 */ 368 */
364 const Keyword(String lexeme, String name, 369 const Keyword(String lexeme, String name,
365 {this.isBuiltIn: false, 370 {this.isBuiltIn: false,
371 bool isModifier: false,
366 this.isPseudo: false, 372 this.isPseudo: false,
373 bool isTopLevelKeyword: false,
367 int precedence: NO_PRECEDENCE}) 374 int precedence: NO_PRECEDENCE})
368 : super(lexeme, name, precedence, KEYWORD_TOKEN); 375 : super(lexeme, name, precedence, KEYWORD_TOKEN,
376 isModifier: isModifier, isTopLevelKeyword: isTopLevelKeyword);
369 377
370 bool get isBuiltInOrPseudo => isBuiltIn || isPseudo; 378 bool get isBuiltInOrPseudo => isBuiltIn || isPseudo;
371 379
372 /** 380 /**
373 * A flag indicating whether the keyword is "built-in" identifier. 381 * A flag indicating whether the keyword is "built-in" identifier.
374 * This method exists for backward compatibility and will be removed. 382 * This method exists for backward compatibility and will be removed.
375 * Use [isBuiltIn] instead. 383 * Use [isBuiltIn] instead.
376 */ 384 */
377 @deprecated 385 @deprecated
378 bool get isPseudoKeyword => isBuiltIn; // TODO (danrubel): remove this 386 bool get isPseudoKeyword => isBuiltIn; // TODO (danrubel): remove this
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
483 @override 491 @override
484 int get end => offset + length; 492 int get end => offset + length;
485 493
486 @override 494 @override
487 bool get isEof => type == TokenType.EOF; 495 bool get isEof => type == TokenType.EOF;
488 496
489 @override 497 @override
490 bool get isIdentifier => false; 498 bool get isIdentifier => false;
491 499
492 @override 500 @override
501 bool get isModifier => type.isModifier;
502
503 @override
493 bool get isOperator => type.isOperator; 504 bool get isOperator => type.isOperator;
494 505
495 @override 506 @override
496 bool get isSynthetic => length == 0; 507 bool get isSynthetic => length == 0;
497 508
498 @override 509 @override
510 bool get isTopLevelKeyword => type.isTopLevelKeyword;
511
512 @override
499 bool get isUserDefinableOperator => type.isUserDefinableOperator; 513 bool get isUserDefinableOperator => type.isUserDefinableOperator;
500 514
501 @override 515 @override
502 Keyword get keyword => null; 516 Keyword get keyword => null;
503 517
504 @override 518 @override
505 int get kind => type.kind; 519 int get kind => type.kind;
506 520
507 @override 521 @override
508 int get length => lexeme.length; 522 int get length => lexeme.length;
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
715 */ 729 */
716 bool get isEof; 730 bool get isEof;
717 731
718 /** 732 /**
719 * True if this token is an identifier. Some keywords allowed as identifiers, 733 * True if this token is an identifier. Some keywords allowed as identifiers,
720 * see implementation in [KeywordToken]. 734 * see implementation in [KeywordToken].
721 */ 735 */
722 bool get isIdentifier; 736 bool get isIdentifier;
723 737
724 /** 738 /**
739 * Return `true` if this token is a modifier such as `abstract` or `const`.
740 */
741 bool get isModifier;
742
743 /**
725 * Return `true` if this token represents an operator. 744 * Return `true` if this token represents an operator.
726 */ 745 */
727 bool get isOperator; 746 bool get isOperator;
728 747
729 /** 748 /**
730 * Return `true` if this token is a synthetic token. A synthetic token is a 749 * Return `true` if this token is a synthetic token. A synthetic token is a
731 * token that was introduced by the parser in order to recover from an error 750 * token that was introduced by the parser in order to recover from an error
732 * in the code. 751 * in the code.
733 */ 752 */
734 bool get isSynthetic; 753 bool get isSynthetic;
735 754
736 /** 755 /**
756 * Return `true` if this token is a keyword starting a top level declaration
757 * such as `class`, `enum`, `import`, etc.
758 */
759 bool get isTopLevelKeyword;
760
761 /**
737 * Return `true` if this token represents an operator that can be defined by 762 * Return `true` if this token represents an operator that can be defined by
738 * users. 763 * users.
739 */ 764 */
740 bool get isUserDefinableOperator; 765 bool get isUserDefinableOperator;
741 766
742 /** 767 /**
743 * Return the keyword, if a keyword token, or `null` otherwise. 768 * Return the keyword, if a keyword token, or `null` otherwise.
744 */ 769 */
745 Keyword get keyword; 770 Keyword get keyword;
746 771
(...skipping 690 matching lines...) Expand 10 before | Expand all | Expand 10 after
1437 //TokenType.EQ_EQ_EQ, 1462 //TokenType.EQ_EQ_EQ,
1438 1463
1439 // Used by synthetic tokens generated during recovery 1464 // Used by synthetic tokens generated during recovery
1440 //TokenType.BAD_INPUT, 1465 //TokenType.BAD_INPUT,
1441 //TokenType.RECOVERY, 1466 //TokenType.RECOVERY,
1442 ]; 1467 ];
1443 1468
1444 final int kind; 1469 final int kind;
1445 1470
1446 /** 1471 /**
1472 * `true` if this token type represents a modifier
1473 * such as `abstract` or `const`.
1474 */
1475 final bool isModifier;
1476
1477 /**
1447 * `true` if this token type represents an operator. 1478 * `true` if this token type represents an operator.
1448 */ 1479 */
1449 final bool isOperator; 1480 final bool isOperator;
1450 1481
1451 /** 1482 /**
1483 * `true` if this token type represents a keyword starting a top level
1484 * declaration such as `class`, `enum`, `import`, etc.
1485 */
1486 final bool isTopLevelKeyword;
1487
1488 /**
1452 * `true` if this token type represents an operator 1489 * `true` if this token type represents an operator
1453 * that can be defined by users. 1490 * that can be defined by users.
1454 */ 1491 */
1455 final bool isUserDefinableOperator; 1492 final bool isUserDefinableOperator;
1456 1493
1457 /** 1494 /**
1458 * The lexeme that defines this type of token, 1495 * The lexeme that defines this type of token,
1459 * or `null` if there is more than one possible lexeme for this type of token. 1496 * or `null` if there is more than one possible lexeme for this type of token.
1460 */ 1497 */
1461 final String lexeme; 1498 final String lexeme;
1462 1499
1463 /** 1500 /**
1464 * The name of the token type. 1501 * The name of the token type.
1465 */ 1502 */
1466 final String name; 1503 final String name;
1467 1504
1468 /** 1505 /**
1469 * The precedence of this type of token, 1506 * The precedence of this type of token,
1470 * or `0` if the token does not represent an operator. 1507 * or `0` if the token does not represent an operator.
1471 */ 1508 */
1472 final int precedence; 1509 final int precedence;
1473 1510
1474 /** 1511 /**
1475 * See [Token.stringValue] for an explanation. 1512 * See [Token.stringValue] for an explanation.
1476 */ 1513 */
1477 final String stringValue; 1514 final String stringValue;
1478 1515
1479 const TokenType(this.lexeme, this.name, this.precedence, this.kind, 1516 const TokenType(this.lexeme, this.name, this.precedence, this.kind,
1480 {this.isOperator: false, 1517 {this.isModifier: false,
1518 this.isOperator: false,
1519 this.isTopLevelKeyword: false,
1481 this.isUserDefinableOperator: false, 1520 this.isUserDefinableOperator: false,
1482 String stringValue: 'unspecified'}) 1521 String stringValue: 'unspecified'})
1483 : this.stringValue = stringValue == 'unspecified' ? lexeme : stringValue; 1522 : this.stringValue = stringValue == 'unspecified' ? lexeme : stringValue;
1484 1523
1485 /** 1524 /**
1486 * Return `true` if this type of token represents an additive operator. 1525 * Return `true` if this type of token represents an additive operator.
1487 */ 1526 */
1488 bool get isAdditiveOperator => precedence == ADDITIVE_PRECEDENCE; 1527 bool get isAdditiveOperator => precedence == ADDITIVE_PRECEDENCE;
1489 1528
1490 /** 1529 /**
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
1575 1614
1576 @override 1615 @override
1577 String toString() => name; 1616 String toString() => name;
1578 1617
1579 /** 1618 /**
1580 * Use [lexeme] instead of this method 1619 * Use [lexeme] instead of this method
1581 */ 1620 */
1582 @deprecated 1621 @deprecated
1583 String get value => lexeme; 1622 String get value => lexeme;
1584 } 1623 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698