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

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

Powered by Google App Engine
This is Rietveld 408576698