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

Side by Side Diff: dart/sdk/lib/_internal/compiler/implementation/scanner/parser.dart

Issue 23606010: Fix various parser bugs related to modifiers of top-level and class members. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
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 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
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
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
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698