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

Side by Side Diff: pkg/compiler/lib/src/parser/parser.dart

Issue 2627343004: Revert "Add support for the new function-type syntax." (Closed)
Patch Set: Created 3 years, 11 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 dart2js.parser; 5 library dart2js.parser;
6 6
7 import '../common.dart'; 7 import '../common.dart';
8 import '../tokens/keyword.dart' show Keyword; 8 import '../tokens/keyword.dart' show Keyword;
9 import '../tokens/precedence.dart' show PrecedenceInfo; 9 import '../tokens/precedence.dart' show PrecedenceInfo;
10 import '../tokens/precedence_constants.dart' 10 import '../tokens/precedence_constants.dart'
(...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after
355 period = token; 355 period = token;
356 token = parseIdentifier(token.next); 356 token = parseIdentifier(token.next);
357 } 357 }
358 token = parseArgumentsOpt(token); 358 token = parseArgumentsOpt(token);
359 listener.endMetadata(atToken, period, token); 359 listener.endMetadata(atToken, period, token);
360 return token; 360 return token;
361 } 361 }
362 362
363 Token parseTypedef(Token token) { 363 Token parseTypedef(Token token) {
364 Token typedefKeyword = token; 364 Token typedefKeyword = token;
365 listener.beginTypedef(token); 365 listener.beginFunctionTypeAlias(token);
366 Token equals; 366 token = parseReturnTypeOpt(token.next);
367 if (optional('=', peekAfterNominalType(token.next))) { 367 token = parseIdentifier(token);
368 token = parseIdentifier(token.next); 368 token = parseTypeVariablesOpt(token);
369 token = parseTypeVariablesOpt(token); 369 token = parseFormalParameters(token);
370 equals = token; 370 listener.endFunctionTypeAlias(typedefKeyword, token);
371 token = expect('=', token);
372 token = parseType(token);
373 } else {
374 token = parseReturnTypeOpt(token.next);
375 token = parseIdentifier(token);
376 token = parseTypeVariablesOpt(token);
377 token = parseFormalParameters(token);
378 }
379 listener.endTypedef(typedefKeyword, equals, token);
380 return expect(';', token); 371 return expect(';', token);
381 } 372 }
382 373
383 Token parseMixinApplication(Token token) { 374 Token parseMixinApplication(Token token) {
384 listener.beginMixinApplication(token); 375 listener.beginMixinApplication(token);
385 token = parseType(token); 376 token = parseType(token);
386 token = expect('with', token); 377 token = expect('with', token);
387 token = parseTypeList(token); 378 token = parseTypeList(token);
388 listener.endMixinApplication(); 379 listener.endMixinApplication();
389 return token; 380 return token;
(...skipping 10 matching lines...) Expand all
400 391
401 Token parseFormalParametersOpt(Token token) { 392 Token parseFormalParametersOpt(Token token) {
402 if (optional('(', token)) { 393 if (optional('(', token)) {
403 return parseFormalParameters(token); 394 return parseFormalParameters(token);
404 } else { 395 } else {
405 listener.handleNoFormalParameters(token); 396 listener.handleNoFormalParameters(token);
406 return token; 397 return token;
407 } 398 }
408 } 399 }
409 400
410 /// Parses the formal parameter list of a function. 401 Token parseFormalParameters(Token token) {
411 ///
412 /// If [inFunctionType] is true, then the names may be omitted (except for
413 /// named arguments). If it is false, then the types may be omitted.
414 Token parseFormalParameters(Token token, {bool inFunctionType: false}) {
415 Token begin = token; 402 Token begin = token;
416 listener.beginFormalParameters(begin); 403 listener.beginFormalParameters(begin);
417 expect('(', token); 404 expect('(', token);
418 int parameterCount = 0; 405 int parameterCount = 0;
419 do { 406 do {
420 token = token.next; 407 token = token.next;
421 if (optional(')', token)) { 408 if (optional(')', token)) {
422 break; 409 break;
423 } 410 }
424 ++parameterCount; 411 ++parameterCount;
425 String value = token.stringValue; 412 String value = token.stringValue;
426 if (identical(value, '[')) { 413 if (identical(value, '[')) {
427 token = parseOptionalFormalParameters( 414 token = parseOptionalFormalParameters(token, false);
428 token, false, inFunctionType: inFunctionType);
429 break; 415 break;
430 } else if (identical(value, '{')) { 416 } else if (identical(value, '{')) {
431 token = parseOptionalFormalParameters( 417 token = parseOptionalFormalParameters(token, true);
432 token, true, inFunctionType: inFunctionType);
433 break; 418 break;
434 } 419 }
435 token = parseFormalParameter(token, FormalParameterType.REQUIRED, 420 token = parseFormalParameter(token, FormalParameterType.REQUIRED);
436 inFunctionType: inFunctionType);
437 } while (optional(',', token)); 421 } while (optional(',', token));
438 listener.endFormalParameters(parameterCount, begin, token); 422 listener.endFormalParameters(parameterCount, begin, token);
439 return expect(')', token); 423 return expect(')', token);
440 } 424 }
441 425
442 Token parseFormalParameter(Token token, FormalParameterType type, 426 Token parseFormalParameter(Token token, FormalParameterType type) {
443 {bool inFunctionType}) {
444 token = parseMetadataStar(token, forParameter: true); 427 token = parseMetadataStar(token, forParameter: true);
445 listener.beginFormalParameter(token); 428 listener.beginFormalParameter(token);
446 429
447 // Skip over `covariant` token, if the next token is an identifier or 430 // Skip over `covariant` token, if the next token is an identifier or
448 // modifier. 431 // modifier.
449 // This enables the case where `covariant` is the name of the parameter: 432 // This enables the case where `covariant` is the name of the parameter:
450 // void foo(covariant); 433 // void foo(covariant);
451 if (identical(token.stringValue, 'covariant') && 434 if (identical(token.stringValue, 'covariant') &&
452 (token.next.isIdentifier() || isModifier(token.next))) { 435 (token.next.isIdentifier() || isModifier(token.next))) {
453 token = token.next; 436 token = token.next;
454 } 437 }
455 token = parseModifiers(token); 438 token = parseModifiers(token);
456 bool isNamedParameter = type == FormalParameterType.NAMED; 439 // TODO(ahe): Validate that there are formal parameters if void.
457 440 token = parseReturnTypeOpt(token);
458 Token thisKeyword = null; 441 Token thisKeyword = null;
459 if (inFunctionType && isNamedParameter) { 442 if (optional('this', token)) {
460 token = parseType(token); 443 thisKeyword = token;
461 token = parseIdentifier(token); 444 // TODO(ahe): Validate field initializers are only used in
462 } else if (inFunctionType) { 445 // constructors, and not for function-typed arguments.
463 token = parseType(token); 446 token = expect('.', token.next);
464 if (token.isIdentifier()) {
465 token = parseIdentifier(token);
466 } else {
467 listener.handleNoName(token);
468 }
469 } else {
470 token = parseReturnTypeOpt(token);
471 if (optional('this', token)) {
472 thisKeyword = token;
473 token = expect('.', token.next);
474 }
475 token = parseIdentifier(token);
476 } 447 }
477 448 token = parseIdentifier(token);
478 // Generalized function types don't allow inline function types. 449 if (optional('(', token)) {
479 // The following isn't allowed: 450 listener.handleNoTypeVariables(token);
480 // int Function(int bar(String x)). 451 token = parseFormalParameters(token);
481 if (!inFunctionType) { 452 listener.handleFunctionTypedFormalParameter(token);
482 if (optional('(', token)) { 453 } else if (optional('<', token)) {
483 listener.handleNoTypeVariables(token); 454 token = parseTypeVariablesOpt(token);
484 token = parseFormalParameters(token); 455 token = parseFormalParameters(token);
485 listener.handleFunctionTypedFormalParameter(token); 456 listener.handleFunctionTypedFormalParameter(token);
486 } else if (optional('<', token)) {
487 token = parseTypeVariablesOpt(token);
488 token = parseFormalParameters(token);
489 listener.handleFunctionTypedFormalParameter(token);
490 }
491 } 457 }
492 String value = token.stringValue; 458 String value = token.stringValue;
493 if ((identical('=', value)) || (identical(':', value))) { 459 if ((identical('=', value)) || (identical(':', value))) {
494 // TODO(ahe): Validate that these are only used for optional parameters. 460 // TODO(ahe): Validate that these are only used for optional parameters.
495 Token equal = token; 461 Token equal = token;
496 token = parseExpression(token.next); 462 token = parseExpression(token.next);
497 listener.handleValuedFormalParameter(equal, token); 463 listener.handleValuedFormalParameter(equal, token);
498 if (type.isRequired) { 464 if (type.isRequired) {
499 listener.reportError( 465 listener.reportError(
500 equal, MessageKind.REQUIRED_PARAMETER_WITH_DEFAULT); 466 equal, MessageKind.REQUIRED_PARAMETER_WITH_DEFAULT);
501 } else if (type.isPositional && identical(':', value)) { 467 } else if (type.isPositional && identical(':', value)) {
502 listener.reportError( 468 listener.reportError(
503 equal, MessageKind.POSITIONAL_PARAMETER_WITH_EQUALS); 469 equal, MessageKind.POSITIONAL_PARAMETER_WITH_EQUALS);
504 } 470 }
505 } 471 }
506 listener.endFormalParameter(thisKeyword); 472 listener.endFormalParameter(thisKeyword);
507 return token; 473 return token;
508 } 474 }
509 475
510 Token parseOptionalFormalParameters(Token token, bool isNamed, 476 Token parseOptionalFormalParameters(Token token, bool isNamed) {
511 {bool inFunctionType}) {
512 Token begin = token; 477 Token begin = token;
513 listener.beginOptionalFormalParameters(begin); 478 listener.beginOptionalFormalParameters(begin);
514 assert((isNamed && optional('{', token)) || optional('[', token)); 479 assert((isNamed && optional('{', token)) || optional('[', token));
515 int parameterCount = 0; 480 int parameterCount = 0;
516 do { 481 do {
517 token = token.next; 482 token = token.next;
518 if (isNamed && optional('}', token)) { 483 if (isNamed && optional('}', token)) {
519 break; 484 break;
520 } else if (!isNamed && optional(']', token)) { 485 } else if (!isNamed && optional(']', token)) {
521 break; 486 break;
522 } 487 }
523 var type = 488 var type =
524 isNamed ? FormalParameterType.NAMED : FormalParameterType.POSITIONAL; 489 isNamed ? FormalParameterType.NAMED : FormalParameterType.POSITIONAL;
525 token = 490 token = parseFormalParameter(token, type);
526 parseFormalParameter(token, type, inFunctionType: inFunctionType);
527 ++parameterCount; 491 ++parameterCount;
528 } while (optional(',', token)); 492 } while (optional(',', token));
529 if (parameterCount == 0) { 493 if (parameterCount == 0) {
530 listener.reportError( 494 listener.reportError(
531 token, 495 token,
532 isNamed 496 isNamed
533 ? MessageKind.EMPTY_NAMED_PARAMETER_LIST 497 ? MessageKind.EMPTY_NAMED_PARAMETER_LIST
534 : MessageKind.EMPTY_OPTIONAL_PARAMETER_LIST); 498 : MessageKind.EMPTY_OPTIONAL_PARAMETER_LIST);
535 } 499 }
536 listener.endOptionalFormalParameters(parameterCount, begin, token); 500 listener.endOptionalFormalParameters(parameterCount, begin, token);
537 if (isNamed) { 501 if (isNamed) {
538 return expect('}', token); 502 return expect('}', token);
539 } else { 503 } else {
540 return expect(']', token); 504 return expect(']', token);
541 } 505 }
542 } 506 }
543 507
544 Token parseTypeOpt(Token token) { 508 Token parseTypeOpt(Token token) {
545 if (isGeneralizedFunctionType(token)) {
546 // Function type without return type.
547 return parseType(token);
548 }
549 Token peek = peekAfterIfType(token); 509 Token peek = peekAfterIfType(token);
550 if (peek != null && (peek.isIdentifier() || optional('this', peek))) { 510 if (peek != null && (peek.isIdentifier() || optional('this', peek))) {
551 return parseType(token); 511 return parseType(token);
552 } 512 }
553 listener.handleNoType(token); 513 listener.handleNoType(token);
554 return token; 514 return token;
555 } 515 }
556 516
557 bool isValidTypeReference(Token token) { 517 bool isValidTypeReference(Token token) {
558 final kind = token.kind; 518 final kind = token.kind;
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
703 } 663 }
704 664
705 Token parseClassOrNamedMixinApplication(Token token) { 665 Token parseClassOrNamedMixinApplication(Token token) {
706 Token begin = token; 666 Token begin = token;
707 Token abstractKeyword; 667 Token abstractKeyword;
708 if (optional('abstract', token)) { 668 if (optional('abstract', token)) {
709 abstractKeyword = token; 669 abstractKeyword = token;
710 token = token.next; 670 token = token.next;
711 } 671 }
712 Token classKeyword = token; 672 Token classKeyword = token;
713 var isMixinApplication = optional('=', peekAfterNominalType(token.next)); 673 var isMixinApplication = optional('=', peekAfterType(token.next));
714 if (isMixinApplication) { 674 if (isMixinApplication) {
715 listener.beginNamedMixinApplication(begin); 675 listener.beginNamedMixinApplication(begin);
716 } else { 676 } else {
717 listener.beginClassDeclaration(begin); 677 listener.beginClassDeclaration(begin);
718 } 678 }
719 679
720 int modifierCount = 0; 680 int modifierCount = 0;
721 if (abstractKeyword != null) { 681 if (abstractKeyword != null) {
722 parseModifier(abstractKeyword); 682 parseModifier(abstractKeyword);
723 modifierCount++; 683 modifierCount++;
(...skipping 20 matching lines...) Expand all
744 listener.endNamedMixinApplication(classKeyword, implementsKeyword, token); 704 listener.endNamedMixinApplication(classKeyword, implementsKeyword, token);
745 return expect(';', token); 705 return expect(';', token);
746 } 706 }
747 707
748 Token parseClass(Token begin, Token classKeyword) { 708 Token parseClass(Token begin, Token classKeyword) {
749 Token token = parseIdentifier(classKeyword.next); 709 Token token = parseIdentifier(classKeyword.next);
750 token = parseTypeVariablesOpt(token); 710 token = parseTypeVariablesOpt(token);
751 Token extendsKeyword; 711 Token extendsKeyword;
752 if (optional('extends', token)) { 712 if (optional('extends', token)) {
753 extendsKeyword = token; 713 extendsKeyword = token;
754 if (optional('with', peekAfterNominalType(token.next))) { 714 if (optional('with', peekAfterType(token.next))) {
755 token = parseMixinApplication(token.next); 715 token = parseMixinApplication(token.next);
756 } else { 716 } else {
757 token = parseType(token.next); 717 token = parseType(token.next);
758 } 718 }
759 } else { 719 } else {
760 extendsKeyword = null; 720 extendsKeyword = null;
761 listener.handleNoType(token); 721 listener.handleNoType(token);
762 } 722 }
763 Token implementsKeyword; 723 Token implementsKeyword;
764 int interfacesCount = 0; 724 int interfacesCount = 0;
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
842 value2 == stringValue || 802 value2 == stringValue ||
843 value3 == stringValue || 803 value3 == stringValue ||
844 value4 == stringValue; 804 value4 == stringValue;
845 } 805 }
846 806
847 bool notEofOrValue(String value, Token token) { 807 bool notEofOrValue(String value, Token token) {
848 return !identical(token.kind, EOF_TOKEN) && 808 return !identical(token.kind, EOF_TOKEN) &&
849 !identical(value, token.stringValue); 809 !identical(value, token.stringValue);
850 } 810 }
851 811
852 bool isGeneralizedFunctionType(Token token) {
853 // TODO(floitsch): don't use string comparison, but the keyword-state
854 // table is currently not set up to deal with upper-case characters.
855 return (optional('<', token.next) || optional('(', token.next)) &&
856 token.value == "Function";
857 }
858
859 Token parseType(Token token) { 812 Token parseType(Token token) {
860 Token begin = token; 813 Token begin = token;
861 if (isGeneralizedFunctionType(token)) { 814 if (isValidTypeReference(token)) {
862 // A function type without return type. 815 token = parseIdentifier(token);
863 // Push the non-existing return type first. The loop below will 816 token = parseQualifiedRestOpt(token);
864 // generate the full type.
865 listener.handleNoType(token);
866 } else { 817 } else {
867 if (isValidTypeReference(token)) { 818 token = listener.expectedType(token);
868 token = parseIdentifier(token);
869 token = parseQualifiedRestOpt(token);
870 } else {
871 token = listener.expectedType(token);
872 }
873 token = parseTypeArgumentsOpt(token);
874 listener.endType(begin, token);
875 } 819 }
876 820 token = parseTypeArgumentsOpt(token);
877 // While we see a `Function(` treat the pushed type as return type. 821 listener.endType(begin, token);
878 // For example: `int Function() Function(int) Function(String x)`.
879 while (isGeneralizedFunctionType(token)) {
880 token = parseFunctionType(token);
881 }
882 return token; 822 return token;
883 } 823 }
884 824
885 /// Parses a generalized function type.
886 ///
887 /// The return type must already be pushed.
888 Token parseFunctionType(Token token) {
889 // TODO(floitsch): don't use string comparison, but the keyword-state
890 // table is currently not set up to deal with upper-case characters.
891 if (token.value != "Function") {
892 return listener.expected("Function", token);
893 }
894 Token functionToken = token;
895 token = token.next;
896 token = parseTypeVariablesOpt(token);
897 token = parseFormalParameters(token, inFunctionType: true);
898 listener.endFunctionType(functionToken, token);
899 return token;
900 }
901
902 Token parseTypeArgumentsOpt(Token token) { 825 Token parseTypeArgumentsOpt(Token token) {
903 return parseStuff( 826 return parseStuff(
904 token, 827 token,
905 (t) => listener.beginTypeArguments(t), 828 (t) => listener.beginTypeArguments(t),
906 (t) => parseType(t), 829 (t) => parseType(t),
907 (c, bt, et) => listener.endTypeArguments(c, bt, et), 830 (c, bt, et) => listener.endTypeArguments(c, bt, et),
908 (t) => listener.handleNoTypeArguments(t)); 831 (t) => listener.handleNoTypeArguments(t));
909 } 832 }
910 833
911 Token parseTypeVariablesOpt(Token token) { 834 Token parseTypeVariablesOpt(Token token) {
(...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after
1245 identifiers = identifiers.prepend(token); 1168 identifiers = identifiers.prepend(token);
1246 return identifiers; 1169 return identifiers;
1247 } else if (value == '=' || value == ';' || value == ',') { 1170 } else if (value == '=' || value == ';' || value == ',') {
1248 // A field or abstract getter. 1171 // A field or abstract getter.
1249 identifiers = identifiers.prepend(token); 1172 identifiers = identifiers.prepend(token);
1250 return identifiers; 1173 return identifiers;
1251 } else if (isGetter) { 1174 } else if (isGetter) {
1252 hasName = true; 1175 hasName = true;
1253 } 1176 }
1254 identifiers = identifiers.prepend(token); 1177 identifiers = identifiers.prepend(token);
1255 1178 if (isValidTypeReference(token)) {
1256 if (!isGeneralizedFunctionType(token)) { 1179 // type ...
1257 // Read a potential return type. 1180 if (optional('.', token.next)) {
1258 if (isValidTypeReference(token)) { 1181 // type '.' ...
1259 // type ... 1182 if (token.next.next.isIdentifier()) {
1260 if (optional('.', token.next)) { 1183 // type '.' identifier
1261 // type '.' ... 1184 token = token.next.next;
1262 if (token.next.next.isIdentifier()) {
1263 // type '.' identifier
1264 token = token.next.next;
1265 }
1266 }
1267 if (optional('<', token.next)) {
1268 if (token.next is BeginGroupToken) {
1269 BeginGroupToken beginGroup = token.next;
1270 if (beginGroup.endGroup == null) {
1271 listener.unmatched(beginGroup);
1272 }
1273 token = beginGroup.endGroup;
1274 }
1275 } 1185 }
1276 } 1186 }
1277 token = token.next; 1187 if (optional('<', token.next)) {
1278 } 1188 if (token.next is BeginGroupToken) {
1279 while (isGeneralizedFunctionType(token)) { 1189 BeginGroupToken beginGroup = token.next;
1280 token = token.next;
1281 if (optional('<', token)) {
1282 if (token is BeginGroupToken) {
1283 BeginGroupToken beginGroup = token;
1284 if (beginGroup.endGroup == null) { 1190 if (beginGroup.endGroup == null) {
1285 listener.unmatched(beginGroup); 1191 listener.unmatched(beginGroup);
1286 } 1192 }
1287 token = beginGroup.endGroup.next; 1193 token = beginGroup.endGroup;
1288 } 1194 }
1289 } 1195 }
1290 if (!optional('(', token)) {
1291 if (optional(';', token)) {
1292 listener.recoverableError(token, "expected '('");
1293 }
1294 token = listener.unexpected(token);
1295 }
1296 if (token is BeginGroupToken) {
1297 BeginGroupToken beginGroup = token;
1298 if (beginGroup.endGroup == null) {
1299 listener.unmatched(beginGroup);
1300 }
1301 token = beginGroup.endGroup.next;
1302 }
1303 } 1196 }
1197 token = token.next;
1304 } 1198 }
1305 return const Link<Token>(); 1199 return const Link<Token>();
1306 } 1200 }
1307 1201
1308 Token parseVariableInitializerOpt(Token token) { 1202 Token parseVariableInitializerOpt(Token token) {
1309 if (optional('=', token)) { 1203 if (optional('=', token)) {
1310 Token assignment = token; 1204 Token assignment = token;
1311 listener.beginInitializer(token); 1205 listener.beginInitializer(token);
1312 token = parseExpression(token.next); 1206 token = parseExpression(token.next);
1313 listener.endInitializer(assignment); 1207 listener.endInitializer(assignment);
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
1391 if (!isModifier(token)) break; 1285 if (!isModifier(token)) break;
1392 token = parseModifier(token); 1286 token = parseModifier(token);
1393 count++; 1287 count++;
1394 } 1288 }
1395 listener.handleModifiers(count); 1289 listener.handleModifiers(count);
1396 return token; 1290 return token;
1397 } 1291 }
1398 1292
1399 /** 1293 /**
1400 * Returns the first token after the type starting at [token]. 1294 * Returns the first token after the type starting at [token].
1401 *
1402 * This method assumes that [token] is an identifier (or void). 1295 * This method assumes that [token] is an identifier (or void).
1403 * Use [peekAfterIfType] if [token] isn't known to be an identifier. 1296 * Use [peekAfterIfType] if [token] isn't known to be an identifier.
1404 */ 1297 */
1405 Token peekAfterType(Token token) { 1298 Token peekAfterType(Token token) {
1406 // We are looking at "identifier ...". 1299 // We are looking at "identifier ...".
1407 Token peek = token;
1408 if (!isGeneralizedFunctionType(token)) {
1409 peek = peekAfterNominalType(token);
1410 }
1411
1412 // We might have just skipped over the return value of the function type.
1413 // Check again, if we are now at a function type position.
1414 while (isGeneralizedFunctionType(peek)) {
1415 peek = peekAfterFunctionType(peek);
1416 }
1417 return peek;
1418 }
1419
1420 /**
1421 * Returns the first token after the nominal type starting at [token].
1422 *
1423 * This method assumes that [token] is an identifier (or void).
1424 */
1425 Token peekAfterNominalType(Token token) {
1426 Token peek = token.next; 1300 Token peek = token.next;
1427 if (identical(peek.kind, PERIOD_TOKEN)) { 1301 if (identical(peek.kind, PERIOD_TOKEN)) {
1428 if (peek.next.isIdentifier()) { 1302 if (peek.next.isIdentifier()) {
1429 // Look past a library prefix. 1303 // Look past a library prefix.
1430 peek = peek.next.next; 1304 peek = peek.next.next;
1431 } 1305 }
1432 } 1306 }
1433 // We are looking at "qualified ...". 1307 // We are looking at "qualified ...".
1434 if (identical(peek.kind, LT_TOKEN)) { 1308 if (identical(peek.kind, LT_TOKEN)) {
1435 // Possibly generic type. 1309 // Possibly generic type.
1436 // We are looking at "qualified '<'". 1310 // We are looking at "qualified '<'".
1437 BeginGroupToken beginGroupToken = peek; 1311 BeginGroupToken beginGroupToken = peek;
1438 Token gtToken = beginGroupToken.endGroup; 1312 Token gtToken = beginGroupToken.endGroup;
1439 if (gtToken != null) { 1313 if (gtToken != null) {
1440 // We are looking at "qualified '<' ... '>' ...". 1314 // We are looking at "qualified '<' ... '>' ...".
1441 peek = gtToken.next; 1315 return gtToken.next;
1442 } 1316 }
1443 } 1317 }
1444 return peek; 1318 return peek;
1445 } 1319 }
1446 1320
1447 /** 1321 /**
1448 * Returns the first token after the function type starting at [token].
1449 *
1450 * The token must be at the `Function` token position. That is, the return
1451 * type must have already been skipped.
1452 *
1453 * This function only skips over one function type syntax.
1454 * If necessary, this function must be called multiple times.
1455 *
1456 * Example:
1457 * ```
1458 * int Function() Function<T>(int)
1459 * ^ ^
1460 * A call to this function must be at one of the `Function` tokens.
1461 * If `token` pointed to the first `Function` token, then the returned
1462 * token points to the second `Function` token.
1463 */
1464 Token peekAfterFunctionType(Token token) {
1465 // Possible inputs are:
1466 // Function( ... )
1467 // Function< ... >( ... )
1468
1469 Token peek = token.next; // Skip over the Function token.
1470 // If there is a generic argument to the function, skip over that one first.
1471 if (identical(peek.kind, LT_TOKEN)) {
1472 BeginGroupToken beginGroupToken = peek;
1473 Token closeToken = beginGroupToken.endGroup;
1474 if (closeToken != null) {
1475 peek = closeToken.next;
1476 }
1477 }
1478
1479 // Now we just need to skip over the formals.
1480 expect('(', peek);
1481
1482 BeginGroupToken beginGroupToken = peek;
1483 Token closeToken = beginGroupToken.endGroup;
1484 if (closeToken != null) {
1485 peek = closeToken.next;
1486 }
1487
1488 return peek;
1489 }
1490
1491 /**
1492 * If [token] is the start of a type, returns the token after that type. 1322 * If [token] is the start of a type, returns the token after that type.
1493 * If [token] is not the start of a type, null is returned. 1323 * If [token] is not the start of a type, null is returned.
1494 */ 1324 */
1495 Token peekAfterIfType(Token token) { 1325 Token peekAfterIfType(Token token) {
1496 if (!optional('void', token) && !token.isIdentifier()) { 1326 if (!optional('void', token) && !token.isIdentifier()) {
1497 return null; 1327 return null;
1498 } 1328 }
1499 return peekAfterType(token); 1329 return peekAfterType(token);
1500 } 1330 }
1501 1331
(...skipping 1666 matching lines...) Expand 10 before | Expand all | Expand 10 after
3168 } 2998 }
3169 listener.handleContinueStatement(hasTarget, continueKeyword, token); 2999 listener.handleContinueStatement(hasTarget, continueKeyword, token);
3170 return expectSemicolon(token); 3000 return expectSemicolon(token);
3171 } 3001 }
3172 3002
3173 Token parseEmptyStatement(Token token) { 3003 Token parseEmptyStatement(Token token) {
3174 listener.handleEmptyStatement(token); 3004 listener.handleEmptyStatement(token);
3175 return expectSemicolon(token); 3005 return expectSemicolon(token);
3176 } 3006 }
3177 } 3007 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/parser/node_listener.dart ('k') | pkg/compiler/lib/src/parser/partial_parser.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698