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 // 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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 } |
OLD | NEW |