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

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

Issue 1859343004: dartfmt pkg/compiler (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 8 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 '../options.dart' show 7 import '../options.dart' show ParserOptions;
8 ParserOptions;
9 import '../common.dart'; 8 import '../common.dart';
10 import '../tokens/keyword.dart' show 9 import '../tokens/keyword.dart' show Keyword;
11 Keyword; 10 import '../tokens/precedence.dart' show PrecedenceInfo;
12 import '../tokens/precedence.dart' show 11 import '../tokens/precedence_constants.dart'
13 PrecedenceInfo; 12 show
14 import '../tokens/precedence_constants.dart' show 13 AS_INFO,
15 AS_INFO, 14 ASSIGNMENT_PRECEDENCE,
16 ASSIGNMENT_PRECEDENCE, 15 CASCADE_PRECEDENCE,
17 CASCADE_PRECEDENCE, 16 EQUALITY_PRECEDENCE,
18 EQUALITY_PRECEDENCE, 17 GT_INFO,
19 GT_INFO, 18 GT_GT_INFO,
20 GT_GT_INFO, 19 IS_INFO,
21 IS_INFO, 20 MINUS_MINUS_INFO,
22 MINUS_MINUS_INFO, 21 OPEN_PAREN_INFO,
23 OPEN_PAREN_INFO, 22 OPEN_SQUARE_BRACKET_INFO,
24 OPEN_SQUARE_BRACKET_INFO, 23 PERIOD_INFO,
25 PERIOD_INFO, 24 PLUS_PLUS_INFO,
26 PLUS_PLUS_INFO, 25 POSTFIX_PRECEDENCE,
27 POSTFIX_PRECEDENCE, 26 QUESTION_INFO,
28 QUESTION_INFO, 27 QUESTION_PERIOD_INFO,
29 QUESTION_PERIOD_INFO, 28 RELATIONAL_PRECEDENCE;
30 RELATIONAL_PRECEDENCE; 29 import '../tokens/token.dart'
31 import '../tokens/token.dart' show 30 show
32 BeginGroupToken, 31 BeginGroupToken,
33 isUserDefinableOperator, 32 isUserDefinableOperator,
34 KeywordToken, 33 KeywordToken,
35 SymbolToken, 34 SymbolToken,
36 Token; 35 Token;
37 import '../tokens/token_constants.dart' show 36 import '../tokens/token_constants.dart'
38 BAD_INPUT_TOKEN, 37 show
39 COMMA_TOKEN, 38 BAD_INPUT_TOKEN,
40 DOUBLE_TOKEN, 39 COMMA_TOKEN,
41 EOF_TOKEN, 40 DOUBLE_TOKEN,
42 EQ_TOKEN, 41 EOF_TOKEN,
43 FUNCTION_TOKEN, 42 EQ_TOKEN,
44 HASH_TOKEN, 43 FUNCTION_TOKEN,
45 HEXADECIMAL_TOKEN, 44 HASH_TOKEN,
46 IDENTIFIER_TOKEN, 45 HEXADECIMAL_TOKEN,
47 INT_TOKEN, 46 IDENTIFIER_TOKEN,
48 KEYWORD_TOKEN, 47 INT_TOKEN,
49 LT_TOKEN, 48 KEYWORD_TOKEN,
50 OPEN_CURLY_BRACKET_TOKEN, 49 LT_TOKEN,
51 OPEN_PAREN_TOKEN, 50 OPEN_CURLY_BRACKET_TOKEN,
52 OPEN_SQUARE_BRACKET_TOKEN, 51 OPEN_PAREN_TOKEN,
53 PERIOD_TOKEN, 52 OPEN_SQUARE_BRACKET_TOKEN,
54 SEMICOLON_TOKEN, 53 PERIOD_TOKEN,
55 STRING_INTERPOLATION_IDENTIFIER_TOKEN, 54 SEMICOLON_TOKEN,
56 STRING_INTERPOLATION_TOKEN, 55 STRING_INTERPOLATION_IDENTIFIER_TOKEN,
57 STRING_TOKEN; 56 STRING_INTERPOLATION_TOKEN,
58 import '../util/characters.dart' as Characters show 57 STRING_TOKEN;
59 $CLOSE_CURLY_BRACKET; 58 import '../util/characters.dart' as Characters show $CLOSE_CURLY_BRACKET;
60 import '../util/util.dart' show 59 import '../util/util.dart' show Link;
61 Link;
62 60
63 import 'listener.dart' show 61 import 'listener.dart' show Listener;
64 Listener;
65 62
66 class FormalParameterType { 63 class FormalParameterType {
67 final String type; 64 final String type;
68 const FormalParameterType(this.type); 65 const FormalParameterType(this.type);
69 bool get isRequired => this == REQUIRED; 66 bool get isRequired => this == REQUIRED;
70 bool get isPositional => this == POSITIONAL; 67 bool get isPositional => this == POSITIONAL;
71 bool get isNamed => this == NAMED; 68 bool get isNamed => this == NAMED;
72 static final REQUIRED = const FormalParameterType('required'); 69 static final REQUIRED = const FormalParameterType('required');
73 static final POSITIONAL = const FormalParameterType('positional'); 70 static final POSITIONAL = const FormalParameterType('positional');
74 static final NAMED = const FormalParameterType('named'); 71 static final NAMED = const FormalParameterType('named');
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
114 listener.endTopLevelDeclaration(token); 111 listener.endTopLevelDeclaration(token);
115 count++; 112 count++;
116 } 113 }
117 listener.endCompilationUnit(count, token); 114 listener.endCompilationUnit(count, token);
118 return token; 115 return token;
119 } 116 }
120 117
121 Token parseTopLevelDeclaration(Token token) { 118 Token parseTopLevelDeclaration(Token token) {
122 token = parseMetadataStar(token); 119 token = parseMetadataStar(token);
123 final String value = token.stringValue; 120 final String value = token.stringValue;
124 if ((identical(value, 'abstract') && optional('class', token.next)) 121 if ((identical(value, 'abstract') && optional('class', token.next)) ||
125 || identical(value, 'class')) { 122 identical(value, 'class')) {
126 return parseClassOrNamedMixinApplication(token); 123 return parseClassOrNamedMixinApplication(token);
127 } else if (identical(value, 'enum')) { 124 } else if (identical(value, 'enum')) {
128 return parseEnum(token); 125 return parseEnum(token);
129 } else if (identical(value, 'typedef')) { 126 } else if (identical(value, 'typedef')) {
130 return parseTypedef(token); 127 return parseTypedef(token);
131 } else if (identical(value, 'library')) { 128 } else if (identical(value, 'library')) {
132 return parseLibraryName(token); 129 return parseLibraryName(token);
133 } else if (identical(value, 'import')) { 130 } else if (identical(value, 'import')) {
134 return parseImport(token); 131 return parseImport(token);
135 } else if (identical(value, 'export')) { 132 } else if (identical(value, 'export')) {
(...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after
463 token = parseFormalParameters(token); 460 token = parseFormalParameters(token);
464 listener.handleFunctionTypedFormalParameter(token); 461 listener.handleFunctionTypedFormalParameter(token);
465 } 462 }
466 String value = token.stringValue; 463 String value = token.stringValue;
467 if ((identical('=', value)) || (identical(':', value))) { 464 if ((identical('=', value)) || (identical(':', value))) {
468 // TODO(ahe): Validate that these are only used for optional parameters. 465 // TODO(ahe): Validate that these are only used for optional parameters.
469 Token equal = token; 466 Token equal = token;
470 token = parseExpression(token.next); 467 token = parseExpression(token.next);
471 listener.handleValuedFormalParameter(equal, token); 468 listener.handleValuedFormalParameter(equal, token);
472 if (type.isRequired) { 469 if (type.isRequired) {
473 listener.reportError(equal, 470 listener.reportError(
474 MessageKind.REQUIRED_PARAMETER_WITH_DEFAULT); 471 equal, MessageKind.REQUIRED_PARAMETER_WITH_DEFAULT);
475 } else if (type.isNamed && identical('=', value)) { 472 } else if (type.isNamed && identical('=', value)) {
476 listener.reportError(equal, MessageKind.NAMED_PARAMETER_WITH_EQUALS); 473 listener.reportError(equal, MessageKind.NAMED_PARAMETER_WITH_EQUALS);
477 } else if (type.isPositional && identical(':', value)) { 474 } else if (type.isPositional && identical(':', value)) {
478 listener.reportError(equal, 475 listener.reportError(
479 MessageKind.POSITIONAL_PARAMETER_WITH_EQUALS); 476 equal, MessageKind.POSITIONAL_PARAMETER_WITH_EQUALS);
480 } 477 }
481 } 478 }
482 listener.endFormalParameter(thisKeyword); 479 listener.endFormalParameter(thisKeyword);
483 return token; 480 return token;
484 } 481 }
485 482
486 Token parseOptionalFormalParameters(Token token, bool isNamed) { 483 Token parseOptionalFormalParameters(Token token, bool isNamed) {
487 Token begin = token; 484 Token begin = token;
488 listener.beginOptionalFormalParameters(begin); 485 listener.beginOptionalFormalParameters(begin);
489 assert((isNamed && optional('{', token)) || optional('[', token)); 486 assert((isNamed && optional('{', token)) || optional('[', token));
490 int parameterCount = 0; 487 int parameterCount = 0;
491 do { 488 do {
492 token = token.next; 489 token = token.next;
493 var type = isNamed ? FormalParameterType.NAMED 490 var type =
494 : FormalParameterType.POSITIONAL; 491 isNamed ? FormalParameterType.NAMED : FormalParameterType.POSITIONAL;
495 token = parseFormalParameter(token, type); 492 token = parseFormalParameter(token, type);
496 ++parameterCount; 493 ++parameterCount;
497 } while (optional(',', token)); 494 } while (optional(',', token));
498 listener.endOptionalFormalParameters(parameterCount, begin, token); 495 listener.endOptionalFormalParameters(parameterCount, begin, token);
499 if (isNamed) { 496 if (isNamed) {
500 return expect('}', token); 497 return expect('}', token);
501 } else { 498 } else {
502 return expect(']', token); 499 return expect(']', token);
503 } 500 }
504 } 501 }
505 502
506 Token parseTypeOpt(Token token) { 503 Token parseTypeOpt(Token token) {
507 Token peek = peekAfterIfType(token); 504 Token peek = peekAfterIfType(token);
508 if (peek != null && (peek.isIdentifier() || optional('this', peek))) { 505 if (peek != null && (peek.isIdentifier() || optional('this', peek))) {
509 return parseType(token); 506 return parseType(token);
510 } 507 }
511 listener.handleNoType(token); 508 listener.handleNoType(token);
512 return token; 509 return token;
513 } 510 }
514 511
515 bool isValidTypeReference(Token token) { 512 bool isValidTypeReference(Token token) {
516 final kind = token.kind; 513 final kind = token.kind;
517 if (identical(kind, IDENTIFIER_TOKEN)) return true; 514 if (identical(kind, IDENTIFIER_TOKEN)) return true;
518 if (identical(kind, KEYWORD_TOKEN)) { 515 if (identical(kind, KEYWORD_TOKEN)) {
519 Keyword keyword = (token as KeywordToken).keyword; 516 Keyword keyword = (token as KeywordToken).keyword;
520 String value = keyword.syntax; 517 String value = keyword.syntax;
521 return keyword.isPseudo 518 return keyword.isPseudo ||
522 || (identical(value, 'dynamic')) 519 (identical(value, 'dynamic')) ||
523 || (identical(value, 'void')); 520 (identical(value, 'void'));
524 } 521 }
525 return false; 522 return false;
526 } 523 }
527 524
528 Token parseQualified(Token token) { 525 Token parseQualified(Token token) {
529 token = parseIdentifier(token); 526 token = parseIdentifier(token);
530 while (optional('.', token)) { 527 while (optional('.', token)) {
531 token = parseQualifiedRest(token); 528 token = parseQualifiedRest(token);
532 } 529 }
533 return token; 530 return token;
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
621 } 618 }
622 } 619 }
623 620
624 Token parseNamedMixinApplication(Token token, Token classKeyword) { 621 Token parseNamedMixinApplication(Token token, Token classKeyword) {
625 token = parseMixinApplication(token); 622 token = parseMixinApplication(token);
626 Token implementsKeyword = null; 623 Token implementsKeyword = null;
627 if (optional('implements', token)) { 624 if (optional('implements', token)) {
628 implementsKeyword = token; 625 implementsKeyword = token;
629 token = parseTypeList(token.next); 626 token = parseTypeList(token.next);
630 } 627 }
631 listener.endNamedMixinApplication( 628 listener.endNamedMixinApplication(classKeyword, implementsKeyword, token);
632 classKeyword, implementsKeyword, token);
633 return expect(';', token); 629 return expect(';', token);
634 } 630 }
635 631
636 Token parseClass(Token begin, Token classKeyword) { 632 Token parseClass(Token begin, Token classKeyword) {
637 Token token = parseIdentifier(classKeyword.next); 633 Token token = parseIdentifier(classKeyword.next);
638 token = parseTypeVariablesOpt(token); 634 token = parseTypeVariablesOpt(token);
639 Token extendsKeyword; 635 Token extendsKeyword;
640 if (optional('extends', token)) { 636 if (optional('extends', token)) {
641 extendsKeyword = token; 637 extendsKeyword = token;
642 if (optional('with', peekAfterType(token.next))) { 638 if (optional('with', peekAfterType(token.next))) {
643 token = parseMixinApplication(token.next); 639 token = parseMixinApplication(token.next);
644 } else { 640 } else {
645 token = parseType(token.next); 641 token = parseType(token.next);
646 } 642 }
647 } else { 643 } else {
648 extendsKeyword = null; 644 extendsKeyword = null;
649 listener.handleNoType(token); 645 listener.handleNoType(token);
650 } 646 }
651 Token implementsKeyword; 647 Token implementsKeyword;
652 int interfacesCount = 0; 648 int interfacesCount = 0;
653 if (optional('implements', token)) { 649 if (optional('implements', token)) {
654 implementsKeyword = token; 650 implementsKeyword = token;
655 do { 651 do {
656 token = parseType(token.next); 652 token = parseType(token.next);
657 ++interfacesCount; 653 ++interfacesCount;
658 } while (optional(',', token)); 654 } while (optional(',', token));
659 } 655 }
660 token = parseClassBody(token); 656 token = parseClassBody(token);
661 listener.endClassDeclaration(interfacesCount, begin, extendsKeyword, 657 listener.endClassDeclaration(
662 implementsKeyword, token); 658 interfacesCount, begin, extendsKeyword, implementsKeyword, token);
663 return token.next; 659 return token.next;
664 } 660 }
665 661
666 Token parseStringPart(Token token) { 662 Token parseStringPart(Token token) {
667 if (identical(token.kind, STRING_TOKEN)) { 663 if (identical(token.kind, STRING_TOKEN)) {
668 listener.handleStringPart(token); 664 listener.handleStringPart(token);
669 return token.next; 665 return token.next;
670 } else { 666 } else {
671 return listener.expected('string', token); 667 return listener.expected('string', token);
672 } 668 }
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
705 bool optional(String value, Token token) { 701 bool optional(String value, Token token) {
706 return identical(value, token.stringValue); 702 return identical(value, token.stringValue);
707 } 703 }
708 704
709 /** 705 /**
710 * Returns true if the stringValue of the [token] is either [value1], 706 * Returns true if the stringValue of the [token] is either [value1],
711 * [value2], or [value3]. 707 * [value2], or [value3].
712 */ 708 */
713 bool isOneOf3(Token token, String value1, String value2, String value3) { 709 bool isOneOf3(Token token, String value1, String value2, String value3) {
714 String stringValue = token.stringValue; 710 String stringValue = token.stringValue;
715 return 711 return value1 == stringValue ||
716 value1 == stringValue ||
717 value2 == stringValue || 712 value2 == stringValue ||
718 value3 == stringValue; 713 value3 == stringValue;
719 } 714 }
720 715
721 /** 716 /**
722 * Returns true if the stringValue of the [token] is either [value1], 717 * Returns true if the stringValue of the [token] is either [value1],
723 * [value2], [value3], or [value4]. 718 * [value2], [value3], or [value4].
724 */ 719 */
725 bool isOneOf4(Token token, 720 bool isOneOf4(
726 String value1, String value2, String value3, String value4) { 721 Token token, String value1, String value2, String value3, String value4) {
727 String stringValue = token.stringValue; 722 String stringValue = token.stringValue;
728 return value1 == stringValue || 723 return value1 == stringValue ||
729 value2 == stringValue || 724 value2 == stringValue ||
730 value3 == stringValue || 725 value3 == stringValue ||
731 value4 == stringValue; 726 value4 == stringValue;
732 } 727 }
733 728
734 bool notEofOrValue(String value, Token token) { 729 bool notEofOrValue(String value, Token token) {
735 return !identical(token.kind, EOF_TOKEN) && 730 return !identical(token.kind, EOF_TOKEN) &&
736 !identical(value, token.stringValue); 731 !identical(value, token.stringValue);
737 } 732 }
738 733
739 Token parseType(Token token) { 734 Token parseType(Token token) {
740 Token begin = token; 735 Token begin = token;
741 if (isValidTypeReference(token)) { 736 if (isValidTypeReference(token)) {
742 token = parseIdentifier(token); 737 token = parseIdentifier(token);
743 token = parseQualifiedRestOpt(token); 738 token = parseQualifiedRestOpt(token);
744 } else { 739 } else {
745 token = listener.expectedType(token); 740 token = listener.expectedType(token);
746 } 741 }
747 token = parseTypeArgumentsOpt(token); 742 token = parseTypeArgumentsOpt(token);
748 listener.endType(begin, token); 743 listener.endType(begin, token);
749 return token; 744 return token;
750 } 745 }
751 746
752 Token parseTypeArgumentsOpt(Token token) { 747 Token parseTypeArgumentsOpt(Token token) {
753 return parseStuff(token, 748 return parseStuff(
754 (t) => listener.beginTypeArguments(t), 749 token,
755 (t) => parseType(t), 750 (t) => listener.beginTypeArguments(t),
756 (c, bt, et) => listener.endTypeArguments(c, bt, et), 751 (t) => parseType(t),
757 (t) => listener.handleNoTypeArguments(t)); 752 (c, bt, et) => listener.endTypeArguments(c, bt, et),
753 (t) => listener.handleNoTypeArguments(t));
758 } 754 }
759 755
760 Token parseTypeVariablesOpt(Token token) { 756 Token parseTypeVariablesOpt(Token token) {
761 return parseStuff(token, 757 return parseStuff(
762 (t) => listener.beginTypeVariables(t), 758 token,
763 (t) => parseTypeVariable(t), 759 (t) => listener.beginTypeVariables(t),
764 (c, bt, et) => listener.endTypeVariables(c, bt, et), 760 (t) => parseTypeVariable(t),
765 (t) => listener.handleNoTypeVariables(t)); 761 (c, bt, et) => listener.endTypeVariables(c, bt, et),
762 (t) => listener.handleNoTypeVariables(t));
766 } 763 }
767 764
768 // TODO(ahe): Clean this up. 765 // TODO(ahe): Clean this up.
769 Token parseStuff(Token token, Function beginStuff, Function stuffParser, 766 Token parseStuff(Token token, Function beginStuff, Function stuffParser,
770 Function endStuff, Function handleNoStuff) { 767 Function endStuff, Function handleNoStuff) {
771 if (optional('<', token)) { 768 if (optional('<', token)) {
772 Token begin = token; 769 Token begin = token;
773 beginStuff(begin); 770 beginStuff(begin);
774 int count = 0; 771 int count = 0;
775 do { 772 do {
776 token = stuffParser(token.next); 773 token = stuffParser(token.next);
777 ++count; 774 ++count;
778 } while (optional(',', token)); 775 } while (optional(',', token));
779 Token next = token.next; 776 Token next = token.next;
780 if (identical(token.stringValue, '>>')) { 777 if (identical(token.stringValue, '>>')) {
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
820 identifiers = identifiers.tail; 817 identifiers = identifiers.tail;
821 } 818 }
822 } 819 }
823 820
824 token = afterName; 821 token = afterName;
825 bool isField; 822 bool isField;
826 while (true) { 823 while (true) {
827 // Loop to allow the listener to rewrite the token stream for 824 // Loop to allow the listener to rewrite the token stream for
828 // error handling. 825 // error handling.
829 final String value = token.stringValue; 826 final String value = token.stringValue;
830 if ((identical(value, '(')) || (identical(value, '{')) 827 if ((identical(value, '(')) ||
831 || (identical(value, '=>'))) { 828 (identical(value, '{')) ||
829 (identical(value, '=>'))) {
832 isField = false; 830 isField = false;
833 break; 831 break;
834 } else if ((identical(value, '=')) || (identical(value, ','))) { 832 } else if ((identical(value, '=')) || (identical(value, ','))) {
835 isField = true; 833 isField = true;
836 break; 834 break;
837 } else if (identical(value, ';')) { 835 } else if (identical(value, ';')) {
838 if (getOrSet != null) { 836 if (getOrSet != null) {
839 // If we found a "get" keyword, this must be an abstract 837 // If we found a "get" keyword, this must be an abstract
840 // getter. 838 // getter.
841 isField = (!identical(getOrSet.stringValue, 'get')); 839 isField = (!identical(getOrSet.stringValue, 'get'));
842 // TODO(ahe): This feels like a hack. 840 // TODO(ahe): This feels like a hack.
843 } else { 841 } else {
844 isField = true; 842 isField = true;
845 } 843 }
846 break; 844 break;
847 } else { 845 } else {
848 token = listener.unexpected(token); 846 token = listener.unexpected(token);
849 if (identical(token.kind, EOF_TOKEN)) return token; 847 if (identical(token.kind, EOF_TOKEN)) return token;
850 } 848 }
851 } 849 }
852 var modifiers = identifiers.reverse(); 850 var modifiers = identifiers.reverse();
853 return isField 851 return isField
854 ? parseFields(start, modifiers, type, getOrSet, name, true) 852 ? parseFields(start, modifiers, type, getOrSet, name, true)
855 : parseTopLevelMethod(start, modifiers, type, getOrSet, name); 853 : parseTopLevelMethod(start, modifiers, type, getOrSet, name);
856 } 854 }
857 855
858 bool isVarFinalOrConst(Token token) { 856 bool isVarFinalOrConst(Token token) {
859 String value = token.stringValue; 857 String value = token.stringValue;
860 return identical('var', value) 858 return identical('var', value) ||
861 || identical('final', value) 859 identical('final', value) ||
862 || identical('const', value); 860 identical('const', value);
863 } 861 }
864 862
865 Token expectVarFinalOrConst(Link<Token> modifiers, 863 Token expectVarFinalOrConst(
866 bool hasType, 864 Link<Token> modifiers, bool hasType, bool allowStatic) {
867 bool allowStatic) {
868 int modifierCount = 0; 865 int modifierCount = 0;
869 Token staticModifier; 866 Token staticModifier;
870 if (allowStatic && !modifiers.isEmpty 867 if (allowStatic &&
871 && optional('static', modifiers.head)) { 868 !modifiers.isEmpty &&
869 optional('static', modifiers.head)) {
872 staticModifier = modifiers.head; 870 staticModifier = modifiers.head;
873 modifierCount++; 871 modifierCount++;
874 parseModifier(staticModifier); 872 parseModifier(staticModifier);
875 modifiers = modifiers.tail; 873 modifiers = modifiers.tail;
876 } 874 }
877 if (modifiers.isEmpty) { 875 if (modifiers.isEmpty) {
878 listener.handleModifiers(modifierCount); 876 listener.handleModifiers(modifierCount);
879 return null; 877 return null;
880 } 878 }
881 if (modifiers.tail.isEmpty) { 879 if (modifiers.tail.isEmpty) {
882 Token modifier = modifiers.head; 880 Token modifier = modifiers.head;
883 if (isVarFinalOrConst(modifier)) { 881 if (isVarFinalOrConst(modifier)) {
884 modifierCount++; 882 modifierCount++;
885 parseModifier(modifier); 883 parseModifier(modifier);
886 listener.handleModifiers(modifierCount); 884 listener.handleModifiers(modifierCount);
887 // TODO(ahe): The caller checks for "var Type name", perhaps we should 885 // TODO(ahe): The caller checks for "var Type name", perhaps we should
888 // check here instead. 886 // check here instead.
889 return modifier; 887 return modifier;
890 } 888 }
891 } 889 }
892 890
893 // Slow case to report errors. 891 // Slow case to report errors.
894 List<Token> modifierList = modifiers.toList(); 892 List<Token> modifierList = modifiers.toList();
895 Token varFinalOrConst = 893 Token varFinalOrConst =
896 modifierList.firstWhere(isVarFinalOrConst, orElse: () => null); 894 modifierList.firstWhere(isVarFinalOrConst, orElse: () => null);
897 if (allowStatic && staticModifier == null) { 895 if (allowStatic && staticModifier == null) {
898 staticModifier = 896 staticModifier = modifierList.firstWhere(
899 modifierList.firstWhere( 897 (modifier) => optional('static', modifier),
900 (modifier) => optional('static', modifier), orElse: () => null); 898 orElse: () => null);
901 if (staticModifier != null) { 899 if (staticModifier != null) {
902 modifierCount++; 900 modifierCount++;
903 parseModifier(staticModifier); 901 parseModifier(staticModifier);
904 modifierList.remove(staticModifier); 902 modifierList.remove(staticModifier);
905 } 903 }
906 } 904 }
907 bool hasTypeOrModifier = hasType; 905 bool hasTypeOrModifier = hasType;
908 if (varFinalOrConst != null) { 906 if (varFinalOrConst != null) {
909 parseModifier(varFinalOrConst); 907 parseModifier(varFinalOrConst);
910 modifierCount++; 908 modifierCount++;
911 hasTypeOrModifier = true; 909 hasTypeOrModifier = true;
912 modifierList.remove(varFinalOrConst); 910 modifierList.remove(varFinalOrConst);
913 } 911 }
914 listener.handleModifiers(modifierCount); 912 listener.handleModifiers(modifierCount);
915 var kind = hasTypeOrModifier 913 var kind = hasTypeOrModifier
916 ? MessageKind.EXTRANEOUS_MODIFIER 914 ? MessageKind.EXTRANEOUS_MODIFIER
917 : MessageKind.EXTRANEOUS_MODIFIER_REPLACE; 915 : MessageKind.EXTRANEOUS_MODIFIER_REPLACE;
918 for (Token modifier in modifierList) { 916 for (Token modifier in modifierList) {
919 listener.reportError(modifier, kind, {'modifier': modifier}); 917 listener.reportError(modifier, kind, {'modifier': modifier});
920 } 918 }
921 return null; 919 return null;
922 } 920 }
923 921
924 Token parseFields(Token start, 922 Token parseFields(Token start, Link<Token> modifiers, Token type,
925 Link<Token> modifiers, 923 Token getOrSet, Token name, bool isTopLevel) {
926 Token type,
927 Token getOrSet,
928 Token name,
929 bool isTopLevel) {
930 bool hasType = type != null; 924 bool hasType = type != null;
931 Token varFinalOrConst = 925 Token varFinalOrConst =
932 expectVarFinalOrConst(modifiers, hasType, !isTopLevel); 926 expectVarFinalOrConst(modifiers, hasType, !isTopLevel);
933 bool isVar = false; 927 bool isVar = false;
934 bool hasModifier = false; 928 bool hasModifier = false;
935 if (varFinalOrConst != null) { 929 if (varFinalOrConst != null) {
936 hasModifier = true; 930 hasModifier = true;
937 isVar = optional('var', varFinalOrConst); 931 isVar = optional('var', varFinalOrConst);
938 } 932 }
939 933
940 if (getOrSet != null) { 934 if (getOrSet != null) {
941 var kind = (hasModifier || hasType) 935 var kind = (hasModifier || hasType)
942 ? MessageKind.EXTRANEOUS_MODIFIER 936 ? MessageKind.EXTRANEOUS_MODIFIER
943 : MessageKind.EXTRANEOUS_MODIFIER_REPLACE; 937 : MessageKind.EXTRANEOUS_MODIFIER_REPLACE;
944 listener.reportError(getOrSet, kind, {'modifier': getOrSet}); 938 listener.reportError(getOrSet, kind, {'modifier': getOrSet});
945 } 939 }
946 940
947 if (!hasType) { 941 if (!hasType) {
948 listener.handleNoType(name); 942 listener.handleNoType(name);
949 } else if (optional('void', type)) { 943 } else if (optional('void', type)) {
950 listener.handleNoType(name); 944 listener.handleNoType(name);
951 // TODO(ahe): This error is reported twice, second time is from 945 // TODO(ahe): This error is reported twice, second time is from
952 // [parseVariablesDeclarationMaybeSemicolon] via 946 // [parseVariablesDeclarationMaybeSemicolon] via
953 // [PartialFieldListElement.parseNode]. 947 // [PartialFieldListElement.parseNode].
954 listener.reportError(type, MessageKind.VOID_NOT_ALLOWED); 948 listener.reportError(type, MessageKind.VOID_NOT_ALLOWED);
955 } else { 949 } else {
956 parseType(type); 950 parseType(type);
957 if (isVar) { 951 if (isVar) {
958 listener.reportError( 952 listener.reportError(modifiers.head, MessageKind.EXTRANEOUS_MODIFIER,
959 modifiers.head, MessageKind.EXTRANEOUS_MODIFIER,
960 {'modifier': modifiers.head}); 953 {'modifier': modifiers.head});
961 } 954 }
962 } 955 }
963 956
964 Token token = parseIdentifier(name); 957 Token token = parseIdentifier(name);
965 958
966 int fieldCount = 1; 959 int fieldCount = 1;
967 token = parseVariableInitializerOpt(token); 960 token = parseVariableInitializerOpt(token);
968 while (optional(',', token)) { 961 while (optional(',', token)) {
969 token = parseIdentifier(token.next); 962 token = parseIdentifier(token.next);
970 token = parseVariableInitializerOpt(token); 963 token = parseVariableInitializerOpt(token);
971 ++fieldCount; 964 ++fieldCount;
972 } 965 }
973 Token semicolon = token; 966 Token semicolon = token;
974 token = expectSemicolon(token); 967 token = expectSemicolon(token);
975 if (isTopLevel) { 968 if (isTopLevel) {
976 listener.endTopLevelFields(fieldCount, start, semicolon); 969 listener.endTopLevelFields(fieldCount, start, semicolon);
977 } else { 970 } else {
978 listener.endFields(fieldCount, start, semicolon); 971 listener.endFields(fieldCount, start, semicolon);
979 } 972 }
980 return token; 973 return token;
981 } 974 }
982 975
983 Token parseTopLevelMethod(Token start, 976 Token parseTopLevelMethod(Token start, Link<Token> modifiers, Token type,
984 Link<Token> modifiers, 977 Token getOrSet, Token name) {
985 Token type,
986 Token getOrSet,
987 Token name) {
988
989 Token externalModifier; 978 Token externalModifier;
990 // TODO(johnniwinther): Move error reporting to resolution to give more 979 // TODO(johnniwinther): Move error reporting to resolution to give more
991 // specific error messages. 980 // specific error messages.
992 for (Token modifier in modifiers) { 981 for (Token modifier in modifiers) {
993 if (externalModifier == null && optional('external', modifier)) { 982 if (externalModifier == null && optional('external', modifier)) {
994 externalModifier = modifier; 983 externalModifier = modifier;
995 } else { 984 } else {
996 listener.reportError( 985 listener.reportError(
997 modifier, MessageKind.EXTRANEOUS_MODIFIER, {'modifier': modifier}); 986 modifier, MessageKind.EXTRANEOUS_MODIFIER, {'modifier': modifier});
998 } 987 }
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
1055 1044
1056 // `true` if 'get' has been seen. 1045 // `true` if 'get' has been seen.
1057 bool isGetter = false; 1046 bool isGetter = false;
1058 // `true` if an identifier has been seen after 'get'. 1047 // `true` if an identifier has been seen after 'get'.
1059 bool hasName = false; 1048 bool hasName = false;
1060 1049
1061 while (token.kind != EOF_TOKEN) { 1050 while (token.kind != EOF_TOKEN) {
1062 String value = token.stringValue; 1051 String value = token.stringValue;
1063 if (value == 'get') { 1052 if (value == 'get') {
1064 isGetter = true; 1053 isGetter = true;
1065 } else if (hasName && 1054 } else if (hasName && (value == 'sync' || value == 'async')) {
1066 (value == 'sync' || value == 'async')) {
1067 // Skip. 1055 // Skip.
1068 token = token.next; 1056 token = token.next;
1069 value = token.stringValue; 1057 value = token.stringValue;
1070 if (value == '*') { 1058 if (value == '*') {
1071 // Skip. 1059 // Skip.
1072 token = token.next; 1060 token = token.next;
1073 } 1061 }
1074 continue; 1062 continue;
1075 } else if (value == '(' || 1063 } else if (value == '(' || value == '{' || value == '=>') {
1076 value == '{' ||
1077 value == '=>') {
1078 // A method. 1064 // A method.
1079 identifiers = identifiers.prepend(token); 1065 identifiers = identifiers.prepend(token);
1080 return identifiers; 1066 return identifiers;
1081 } else if (value == '=' || 1067 } else if (value == '=' || value == ';' || value == ',') {
1082 value == ';' ||
1083 value == ',') {
1084 // A field or abstract getter. 1068 // A field or abstract getter.
1085 identifiers = identifiers.prepend(token); 1069 identifiers = identifiers.prepend(token);
1086 return identifiers; 1070 return identifiers;
1087 } else if (isGetter) { 1071 } else if (isGetter) {
1088 hasName = true; 1072 hasName = true;
1089 } 1073 }
1090 identifiers = identifiers.prepend(token); 1074 identifiers = identifiers.prepend(token);
1091 if (isValidTypeReference(token)) { 1075 if (isValidTypeReference(token)) {
1092 // type ... 1076 // type ...
1093 if (optional('.', token.next)) { 1077 if (optional('.', token.next)) {
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
1156 } 1140 }
1157 } 1141 }
1158 1142
1159 Token expectSemicolon(Token token) { 1143 Token expectSemicolon(Token token) {
1160 return expect(';', token); 1144 return expect(';', token);
1161 } 1145 }
1162 1146
1163 bool isModifier(Token token) { 1147 bool isModifier(Token token) {
1164 final String value = token.stringValue; 1148 final String value = token.stringValue;
1165 return (identical('final', value)) || 1149 return (identical('final', value)) ||
1166 (identical('var', value)) || 1150 (identical('var', value)) ||
1167 (identical('const', value)) || 1151 (identical('const', value)) ||
1168 (identical('abstract', value)) || 1152 (identical('abstract', value)) ||
1169 (identical('static', value)) || 1153 (identical('static', value)) ||
1170 (identical('external', value)); 1154 (identical('external', value));
1171 } 1155 }
1172 1156
1173 Token parseModifier(Token token) { 1157 Token parseModifier(Token token) {
1174 assert(isModifier(token)); 1158 assert(isModifier(token));
1175 listener.handleModifier(token); 1159 listener.handleModifier(token);
1176 return token.next; 1160 return token.next;
1177 } 1161 }
1178 1162
1179 void parseModifierList(Link<Token> tokens) { 1163 void parseModifierList(Link<Token> tokens) {
1180 int count = 0; 1164 int count = 0;
1181 for (; !tokens.isEmpty; tokens = tokens.tail) { 1165 for (; !tokens.isEmpty; tokens = tokens.tail) {
1182 Token token = tokens.head; 1166 Token token = tokens.head;
1183 if (isModifier(token)) { 1167 if (isModifier(token)) {
1184 parseModifier(token); 1168 parseModifier(token);
1185 } else { 1169 } else {
1186 listener.unexpected(token); 1170 listener.unexpected(token);
1187 // Skip the remaining modifiers. 1171 // Skip the remaining modifiers.
1188 break; 1172 break;
1189 } 1173 }
1190 count++; 1174 count++;
1191 } 1175 }
1192 listener.handleModifiers(count); 1176 listener.handleModifiers(count);
1193 } 1177 }
1194 1178
1195 Token parseModifiers(Token token) { 1179 Token parseModifiers(Token token) {
1196 int count = 0; 1180 int count = 0;
1197 while (identical(token.kind, KEYWORD_TOKEN)) { 1181 while (identical(token.kind, KEYWORD_TOKEN)) {
1198 if (!isModifier(token)) 1182 if (!isModifier(token)) break;
1199 break;
1200 token = parseModifier(token); 1183 token = parseModifier(token);
1201 count++; 1184 count++;
1202 } 1185 }
1203 listener.handleModifiers(count); 1186 listener.handleModifiers(count);
1204 return token; 1187 return token;
1205 } 1188 }
1206 1189
1207 /** 1190 /**
1208 * Returns the first token after the type starting at [token]. 1191 * Returns the first token after the type starting at [token].
1209 * This method assumes that [token] is an identifier (or void). 1192 * This method assumes that [token] is an identifier (or void).
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
1311 identifiers = identifiers.tail; 1294 identifiers = identifiers.tail;
1312 } 1295 }
1313 } 1296 }
1314 1297
1315 token = afterName; 1298 token = afterName;
1316 bool isField; 1299 bool isField;
1317 while (true) { 1300 while (true) {
1318 // Loop to allow the listener to rewrite the token stream for 1301 // Loop to allow the listener to rewrite the token stream for
1319 // error handling. 1302 // error handling.
1320 final String value = token.stringValue; 1303 final String value = token.stringValue;
1321 if ((identical(value, '(')) || (identical(value, '.')) 1304 if ((identical(value, '(')) ||
1322 || (identical(value, '{')) || (identical(value, '=>'))) { 1305 (identical(value, '.')) ||
1306 (identical(value, '{')) ||
1307 (identical(value, '=>'))) {
1323 isField = false; 1308 isField = false;
1324 break; 1309 break;
1325 } else if (identical(value, ';')) { 1310 } else if (identical(value, ';')) {
1326 if (getOrSet != null) { 1311 if (getOrSet != null) {
1327 // If we found a "get" keyword, this must be an abstract 1312 // If we found a "get" keyword, this must be an abstract
1328 // getter. 1313 // getter.
1329 isField = (!identical(getOrSet.stringValue, 'get')); 1314 isField = (!identical(getOrSet.stringValue, 'get'));
1330 // TODO(ahe): This feels like a hack. 1315 // TODO(ahe): This feels like a hack.
1331 } else { 1316 } else {
1332 isField = true; 1317 isField = true;
1333 } 1318 }
1334 break; 1319 break;
1335 } else if ((identical(value, '=')) || (identical(value, ','))) { 1320 } else if ((identical(value, '=')) || (identical(value, ','))) {
1336 isField = true; 1321 isField = true;
1337 break; 1322 break;
1338 } else { 1323 } else {
1339 token = listener.unexpected(token); 1324 token = listener.unexpected(token);
1340 if (identical(token.kind, EOF_TOKEN)) { 1325 if (identical(token.kind, EOF_TOKEN)) {
1341 // TODO(ahe): This is a hack, see parseTopLevelMember. 1326 // TODO(ahe): This is a hack, see parseTopLevelMember.
1342 listener.endFields(1, start, token); 1327 listener.endFields(1, start, token);
1343 return token; 1328 return token;
1344 } 1329 }
1345 } 1330 }
1346 } 1331 }
1347 1332
1348 var modifiers = identifiers.reverse(); 1333 var modifiers = identifiers.reverse();
1349 return isField 1334 return isField
1350 ? parseFields(start, modifiers, type, getOrSet, name, false) 1335 ? parseFields(start, modifiers, type, getOrSet, name, false)
1351 : parseMethod(start, modifiers, type, getOrSet, name); 1336 : parseMethod(start, modifiers, type, getOrSet, name);
1352
1353 } 1337 }
1354 1338
1355 Token parseMethod(Token start, 1339 Token parseMethod(Token start, Link<Token> modifiers, Token type,
1356 Link<Token> modifiers, 1340 Token getOrSet, Token name) {
1357 Token type,
1358 Token getOrSet,
1359 Token name) {
1360 Token externalModifier; 1341 Token externalModifier;
1361 Token staticModifier; 1342 Token staticModifier;
1362 Token constModifier; 1343 Token constModifier;
1363 int modifierCount = 0; 1344 int modifierCount = 0;
1364 int allowedModifierCount = 1; 1345 int allowedModifierCount = 1;
1365 // TODO(johnniwinther): Move error reporting to resolution to give more 1346 // TODO(johnniwinther): Move error reporting to resolution to give more
1366 // specific error messages. 1347 // specific error messages.
1367 for (Token modifier in modifiers) { 1348 for (Token modifier in modifiers) {
1368 if (externalModifier == null && optional('external', modifier)) { 1349 if (externalModifier == null && optional('external', modifier)) {
1369 modifierCount++; 1350 modifierCount++;
1370 externalModifier = modifier; 1351 externalModifier = modifier;
1371 if (modifierCount != allowedModifierCount) { 1352 if (modifierCount != allowedModifierCount) {
1372 listener.reportError( 1353 listener.reportError(modifier, MessageKind.EXTRANEOUS_MODIFIER,
1373 modifier, 1354 {'modifier': modifier});
1374 MessageKind.EXTRANEOUS_MODIFIER, {'modifier': modifier});
1375 } 1355 }
1376 allowedModifierCount++; 1356 allowedModifierCount++;
1377 } else if (staticModifier == null && optional('static', modifier)) { 1357 } else if (staticModifier == null && optional('static', modifier)) {
1378 modifierCount++; 1358 modifierCount++;
1379 staticModifier = modifier; 1359 staticModifier = modifier;
1380 if (modifierCount != allowedModifierCount) { 1360 if (modifierCount != allowedModifierCount) {
1381 listener.reportError( 1361 listener.reportError(modifier, MessageKind.EXTRANEOUS_MODIFIER,
1382 modifier, 1362 {'modifier': modifier});
1383 MessageKind.EXTRANEOUS_MODIFIER, {'modifier': modifier});
1384 } 1363 }
1385 } else if (constModifier == null && optional('const', modifier)) { 1364 } else if (constModifier == null && optional('const', modifier)) {
1386 modifierCount++; 1365 modifierCount++;
1387 constModifier = modifier; 1366 constModifier = modifier;
1388 if (modifierCount != allowedModifierCount) { 1367 if (modifierCount != allowedModifierCount) {
1389 listener.reportError( 1368 listener.reportError(modifier, MessageKind.EXTRANEOUS_MODIFIER,
1390 modifier, 1369 {'modifier': modifier});
1391 MessageKind.EXTRANEOUS_MODIFIER, {'modifier': modifier});
1392 } 1370 }
1393 } else { 1371 } else {
1394 listener.reportError( 1372 listener.reportError(
1395 modifier, MessageKind.EXTRANEOUS_MODIFIER, {'modifier': modifier}); 1373 modifier, MessageKind.EXTRANEOUS_MODIFIER, {'modifier': modifier});
1396 } 1374 }
1397 } 1375 }
1398 if (getOrSet != null && constModifier != null) { 1376 if (getOrSet != null && constModifier != null) {
1399 listener.reportError( 1377 listener.reportError(constModifier, MessageKind.EXTRANEOUS_MODIFIER,
1400 constModifier, MessageKind.EXTRANEOUS_MODIFIER,
1401 {'modifier': constModifier}); 1378 {'modifier': constModifier});
1402 } 1379 }
1403 parseModifierList(modifiers); 1380 parseModifierList(modifiers);
1404 1381
1405 if (type == null) { 1382 if (type == null) {
1406 listener.handleNoType(name); 1383 listener.handleNoType(name);
1407 } else { 1384 } else {
1408 parseReturnTypeOpt(type); 1385 parseReturnTypeOpt(type);
1409 } 1386 }
1410 Token token; 1387 Token token;
1411 if (optional('operator', name)) { 1388 if (optional('operator', name)) {
1412 token = parseOperatorName(name); 1389 token = parseOperatorName(name);
1413 if (staticModifier != null) { 1390 if (staticModifier != null) {
1414 listener.reportError( 1391 listener.reportError(staticModifier, MessageKind.EXTRANEOUS_MODIFIER,
1415 staticModifier, MessageKind.EXTRANEOUS_MODIFIER,
1416 {'modifier': staticModifier}); 1392 {'modifier': staticModifier});
1417 } 1393 }
1418 } else { 1394 } else {
1419 token = parseIdentifier(name); 1395 token = parseIdentifier(name);
1420 } 1396 }
1421 1397
1422 token = parseQualifiedRestOpt(token); 1398 token = parseQualifiedRestOpt(token);
1423 token = parseFormalParametersOpt(token); 1399 token = parseFormalParametersOpt(token);
1424 token = parseInitializersOpt(token); 1400 token = parseInitializersOpt(token);
1425 bool previousAsyncAwaitKeywordsEnabled = asyncAwaitKeywordsEnabled; 1401 bool previousAsyncAwaitKeywordsEnabled = asyncAwaitKeywordsEnabled;
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after
1631 token = token.next; 1607 token = token.next;
1632 } 1608 }
1633 } else if (optional('sync', token)) { 1609 } else if (optional('sync', token)) {
1634 async = token; 1610 async = token;
1635 token = token.next; 1611 token = token.next;
1636 if (optional('*', token)) { 1612 if (optional('*', token)) {
1637 asyncAwaitKeywordsEnabled = true; 1613 asyncAwaitKeywordsEnabled = true;
1638 star = token; 1614 star = token;
1639 token = token.next; 1615 token = token.next;
1640 } else { 1616 } else {
1641 listener.reportError(async, 1617 listener.reportError(async, MessageKind.INVALID_SYNC_MODIFIER);
1642 MessageKind.INVALID_SYNC_MODIFIER);
1643 } 1618 }
1644 } 1619 }
1645 listener.handleAsyncModifier(async, star); 1620 listener.handleAsyncModifier(async, star);
1646 return token; 1621 return token;
1647 } 1622 }
1648 1623
1649 Token parseStatement(Token token) { 1624 Token parseStatement(Token token) {
1650 final value = token.stringValue; 1625 final value = token.stringValue;
1651 if (identical(token.kind, IDENTIFIER_TOKEN)) { 1626 if (identical(token.kind, IDENTIFIER_TOKEN)) {
1652 return parseExpressionStatementOrDeclaration(token); 1627 return parseExpressionStatementOrDeclaration(token);
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
1708 Token starToken; 1683 Token starToken;
1709 if (optional('*', token)) { 1684 if (optional('*', token)) {
1710 starToken = token; 1685 starToken = token;
1711 token = token.next; 1686 token = token.next;
1712 } 1687 }
1713 token = parseExpression(token); 1688 token = parseExpression(token);
1714 listener.endYieldStatement(begin, starToken, token); 1689 listener.endYieldStatement(begin, starToken, token);
1715 return expectSemicolon(token); 1690 return expectSemicolon(token);
1716 } 1691 }
1717 1692
1718
1719 Token parseReturnStatement(Token token) { 1693 Token parseReturnStatement(Token token) {
1720 Token begin = token; 1694 Token begin = token;
1721 listener.beginReturnStatement(begin); 1695 listener.beginReturnStatement(begin);
1722 assert(identical('return', token.stringValue)); 1696 assert(identical('return', token.stringValue));
1723 token = token.next; 1697 token = token.next;
1724 if (optional(';', token)) { 1698 if (optional(';', token)) {
1725 listener.endReturnStatement(false, begin, token); 1699 listener.endReturnStatement(false, begin, token);
1726 } else { 1700 } else {
1727 token = parseExpression(token); 1701 token = parseExpression(token);
1728 listener.endReturnStatement(true, begin, token); 1702 listener.endReturnStatement(true, begin, token);
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
1863 assert(optional('?', token)); 1837 assert(optional('?', token));
1864 Token question = token; 1838 Token question = token;
1865 token = parseExpressionWithoutCascade(token.next); 1839 token = parseExpressionWithoutCascade(token.next);
1866 Token colon = token; 1840 Token colon = token;
1867 token = expect(':', token); 1841 token = expect(':', token);
1868 token = parseExpressionWithoutCascade(token); 1842 token = parseExpressionWithoutCascade(token);
1869 listener.handleConditionalExpression(question, colon); 1843 listener.handleConditionalExpression(question, colon);
1870 return token; 1844 return token;
1871 } 1845 }
1872 1846
1873 Token parsePrecedenceExpression(Token token, int precedence, 1847 Token parsePrecedenceExpression(
1874 bool allowCascades) { 1848 Token token, int precedence, bool allowCascades) {
1875 assert(precedence >= 1); 1849 assert(precedence >= 1);
1876 assert(precedence <= POSTFIX_PRECEDENCE); 1850 assert(precedence <= POSTFIX_PRECEDENCE);
1877 token = parseUnaryExpression(token, allowCascades); 1851 token = parseUnaryExpression(token, allowCascades);
1878 PrecedenceInfo info = token.info; 1852 PrecedenceInfo info = token.info;
1879 int tokenLevel = info.precedence; 1853 int tokenLevel = info.precedence;
1880 for (int level = tokenLevel; level >= precedence; --level) { 1854 for (int level = tokenLevel; level >= precedence; --level) {
1881 while (identical(tokenLevel, level)) { 1855 while (identical(tokenLevel, level)) {
1882 Token operator = token; 1856 Token operator = token;
1883 if (identical(tokenLevel, CASCADE_PRECEDENCE)) { 1857 if (identical(tokenLevel, CASCADE_PRECEDENCE)) {
1884 if (!allowCascades) { 1858 if (!allowCascades) {
1885 return token; 1859 return token;
1886 } 1860 }
1887 token = parseCascadeExpression(token); 1861 token = parseCascadeExpression(token);
1888 } else if (identical(tokenLevel, ASSIGNMENT_PRECEDENCE)) { 1862 } else if (identical(tokenLevel, ASSIGNMENT_PRECEDENCE)) {
1889 // Right associative, so we recurse at the same precedence 1863 // Right associative, so we recurse at the same precedence
1890 // level. 1864 // level.
1891 token = parsePrecedenceExpression(token.next, level, allowCascades); 1865 token = parsePrecedenceExpression(token.next, level, allowCascades);
1892 listener.handleAssignmentExpression(operator); 1866 listener.handleAssignmentExpression(operator);
1893 } else if (identical(tokenLevel, POSTFIX_PRECEDENCE)) { 1867 } else if (identical(tokenLevel, POSTFIX_PRECEDENCE)) {
1894 if (identical(info, PERIOD_INFO) || 1868 if (identical(info, PERIOD_INFO) ||
1895 identical(info, QUESTION_PERIOD_INFO)) { 1869 identical(info, QUESTION_PERIOD_INFO)) {
1896 // Left associative, so we recurse at the next higher 1870 // Left associative, so we recurse at the next higher
1897 // precedence level. However, POSTFIX_PRECEDENCE is the 1871 // precedence level. However, POSTFIX_PRECEDENCE is the
1898 // highest level, so we just call parseUnaryExpression 1872 // highest level, so we just call parseUnaryExpression
1899 // directly. 1873 // directly.
1900 token = parseUnaryExpression(token.next, allowCascades); 1874 token = parseUnaryExpression(token.next, allowCascades);
1901 listener.handleBinaryExpression(operator); 1875 listener.handleBinaryExpression(operator);
1902 } else if ((identical(info, OPEN_PAREN_INFO)) || 1876 } else if ((identical(info, OPEN_PAREN_INFO)) ||
1903 (identical(info, OPEN_SQUARE_BRACKET_INFO))) { 1877 (identical(info, OPEN_SQUARE_BRACKET_INFO))) {
1904 token = parseArgumentOrIndexStar(token); 1878 token = parseArgumentOrIndexStar(token);
1905 } else if ((identical(info, PLUS_PLUS_INFO)) || 1879 } else if ((identical(info, PLUS_PLUS_INFO)) ||
1906 (identical(info, MINUS_MINUS_INFO))) { 1880 (identical(info, MINUS_MINUS_INFO))) {
1907 listener.handleUnaryPostfixAssignmentExpression(token); 1881 listener.handleUnaryPostfixAssignmentExpression(token);
1908 token = token.next; 1882 token = token.next;
1909 } else { 1883 } else {
1910 token = listener.unexpected(token); 1884 token = listener.unexpected(token);
1911 } 1885 }
1912 } else if (identical(info, IS_INFO)) { 1886 } else if (identical(info, IS_INFO)) {
1913 token = parseIsOperatorRest(token); 1887 token = parseIsOperatorRest(token);
1914 } else if (identical(info, AS_INFO)) { 1888 } else if (identical(info, AS_INFO)) {
1915 token = parseAsOperatorRest(token); 1889 token = parseAsOperatorRest(token);
1916 } else if (identical(info, QUESTION_INFO)) { 1890 } else if (identical(info, QUESTION_INFO)) {
1917 token = parseConditionalExpressionRest(token); 1891 token = parseConditionalExpressionRest(token);
1918 } else { 1892 } else {
1919 // Left associative, so we recurse at the next higher 1893 // Left associative, so we recurse at the next higher
1920 // precedence level. 1894 // precedence level.
1921 token = parsePrecedenceExpression(token.next, level + 1, 1895 token =
1922 allowCascades); 1896 parsePrecedenceExpression(token.next, level + 1, allowCascades);
1923 listener.handleBinaryExpression(operator); 1897 listener.handleBinaryExpression(operator);
1924 } 1898 }
1925 info = token.info; 1899 info = token.info;
1926 tokenLevel = info.precedence; 1900 tokenLevel = info.precedence;
1927 if (level == EQUALITY_PRECEDENCE || level == RELATIONAL_PRECEDENCE) { 1901 if (level == EQUALITY_PRECEDENCE || level == RELATIONAL_PRECEDENCE) {
1928 // We don't allow (a == b == c) or (a < b < c). 1902 // We don't allow (a == b == c) or (a < b < c).
1929 // Continue the outer loop if we have matched one equality or 1903 // Continue the outer loop if we have matched one equality or
1930 // relational operator. 1904 // relational operator.
1931 break; 1905 break;
1932 } 1906 }
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1971 Token parseUnaryExpression(Token token, bool allowCascades) { 1945 Token parseUnaryExpression(Token token, bool allowCascades) {
1972 String value = token.stringValue; 1946 String value = token.stringValue;
1973 // Prefix: 1947 // Prefix:
1974 if (asyncAwaitKeywordsEnabled && optional('await', token)) { 1948 if (asyncAwaitKeywordsEnabled && optional('await', token)) {
1975 return parseAwaitExpression(token, allowCascades); 1949 return parseAwaitExpression(token, allowCascades);
1976 } else if (identical(value, '+')) { 1950 } else if (identical(value, '+')) {
1977 // Dart no longer allows prefix-plus. 1951 // Dart no longer allows prefix-plus.
1978 listener.reportError(token, MessageKind.UNSUPPORTED_PREFIX_PLUS); 1952 listener.reportError(token, MessageKind.UNSUPPORTED_PREFIX_PLUS);
1979 return parseUnaryExpression(token.next, allowCascades); 1953 return parseUnaryExpression(token.next, allowCascades);
1980 } else if ((identical(value, '!')) || 1954 } else if ((identical(value, '!')) ||
1981 (identical(value, '-')) || 1955 (identical(value, '-')) ||
1982 (identical(value, '~'))) { 1956 (identical(value, '~'))) {
1983 Token operator = token; 1957 Token operator = token;
1984 // Right associative, so we recurse at the same precedence 1958 // Right associative, so we recurse at the same precedence
1985 // level. 1959 // level.
1986 token = parsePrecedenceExpression(token.next, POSTFIX_PRECEDENCE, 1960 token = parsePrecedenceExpression(
1987 allowCascades); 1961 token.next, POSTFIX_PRECEDENCE, allowCascades);
1988 listener.handleUnaryPrefixExpression(operator); 1962 listener.handleUnaryPrefixExpression(operator);
1989 } else if ((identical(value, '++')) || identical(value, '--')) { 1963 } else if ((identical(value, '++')) || identical(value, '--')) {
1990 // TODO(ahe): Validate this is used correctly. 1964 // TODO(ahe): Validate this is used correctly.
1991 Token operator = token; 1965 Token operator = token;
1992 // Right associative, so we recurse at the same precedence 1966 // Right associative, so we recurse at the same precedence
1993 // level. 1967 // level.
1994 token = parsePrecedenceExpression(token.next, POSTFIX_PRECEDENCE, 1968 token = parsePrecedenceExpression(
1995 allowCascades); 1969 token.next, POSTFIX_PRECEDENCE, allowCascades);
1996 listener.handleUnaryPrefixAssignmentExpression(operator); 1970 listener.handleUnaryPrefixAssignmentExpression(operator);
1997 } else { 1971 } else {
1998 token = parsePrimary(token); 1972 token = parsePrimary(token);
1999 } 1973 }
2000 return token; 1974 return token;
2001 } 1975 }
2002 1976
2003 Token parseArgumentOrIndexStar(Token token) { 1977 Token parseArgumentOrIndexStar(Token token) {
2004 while (true) { 1978 while (true) {
2005 if (optional('[', token)) { 1979 if (optional('[', token)) {
(...skipping 11 matching lines...) Expand all
2017 break; 1991 break;
2018 } 1992 }
2019 } 1993 }
2020 return token; 1994 return token;
2021 } 1995 }
2022 1996
2023 Token parsePrimary(Token token) { 1997 Token parsePrimary(Token token) {
2024 final kind = token.kind; 1998 final kind = token.kind;
2025 if (kind == IDENTIFIER_TOKEN) { 1999 if (kind == IDENTIFIER_TOKEN) {
2026 return parseSendOrFunctionLiteral(token); 2000 return parseSendOrFunctionLiteral(token);
2027 } else if (kind == INT_TOKEN 2001 } else if (kind == INT_TOKEN || kind == HEXADECIMAL_TOKEN) {
2028 || kind == HEXADECIMAL_TOKEN) {
2029 return parseLiteralInt(token); 2002 return parseLiteralInt(token);
2030 } else if (kind == DOUBLE_TOKEN) { 2003 } else if (kind == DOUBLE_TOKEN) {
2031 return parseLiteralDouble(token); 2004 return parseLiteralDouble(token);
2032 } else if (kind == STRING_TOKEN) { 2005 } else if (kind == STRING_TOKEN) {
2033 return parseLiteralString(token); 2006 return parseLiteralString(token);
2034 } else if (kind == HASH_TOKEN) { 2007 } else if (kind == HASH_TOKEN) {
2035 return parseLiteralSymbol(token); 2008 return parseLiteralSymbol(token);
2036 } else if (kind == KEYWORD_TOKEN) { 2009 } else if (kind == KEYWORD_TOKEN) {
2037 final value = token.stringValue; 2010 final value = token.stringValue;
2038 if (value == 'true' || value == 'false') { 2011 if (value == 'true' || value == 'false') {
2039 return parseLiteralBool(token); 2012 return parseLiteralBool(token);
2040 } else if (value == 'null') { 2013 } else if (value == 'null') {
2041 return parseLiteralNull(token); 2014 return parseLiteralNull(token);
2042 } else if (value == 'this') { 2015 } else if (value == 'this') {
2043 return parseThisExpression(token); 2016 return parseThisExpression(token);
2044 } else if (value == 'super') { 2017 } else if (value == 'super') {
2045 return parseSuperExpression(token); 2018 return parseSuperExpression(token);
2046 } else if (value == 'new') { 2019 } else if (value == 'new') {
2047 return parseNewExpression(token); 2020 return parseNewExpression(token);
2048 } else if (value == 'const') { 2021 } else if (value == 'const') {
2049 return parseConstExpression(token); 2022 return parseConstExpression(token);
2050 } else if (value == 'void') { 2023 } else if (value == 'void') {
2051 return parseFunctionExpression(token); 2024 return parseFunctionExpression(token);
2052 } else if (asyncAwaitKeywordsEnabled && 2025 } else if (asyncAwaitKeywordsEnabled &&
2053 (value == 'yield' || value == 'async')) { 2026 (value == 'yield' || value == 'async')) {
2054 return listener.expectedExpression(token); 2027 return listener.expectedExpression(token);
2055 } else if (token.isIdentifier()) { 2028 } else if (token.isIdentifier()) {
2056 return parseSendOrFunctionLiteral(token); 2029 return parseSendOrFunctionLiteral(token);
2057 } else { 2030 } else {
2058 return listener.expectedExpression(token); 2031 return listener.expectedExpression(token);
2059 } 2032 }
2060 } else if (kind == OPEN_PAREN_TOKEN) { 2033 } else if (kind == OPEN_PAREN_TOKEN) {
2061 return parseParenthesizedExpressionOrFunctionLiteral(token); 2034 return parseParenthesizedExpressionOrFunctionLiteral(token);
2062 } else if ((kind == LT_TOKEN) || 2035 } else if ((kind == LT_TOKEN) ||
2063 (kind == OPEN_SQUARE_BRACKET_TOKEN) || 2036 (kind == OPEN_SQUARE_BRACKET_TOKEN) ||
2064 (kind == OPEN_CURLY_BRACKET_TOKEN) || 2037 (kind == OPEN_CURLY_BRACKET_TOKEN) ||
2065 token.stringValue == '[]') { 2038 token.stringValue == '[]') {
2066 return parseLiteralListOrMap(token); 2039 return parseLiteralListOrMap(token);
2067 } else { 2040 } else {
2068 return listener.expectedExpression(token); 2041 return listener.expectedExpression(token);
2069 } 2042 }
2070 } 2043 }
2071 2044
2072 Token parseParenthesizedExpressionOrFunctionLiteral(Token token) { 2045 Token parseParenthesizedExpressionOrFunctionLiteral(Token token) {
2073 BeginGroupToken beginGroup = token; 2046 BeginGroupToken beginGroup = token;
2074 Token nextToken = beginGroup.endGroup.next; 2047 Token nextToken = beginGroup.endGroup.next;
2075 int kind = nextToken.kind; 2048 int kind = nextToken.kind;
2076 if (mayParseFunctionExpressions && 2049 if (mayParseFunctionExpressions &&
2077 (identical(kind, FUNCTION_TOKEN) || 2050 (identical(kind, FUNCTION_TOKEN) ||
2078 identical(kind, OPEN_CURLY_BRACKET_TOKEN) || 2051 identical(kind, OPEN_CURLY_BRACKET_TOKEN) ||
2079 (identical(kind, KEYWORD_TOKEN) && 2052 (identical(kind, KEYWORD_TOKEN) &&
2080 (nextToken.value == 'async' || nextToken.value == 'sync')))) { 2053 (nextToken.value == 'async' || nextToken.value == 'sync')))) {
2081 return parseUnnamedFunction(token); 2054 return parseUnnamedFunction(token);
2082 } else { 2055 } else {
2083 bool old = mayParseFunctionExpressions; 2056 bool old = mayParseFunctionExpressions;
2084 mayParseFunctionExpressions = true; 2057 mayParseFunctionExpressions = true;
2085 token = parseParenthesizedExpression(token); 2058 token = parseParenthesizedExpression(token);
2086 mayParseFunctionExpressions = old; 2059 mayParseFunctionExpressions = old;
2087 return token; 2060 return token;
2088 } 2061 }
2089 } 2062 }
2090 2063
(...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after
2409 2382
2410 Token parseVariablesDeclaration(Token token) { 2383 Token parseVariablesDeclaration(Token token) {
2411 return parseVariablesDeclarationMaybeSemicolon(token, true); 2384 return parseVariablesDeclarationMaybeSemicolon(token, true);
2412 } 2385 }
2413 2386
2414 Token parseVariablesDeclarationNoSemicolon(Token token) { 2387 Token parseVariablesDeclarationNoSemicolon(Token token) {
2415 // Only called when parsing a for loop, so this is for parsing locals. 2388 // Only called when parsing a for loop, so this is for parsing locals.
2416 return parseVariablesDeclarationMaybeSemicolon(token, false); 2389 return parseVariablesDeclarationMaybeSemicolon(token, false);
2417 } 2390 }
2418 2391
2419 Token parseVariablesDeclarationMaybeSemicolon(Token token, 2392 Token parseVariablesDeclarationMaybeSemicolon(
2420 bool endWithSemicolon) { 2393 Token token, bool endWithSemicolon) {
2421 int count = 1; 2394 int count = 1;
2422 listener.beginVariablesDeclaration(token); 2395 listener.beginVariablesDeclaration(token);
2423 token = parseModifiers(token); 2396 token = parseModifiers(token);
2424 token = parseTypeOpt(token); 2397 token = parseTypeOpt(token);
2425 token = parseOptionallyInitializedIdentifier(token); 2398 token = parseOptionallyInitializedIdentifier(token);
2426 while (optional(',', token)) { 2399 while (optional(',', token)) {
2427 token = parseOptionallyInitializedIdentifier(token.next); 2400 token = parseOptionallyInitializedIdentifier(token.next);
2428 ++count; 2401 ++count;
2429 } 2402 }
2430 if (endWithSemicolon) { 2403 if (endWithSemicolon) {
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
2561 ++statementCount; 2534 ++statementCount;
2562 } 2535 }
2563 listener.endBlock(statementCount, begin, token); 2536 listener.endBlock(statementCount, begin, token);
2564 return expect('}', token); 2537 return expect('}', token);
2565 } 2538 }
2566 2539
2567 Token parseAwaitExpression(Token token, bool allowCascades) { 2540 Token parseAwaitExpression(Token token, bool allowCascades) {
2568 Token awaitToken = token; 2541 Token awaitToken = token;
2569 listener.beginAwaitExpression(awaitToken); 2542 listener.beginAwaitExpression(awaitToken);
2570 token = expect('await', token); 2543 token = expect('await', token);
2571 token = parsePrecedenceExpression(token, POSTFIX_PRECEDENCE, 2544 token = parsePrecedenceExpression(token, POSTFIX_PRECEDENCE, allowCascades);
2572 allowCascades);
2573 listener.endAwaitExpression(awaitToken, token); 2545 listener.endAwaitExpression(awaitToken, token);
2574 return token; 2546 return token;
2575 } 2547 }
2576 2548
2577 Token parseThrowExpression(Token token, bool allowCascades) { 2549 Token parseThrowExpression(Token token, bool allowCascades) {
2578 Token throwToken = token; 2550 Token throwToken = token;
2579 listener.beginThrowExpression(throwToken); 2551 listener.beginThrowExpression(throwToken);
2580 token = expect('throw', token); 2552 token = expect('throw', token);
2581 token = allowCascades 2553 token = allowCascades
2582 ? parseExpression(token) 2554 ? parseExpression(token)
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
2725 ((identical(value, '}')) && (identical(token, peek)))) { 2697 ((identical(value, '}')) && (identical(token, peek)))) {
2726 // A label just before "}" will be handled as a statement error. 2698 // A label just before "}" will be handled as a statement error.
2727 break; 2699 break;
2728 } else { 2700 } else {
2729 token = parseStatement(token); 2701 token = parseStatement(token);
2730 } 2702 }
2731 statementCount++; 2703 statementCount++;
2732 peek = peekPastLabels(token); 2704 peek = peekPastLabels(token);
2733 } 2705 }
2734 listener.handleSwitchCase(labelCount, expressionCount, defaultKeyword, 2706 listener.handleSwitchCase(labelCount, expressionCount, defaultKeyword,
2735 statementCount, begin, token); 2707 statementCount, begin, token);
2736 return token; 2708 return token;
2737 } 2709 }
2738 2710
2739 Token parseBreakStatement(Token token) { 2711 Token parseBreakStatement(Token token) {
2740 assert(optional('break', token)); 2712 assert(optional('break', token));
2741 Token breakKeyword = token; 2713 Token breakKeyword = token;
2742 token = token.next; 2714 token = token.next;
2743 bool hasTarget = false; 2715 bool hasTarget = false;
2744 if (token.isIdentifier()) { 2716 if (token.isIdentifier()) {
2745 token = parseIdentifier(token); 2717 token = parseIdentifier(token);
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
2779 } 2751 }
2780 listener.handleContinueStatement(hasTarget, continueKeyword, token); 2752 listener.handleContinueStatement(hasTarget, continueKeyword, token);
2781 return expectSemicolon(token); 2753 return expectSemicolon(token);
2782 } 2754 }
2783 2755
2784 Token parseEmptyStatement(Token token) { 2756 Token parseEmptyStatement(Token token) {
2785 listener.handleEmptyStatement(token); 2757 listener.handleEmptyStatement(token);
2786 return expectSemicolon(token); 2758 return expectSemicolon(token);
2787 } 2759 }
2788 } 2760 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/parser/node_listener.dart ('k') | pkg/compiler/lib/src/parser/parser_task.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698