Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 part of scanner; | 5 part of scanner; |
| 6 | 6 |
| 7 /** | 7 /** |
| 8 * An event generating parser of Dart programs. This parser expects | 8 * An event generating parser of Dart programs. This parser expects |
| 9 * all tokens in a linked list (aka a token stream). | 9 * all tokens in a linked list (aka a token stream). |
| 10 * | 10 * |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 41 listener.endTopLevelDeclaration(token); | 41 listener.endTopLevelDeclaration(token); |
| 42 count++; | 42 count++; |
| 43 } | 43 } |
| 44 listener.endCompilationUnit(count, token); | 44 listener.endCompilationUnit(count, token); |
| 45 return token; | 45 return token; |
| 46 } | 46 } |
| 47 | 47 |
| 48 Token parseTopLevelDeclaration(Token token) { | 48 Token parseTopLevelDeclaration(Token token) { |
| 49 token = parseMetadataStar(token); | 49 token = parseMetadataStar(token); |
| 50 final String value = token.stringValue; | 50 final String value = token.stringValue; |
| 51 if ((identical(value, 'abstract')) || (identical(value, 'class'))) { | 51 if ((identical(value, 'abstract') && optional('class', token.next)) |
| 52 || identical(value, 'class')) { | |
| 52 return parseClass(token); | 53 return parseClass(token); |
| 53 } else if (identical(value, 'typedef')) { | 54 } else if (identical(value, 'typedef')) { |
| 54 return parseTypedef(token); | 55 return parseTypedef(token); |
| 55 } else if (identical(value, 'library')) { | 56 } else if (identical(value, 'library')) { |
| 56 return parseLibraryName(token); | 57 return parseLibraryName(token); |
| 57 } else if (identical(value, 'import')) { | 58 } else if (identical(value, 'import')) { |
| 58 return parseImport(token); | 59 return parseImport(token); |
| 59 } else if (identical(value, 'export')) { | 60 } else if (identical(value, 'export')) { |
| 60 return parseExport(token); | 61 return parseExport(token); |
| 61 } else if (identical(value, 'part')) { | 62 } else if (identical(value, 'part')) { |
| (...skipping 575 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 637 isField = true; | 638 isField = true; |
| 638 } | 639 } |
| 639 break; | 640 break; |
| 640 } else { | 641 } else { |
| 641 token = listener.unexpected(token); | 642 token = listener.unexpected(token); |
| 642 if (identical(token.kind, EOF_TOKEN)) return token; | 643 if (identical(token.kind, EOF_TOKEN)) return token; |
| 643 } | 644 } |
| 644 } | 645 } |
| 645 var modifiers = identifiers.reverse(); | 646 var modifiers = identifiers.reverse(); |
| 646 return isField | 647 return isField |
| 647 ? parseTopLevelFields(start, modifiers, type, getOrSet, name) | 648 ? parseFields(start, modifiers, type, getOrSet, name, true) |
| 648 : parseTopLevelMethod(start, modifiers, type, getOrSet, name); | 649 : parseTopLevelMethod(start, modifiers, type, getOrSet, name); |
| 649 } | 650 } |
| 650 | 651 |
| 651 Token parseTopLevelFields(Token start, | 652 bool isVarFinalOrConst(Token token) { |
| 652 Link<Token> modifiers, | 653 String value = token.stringValue; |
| 653 Token type, | 654 return identical('var', value) |
| 654 Token getOrSet, | 655 || identical('final', value) |
| 655 Token name) { | 656 || identical('const', value); |
| 657 } | |
| 658 | |
| 659 Token expectVarFinalOrConst(Link<Token> modifiers, | |
| 660 bool hasType, | |
| 661 bool allowStatic) { | |
| 662 int modifierCount = 0; | |
| 663 Token staticModifier; | |
| 664 if (allowStatic && !modifiers.isEmpty | |
| 665 && optional('static', modifiers.head)) { | |
| 666 staticModifier = modifiers.head; | |
| 667 modifierCount++; | |
| 668 parseModifier(staticModifier); | |
| 669 modifiers = modifiers.tail; | |
| 670 } | |
| 671 if (modifiers.isEmpty) { | |
| 672 listener.handleModifiers(modifierCount); | |
| 673 return null; | |
| 674 } | |
| 675 if (modifiers.tail.isEmpty) { | |
| 676 Token modifier = modifiers.head; | |
| 677 if (isVarFinalOrConst(modifier)) { | |
| 678 modifierCount++; | |
| 679 parseModifier(modifier); | |
| 680 listener.handleModifiers(modifierCount); | |
| 681 return modifier; | |
|
Johnni Winther
2013/09/02 11:02:08
Add a comment that the caller checks for 'var Type
ahe
2013/09/02 17:49:59
Done.
| |
| 682 } | |
| 683 } | |
| 684 | |
| 685 // Slow case to report errors. | |
| 686 List<Token> modifierList = modifiers.toList(); | |
| 687 Token varFinalOrConst = | |
| 688 modifierList.firstWhere(isVarFinalOrConst, orElse: () => null); | |
| 689 if (allowStatic && staticModifier == null) { | |
| 690 staticModifier = | |
| 691 modifierList.firstWhere( | |
| 692 (modifier) => optional('static', modifier), orElse: () => null); | |
| 693 if (staticModifier != null) { | |
| 694 modifierCount++; | |
| 695 parseModifier(staticModifier); | |
| 696 modifierList.remove(staticModifier); | |
| 697 } | |
| 698 } | |
| 699 bool hasTypeOrModifier = hasType; | |
| 700 if (varFinalOrConst != null) { | |
| 701 parseModifier(varFinalOrConst); | |
| 702 modifierCount++; | |
| 703 hasTypeOrModifier = true; | |
| 704 modifierList.remove(varFinalOrConst); | |
| 705 } | |
| 706 listener.handleModifiers(modifierCount); | |
| 707 var kind = hasTypeOrModifier | |
| 708 ? MessageKind.EXTRANEOUS_MODIFIER | |
| 709 : MessageKind.EXTRANEOUS_MODIFIER_REPLACE; | |
| 710 for (Token modifier in modifierList) { | |
| 711 listener.reportError(modifier, kind, {'modifier': modifier}); | |
| 712 } | |
| 713 return null; | |
| 714 } | |
| 715 | |
| 716 Token parseFields(Token start, | |
| 717 Link<Token> modifiers, | |
| 718 Token type, | |
| 719 Token getOrSet, | |
| 720 Token name, | |
| 721 bool isTopLevel) { | |
| 722 bool hasType = type != null; | |
| 723 Token varFinalOrConst = | |
| 724 expectVarFinalOrConst(modifiers, hasType, !isTopLevel); | |
| 725 bool isVar = false; | |
| 726 bool hasModifier = false; | |
| 727 if (varFinalOrConst != null) { | |
| 728 hasModifier = true; | |
| 729 isVar = optional('var', varFinalOrConst); | |
| 730 } | |
| 731 | |
| 656 if (getOrSet != null) { | 732 if (getOrSet != null) { |
| 657 // TODO(ahe): Enable this error: | 733 var kind = (hasModifier || hasType) |
| 658 // listener.recoverableError("unexpected", token: getOrSet); | 734 ? MessageKind.EXTRANEOUS_MODIFIER |
| 735 : MessageKind.EXTRANEOUS_MODIFIER_REPLACE; | |
| 736 listener.reportError(getOrSet, kind, {'modifier': getOrSet}); | |
| 659 } | 737 } |
| 660 parseModifierList(modifiers); | 738 |
| 661 if (type == null) { | 739 if (!hasType) { |
| 662 listener.handleNoType(name); | 740 listener.handleNoType(name); |
| 741 } else if (optional('void', type)) { | |
| 742 listener.handleNoType(name); | |
| 743 // TODO(ahe): This error is reported twice, second time is from | |
| 744 // [parseVariablesDeclarationMaybeSemicolon] via | |
| 745 // [PartialFieldListElement.parseNode]. | |
| 746 listener.reportError(type, MessageKind.VOID_NOT_ALLOWED); | |
| 663 } else { | 747 } else { |
| 664 // TODO(ahe): Report recoverable error on 'void'. | 748 parseType(type); |
| 665 parseReturnTypeOpt(type); | 749 if (isVar) { |
| 750 listener.reportError( | |
| 751 modifiers.head, MessageKind.EXTRANEOUS_MODIFIER, | |
| 752 {'modifier': modifiers.head}); | |
| 753 } | |
| 666 } | 754 } |
| 755 | |
| 667 Token token = parseIdentifier(name); | 756 Token token = parseIdentifier(name); |
| 668 | 757 |
| 669 int fieldCount = 1; | 758 int fieldCount = 1; |
| 670 token = parseVariableInitializerOpt(token); | 759 token = parseVariableInitializerOpt(token); |
| 671 while (optional(',', token)) { | 760 while (optional(',', token)) { |
| 672 token = parseIdentifier(token.next); | 761 token = parseIdentifier(token.next); |
| 673 token = parseVariableInitializerOpt(token); | 762 token = parseVariableInitializerOpt(token); |
| 674 ++fieldCount; | 763 ++fieldCount; |
| 675 } | 764 } |
| 676 expectSemicolon(token); | 765 expectSemicolon(token); |
| 677 listener.endTopLevelFields(fieldCount, start, token); | 766 if (isTopLevel) { |
| 767 listener.endTopLevelFields(fieldCount, start, token); | |
| 768 } else { | |
| 769 listener.endFields(fieldCount, start, token); | |
| 770 } | |
| 678 return token.next; | 771 return token.next; |
| 679 } | 772 } |
| 680 | 773 |
| 681 Token parseTopLevelMethod(Token start, | 774 Token parseTopLevelMethod(Token start, |
| 682 Link<Token> modifiers, | 775 Link<Token> modifiers, |
| 683 Token type, | 776 Token type, |
| 684 Token getOrSet, | 777 Token getOrSet, |
| 685 Token name) { | 778 Token name) { |
| 686 parseModifierList(modifiers); | 779 Token externalModifier; |
| 780 for (Token modifier in modifiers) { | |
| 781 if (externalModifier == null && optional('external', modifier)) { | |
| 782 externalModifier = modifier; | |
| 783 } else { | |
| 784 listener.reportError( | |
| 785 modifier, MessageKind.EXTRANEOUS_MODIFIER, {'modifier': modifier}); | |
| 786 } | |
| 787 } | |
| 788 if (externalModifier != null) { | |
| 789 parseModifier(externalModifier); | |
| 790 listener.handleModifiers(1); | |
| 791 } else { | |
| 792 listener.handleModifiers(0); | |
| 793 } | |
| 794 | |
| 687 if (type == null) { | 795 if (type == null) { |
| 688 listener.handleNoType(name); | 796 listener.handleNoType(name); |
| 689 } else { | 797 } else { |
| 690 parseReturnTypeOpt(type); | 798 parseReturnTypeOpt(type); |
| 691 } | 799 } |
| 692 Token token = parseIdentifier(name); | 800 Token token = parseIdentifier(name); |
| 693 | 801 |
| 694 token = parseFormalParametersOpt(token); | 802 token = parseFormalParametersOpt(token); |
| 695 token = parseFunctionBody(token, false); | 803 token = parseFunctionBody(token, false, externalModifier != null); |
| 696 listener.endTopLevelMethod(start, getOrSet, token); | 804 listener.endTopLevelMethod(start, getOrSet, token); |
| 697 return token.next; | 805 return token.next; |
| 698 } | 806 } |
| 699 | 807 |
| 700 Link<Token> findMemberName(Token token) { | 808 Link<Token> findMemberName(Token token) { |
| 701 Token start = token; | 809 Token start = token; |
| 702 Link<Token> identifiers = const Link<Token>(); | 810 Link<Token> identifiers = const Link<Token>(); |
| 703 while (!identical(token.kind, EOF_TOKEN)) { | 811 while (!identical(token.kind, EOF_TOKEN)) { |
| 704 String value = token.stringValue; | 812 String value = token.stringValue; |
| 705 if ((identical(value, '(')) || (identical(value, '{')) | 813 if ((identical(value, '(')) || (identical(value, '{')) |
| (...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 954 if (identical(token.kind, EOF_TOKEN)) { | 1062 if (identical(token.kind, EOF_TOKEN)) { |
| 955 // TODO(ahe): This is a hack, see parseTopLevelMember. | 1063 // TODO(ahe): This is a hack, see parseTopLevelMember. |
| 956 listener.endFields(1, start, token); | 1064 listener.endFields(1, start, token); |
| 957 return token; | 1065 return token; |
| 958 } | 1066 } |
| 959 } | 1067 } |
| 960 } | 1068 } |
| 961 | 1069 |
| 962 var modifiers = identifiers.reverse(); | 1070 var modifiers = identifiers.reverse(); |
| 963 return isField | 1071 return isField |
| 964 ? parseFields(start, modifiers, type, getOrSet, name) | 1072 ? parseFields(start, modifiers, type, getOrSet, name, false) |
| 965 : parseMethod(start, modifiers, type, getOrSet, name); | 1073 : parseMethod(start, modifiers, type, getOrSet, name); |
| 966 | 1074 |
| 967 } | 1075 } |
| 968 | 1076 |
| 969 Token parseFields(Token start, | |
| 970 Link<Token> modifiers, | |
| 971 Token type, | |
| 972 Token getOrSet, | |
| 973 Token name) { | |
| 974 parseModifierList(modifiers); | |
| 975 if (type == null) { | |
| 976 listener.handleNoType(name); | |
| 977 } else { | |
| 978 parseReturnTypeOpt(type); | |
| 979 } | |
| 980 | |
| 981 Token token = parseIdentifier(name); | |
| 982 | |
| 983 int fieldCount = 1; | |
| 984 token = parseVariableInitializerOpt(token); | |
| 985 if (getOrSet != null) { | |
| 986 listener.recoverableError("unexpected", token: getOrSet); | |
| 987 } | |
| 988 while (optional(',', token)) { | |
| 989 // TODO(ahe): Count these. | |
| 990 token = parseIdentifier(token.next); | |
| 991 token = parseVariableInitializerOpt(token); | |
| 992 ++fieldCount; | |
| 993 } | |
| 994 expectSemicolon(token); | |
| 995 listener.endFields(fieldCount, start, token); | |
| 996 return token.next; | |
| 997 } | |
| 998 | |
| 999 Token parseMethod(Token start, | 1077 Token parseMethod(Token start, |
| 1000 Link<Token> modifiers, | 1078 Link<Token> modifiers, |
| 1001 Token type, | 1079 Token type, |
| 1002 Token getOrSet, | 1080 Token getOrSet, |
| 1003 Token name) { | 1081 Token name) { |
| 1082 Token externalModifier; | |
| 1083 Token staticModifier; | |
| 1084 Token constModifier; | |
| 1085 int modifierCount = 0; | |
| 1086 int allowedModifierCount = 1; | |
| 1087 for (Token modifier in modifiers) { | |
| 1088 if (externalModifier == null && optional('external', modifier)) { | |
| 1089 modifierCount++; | |
| 1090 externalModifier = modifier; | |
| 1091 if (modifierCount != allowedModifierCount) { | |
| 1092 listener.reportError( | |
| 1093 modifier, | |
| 1094 MessageKind.EXTRANEOUS_MODIFIER, {'modifier': modifier}); | |
| 1095 } | |
| 1096 allowedModifierCount++; | |
| 1097 } else if (staticModifier == null && optional('static', modifier)) { | |
| 1098 modifierCount++; | |
| 1099 staticModifier = modifier; | |
| 1100 if (modifierCount != allowedModifierCount) { | |
| 1101 listener.reportError( | |
| 1102 modifier, | |
| 1103 MessageKind.EXTRANEOUS_MODIFIER, {'modifier': modifier}); | |
| 1104 } | |
| 1105 } else if (constModifier == null && optional('const', modifier)) { | |
| 1106 modifierCount++; | |
| 1107 constModifier = modifier; | |
| 1108 if (modifierCount != allowedModifierCount) { | |
| 1109 listener.reportError( | |
| 1110 modifier, | |
| 1111 MessageKind.EXTRANEOUS_MODIFIER, {'modifier': modifier}); | |
| 1112 } | |
| 1113 } else { | |
| 1114 listener.reportError( | |
| 1115 modifier, MessageKind.EXTRANEOUS_MODIFIER, {'modifier': modifier}); | |
| 1116 } | |
| 1117 } | |
| 1004 parseModifierList(modifiers); | 1118 parseModifierList(modifiers); |
| 1119 | |
| 1005 if (type == null) { | 1120 if (type == null) { |
| 1006 listener.handleNoType(name); | 1121 listener.handleNoType(name); |
| 1007 } else { | 1122 } else { |
| 1008 parseReturnTypeOpt(type); | 1123 parseReturnTypeOpt(type); |
| 1009 } | 1124 } |
| 1010 Token token; | 1125 Token token; |
| 1011 if (optional('operator', name)) { | 1126 if (optional('operator', name)) { |
| 1012 token = parseOperatorName(name); | 1127 token = parseOperatorName(name); |
| 1128 if (staticModifier != null) { | |
| 1129 // TODO(ahe): Consider a more specific error message. | |
| 1130 listener.reportError( | |
| 1131 staticModifier, MessageKind.EXTRANEOUS_MODIFIER, | |
| 1132 {'modifier': staticModifier}); | |
| 1133 } | |
| 1013 } else { | 1134 } else { |
| 1014 token = parseIdentifier(name); | 1135 token = parseIdentifier(name); |
| 1015 } | 1136 } |
| 1016 | 1137 |
| 1017 token = parseQualifiedRestOpt(token); | 1138 token = parseQualifiedRestOpt(token); |
| 1018 token = parseFormalParametersOpt(token); | 1139 token = parseFormalParametersOpt(token); |
| 1019 token = parseInitializersOpt(token); | 1140 token = parseInitializersOpt(token); |
| 1020 if (optional('=', token)) { | 1141 if (optional('=', token)) { |
| 1021 token = parseRedirectingFactoryBody(token); | 1142 token = parseRedirectingFactoryBody(token); |
| 1022 } else { | 1143 } else { |
| 1023 token = parseFunctionBody(token, false); | 1144 token = parseFunctionBody( |
| 1145 token, false, staticModifier == null || externalModifier != null); | |
| 1024 } | 1146 } |
| 1025 listener.endMethod(getOrSet, start, token); | 1147 listener.endMethod(getOrSet, start, token); |
| 1026 return token.next; | 1148 return token.next; |
| 1027 } | 1149 } |
| 1028 | 1150 |
| 1029 Token parseFactoryMethod(Token token) { | 1151 Token parseFactoryMethod(Token token) { |
| 1030 assert(isFactoryDeclaration(token)); | 1152 assert(isFactoryDeclaration(token)); |
| 1031 Token start = token; | 1153 Token start = token; |
| 1032 if (identical(token.stringValue, 'external')) token = token.next; | 1154 Token externalModifier; |
| 1155 if (identical(token.stringValue, 'external')) { | |
| 1156 externalModifier = token; | |
| 1157 token = token.next; | |
| 1158 } | |
| 1033 Token constKeyword = null; | 1159 Token constKeyword = null; |
| 1034 if (optional('const', token)) { | 1160 if (optional('const', token)) { |
| 1035 constKeyword = token; | 1161 constKeyword = token; |
| 1036 token = token.next; | 1162 token = token.next; |
| 1037 } | 1163 } |
| 1038 Token factoryKeyword = token; | 1164 Token factoryKeyword = token; |
| 1039 listener.beginFactoryMethod(factoryKeyword); | 1165 listener.beginFactoryMethod(factoryKeyword); |
| 1040 token = token.next; // Skip 'factory'. | 1166 token = token.next; // Skip 'factory'. |
| 1041 token = parseConstructorReference(token); | 1167 token = parseConstructorReference(token); |
| 1042 token = parseFormalParameters(token); | 1168 token = parseFormalParameters(token); |
| 1043 if (optional('=', token)) { | 1169 if (optional('=', token)) { |
| 1044 token = parseRedirectingFactoryBody(token); | 1170 token = parseRedirectingFactoryBody(token); |
| 1045 } else { | 1171 } else { |
| 1046 token = parseFunctionBody(token, false); | 1172 token = parseFunctionBody(token, false, externalModifier != null); |
| 1047 } | 1173 } |
| 1048 listener.endFactoryMethod(start, token); | 1174 listener.endFactoryMethod(start, token); |
| 1049 return token.next; | 1175 return token.next; |
| 1050 } | 1176 } |
| 1051 | 1177 |
| 1052 Token parseOperatorName(Token token) { | 1178 Token parseOperatorName(Token token) { |
| 1053 assert(optional('operator', token)); | 1179 assert(optional('operator', token)); |
| 1054 if (isUserDefinableOperator(token.next.stringValue)) { | 1180 if (isUserDefinableOperator(token.next.stringValue)) { |
| 1055 Token operator = token; | 1181 Token operator = token; |
| 1056 token = token.next; | 1182 token = token.next; |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 1079 token = parseIdentifier(token); | 1205 token = parseIdentifier(token); |
| 1080 } | 1206 } |
| 1081 } | 1207 } |
| 1082 token = parseQualifiedRestOpt(token); | 1208 token = parseQualifiedRestOpt(token); |
| 1083 listener.endFunctionName(token); | 1209 listener.endFunctionName(token); |
| 1084 token = parseFormalParametersOpt(token); | 1210 token = parseFormalParametersOpt(token); |
| 1085 token = parseInitializersOpt(token); | 1211 token = parseInitializersOpt(token); |
| 1086 if (optional('=', token)) { | 1212 if (optional('=', token)) { |
| 1087 token = parseRedirectingFactoryBody(token); | 1213 token = parseRedirectingFactoryBody(token); |
| 1088 } else { | 1214 } else { |
| 1089 token = parseFunctionBody(token, false); | 1215 token = parseFunctionBody(token, false, true); |
| 1090 } | 1216 } |
| 1091 listener.endFunction(getOrSet, token); | 1217 listener.endFunction(getOrSet, token); |
| 1092 return token.next; | 1218 return token.next; |
| 1093 } | 1219 } |
| 1094 | 1220 |
| 1095 Token parseUnamedFunction(Token token) { | 1221 Token parseUnamedFunction(Token token) { |
| 1096 listener.beginUnamedFunction(token); | 1222 listener.beginUnamedFunction(token); |
| 1097 token = parseFormalParameters(token); | 1223 token = parseFormalParameters(token); |
| 1098 bool isBlock = optional('{', token); | 1224 bool isBlock = optional('{', token); |
| 1099 token = parseFunctionBody(token, true); | 1225 token = parseFunctionBody(token, true, false); |
| 1100 listener.endUnamedFunction(token); | 1226 listener.endUnamedFunction(token); |
| 1101 return isBlock ? token.next : token; | 1227 return isBlock ? token.next : token; |
| 1102 } | 1228 } |
| 1103 | 1229 |
| 1104 Token parseFunctionDeclaration(Token token) { | 1230 Token parseFunctionDeclaration(Token token) { |
| 1105 listener.beginFunctionDeclaration(token); | 1231 listener.beginFunctionDeclaration(token); |
| 1106 token = parseFunction(token, null); | 1232 token = parseFunction(token, null); |
| 1107 listener.endFunctionDeclaration(token); | 1233 listener.endFunctionDeclaration(token); |
| 1108 return token; | 1234 return token; |
| 1109 } | 1235 } |
| 1110 | 1236 |
| 1111 Token parseFunctionExpression(Token token) { | 1237 Token parseFunctionExpression(Token token) { |
| 1112 listener.beginFunction(token); | 1238 listener.beginFunction(token); |
| 1113 listener.handleModifiers(0); | 1239 listener.handleModifiers(0); |
| 1114 token = parseReturnTypeOpt(token); | 1240 token = parseReturnTypeOpt(token); |
| 1115 listener.beginFunctionName(token); | 1241 listener.beginFunctionName(token); |
| 1116 token = parseIdentifier(token); | 1242 token = parseIdentifier(token); |
| 1117 listener.endFunctionName(token); | 1243 listener.endFunctionName(token); |
| 1118 token = parseFormalParameters(token); | 1244 token = parseFormalParameters(token); |
| 1119 listener.handleNoInitializers(); | 1245 listener.handleNoInitializers(); |
| 1120 bool isBlock = optional('{', token); | 1246 bool isBlock = optional('{', token); |
| 1121 token = parseFunctionBody(token, true); | 1247 token = parseFunctionBody(token, true, false); |
| 1122 listener.endFunction(null, token); | 1248 listener.endFunction(null, token); |
| 1123 return isBlock ? token.next : token; | 1249 return isBlock ? token.next : token; |
| 1124 } | 1250 } |
| 1125 | 1251 |
| 1126 Token parseConstructorReference(Token token) { | 1252 Token parseConstructorReference(Token token) { |
| 1127 Token start = token; | 1253 Token start = token; |
| 1128 listener.beginConstructorReference(start); | 1254 listener.beginConstructorReference(start); |
| 1129 token = parseIdentifier(token); | 1255 token = parseIdentifier(token); |
| 1130 token = parseQualifiedRestOpt(token); | 1256 token = parseQualifiedRestOpt(token); |
| 1131 token = parseTypeArgumentsOpt(token); | 1257 token = parseTypeArgumentsOpt(token); |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 1142 listener.beginRedirectingFactoryBody(token); | 1268 listener.beginRedirectingFactoryBody(token); |
| 1143 assert(optional('=', token)); | 1269 assert(optional('=', token)); |
| 1144 Token equals = token; | 1270 Token equals = token; |
| 1145 token = parseConstructorReference(token.next); | 1271 token = parseConstructorReference(token.next); |
| 1146 Token semicolon = token; | 1272 Token semicolon = token; |
| 1147 expectSemicolon(token); | 1273 expectSemicolon(token); |
| 1148 listener.endRedirectingFactoryBody(equals, semicolon); | 1274 listener.endRedirectingFactoryBody(equals, semicolon); |
| 1149 return token; | 1275 return token; |
| 1150 } | 1276 } |
| 1151 | 1277 |
| 1152 Token parseFunctionBody(Token token, bool isExpression) { | 1278 Token parseFunctionBody(Token token, bool isExpression, bool allowAbstract) { |
| 1153 if (optional(';', token)) { | 1279 if (optional(';', token)) { |
| 1280 if (!allowAbstract) { | |
| 1281 listener.reportError(token, MessageKind.BODY_EXPECTED); | |
| 1282 } | |
| 1154 listener.endFunctionBody(0, null, token); | 1283 listener.endFunctionBody(0, null, token); |
| 1155 return token; | 1284 return token; |
| 1156 } else if (optional('=>', token)) { | 1285 } else if (optional('=>', token)) { |
| 1157 Token begin = token; | 1286 Token begin = token; |
| 1158 token = parseExpression(token.next); | 1287 token = parseExpression(token.next); |
| 1159 if (!isExpression) { | 1288 if (!isExpression) { |
| 1160 expectSemicolon(token); | 1289 expectSemicolon(token); |
| 1161 listener.endReturnStatement(true, begin, token); | 1290 listener.endReturnStatement(true, begin, token); |
| 1162 } else { | 1291 } else { |
| 1163 listener.endReturnStatement(true, begin, null); | 1292 listener.endReturnStatement(true, begin, null); |
| (...skipping 711 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1875 listener.unexpected(token); | 2004 listener.unexpected(token); |
| 1876 } | 2005 } |
| 1877 return token; | 2006 return token; |
| 1878 } | 2007 } |
| 1879 | 2008 |
| 1880 Token parseVariablesDeclaration(Token token) { | 2009 Token parseVariablesDeclaration(Token token) { |
| 1881 return parseVariablesDeclarationMaybeSemicolon(token, true); | 2010 return parseVariablesDeclarationMaybeSemicolon(token, true); |
| 1882 } | 2011 } |
| 1883 | 2012 |
| 1884 Token parseVariablesDeclarationNoSemicolon(Token token) { | 2013 Token parseVariablesDeclarationNoSemicolon(Token token) { |
| 2014 // Only called when parsing a for loop, so this is for parsing locals. | |
| 1885 return parseVariablesDeclarationMaybeSemicolon(token, false); | 2015 return parseVariablesDeclarationMaybeSemicolon(token, false); |
| 1886 } | 2016 } |
| 1887 | 2017 |
| 1888 Token parseVariablesDeclarationMaybeSemicolon(Token token, | 2018 Token parseVariablesDeclarationMaybeSemicolon(Token token, |
| 1889 bool endWithSemicolon) { | 2019 bool endWithSemicolon) { |
| 1890 int count = 1; | 2020 int count = 1; |
| 1891 listener.beginVariablesDeclaration(token); | 2021 listener.beginVariablesDeclaration(token); |
| 1892 token = parseModifiers(token); | 2022 token = parseModifiers(token); |
| 1893 token = parseTypeOpt(token); | 2023 token = parseTypeOpt(token); |
| 1894 token = parseOptionallyInitializedIdentifier(token); | 2024 token = parseOptionallyInitializedIdentifier(token); |
| (...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2225 } | 2355 } |
| 2226 listener.handleContinueStatement(hasTarget, continueKeyword, token); | 2356 listener.handleContinueStatement(hasTarget, continueKeyword, token); |
| 2227 return expectSemicolon(token); | 2357 return expectSemicolon(token); |
| 2228 } | 2358 } |
| 2229 | 2359 |
| 2230 Token parseEmptyStatement(Token token) { | 2360 Token parseEmptyStatement(Token token) { |
| 2231 listener.handleEmptyStatement(token); | 2361 listener.handleEmptyStatement(token); |
| 2232 return expectSemicolon(token); | 2362 return expectSemicolon(token); |
| 2233 } | 2363 } |
| 2234 } | 2364 } |
| OLD | NEW |