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 library fasta.parser.parser; | 5 library fasta.parser.parser; |
6 | 6 |
7 import '../scanner.dart' show ErrorToken; | 7 import '../scanner.dart' show ErrorToken; |
8 | 8 |
9 import '../scanner/recover.dart' show closeBraceFor, skipToEof; | 9 import '../scanner/recover.dart' show closeBraceFor, skipToEof; |
10 | 10 |
(...skipping 383 matching lines...) Loading... |
394 Token typedefKeyword = token; | 394 Token typedefKeyword = token; |
395 listener.beginFunctionTypeAlias(token); | 395 listener.beginFunctionTypeAlias(token); |
396 Token equals; | 396 Token equals; |
397 if (optional('=', peekAfterNominalType(token.next))) { | 397 if (optional('=', peekAfterNominalType(token.next))) { |
398 token = parseIdentifier(token.next, IdentifierContext.typedefDeclaration); | 398 token = parseIdentifier(token.next, IdentifierContext.typedefDeclaration); |
399 token = parseTypeVariablesOpt(token); | 399 token = parseTypeVariablesOpt(token); |
400 equals = token; | 400 equals = token; |
401 token = expect('=', token); | 401 token = expect('=', token); |
402 token = parseType(token); | 402 token = parseType(token); |
403 } else { | 403 } else { |
404 token = parseReturnTypeOpt(token.next); | 404 token = parseTypeOpt(token.next); |
405 token = parseIdentifier(token, IdentifierContext.typedefDeclaration); | 405 token = parseIdentifier(token, IdentifierContext.typedefDeclaration); |
406 token = parseTypeVariablesOpt(token); | 406 token = parseTypeVariablesOpt(token); |
407 token = parseFormalParameters(token); | 407 token = parseFormalParameters(token); |
408 } | 408 } |
409 listener.endFunctionTypeAlias(typedefKeyword, equals, token); | 409 listener.endFunctionTypeAlias(typedefKeyword, equals, token); |
410 return expect(';', token); | 410 return expect(';', token); |
411 } | 411 } |
412 | 412 |
413 Token parseMixinApplication(Token token) { | 413 Token parseMixinApplication(Token token) { |
414 listener.beginMixinApplication(token); | 414 listener.beginMixinApplication(token); |
415 token = parseType(token); | 415 token = parseType(token); |
416 token = expect('with', token); | 416 token = expect('with', token); |
417 token = parseTypeList(token); | 417 token = parseTypeList(token); |
418 listener.endMixinApplication(); | 418 listener.endMixinApplication(); |
419 return token; | 419 return token; |
420 } | 420 } |
421 | 421 |
422 Token parseReturnTypeOpt(Token token) { | |
423 if (identical(token.stringValue, 'void')) { | |
424 if (isGeneralizedFunctionType(token.next)) { | |
425 return parseType(token); | |
426 } else { | |
427 listener.handleVoidKeyword(token); | |
428 return token.next; | |
429 } | |
430 } else { | |
431 return parseTypeOpt(token); | |
432 } | |
433 } | |
434 | |
435 Token parseFormalParametersOpt(Token token) { | 422 Token parseFormalParametersOpt(Token token) { |
436 if (optional('(', token)) { | 423 if (optional('(', token)) { |
437 return parseFormalParameters(token); | 424 return parseFormalParameters(token); |
438 } else { | 425 } else { |
439 listener.handleNoFormalParameters(token); | 426 listener.handleNoFormalParameters(token); |
440 return token; | 427 return token; |
441 } | 428 } |
442 } | 429 } |
443 | 430 |
444 Token skipFormalParameters(Token token) { | 431 Token skipFormalParameters(Token token) { |
(...skipping 70 matching lines...) Loading... |
515 parseIdentifier(token, IdentifierContext.formalParameterDeclaration); | 502 parseIdentifier(token, IdentifierContext.formalParameterDeclaration); |
516 } else if (inFunctionType) { | 503 } else if (inFunctionType) { |
517 token = parseType(token); | 504 token = parseType(token); |
518 if (token.isIdentifier()) { | 505 if (token.isIdentifier()) { |
519 token = parseIdentifier( | 506 token = parseIdentifier( |
520 token, IdentifierContext.formalParameterDeclaration); | 507 token, IdentifierContext.formalParameterDeclaration); |
521 } else { | 508 } else { |
522 listener.handleNoName(token); | 509 listener.handleNoName(token); |
523 } | 510 } |
524 } else { | 511 } else { |
525 token = parseReturnTypeOpt(token); | 512 token = parseTypeOpt(token); |
526 if (optional('this', token)) { | 513 if (optional('this', token)) { |
527 thisKeyword = token; | 514 thisKeyword = token; |
528 token = expect('.', token.next); | 515 token = expect('.', token.next); |
529 token = parseIdentifier(token, IdentifierContext.fieldInitializer); | 516 token = parseIdentifier(token, IdentifierContext.fieldInitializer); |
530 } else { | 517 } else { |
531 token = parseIdentifier( | 518 token = parseIdentifier( |
532 token, IdentifierContext.formalParameterDeclaration); | 519 token, IdentifierContext.formalParameterDeclaration); |
533 } | 520 } |
534 } | 521 } |
535 | 522 |
(...skipping 394 matching lines...) Loading... |
930 (optional('<', token.next) || optional('(', token.next)); | 917 (optional('<', token.next) || optional('(', token.next)); |
931 } | 918 } |
932 | 919 |
933 Token parseType(Token token) { | 920 Token parseType(Token token) { |
934 Token begin = token; | 921 Token begin = token; |
935 if (isGeneralizedFunctionType(token)) { | 922 if (isGeneralizedFunctionType(token)) { |
936 // A function type without return type. | 923 // A function type without return type. |
937 // Push the non-existing return type first. The loop below will | 924 // Push the non-existing return type first. The loop below will |
938 // generate the full type. | 925 // generate the full type. |
939 listener.handleNoType(token); | 926 listener.handleNoType(token); |
940 } else if (identical(token.stringValue, 'void') && | |
941 isGeneralizedFunctionType(token.next)) { | |
942 listener.handleVoidKeyword(token); | |
943 token = token.next; | |
944 } else { | 927 } else { |
945 if (isValidTypeReference(token)) { | 928 if (isValidTypeReference(token)) { |
946 token = parseIdentifier(token, IdentifierContext.typeReference); | 929 token = parseIdentifier(token, IdentifierContext.typeReference); |
947 token = parseQualifiedRestOpt( | 930 token = parseQualifiedRestOpt( |
948 token, IdentifierContext.typeReferenceContinuation); | 931 token, IdentifierContext.typeReferenceContinuation); |
949 } else { | 932 } else { |
950 token = reportUnrecoverableError(token, ErrorKind.ExpectedType); | 933 token = reportUnrecoverableError(token, ErrorKind.ExpectedType); |
951 listener.handleInvalidTypeReference(token); | 934 listener.handleInvalidTypeReference(token); |
952 } | 935 } |
953 token = parseTypeArgumentsOpt(token); | 936 token = parseTypeArgumentsOpt(token); |
(...skipping 237 matching lines...) Loading... |
1191 | 1174 |
1192 if (getOrSet != null) { | 1175 if (getOrSet != null) { |
1193 var kind = (hasModifier || hasType) | 1176 var kind = (hasModifier || hasType) |
1194 ? ErrorKind.ExtraneousModifier | 1177 ? ErrorKind.ExtraneousModifier |
1195 : ErrorKind.ExtraneousModifierReplace; | 1178 : ErrorKind.ExtraneousModifierReplace; |
1196 reportRecoverableError(getOrSet, kind, {'modifier': getOrSet}); | 1179 reportRecoverableError(getOrSet, kind, {'modifier': getOrSet}); |
1197 } | 1180 } |
1198 | 1181 |
1199 if (!hasType) { | 1182 if (!hasType) { |
1200 listener.handleNoType(name); | 1183 listener.handleNoType(name); |
1201 } else if (optional('void', type) && | |
1202 !isGeneralizedFunctionType(type.next)) { | |
1203 listener.handleNoType(name); | |
1204 // TODO(ahe): This error is reported twice, second time is from | |
1205 // [parseVariablesDeclarationMaybeSemicolon] via | |
1206 // [PartialFieldListElement.parseNode]. | |
1207 reportRecoverableError(type, ErrorKind.InvalidVoid); | |
1208 } else { | 1184 } else { |
1209 parseType(type); | 1185 parseType(type); |
1210 if (isVar) { | 1186 if (isVar) { |
1211 reportRecoverableError(modifiers.head, ErrorKind.ExtraneousModifier, | 1187 reportRecoverableError(modifiers.head, ErrorKind.ExtraneousModifier, |
1212 {'modifier': modifiers.head}); | 1188 {'modifier': modifiers.head}); |
1213 } | 1189 } |
1214 } | 1190 } |
1215 | 1191 |
1216 IdentifierContext context = isTopLevel | 1192 IdentifierContext context = isTopLevel |
1217 ? IdentifierContext.topLevelVariableDeclaration | 1193 ? IdentifierContext.topLevelVariableDeclaration |
(...skipping 34 matching lines...) Loading... |
1252 if (externalModifier != null) { | 1228 if (externalModifier != null) { |
1253 parseModifier(externalModifier); | 1229 parseModifier(externalModifier); |
1254 listener.handleModifiers(1); | 1230 listener.handleModifiers(1); |
1255 } else { | 1231 } else { |
1256 listener.handleModifiers(0); | 1232 listener.handleModifiers(0); |
1257 } | 1233 } |
1258 | 1234 |
1259 if (type == null) { | 1235 if (type == null) { |
1260 listener.handleNoType(name); | 1236 listener.handleNoType(name); |
1261 } else { | 1237 } else { |
1262 parseReturnTypeOpt(type); | 1238 parseTypeOpt(type); |
1263 } | 1239 } |
1264 Token token = | 1240 Token token = |
1265 parseIdentifier(name, IdentifierContext.topLevelFunctionDeclaration); | 1241 parseIdentifier(name, IdentifierContext.topLevelFunctionDeclaration); |
1266 | 1242 |
1267 if (getOrSet == null) { | 1243 if (getOrSet == null) { |
1268 token = parseTypeVariablesOpt(token); | 1244 token = parseTypeVariablesOpt(token); |
1269 } else { | 1245 } else { |
1270 listener.handleNoTypeVariables(token); | 1246 listener.handleNoTypeVariables(token); |
1271 } | 1247 } |
1272 token = parseFormalParametersOpt(token); | 1248 token = parseFormalParametersOpt(token); |
(...skipping 323 matching lines...) Loading... |
1596 } | 1572 } |
1597 | 1573 |
1598 return peek; | 1574 return peek; |
1599 } | 1575 } |
1600 | 1576 |
1601 /** | 1577 /** |
1602 * If [token] is the start of a type, returns the token after that type. | 1578 * If [token] is the start of a type, returns the token after that type. |
1603 * If [token] is not the start of a type, null is returned. | 1579 * If [token] is not the start of a type, null is returned. |
1604 */ | 1580 */ |
1605 Token peekAfterIfType(Token token) { | 1581 Token peekAfterIfType(Token token) { |
1606 if (!optional('void', token) && !token.isIdentifier()) { | 1582 if (!token.isIdentifier()) { |
1607 return null; | 1583 return null; |
1608 } | 1584 } |
1609 return peekAfterType(token); | 1585 return peekAfterType(token); |
1610 } | 1586 } |
1611 | 1587 |
1612 Token skipClassBody(Token token) { | 1588 Token skipClassBody(Token token) { |
1613 if (!optional('{', token)) { | 1589 if (!optional('{', token)) { |
1614 return reportUnrecoverableError(token, ErrorKind.ExpectedClassBodyToSkip); | 1590 return reportUnrecoverableError(token, ErrorKind.ExpectedClassBodyToSkip); |
1615 } | 1591 } |
1616 BeginGroupToken beginGroupToken = token; | 1592 BeginGroupToken beginGroupToken = token; |
(...skipping 165 matching lines...) Loading... |
1782 } | 1758 } |
1783 if (getOrSet != null && constModifier != null) { | 1759 if (getOrSet != null && constModifier != null) { |
1784 reportRecoverableError(constModifier, ErrorKind.ExtraneousModifier, | 1760 reportRecoverableError(constModifier, ErrorKind.ExtraneousModifier, |
1785 {'modifier': constModifier}); | 1761 {'modifier': constModifier}); |
1786 } | 1762 } |
1787 parseModifierList(modifiers); | 1763 parseModifierList(modifiers); |
1788 | 1764 |
1789 if (type == null) { | 1765 if (type == null) { |
1790 listener.handleNoType(name); | 1766 listener.handleNoType(name); |
1791 } else { | 1767 } else { |
1792 parseReturnTypeOpt(type); | 1768 parseTypeOpt(type); |
1793 } | 1769 } |
1794 Token token; | 1770 Token token; |
1795 if (optional('operator', name)) { | 1771 if (optional('operator', name)) { |
1796 token = parseOperatorName(name); | 1772 token = parseOperatorName(name); |
1797 if (staticModifier != null) { | 1773 if (staticModifier != null) { |
1798 reportRecoverableError(staticModifier, ErrorKind.ExtraneousModifier, | 1774 reportRecoverableError(staticModifier, ErrorKind.ExtraneousModifier, |
1799 {'modifier': staticModifier}); | 1775 {'modifier': staticModifier}); |
1800 } | 1776 } |
1801 } else { | 1777 } else { |
1802 token = parseIdentifier(name, IdentifierContext.methodDeclaration); | 1778 token = parseIdentifier(name, IdentifierContext.methodDeclaration); |
(...skipping 75 matching lines...) Loading... |
1878 token = | 1854 token = |
1879 parseIdentifier(token, IdentifierContext.localAccessorDeclaration); | 1855 parseIdentifier(token, IdentifierContext.localAccessorDeclaration); |
1880 } | 1856 } |
1881 } else if (optional('operator', token)) { | 1857 } else if (optional('operator', token)) { |
1882 // operator <op> (... | 1858 // operator <op> (... |
1883 listener.handleNoType(token); | 1859 listener.handleNoType(token); |
1884 listener.beginFunctionName(token); | 1860 listener.beginFunctionName(token); |
1885 token = parseOperatorName(token); | 1861 token = parseOperatorName(token); |
1886 } else { | 1862 } else { |
1887 // <type>? <get>? <name> | 1863 // <type>? <get>? <name> |
1888 token = parseReturnTypeOpt(token); | 1864 token = parseTypeOpt(token); |
1889 if (identical(getOrSet, token)) { | 1865 if (identical(getOrSet, token)) { |
1890 token = token.next; | 1866 token = token.next; |
1891 } | 1867 } |
1892 listener.beginFunctionName(token); | 1868 listener.beginFunctionName(token); |
1893 if (optional('operator', token)) { | 1869 if (optional('operator', token)) { |
1894 token = parseOperatorName(token); | 1870 token = parseOperatorName(token); |
1895 } else { | 1871 } else { |
1896 token = | 1872 token = |
1897 parseIdentifier(token, IdentifierContext.localFunctionDeclaration); | 1873 parseIdentifier(token, IdentifierContext.localFunctionDeclaration); |
1898 } | 1874 } |
(...skipping 31 matching lines...) Loading... |
1930 Token parseFunctionDeclaration(Token token) { | 1906 Token parseFunctionDeclaration(Token token) { |
1931 listener.beginFunctionDeclaration(token); | 1907 listener.beginFunctionDeclaration(token); |
1932 token = parseFunction(token, null); | 1908 token = parseFunction(token, null); |
1933 listener.endFunctionDeclaration(token); | 1909 listener.endFunctionDeclaration(token); |
1934 return token; | 1910 return token; |
1935 } | 1911 } |
1936 | 1912 |
1937 Token parseFunctionExpression(Token token) { | 1913 Token parseFunctionExpression(Token token) { |
1938 listener.beginFunction(token); | 1914 listener.beginFunction(token); |
1939 listener.handleModifiers(0); | 1915 listener.handleModifiers(0); |
1940 token = parseReturnTypeOpt(token); | 1916 token = parseTypeOpt(token); |
1941 listener.beginFunctionName(token); | 1917 listener.beginFunctionName(token); |
1942 token = parseIdentifier(token, IdentifierContext.functionExpressionName); | 1918 token = parseIdentifier(token, IdentifierContext.functionExpressionName); |
1943 listener.endFunctionName(token); | 1919 listener.endFunctionName(token); |
1944 token = parseTypeVariablesOpt(token); | 1920 token = parseTypeVariablesOpt(token); |
1945 token = parseFormalParameters(token); | 1921 token = parseFormalParameters(token); |
1946 listener.handleNoInitializers(); | 1922 listener.handleNoInitializers(); |
1947 bool previousAsyncAwaitKeywordsEnabled = asyncAwaitKeywordsEnabled; | 1923 bool previousAsyncAwaitKeywordsEnabled = asyncAwaitKeywordsEnabled; |
1948 token = parseAsyncModifier(token); | 1924 token = parseAsyncModifier(token); |
1949 bool isBlock = optional('{', token); | 1925 bool isBlock = optional('{', token); |
1950 token = parseFunctionBody(token, true, false); | 1926 token = parseFunctionBody(token, true, false); |
(...skipping 185 matching lines...) Loading... |
2136 } else { | 2112 } else { |
2137 return parseExpressionStatement(token); | 2113 return parseExpressionStatement(token); |
2138 } | 2114 } |
2139 } else if (identical(value, 'for')) { | 2115 } else if (identical(value, 'for')) { |
2140 return parseForStatement(null, token); | 2116 return parseForStatement(null, token); |
2141 } else if (identical(value, 'rethrow')) { | 2117 } else if (identical(value, 'rethrow')) { |
2142 return parseRethrowStatement(token); | 2118 return parseRethrowStatement(token); |
2143 } else if (identical(value, 'throw') && optional(';', token.next)) { | 2119 } else if (identical(value, 'throw') && optional(';', token.next)) { |
2144 // TODO(kasperl): Stop dealing with throw here. | 2120 // TODO(kasperl): Stop dealing with throw here. |
2145 return parseRethrowStatement(token); | 2121 return parseRethrowStatement(token); |
2146 } else if (identical(value, 'void')) { | |
2147 return parseExpressionStatementOrDeclaration(token); | |
2148 } else if (identical(value, 'while')) { | 2122 } else if (identical(value, 'while')) { |
2149 return parseWhileStatement(token); | 2123 return parseWhileStatement(token); |
2150 } else if (identical(value, 'do')) { | 2124 } else if (identical(value, 'do')) { |
2151 return parseDoWhileStatement(token); | 2125 return parseDoWhileStatement(token); |
2152 } else if (identical(value, 'try')) { | 2126 } else if (identical(value, 'try')) { |
2153 return parseTryStatement(token); | 2127 return parseTryStatement(token); |
2154 } else if (identical(value, 'switch')) { | 2128 } else if (identical(value, 'switch')) { |
2155 return parseSwitchStatement(token); | 2129 return parseSwitchStatement(token); |
2156 } else if (identical(value, 'break')) { | 2130 } else if (identical(value, 'break')) { |
2157 return parseBreakStatement(token); | 2131 return parseBreakStatement(token); |
(...skipping 60 matching lines...) Loading... |
2218 return peek; | 2192 return peek; |
2219 } else if (token.isIdentifier()) { | 2193 } else if (token.isIdentifier()) { |
2220 // We are looking at "identifier". | 2194 // We are looking at "identifier". |
2221 return token; | 2195 return token; |
2222 } else { | 2196 } else { |
2223 return null; | 2197 return null; |
2224 } | 2198 } |
2225 } | 2199 } |
2226 | 2200 |
2227 Token parseExpressionStatementOrDeclaration(Token token) { | 2201 Token parseExpressionStatementOrDeclaration(Token token) { |
2228 assert(token.isIdentifier() || identical(token.stringValue, 'void')); | 2202 assert(token.isIdentifier()); |
2229 Token identifier = peekIdentifierAfterType(token); | 2203 Token identifier = peekIdentifierAfterType(token); |
2230 if (identifier != null) { | 2204 if (identifier != null) { |
2231 assert(identifier.isIdentifier()); | 2205 assert(identifier.isIdentifier()); |
2232 Token afterId = identifier.next; | 2206 Token afterId = identifier.next; |
2233 int afterIdKind = afterId.kind; | 2207 int afterIdKind = afterId.kind; |
2234 if (identical(afterIdKind, EQ_TOKEN) || | 2208 if (identical(afterIdKind, EQ_TOKEN) || |
2235 identical(afterIdKind, SEMICOLON_TOKEN) || | 2209 identical(afterIdKind, SEMICOLON_TOKEN) || |
2236 identical(afterIdKind, COMMA_TOKEN)) { | 2210 identical(afterIdKind, COMMA_TOKEN)) { |
2237 // We are looking at "type identifier" followed by '=', ';', ','. | 2211 // We are looking at "type identifier" followed by '=', ';', ','. |
2238 return parseVariablesDeclaration(token); | 2212 return parseVariablesDeclaration(token); |
(...skipping 393 matching lines...) Loading... |
2632 } else if (value == 'null') { | 2606 } else if (value == 'null') { |
2633 return parseLiteralNull(token); | 2607 return parseLiteralNull(token); |
2634 } else if (value == 'this') { | 2608 } else if (value == 'this') { |
2635 return parseThisExpression(token); | 2609 return parseThisExpression(token); |
2636 } else if (value == 'super') { | 2610 } else if (value == 'super') { |
2637 return parseSuperExpression(token); | 2611 return parseSuperExpression(token); |
2638 } else if (value == 'new') { | 2612 } else if (value == 'new') { |
2639 return parseNewExpression(token); | 2613 return parseNewExpression(token); |
2640 } else if (value == 'const') { | 2614 } else if (value == 'const') { |
2641 return parseConstExpression(token); | 2615 return parseConstExpression(token); |
2642 } else if (value == 'void') { | |
2643 return parseFunctionExpression(token); | |
2644 } else if (asyncAwaitKeywordsEnabled && | 2616 } else if (asyncAwaitKeywordsEnabled && |
2645 (value == 'yield' || value == 'async')) { | 2617 (value == 'yield' || value == 'async')) { |
2646 return expressionExpected(token); | 2618 return expressionExpected(token); |
2647 } else if (token.isIdentifier()) { | 2619 } else if (token.isIdentifier()) { |
2648 return parseSendOrFunctionLiteral(token); | 2620 return parseSendOrFunctionLiteral(token); |
2649 } else { | 2621 } else { |
2650 return expressionExpected(token); | 2622 return expressionExpected(token); |
2651 } | 2623 } |
2652 } else if (kind == OPEN_PAREN_TOKEN) { | 2624 } else if (kind == OPEN_PAREN_TOKEN) { |
2653 return parseParenthesizedExpressionOrFunctionLiteral(token); | 2625 return parseParenthesizedExpressionOrFunctionLiteral(token); |
(...skipping 905 matching lines...) Loading... |
3559 break; | 3531 break; |
3560 } | 3532 } |
3561 if (isRecoverable) { | 3533 if (isRecoverable) { |
3562 listener.handleRecoverableError(token, kind, arguments); | 3534 listener.handleRecoverableError(token, kind, arguments); |
3563 return null; | 3535 return null; |
3564 } else { | 3536 } else { |
3565 return listener.handleUnrecoverableError(token, kind, arguments); | 3537 return listener.handleUnrecoverableError(token, kind, arguments); |
3566 } | 3538 } |
3567 } | 3539 } |
3568 } | 3540 } |
OLD | NEW |