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

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

Issue 2642903003: Update parser and scanner. (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 dart_parser; 5 library dart_parser;
6 6
7 import 'package:dart_scanner/src/keyword.dart' show 7 import 'package:dart_scanner/src/keyword.dart' show
8 Keyword; 8 Keyword;
9 9
10 import 'package:dart_scanner/src/precedence.dart' show 10 import 'package:dart_scanner/src/precedence.dart' show
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
108 * [parseMetadataStar] corresponds to this grammar snippet: [: 108 * [parseMetadataStar] corresponds to this grammar snippet: [:
109 * metadata* :], and [parseTypeOpt] corresponds to: [: type? :]. 109 * metadata* :], and [parseTypeOpt] corresponds to: [: type? :].
110 */ 110 */
111 class Parser { 111 class Parser {
112 final Listener listener; 112 final Listener listener;
113 113
114 bool mayParseFunctionExpressions = true; 114 bool mayParseFunctionExpressions = true;
115 115
116 bool asyncAwaitKeywordsEnabled; 116 bool asyncAwaitKeywordsEnabled;
117 117
118 final bool enableGenericMethodSyntax; 118 Parser(this.listener, {this.asyncAwaitKeywordsEnabled: false});
119
120 Parser(this.listener,
121 {this.asyncAwaitKeywordsEnabled: false,
122 this.enableGenericMethodSyntax: false});
123 119
124 Token parseUnit(Token token) { 120 Token parseUnit(Token token) {
125 listener.beginCompilationUnit(token); 121 listener.beginCompilationUnit(token);
126 int count = 0; 122 int count = 0;
127 while (!identical(token.kind, EOF_TOKEN)) { 123 while (!identical(token.kind, EOF_TOKEN)) {
128 token = parseTopLevelDeclaration(token); 124 token = parseTopLevelDeclaration(token);
129 count++; 125 count++;
130 } 126 }
131 listener.endCompilationUnit(count, token); 127 listener.endCompilationUnit(count, token);
132 return token; 128 return token;
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after
376 period = token; 372 period = token;
377 token = parseIdentifier(token.next); 373 token = parseIdentifier(token.next);
378 } 374 }
379 token = parseArgumentsOpt(token); 375 token = parseArgumentsOpt(token);
380 listener.endMetadata(atToken, period, token); 376 listener.endMetadata(atToken, period, token);
381 return token; 377 return token;
382 } 378 }
383 379
384 Token parseTypedef(Token token) { 380 Token parseTypedef(Token token) {
385 Token typedefKeyword = token; 381 Token typedefKeyword = token;
386 if (optional('=', peekAfterType(token.next))) { 382 listener.beginFunctionTypeAlias(token);
387 // TODO(aprelev@gmail.com): Remove deprecated 'typedef' mixin application, 383 token = parseReturnTypeOpt(token.next);
388 // remove corresponding diagnostic from members.dart. 384 token = parseIdentifier(token);
389 listener.beginNamedMixinApplication(token); 385 token = parseTypeVariablesOpt(token);
390 token = parseIdentifier(token.next); 386 token = parseFormalParameters(token);
391 token = parseTypeVariablesOpt(token); 387 listener.endFunctionTypeAlias(typedefKeyword, token);
392 token = expect('=', token);
393 token = parseModifiers(token);
394 token = parseMixinApplication(token);
395 Token implementsKeyword = null;
396 if (optional('implements', token)) {
397 implementsKeyword = token;
398 token = parseTypeList(token.next);
399 }
400 listener.endNamedMixinApplication(
401 typedefKeyword, implementsKeyword, token);
402 } else {
403 listener.beginFunctionTypeAlias(token);
404 token = parseReturnTypeOpt(token.next);
405 token = parseIdentifier(token);
406 token = parseTypeVariablesOpt(token);
407 token = parseFormalParameters(token);
408 listener.endFunctionTypeAlias(typedefKeyword, token);
409 }
410 return expect(';', token); 388 return expect(';', token);
411 } 389 }
412 390
413 Token parseMixinApplication(Token token) { 391 Token parseMixinApplication(Token token) {
414 listener.beginMixinApplication(token); 392 listener.beginMixinApplication(token);
415 token = parseType(token); 393 token = parseType(token);
416 token = expect('with', token); 394 token = expect('with', token);
417 token = parseTypeList(token); 395 token = parseTypeList(token);
418 listener.endMixinApplication(); 396 listener.endMixinApplication();
419 return token; 397 return token;
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
458 } 436 }
459 token = parseFormalParameter(token, FormalParameterType.REQUIRED); 437 token = parseFormalParameter(token, FormalParameterType.REQUIRED);
460 } while (optional(',', token)); 438 } while (optional(',', token));
461 listener.endFormalParameters(parameterCount, begin, token); 439 listener.endFormalParameters(parameterCount, begin, token);
462 return expect(')', token); 440 return expect(')', token);
463 } 441 }
464 442
465 Token parseFormalParameter(Token token, FormalParameterType type) { 443 Token parseFormalParameter(Token token, FormalParameterType type) {
466 token = parseMetadataStar(token, forParameter: true); 444 token = parseMetadataStar(token, forParameter: true);
467 listener.beginFormalParameter(token); 445 listener.beginFormalParameter(token);
446
447 // Skip over `covariant` token, if the next token is an identifier or
448 // modifier.
449 // This enables the case where `covariant` is the name of the parameter:
450 // void foo(covariant);
451 if (identical(token.stringValue, 'covariant') &&
452 (token.next.isIdentifier() || isModifier(token.next))) {
453 token = token.next;
454 }
468 token = parseModifiers(token); 455 token = parseModifiers(token);
469 // TODO(ahe): Validate that there are formal parameters if void. 456 // TODO(ahe): Validate that there are formal parameters if void.
470 token = parseReturnTypeOpt(token); 457 token = parseReturnTypeOpt(token);
471 Token thisKeyword = null; 458 Token thisKeyword = null;
472 if (optional('this', token)) { 459 if (optional('this', token)) {
473 thisKeyword = token; 460 thisKeyword = token;
474 // TODO(ahe): Validate field initializers are only used in 461 // TODO(ahe): Validate field initializers are only used in
475 // constructors, and not for function-typed arguments. 462 // constructors, and not for function-typed arguments.
476 token = expect('.', token.next); 463 token = expect('.', token.next);
477 } 464 }
478 token = parseIdentifier(token); 465 token = parseIdentifier(token);
479 if (optional('(', token)) { 466 if (optional('(', token)) {
480 listener.beginFunctionTypedFormalParameter(token); 467 listener.beginFunctionTypedFormalParameter(token);
481 listener.handleNoTypeVariables(token); 468 listener.handleNoTypeVariables(token);
482 token = parseFormalParameters(token); 469 token = parseFormalParameters(token);
483 listener.handleFunctionTypedFormalParameter(token); 470 listener.handleFunctionTypedFormalParameter(token);
484 } else if (enableGenericMethodSyntax && optional('<', token)) { 471 } else if (optional('<', token)) {
485 listener.beginFunctionTypedFormalParameter(token); 472 listener.beginFunctionTypedFormalParameter(token);
486 token = parseTypeVariablesOpt(token); 473 token = parseTypeVariablesOpt(token);
487 token = parseFormalParameters(token); 474 token = parseFormalParameters(token);
488 listener.handleFunctionTypedFormalParameter(token); 475 listener.handleFunctionTypedFormalParameter(token);
489 } 476 }
490 String value = token.stringValue; 477 String value = token.stringValue;
491 if ((identical('=', value)) || (identical(':', value))) { 478 if ((identical('=', value)) || (identical(':', value))) {
492 // TODO(ahe): Validate that these are only used for optional parameters. 479 // TODO(ahe): Validate that these are only used for optional parameters.
493 Token equal = token; 480 Token equal = token;
494 token = parseExpression(token.next); 481 token = parseExpression(token.next);
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
593 token = tryParseQualified(token); 580 token = tryParseQualified(token);
594 if (token == null) return null; 581 if (token == null) return null;
595 Token tokenAfterQualified = token; 582 Token tokenAfterQualified = token;
596 token = tryParseNestedTypeArguments(token); 583 token = tryParseNestedTypeArguments(token);
597 return token == null ? tokenAfterQualified : token; 584 return token == null ? tokenAfterQualified : token;
598 } 585 }
599 586
600 /// Returns token after match if [token] matches identifier ('.' identifier)?, 587 /// Returns token after match if [token] matches identifier ('.' identifier)?,
601 /// and otherwise returns null. Does not produce listener events. 588 /// and otherwise returns null. Does not produce listener events.
602 Token tryParseQualified(Token token) { 589 Token tryParseQualified(Token token) {
603 if (!identical(token.kind, IDENTIFIER_TOKEN)) return null; 590 if (!isValidTypeReference(token)) return null;
604 token = token.next; 591 token = token.next;
605 if (!identical(token.kind, PERIOD_TOKEN)) return token; 592 if (!identical(token.kind, PERIOD_TOKEN)) return token;
606 token = token.next; 593 token = token.next;
607 if (!identical(token.kind, IDENTIFIER_TOKEN)) return null; 594 if (!identical(token.kind, IDENTIFIER_TOKEN)) return null;
608 return token.next; 595 return token.next;
609 } 596 }
610 597
611 /// Returns token after match if [token] matches '<' type (',' type)* '>', 598 /// Returns token after match if [token] matches '<' type (',' type)* '>',
612 /// and otherwise returns null. Does not produce listener events. The final 599 /// and otherwise returns null. Does not produce listener events. The final
613 /// '>' may be the first character in a '>>' token, in which case a synthetic 600 /// '>' may be the first character in a '>>' token, in which case a synthetic
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
698 Token begin = token; 685 Token begin = token;
699 Token abstractKeyword; 686 Token abstractKeyword;
700 if (optional('abstract', token)) { 687 if (optional('abstract', token)) {
701 abstractKeyword = token; 688 abstractKeyword = token;
702 token = token.next; 689 token = token.next;
703 } 690 }
704 Token classKeyword = token; 691 Token classKeyword = token;
705 var isMixinApplication = optional('=', peekAfterType(token.next)); 692 var isMixinApplication = optional('=', peekAfterType(token.next));
706 if (isMixinApplication) { 693 if (isMixinApplication) {
707 listener.beginNamedMixinApplication(begin); 694 listener.beginNamedMixinApplication(begin);
708 token = parseIdentifier(token.next);
709 token = parseTypeVariablesOpt(token);
710 token = expect('=', token);
711 } else { 695 } else {
712 listener.beginClassDeclaration(begin); 696 listener.beginClassDeclaration(begin);
713 } 697 }
714 698
715 // TODO(aprelev@gmail.com): Once 'typedef' named mixin application is
716 // removed, move modifiers for named mixin application to the bottom of
717 // listener stack. This is so stacks for class declaration and named
718 // mixin application look similar.
719 int modifierCount = 0; 699 int modifierCount = 0;
720 if (abstractKeyword != null) { 700 if (abstractKeyword != null) {
721 parseModifier(abstractKeyword); 701 parseModifier(abstractKeyword);
722 modifierCount++; 702 modifierCount++;
723 } 703 }
724 listener.handleModifiers(modifierCount); 704 listener.handleModifiers(modifierCount);
725 705
726 if (isMixinApplication) { 706 if (isMixinApplication) {
707 token = parseIdentifier(token.next);
708 token = parseTypeVariablesOpt(token);
709 token = expect('=', token);
727 return parseNamedMixinApplication(token, classKeyword); 710 return parseNamedMixinApplication(token, classKeyword);
728 } else { 711 } else {
729 return parseClass(begin, classKeyword); 712 return parseClass(begin, classKeyword);
730 } 713 }
731 } 714 }
732 715
733 Token parseNamedMixinApplication(Token token, Token classKeyword) { 716 Token parseNamedMixinApplication(Token token, Token classKeyword) {
734 token = parseMixinApplication(token); 717 token = parseMixinApplication(token);
735 Token implementsKeyword = null; 718 Token implementsKeyword = null;
736 if (optional('implements', token)) { 719 if (optional('implements', token)) {
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
792 if (!identical(string, token.stringValue)) { 775 if (!identical(string, token.stringValue)) {
793 return listener.expected(string, token); 776 return listener.expected(string, token);
794 } 777 }
795 return token.next; 778 return token.next;
796 } 779 }
797 780
798 Token parseTypeVariable(Token token) { 781 Token parseTypeVariable(Token token) {
799 listener.beginTypeVariable(token); 782 listener.beginTypeVariable(token);
800 token = parseIdentifier(token); 783 token = parseIdentifier(token);
801 Token extendsOrSuper = null; 784 Token extendsOrSuper = null;
802 if (optional('extends', token) || 785 if (optional('extends', token) || optional('super', token)) {
803 (enableGenericMethodSyntax && optional('super', token))) {
804 extendsOrSuper = token; 786 extendsOrSuper = token;
805 token = parseType(token.next); 787 token = parseType(token.next);
806 } else { 788 } else {
807 listener.handleNoType(token); 789 listener.handleNoType(token);
808 } 790 }
809 listener.endTypeVariable(token, extendsOrSuper); 791 listener.endTypeVariable(token, extendsOrSuper);
810 return token; 792 return token;
811 } 793 }
812 794
813 /** 795 /**
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
1020 listener.handleModifiers(modifierCount); 1002 listener.handleModifiers(modifierCount);
1021 var kind = hasTypeOrModifier 1003 var kind = hasTypeOrModifier
1022 ? ErrorKind.EXTRANEOUS_MODIFIER 1004 ? ErrorKind.EXTRANEOUS_MODIFIER
1023 : ErrorKind.EXTRANEOUS_MODIFIER_REPLACE; 1005 : ErrorKind.EXTRANEOUS_MODIFIER_REPLACE;
1024 for (Token modifier in modifierList) { 1006 for (Token modifier in modifierList) {
1025 listener.reportError(modifier, kind, {'modifier': modifier}); 1007 listener.reportError(modifier, kind, {'modifier': modifier});
1026 } 1008 }
1027 return null; 1009 return null;
1028 } 1010 }
1029 1011
1012 /// Removes the optional `covariant` token from the modifiers, if there
1013 /// is no `static` in the list, and `covariant` is the first modifier.
1014 Link<Token> removeOptCovariantTokenIfNotStatic(Link<Token> modifiers) {
1015 if (modifiers.isEmpty ||
1016 !identical(modifiers.first.stringValue, 'covariant')) {
1017 return modifiers;
1018 }
1019 for (Token modifier in modifiers.tail) {
1020 if (identical(modifier.stringValue, 'static')) {
1021 return modifiers;
1022 }
1023 }
1024 return modifiers.tail;
1025 }
1026
1030 Token parseFields(Token start, Link<Token> modifiers, Token type, 1027 Token parseFields(Token start, Link<Token> modifiers, Token type,
1031 Token getOrSet, Token name, bool isTopLevel) { 1028 Token getOrSet, Token name, bool isTopLevel) {
1032 bool hasType = type != null; 1029 bool hasType = type != null;
1030
1031 if (getOrSet == null && !isTopLevel) {
1032 modifiers = removeOptCovariantTokenIfNotStatic(modifiers);
1033 }
1034
1033 Token varFinalOrConst = 1035 Token varFinalOrConst =
1034 expectVarFinalOrConst(modifiers, hasType, !isTopLevel); 1036 expectVarFinalOrConst(modifiers, hasType, !isTopLevel);
1035 bool isVar = false; 1037 bool isVar = false;
1036 bool hasModifier = false; 1038 bool hasModifier = false;
1037 if (varFinalOrConst != null) { 1039 if (varFinalOrConst != null) {
1038 hasModifier = true; 1040 hasModifier = true;
1039 isVar = optional('var', varFinalOrConst); 1041 isVar = optional('var', varFinalOrConst);
1040 } 1042 }
1041 1043
1042 if (getOrSet != null) { 1044 if (getOrSet != null) {
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
1101 listener.handleModifiers(0); 1103 listener.handleModifiers(0);
1102 } 1104 }
1103 1105
1104 if (type == null) { 1106 if (type == null) {
1105 listener.handleNoType(name); 1107 listener.handleNoType(name);
1106 } else { 1108 } else {
1107 parseReturnTypeOpt(type); 1109 parseReturnTypeOpt(type);
1108 } 1110 }
1109 Token token = parseIdentifier(name); 1111 Token token = parseIdentifier(name);
1110 1112
1111 if (enableGenericMethodSyntax && getOrSet == null) { 1113 if (getOrSet == null) {
1112 token = parseTypeVariablesOpt(token); 1114 token = parseTypeVariablesOpt(token);
1113 } else { 1115 } else {
1114 listener.handleNoTypeVariables(token); 1116 listener.handleNoTypeVariables(token);
1115 } 1117 }
1116 token = parseFormalParametersOpt(token); 1118 token = parseFormalParametersOpt(token);
1117 bool previousAsyncAwaitKeywordsEnabled = asyncAwaitKeywordsEnabled; 1119 bool previousAsyncAwaitKeywordsEnabled = asyncAwaitKeywordsEnabled;
1118 token = parseAsyncModifier(token); 1120 token = parseAsyncModifier(token);
1119 token = parseFunctionBody(token, false, externalModifier != null); 1121 token = parseFunctionBody(token, false, externalModifier != null);
1120 asyncAwaitKeywordsEnabled = previousAsyncAwaitKeywordsEnabled; 1122 asyncAwaitKeywordsEnabled = previousAsyncAwaitKeywordsEnabled;
1121 Token endToken = token; 1123 Token endToken = token;
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after
1386 return optional('factory', token); 1388 return optional('factory', token);
1387 } 1389 }
1388 1390
1389 Token parseMember(Token token) { 1391 Token parseMember(Token token) {
1390 token = parseMetadataStar(token); 1392 token = parseMetadataStar(token);
1391 Token start = token; 1393 Token start = token;
1392 listener.beginMember(token); 1394 listener.beginMember(token);
1393 if (isFactoryDeclaration(token)) { 1395 if (isFactoryDeclaration(token)) {
1394 token = parseFactoryMethod(token); 1396 token = parseFactoryMethod(token);
1395 listener.endMember(); 1397 listener.endMember();
1396 assert (token != null); 1398 assert(token != null);
1397 return token; 1399 return token;
1398 } 1400 }
1399 1401
1400 Link<Token> identifiers = findMemberName(token); 1402 Link<Token> identifiers = findMemberName(token);
1401 if (identifiers.isEmpty) { 1403 if (identifiers.isEmpty) {
1402 return listener.expectedDeclaration(start); 1404 return listener.expectedDeclaration(start);
1403 } 1405 }
1404 Token afterName = identifiers.head; 1406 Token afterName = identifiers.head;
1405 identifiers = identifiers.tail; 1407 identifiers = identifiers.tail;
1406 1408
(...skipping 26 matching lines...) Expand all
1433 token = afterName; 1435 token = afterName;
1434 bool isField; 1436 bool isField;
1435 while (true) { 1437 while (true) {
1436 // Loop to allow the listener to rewrite the token stream for 1438 // Loop to allow the listener to rewrite the token stream for
1437 // error handling. 1439 // error handling.
1438 final String value = token.stringValue; 1440 final String value = token.stringValue;
1439 if ((identical(value, '(')) || 1441 if ((identical(value, '(')) ||
1440 (identical(value, '.')) || 1442 (identical(value, '.')) ||
1441 (identical(value, '{')) || 1443 (identical(value, '{')) ||
1442 (identical(value, '=>')) || 1444 (identical(value, '=>')) ||
1443 (enableGenericMethodSyntax && identical(value, '<'))) { 1445 (identical(value, '<'))) {
1444 isField = false; 1446 isField = false;
1445 break; 1447 break;
1446 } else if (identical(value, ';')) { 1448 } else if (identical(value, ';')) {
1447 if (getOrSet != null) { 1449 if (getOrSet != null) {
1448 // If we found a "get" keyword, this must be an abstract 1450 // If we found a "get" keyword, this must be an abstract
1449 // getter. 1451 // getter.
1450 isField = (!identical(getOrSet.stringValue, 'get')); 1452 isField = (!identical(getOrSet.stringValue, 'get'));
1451 // TODO(ahe): This feels like a hack. 1453 // TODO(ahe): This feels like a hack.
1452 } else { 1454 } else {
1453 isField = true; 1455 isField = true;
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
1528 token = parseOperatorName(name); 1530 token = parseOperatorName(name);
1529 if (staticModifier != null) { 1531 if (staticModifier != null) {
1530 listener.reportError(staticModifier, ErrorKind.EXTRANEOUS_MODIFIER, 1532 listener.reportError(staticModifier, ErrorKind.EXTRANEOUS_MODIFIER,
1531 {'modifier': staticModifier}); 1533 {'modifier': staticModifier});
1532 } 1534 }
1533 } else { 1535 } else {
1534 token = parseIdentifier(name); 1536 token = parseIdentifier(name);
1535 } 1537 }
1536 1538
1537 token = parseQualifiedRestOpt(token); 1539 token = parseQualifiedRestOpt(token);
1538 if (enableGenericMethodSyntax && getOrSet == null) { 1540 if (getOrSet == null) {
1539 token = parseTypeVariablesOpt(token); 1541 token = parseTypeVariablesOpt(token);
1540 } else { 1542 } else {
1541 listener.handleNoTypeVariables(token); 1543 listener.handleNoTypeVariables(token);
1542 } 1544 }
1543 token = parseFormalParametersOpt(token); 1545 token = parseFormalParametersOpt(token);
1544 token = parseInitializersOpt(token); 1546 token = parseInitializersOpt(token);
1545 bool previousAsyncAwaitKeywordsEnabled = asyncAwaitKeywordsEnabled; 1547 bool previousAsyncAwaitKeywordsEnabled = asyncAwaitKeywordsEnabled;
1546 token = parseAsyncModifier(token); 1548 token = parseAsyncModifier(token);
1547 if (optional('=', token)) { 1549 if (optional('=', token)) {
1548 token = parseRedirectingFactoryBody(token); 1550 token = parseRedirectingFactoryBody(token);
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
1619 } 1621 }
1620 listener.beginFunctionName(token); 1622 listener.beginFunctionName(token);
1621 if (optional('operator', token)) { 1623 if (optional('operator', token)) {
1622 token = parseOperatorName(token); 1624 token = parseOperatorName(token);
1623 } else { 1625 } else {
1624 token = parseIdentifier(token); 1626 token = parseIdentifier(token);
1625 } 1627 }
1626 } 1628 }
1627 token = parseQualifiedRestOpt(token); 1629 token = parseQualifiedRestOpt(token);
1628 listener.endFunctionName(token); 1630 listener.endFunctionName(token);
1629 if (enableGenericMethodSyntax && getOrSet == null) { 1631 if (getOrSet == null) {
1630 token = parseTypeVariablesOpt(token); 1632 token = parseTypeVariablesOpt(token);
1631 } else { 1633 } else {
1632 listener.handleNoTypeVariables(token); 1634 listener.handleNoTypeVariables(token);
1633 } 1635 }
1634 token = parseFormalParametersOpt(token); 1636 token = parseFormalParametersOpt(token);
1635 token = parseInitializersOpt(token); 1637 token = parseInitializersOpt(token);
1636 bool previousAsyncAwaitKeywordsEnabled = asyncAwaitKeywordsEnabled; 1638 bool previousAsyncAwaitKeywordsEnabled = asyncAwaitKeywordsEnabled;
1637 token = parseAsyncModifier(token); 1639 token = parseAsyncModifier(token);
1638 if (optional('=', token)) { 1640 if (optional('=', token)) {
1639 token = parseRedirectingFactoryBody(token); 1641 token = parseRedirectingFactoryBody(token);
(...skipping 24 matching lines...) Expand all
1664 return token; 1666 return token;
1665 } 1667 }
1666 1668
1667 Token parseFunctionExpression(Token token) { 1669 Token parseFunctionExpression(Token token) {
1668 listener.beginFunction(token); 1670 listener.beginFunction(token);
1669 listener.handleModifiers(0); 1671 listener.handleModifiers(0);
1670 token = parseReturnTypeOpt(token); 1672 token = parseReturnTypeOpt(token);
1671 listener.beginFunctionName(token); 1673 listener.beginFunctionName(token);
1672 token = parseIdentifier(token); 1674 token = parseIdentifier(token);
1673 listener.endFunctionName(token); 1675 listener.endFunctionName(token);
1674 if (enableGenericMethodSyntax) { 1676 token = parseTypeVariablesOpt(token);
1675 token = parseTypeVariablesOpt(token);
1676 } else {
1677 listener.handleNoTypeVariables(token);
1678 }
1679 token = parseFormalParameters(token); 1677 token = parseFormalParameters(token);
1680 listener.handleNoInitializers(); 1678 listener.handleNoInitializers();
1681 bool previousAsyncAwaitKeywordsEnabled = asyncAwaitKeywordsEnabled; 1679 bool previousAsyncAwaitKeywordsEnabled = asyncAwaitKeywordsEnabled;
1682 token = parseAsyncModifier(token); 1680 token = parseAsyncModifier(token);
1683 bool isBlock = optional('{', token); 1681 bool isBlock = optional('{', token);
1684 token = parseFunctionBody(token, true, false); 1682 token = parseFunctionBody(token, true, false);
1685 asyncAwaitKeywordsEnabled = previousAsyncAwaitKeywordsEnabled; 1683 asyncAwaitKeywordsEnabled = previousAsyncAwaitKeywordsEnabled;
1686 listener.endFunction(null, token); 1684 listener.endFunction(null, token);
1687 return isBlock ? token.next : token; 1685 return isBlock ? token.next : token;
1688 } 1686 }
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after
1944 // TODO(eernst): Check for NPE as described in issue 26252. 1942 // TODO(eernst): Check for NPE as described in issue 26252.
1945 Token afterParens = endParen.next; 1943 Token afterParens = endParen.next;
1946 if (optional('{', afterParens) || 1944 if (optional('{', afterParens) ||
1947 optional('=>', afterParens) || 1945 optional('=>', afterParens) ||
1948 optional('async', afterParens) || 1946 optional('async', afterParens) ||
1949 optional('sync', afterParens)) { 1947 optional('sync', afterParens)) {
1950 // We are looking at "type identifier '(' ... ')'" followed 1948 // We are looking at "type identifier '(' ... ')'" followed
1951 // by '{', '=>', 'async', or 'sync'. 1949 // by '{', '=>', 'async', or 'sync'.
1952 return parseFunctionDeclaration(token); 1950 return parseFunctionDeclaration(token);
1953 } 1951 }
1954 } else if (enableGenericMethodSyntax && 1952 } else if (identical(afterIdKind, LT_TOKEN)) {
1955 identical(afterIdKind, LT_TOKEN)) {
1956 // We are looking at "type identifier '<'". 1953 // We are looking at "type identifier '<'".
1957 BeginGroupToken beginAngle = afterId; 1954 BeginGroupToken beginAngle = afterId;
1958 Token endAngle = beginAngle.endGroup; 1955 Token endAngle = beginAngle.endGroup;
1959 if (endAngle != null && 1956 if (endAngle != null &&
1960 identical(endAngle.next.kind, OPEN_PAREN_TOKEN)) { 1957 identical(endAngle.next.kind, OPEN_PAREN_TOKEN)) {
1961 BeginGroupToken beginParen = endAngle.next; 1958 BeginGroupToken beginParen = endAngle.next;
1962 Token endParen = beginParen.endGroup; 1959 Token endParen = beginParen.endGroup;
1963 if (endParen != null) { 1960 if (endParen != null) {
1964 Token afterParens = endParen.next; 1961 Token afterParens = endParen.next;
1965 if (optional('{', afterParens) || 1962 if (optional('{', afterParens) ||
(...skipping 14 matching lines...) Expand all
1980 } else if (optional('(', token.next)) { 1977 } else if (optional('(', token.next)) {
1981 BeginGroupToken begin = token.next; 1978 BeginGroupToken begin = token.next;
1982 // TODO(eernst): Check for NPE as described in issue 26252. 1979 // TODO(eernst): Check for NPE as described in issue 26252.
1983 String afterParens = begin.endGroup.next.stringValue; 1980 String afterParens = begin.endGroup.next.stringValue;
1984 if (identical(afterParens, '{') || 1981 if (identical(afterParens, '{') ||
1985 identical(afterParens, '=>') || 1982 identical(afterParens, '=>') ||
1986 identical(afterParens, 'async') || 1983 identical(afterParens, 'async') ||
1987 identical(afterParens, 'sync')) { 1984 identical(afterParens, 'sync')) {
1988 return parseFunctionDeclaration(token); 1985 return parseFunctionDeclaration(token);
1989 } 1986 }
1990 } else if (enableGenericMethodSyntax && optional('<', token.next)) { 1987 } else if (optional('<', token.next)) {
1991 BeginGroupToken beginAngle = token.next; 1988 BeginGroupToken beginAngle = token.next;
1992 Token endAngle = beginAngle.endGroup; 1989 Token endAngle = beginAngle.endGroup;
1993 if (endAngle != null && 1990 if (endAngle != null &&
1994 identical(endAngle.next.kind, OPEN_PAREN_TOKEN)) { 1991 identical(endAngle.next.kind, OPEN_PAREN_TOKEN)) {
1995 BeginGroupToken beginParen = endAngle.next; 1992 BeginGroupToken beginParen = endAngle.next;
1996 Token endParen = beginParen.endGroup; 1993 Token endParen = beginParen.endGroup;
1997 if (endParen != null) { 1994 if (endParen != null) {
1998 String afterParens = endParen.next.stringValue; 1995 String afterParens = endParen.next.stringValue;
1999 if (identical(afterParens, '{') || 1996 if (identical(afterParens, '{') ||
2000 identical(afterParens, '=>') || 1997 identical(afterParens, '=>') ||
(...skipping 493 matching lines...) Expand 10 before | Expand all | Expand 10 after
2494 /// Where 2491 /// Where
2495 /// genericListLiteral ::= typeArguments '[' (expressionList ','?)? ']' 2492 /// genericListLiteral ::= typeArguments '[' (expressionList ','?)? ']'
2496 /// genericMapLiteral ::= 2493 /// genericMapLiteral ::=
2497 /// typeArguments '{' (mapLiteralEntry (',' mapLiteralEntry)* ','?)? '}' 2494 /// typeArguments '{' (mapLiteralEntry (',' mapLiteralEntry)* ','?)? '}'
2498 /// genericFunctionLiteral ::= 2495 /// genericFunctionLiteral ::=
2499 /// typeParameters formalParameterList functionBody 2496 /// typeParameters formalParameterList functionBody
2500 /// Provide token for [constKeyword] if preceded by 'const', null if not. 2497 /// Provide token for [constKeyword] if preceded by 'const', null if not.
2501 Token parseLiteralListOrMapOrFunction(Token token, Token constKeyword) { 2498 Token parseLiteralListOrMapOrFunction(Token token, Token constKeyword) {
2502 assert(optional('<', token)); 2499 assert(optional('<', token));
2503 BeginGroupToken begin = token; 2500 BeginGroupToken begin = token;
2504 if (enableGenericMethodSyntax && 2501 if (constKeyword == null &&
2505 constKeyword == null &&
2506 begin.endGroup != null && 2502 begin.endGroup != null &&
2507 identical(begin.endGroup.next.kind, OPEN_PAREN_TOKEN)) { 2503 identical(begin.endGroup.next.kind, OPEN_PAREN_TOKEN)) {
2508 token = parseTypeVariablesOpt(token); 2504 token = parseTypeVariablesOpt(token);
2509 return parseLiteralFunctionSuffix(token); 2505 return parseLiteralFunctionSuffix(token);
2510 } else { 2506 } else {
2511 token = parseTypeArgumentsOpt(token); 2507 token = parseTypeArgumentsOpt(token);
2512 if (optional('{', token)) { 2508 if (optional('{', token)) {
2513 return parseLiteralMapSuffix(token, constKeyword); 2509 return parseLiteralMapSuffix(token, constKeyword);
2514 } else if ((optional('[', token)) || (optional('[]', token))) { 2510 } else if ((optional('[', token)) || (optional('[]', token))) {
2515 return parseLiteralListSuffix(token, constKeyword); 2511 return parseLiteralListSuffix(token, constKeyword);
(...skipping 22 matching lines...) Expand all
2538 isFunctionDeclaration(peek.next)) { 2534 isFunctionDeclaration(peek.next)) {
2539 return parseFunctionExpression(token); 2535 return parseFunctionExpression(token);
2540 } else if (isFunctionDeclaration(token.next)) { 2536 } else if (isFunctionDeclaration(token.next)) {
2541 return parseFunctionExpression(token); 2537 return parseFunctionExpression(token);
2542 } else { 2538 } else {
2543 return parseSend(token); 2539 return parseSend(token);
2544 } 2540 }
2545 } 2541 }
2546 2542
2547 bool isFunctionDeclaration(Token token) { 2543 bool isFunctionDeclaration(Token token) {
2548 if (enableGenericMethodSyntax && optional('<', token)) { 2544 if (optional('<', token)) {
2549 BeginGroupToken begin = token; 2545 BeginGroupToken begin = token;
2550 if (begin.endGroup == null) return false; 2546 if (begin.endGroup == null) return false;
2551 token = begin.endGroup.next; 2547 token = begin.endGroup.next;
2552 } 2548 }
2553 if (optional('(', token)) { 2549 if (optional('(', token)) {
2554 BeginGroupToken begin = token; 2550 BeginGroupToken begin = token;
2555 // TODO(eernst): Check for NPE as described in issue 26252. 2551 // TODO(eernst): Check for NPE as described in issue 26252.
2556 String afterParens = begin.endGroup.next.stringValue; 2552 String afterParens = begin.endGroup.next.stringValue;
2557 if (identical(afterParens, '{') || 2553 if (identical(afterParens, '{') ||
2558 identical(afterParens, '=>') || 2554 identical(afterParens, '=>') ||
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
2687 } 2683 }
2688 2684
2689 Token parseLiteralNull(Token token) { 2685 Token parseLiteralNull(Token token) {
2690 listener.handleLiteralNull(token); 2686 listener.handleLiteralNull(token);
2691 return token.next; 2687 return token.next;
2692 } 2688 }
2693 2689
2694 Token parseSend(Token token) { 2690 Token parseSend(Token token) {
2695 listener.beginSend(token); 2691 listener.beginSend(token);
2696 token = parseIdentifier(token); 2692 token = parseIdentifier(token);
2697 if (enableGenericMethodSyntax && isValidMethodTypeArguments(token)) { 2693 if (isValidMethodTypeArguments(token)) {
2698 token = parseTypeArgumentsOpt(token); 2694 token = parseTypeArgumentsOpt(token);
2699 } else { 2695 } else {
2700 listener.handleNoTypeArguments(token); 2696 listener.handleNoTypeArguments(token);
2701 } 2697 }
2702 token = parseArgumentsOpt(token); 2698 token = parseArgumentsOpt(token);
2703 listener.endSend(token); 2699 listener.endSend(token);
2704 return token; 2700 return token;
2705 } 2701 }
2706 2702
2707 Token skipArgumentsOpt(Token token) { 2703 Token skipArgumentsOpt(Token token) {
(...skipping 466 matching lines...) Expand 10 before | Expand all | Expand 10 after
3174 } 3170 }
3175 listener.handleContinueStatement(hasTarget, continueKeyword, token); 3171 listener.handleContinueStatement(hasTarget, continueKeyword, token);
3176 return expectSemicolon(token); 3172 return expectSemicolon(token);
3177 } 3173 }
3178 3174
3179 Token parseEmptyStatement(Token token) { 3175 Token parseEmptyStatement(Token token) {
3180 listener.handleEmptyStatement(token); 3176 listener.handleEmptyStatement(token);
3181 return expectSemicolon(token); 3177 return expectSemicolon(token);
3182 } 3178 }
3183 } 3179 }
OLDNEW
« no previous file with comments | « pkg/dart_parser/lib/src/class_member_parser.dart ('k') | pkg/dart_parser/lib/src/top_level_parser.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698