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 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
128 bool get inGenerator { | 128 bool get inGenerator { |
129 return asyncState == AsyncModifier.AsyncStar || | 129 return asyncState == AsyncModifier.AsyncStar || |
130 asyncState == AsyncModifier.SyncStar; | 130 asyncState == AsyncModifier.SyncStar; |
131 } | 131 } |
132 | 132 |
133 bool get inAsync { | 133 bool get inAsync { |
134 return asyncState == AsyncModifier.Async || | 134 return asyncState == AsyncModifier.Async || |
135 asyncState == AsyncModifier.AsyncStar; | 135 asyncState == AsyncModifier.AsyncStar; |
136 } | 136 } |
137 | 137 |
| 138 bool get inPlainSync => asyncState == AsyncModifier.Sync; |
| 139 |
138 Token parseUnit(Token token) { | 140 Token parseUnit(Token token) { |
139 listener.beginCompilationUnit(token); | 141 listener.beginCompilationUnit(token); |
140 int count = 0; | 142 int count = 0; |
141 while (!identical(token.kind, EOF_TOKEN)) { | 143 while (!identical(token.kind, EOF_TOKEN)) { |
142 token = parseTopLevelDeclaration(token); | 144 token = parseTopLevelDeclaration(token); |
143 count++; | 145 count++; |
144 } | 146 } |
145 listener.endCompilationUnit(count, token); | 147 listener.endCompilationUnit(count, token); |
146 return token; | 148 return token; |
147 } | 149 } |
(...skipping 754 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
902 if (!token.isIdentifier()) { | 904 if (!token.isIdentifier()) { |
903 token = | 905 token = |
904 reportUnrecoverableError(token, ErrorKind.ExpectedIdentifier)?.next; | 906 reportUnrecoverableError(token, ErrorKind.ExpectedIdentifier)?.next; |
905 } else if (token.isBuiltInIdentifier && | 907 } else if (token.isBuiltInIdentifier && |
906 !context.isBuiltInIdentifierAllowed) { | 908 !context.isBuiltInIdentifierAllowed) { |
907 if (context.inDeclaration) { | 909 if (context.inDeclaration) { |
908 reportRecoverableError(token, ErrorKind.BuiltInIdentifierInDeclaration); | 910 reportRecoverableError(token, ErrorKind.BuiltInIdentifierInDeclaration); |
909 } else if (!optional("dynamic", token)) { | 911 } else if (!optional("dynamic", token)) { |
910 reportRecoverableError(token, ErrorKind.BuiltInIdentifierAsType); | 912 reportRecoverableError(token, ErrorKind.BuiltInIdentifierAsType); |
911 } | 913 } |
| 914 } else if (!inPlainSync && token.isPseudo) { |
| 915 if (optional('await', token)) { |
| 916 reportRecoverableError(token, ErrorKind.AwaitAsIdentifier); |
| 917 } else if (optional('yield', token)) { |
| 918 reportRecoverableError(token, ErrorKind.YieldAsIdentifier); |
| 919 } else if (optional('async', token)) { |
| 920 reportRecoverableError(token, ErrorKind.AsyncAsIdentifier); |
| 921 } |
912 } | 922 } |
913 listener.handleIdentifier(token, context); | 923 listener.handleIdentifier(token, context); |
914 return token.next; | 924 return token.next; |
915 } | 925 } |
916 | 926 |
917 Token expect(String string, Token token) { | 927 Token expect(String string, Token token) { |
918 if (!identical(string, token.stringValue)) { | 928 if (!identical(string, token.stringValue)) { |
919 return reportUnrecoverableError( | 929 return reportUnrecoverableError( |
920 token, ErrorKind.ExpectedButGot, {"expected": string})?.next; | 930 token, ErrorKind.ExpectedButGot, {"expected": string})?.next; |
921 } | 931 } |
(...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1308 Token token = | 1318 Token token = |
1309 parseIdentifier(name, IdentifierContext.topLevelFunctionDeclaration); | 1319 parseIdentifier(name, IdentifierContext.topLevelFunctionDeclaration); |
1310 | 1320 |
1311 if (getOrSet == null) { | 1321 if (getOrSet == null) { |
1312 token = parseTypeVariablesOpt(token); | 1322 token = parseTypeVariablesOpt(token); |
1313 } else { | 1323 } else { |
1314 listener.handleNoTypeVariables(token); | 1324 listener.handleNoTypeVariables(token); |
1315 } | 1325 } |
1316 token = parseFormalParametersOpt(token); | 1326 token = parseFormalParametersOpt(token); |
1317 AsyncModifier savedAsyncModifier = asyncState; | 1327 AsyncModifier savedAsyncModifier = asyncState; |
| 1328 Token asyncToken = token; |
1318 token = parseAsyncModifier(token); | 1329 token = parseAsyncModifier(token); |
| 1330 if (getOrSet != null && !inPlainSync && optional("set", getOrSet)) { |
| 1331 reportRecoverableError(asyncToken, ErrorKind.SetterNotSync); |
| 1332 } |
1319 token = parseFunctionBody(token, false, externalModifier != null); | 1333 token = parseFunctionBody(token, false, externalModifier != null); |
1320 asyncState = savedAsyncModifier; | 1334 asyncState = savedAsyncModifier; |
1321 Token endToken = token; | 1335 Token endToken = token; |
1322 token = token.next; | 1336 token = token.next; |
1323 listener.endTopLevelMethod(start, getOrSet, endToken); | 1337 listener.endTopLevelMethod(start, getOrSet, endToken); |
1324 return token; | 1338 return token; |
1325 } | 1339 } |
1326 | 1340 |
1327 /// Looks ahead to find the name of a member. Returns a link of the modifiers, | 1341 /// Looks ahead to find the name of a member. Returns a link of the modifiers, |
1328 /// set/get, (operator) name, and either the start of the method body or the | 1342 /// set/get, (operator) name, and either the start of the method body or the |
(...skipping 537 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1866 token = parseQualifiedRestOpt( | 1880 token = parseQualifiedRestOpt( |
1867 token, IdentifierContext.methodDeclarationContinuation); | 1881 token, IdentifierContext.methodDeclarationContinuation); |
1868 if (getOrSet == null) { | 1882 if (getOrSet == null) { |
1869 token = parseTypeVariablesOpt(token); | 1883 token = parseTypeVariablesOpt(token); |
1870 } else { | 1884 } else { |
1871 listener.handleNoTypeVariables(token); | 1885 listener.handleNoTypeVariables(token); |
1872 } | 1886 } |
1873 token = parseFormalParametersOpt(token); | 1887 token = parseFormalParametersOpt(token); |
1874 token = parseInitializersOpt(token); | 1888 token = parseInitializersOpt(token); |
1875 AsyncModifier savedAsyncModifier = asyncState; | 1889 AsyncModifier savedAsyncModifier = asyncState; |
| 1890 Token asyncToken = token; |
1876 token = parseAsyncModifier(token); | 1891 token = parseAsyncModifier(token); |
| 1892 if (getOrSet != null && !inPlainSync && optional("set", getOrSet)) { |
| 1893 reportRecoverableError(asyncToken, ErrorKind.SetterNotSync); |
| 1894 } |
1877 if (optional('=', token)) { | 1895 if (optional('=', token)) { |
1878 token = parseRedirectingFactoryBody(token); | 1896 token = parseRedirectingFactoryBody(token); |
1879 } else { | 1897 } else { |
1880 token = parseFunctionBody( | 1898 token = parseFunctionBody( |
1881 token, false, staticModifier == null || externalModifier != null); | 1899 token, false, staticModifier == null || externalModifier != null); |
1882 } | 1900 } |
1883 asyncState = savedAsyncModifier; | 1901 asyncState = savedAsyncModifier; |
1884 listener.endMethod(getOrSet, start, token); | 1902 listener.endMethod(getOrSet, start, token); |
1885 return token.next; | 1903 return token.next; |
1886 } | 1904 } |
1887 | 1905 |
1888 Token parseFactoryMethod(Token token) { | 1906 Token parseFactoryMethod(Token token) { |
1889 assert(isFactoryDeclaration(token)); | 1907 assert(isFactoryDeclaration(token)); |
1890 Token start = token; | 1908 Token start = token; |
1891 bool isExternal = false; | 1909 bool isExternal = false; |
1892 int modifierCount = 0; | 1910 int modifierCount = 0; |
1893 while (isModifier(token)) { | 1911 while (isModifier(token)) { |
1894 if (optional('external', token)) { | 1912 if (optional('external', token)) { |
1895 isExternal = true; | 1913 isExternal = true; |
1896 } | 1914 } |
1897 token = parseModifier(token); | 1915 token = parseModifier(token); |
1898 modifierCount++; | 1916 modifierCount++; |
1899 } | 1917 } |
1900 listener.handleModifiers(modifierCount); | 1918 listener.handleModifiers(modifierCount); |
1901 Token factoryKeyword = token; | 1919 Token factoryKeyword = token; |
1902 listener.beginFactoryMethod(factoryKeyword); | 1920 listener.beginFactoryMethod(factoryKeyword); |
1903 token = expect('factory', token); | 1921 token = expect('factory', token); |
1904 token = parseConstructorReference(token); | 1922 token = parseConstructorReference(token); |
1905 token = parseFormalParameters(token); | 1923 token = parseFormalParameters(token); |
| 1924 Token asyncToken = token; |
1906 token = parseAsyncModifier(token); | 1925 token = parseAsyncModifier(token); |
| 1926 if (!inPlainSync) { |
| 1927 reportRecoverableError(asyncToken, ErrorKind.FactoryNotSync); |
| 1928 } |
1907 if (optional('=', token)) { | 1929 if (optional('=', token)) { |
1908 token = parseRedirectingFactoryBody(token); | 1930 token = parseRedirectingFactoryBody(token); |
1909 } else { | 1931 } else { |
1910 token = parseFunctionBody(token, false, isExternal); | 1932 token = parseFunctionBody(token, false, isExternal); |
1911 } | 1933 } |
1912 listener.endFactoryMethod(start, factoryKeyword, token); | 1934 listener.endFactoryMethod(start, factoryKeyword, token); |
1913 return token.next; | 1935 return token.next; |
1914 } | 1936 } |
1915 | 1937 |
1916 Token parseOperatorName(Token token) { | 1938 Token parseOperatorName(Token token) { |
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2161 token = token.next; | 2183 token = token.next; |
2162 if (optional('*', token)) { | 2184 if (optional('*', token)) { |
2163 asyncState = AsyncModifier.SyncStar; | 2185 asyncState = AsyncModifier.SyncStar; |
2164 star = token; | 2186 star = token; |
2165 token = token.next; | 2187 token = token.next; |
2166 } else { | 2188 } else { |
2167 reportRecoverableError(async, ErrorKind.InvalidSyncModifier); | 2189 reportRecoverableError(async, ErrorKind.InvalidSyncModifier); |
2168 } | 2190 } |
2169 } | 2191 } |
2170 listener.handleAsyncModifier(async, star); | 2192 listener.handleAsyncModifier(async, star); |
| 2193 if (inGenerator && optional('=>', token)) { |
| 2194 reportRecoverableError(token, ErrorKind.GeneratorReturnsValue); |
| 2195 } else if (!inPlainSync && optional(';', token)) { |
| 2196 reportRecoverableError(token, ErrorKind.AbstractNotSync); |
| 2197 } |
2171 return token; | 2198 return token; |
2172 } | 2199 } |
2173 | 2200 |
2174 int statementDepth = 0; | 2201 int statementDepth = 0; |
2175 Token parseStatement(Token token) { | 2202 Token parseStatement(Token token) { |
2176 if (statementDepth++ > 500) { | 2203 if (statementDepth++ > 500) { |
2177 // This happens for degenerate programs, for example, a lot of nested | 2204 // This happens for degenerate programs, for example, a lot of nested |
2178 // if-statements. The language test deep_nesting2_negative_test, for | 2205 // if-statements. The language test deep_nesting2_negative_test, for |
2179 // example, provokes this. | 2206 // example, provokes this. |
2180 return reportUnrecoverableError(token, ErrorKind.StackOverflow)?.next; | 2207 return reportUnrecoverableError(token, ErrorKind.StackOverflow)?.next; |
2181 } | 2208 } |
2182 Token result = parseStatementX(token); | 2209 Token result = parseStatementX(token); |
2183 statementDepth--; | 2210 statementDepth--; |
2184 return result; | 2211 return result; |
2185 } | 2212 } |
2186 | 2213 |
2187 Token parseStatementX(Token token) { | 2214 Token parseStatementX(Token token) { |
2188 final value = token.stringValue; | 2215 final value = token.stringValue; |
2189 if (identical(token.kind, IDENTIFIER_TOKEN)) { | 2216 if (identical(token.kind, IDENTIFIER_TOKEN)) { |
2190 return parseExpressionStatementOrDeclaration(token); | 2217 return parseExpressionStatementOrDeclaration(token); |
2191 } else if (identical(value, '{')) { | 2218 } else if (identical(value, '{')) { |
2192 return parseBlock(token); | 2219 return parseBlock(token); |
2193 } else if (identical(value, 'return')) { | 2220 } else if (identical(value, 'return')) { |
2194 return parseReturnStatement(token); | 2221 return parseReturnStatement(token); |
2195 } else if (identical(value, 'var') || identical(value, 'final')) { | 2222 } else if (identical(value, 'var') || identical(value, 'final')) { |
2196 return parseVariablesDeclaration(token); | 2223 return parseVariablesDeclaration(token); |
2197 } else if (identical(value, 'if')) { | 2224 } else if (identical(value, 'if')) { |
2198 return parseIfStatement(token); | 2225 return parseIfStatement(token); |
2199 } else if (asyncState != AsyncModifier.Sync && identical(value, 'await')) { | 2226 } else if (identical(value, 'await') && optional('for', token.next)) { |
2200 if (identical(token.next.stringValue, 'for')) { | 2227 if (!inAsync) { |
2201 return parseForStatement(token, token.next); | 2228 reportRecoverableError(token, ErrorKind.AwaitForNotAsync); |
2202 } else { | |
2203 return parseExpressionStatement(token); | |
2204 } | 2229 } |
| 2230 return parseForStatement(token, token.next); |
2205 } else if (identical(value, 'for')) { | 2231 } else if (identical(value, 'for')) { |
2206 return parseForStatement(null, token); | 2232 return parseForStatement(null, token); |
2207 } else if (identical(value, 'rethrow')) { | 2233 } else if (identical(value, 'rethrow')) { |
2208 return parseRethrowStatement(token); | 2234 return parseRethrowStatement(token); |
2209 } else if (identical(value, 'throw') && optional(';', token.next)) { | 2235 } else if (identical(value, 'throw') && optional(';', token.next)) { |
2210 // TODO(kasperl): Stop dealing with throw here. | 2236 // TODO(kasperl): Stop dealing with throw here. |
2211 return parseRethrowStatement(token); | 2237 return parseRethrowStatement(token); |
2212 } else if (identical(value, 'void')) { | 2238 } else if (identical(value, 'void')) { |
2213 return parseExpressionStatementOrDeclaration(token); | 2239 return parseExpressionStatementOrDeclaration(token); |
2214 } else if (identical(value, 'while')) { | 2240 } else if (identical(value, 'while')) { |
2215 return parseWhileStatement(token); | 2241 return parseWhileStatement(token); |
2216 } else if (identical(value, 'do')) { | 2242 } else if (identical(value, 'do')) { |
2217 return parseDoWhileStatement(token); | 2243 return parseDoWhileStatement(token); |
2218 } else if (identical(value, 'try')) { | 2244 } else if (identical(value, 'try')) { |
2219 return parseTryStatement(token); | 2245 return parseTryStatement(token); |
2220 } else if (identical(value, 'switch')) { | 2246 } else if (identical(value, 'switch')) { |
2221 return parseSwitchStatement(token); | 2247 return parseSwitchStatement(token); |
2222 } else if (identical(value, 'break')) { | 2248 } else if (identical(value, 'break')) { |
2223 return parseBreakStatement(token); | 2249 return parseBreakStatement(token); |
2224 } else if (identical(value, 'continue')) { | 2250 } else if (identical(value, 'continue')) { |
2225 return parseContinueStatement(token); | 2251 return parseContinueStatement(token); |
2226 } else if (identical(value, 'assert')) { | 2252 } else if (identical(value, 'assert')) { |
2227 return parseAssertStatement(token); | 2253 return parseAssertStatement(token); |
2228 } else if (identical(value, ';')) { | 2254 } else if (identical(value, ';')) { |
2229 return parseEmptyStatement(token); | 2255 return parseEmptyStatement(token); |
2230 } else if (asyncState != AsyncModifier.Sync && identical(value, 'yield')) { | 2256 } else if (identical(value, 'yield')) { |
2231 return parseYieldStatement(token); | 2257 switch (asyncState) { |
| 2258 case AsyncModifier.Sync: |
| 2259 return parseExpressionStatementOrDeclaration(token); |
| 2260 |
| 2261 case AsyncModifier.SyncStar: |
| 2262 case AsyncModifier.AsyncStar: |
| 2263 return parseYieldStatement(token); |
| 2264 |
| 2265 case AsyncModifier.Async: |
| 2266 reportRecoverableError(token, ErrorKind.YieldNotGenerator); |
| 2267 return parseYieldStatement(token); |
| 2268 } |
| 2269 throw "Internal error: Unknown asyncState: '$asyncState'."; |
2232 } else if (identical(value, 'const')) { | 2270 } else if (identical(value, 'const')) { |
2233 return parseExpressionStatementOrConstDeclaration(token); | 2271 return parseExpressionStatementOrConstDeclaration(token); |
2234 } else if (token.isIdentifier()) { | 2272 } else if (token.isIdentifier()) { |
2235 return parseExpressionStatementOrDeclaration(token); | 2273 return parseExpressionStatementOrDeclaration(token); |
2236 } else { | 2274 } else { |
2237 return parseExpressionStatement(token); | 2275 return parseExpressionStatement(token); |
2238 } | 2276 } |
2239 } | 2277 } |
2240 | 2278 |
2241 Token parseYieldStatement(Token token) { | 2279 Token parseYieldStatement(Token token) { |
(...skipping 13 matching lines...) Expand all Loading... |
2255 | 2293 |
2256 Token parseReturnStatement(Token token) { | 2294 Token parseReturnStatement(Token token) { |
2257 Token begin = token; | 2295 Token begin = token; |
2258 listener.beginReturnStatement(begin); | 2296 listener.beginReturnStatement(begin); |
2259 assert(identical('return', token.stringValue)); | 2297 assert(identical('return', token.stringValue)); |
2260 token = token.next; | 2298 token = token.next; |
2261 if (optional(';', token)) { | 2299 if (optional(';', token)) { |
2262 listener.endReturnStatement(false, begin, token); | 2300 listener.endReturnStatement(false, begin, token); |
2263 } else { | 2301 } else { |
2264 token = parseExpression(token); | 2302 token = parseExpression(token); |
| 2303 if (inGenerator) { |
| 2304 reportRecoverableError(begin.next, ErrorKind.GeneratorReturnsValue); |
| 2305 } |
2265 listener.endReturnStatement(true, begin, token); | 2306 listener.endReturnStatement(true, begin, token); |
2266 } | 2307 } |
2267 return expectSemicolon(token); | 2308 return expectSemicolon(token); |
2268 } | 2309 } |
2269 | 2310 |
2270 Token peekIdentifierAfterType(Token token) { | 2311 Token peekIdentifierAfterType(Token token) { |
2271 Token peek = peekAfterType(token); | 2312 Token peek = peekAfterType(token); |
2272 if (peek != null && peek.isIdentifier()) { | 2313 if (peek != null && peek.isIdentifier()) { |
2273 // We are looking at "type identifier". | 2314 // We are looking at "type identifier". |
2274 return peek; | 2315 return peek; |
2275 } else { | 2316 } else { |
2276 return null; | 2317 return null; |
2277 } | 2318 } |
2278 } | 2319 } |
2279 | 2320 |
2280 Token peekIdentifierAfterOptionalType(Token token) { | 2321 Token peekIdentifierAfterOptionalType(Token token) { |
2281 Token peek = peekAfterIfType(token); | 2322 Token peek = peekAfterIfType(token); |
2282 if (peek != null && peek.isIdentifier()) { | 2323 if (peek != null && peek.isIdentifier()) { |
2283 // We are looking at "type identifier". | 2324 // We are looking at "type identifier". |
2284 return peek; | 2325 return peek; |
2285 } else if (token.isIdentifier()) { | 2326 } else if (token.isIdentifier()) { |
2286 // We are looking at "identifier". | 2327 // We are looking at "identifier". |
2287 return token; | 2328 return token; |
2288 } else { | 2329 } else { |
2289 return null; | 2330 return null; |
2290 } | 2331 } |
2291 } | 2332 } |
2292 | 2333 |
2293 Token parseExpressionStatementOrDeclaration(Token token) { | 2334 Token parseExpressionStatementOrDeclaration(Token token) { |
| 2335 if (!inPlainSync && optional("await", token)) { |
| 2336 return parseExpressionStatement(token); |
| 2337 } |
2294 assert(token.isIdentifier() || identical(token.stringValue, 'void')); | 2338 assert(token.isIdentifier() || identical(token.stringValue, 'void')); |
2295 Token identifier = peekIdentifierAfterType(token); | 2339 Token identifier = peekIdentifierAfterType(token); |
2296 if (identifier != null) { | 2340 if (identifier != null) { |
2297 assert(identifier.isIdentifier()); | 2341 assert(identifier.isIdentifier()); |
2298 Token afterId = identifier.next; | 2342 Token afterId = identifier.next; |
2299 int afterIdKind = afterId.kind; | 2343 int afterIdKind = afterId.kind; |
2300 if (identical(afterIdKind, EQ_TOKEN) || | 2344 if (identical(afterIdKind, EQ_TOKEN) || |
2301 identical(afterIdKind, SEMICOLON_TOKEN) || | 2345 identical(afterIdKind, SEMICOLON_TOKEN) || |
2302 identical(afterIdKind, COMMA_TOKEN)) { | 2346 identical(afterIdKind, COMMA_TOKEN)) { |
2303 // We are looking at "type identifier" followed by '=', ';', ','. | 2347 // We are looking at "type identifier" followed by '=', ';', ','. |
(...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2623 token = parseExpressionWithoutCascade(token.next); | 2667 token = parseExpressionWithoutCascade(token.next); |
2624 listener.handleAssignmentExpression(assignment); | 2668 listener.handleAssignmentExpression(assignment); |
2625 } | 2669 } |
2626 listener.endCascade(); | 2670 listener.endCascade(); |
2627 return token; | 2671 return token; |
2628 } | 2672 } |
2629 | 2673 |
2630 Token parseUnaryExpression(Token token, bool allowCascades) { | 2674 Token parseUnaryExpression(Token token, bool allowCascades) { |
2631 String value = token.stringValue; | 2675 String value = token.stringValue; |
2632 // Prefix: | 2676 // Prefix: |
2633 if (asyncState != AsyncModifier.Sync && optional('await', token)) { | 2677 if (optional('await', token)) { |
2634 return parseAwaitExpression(token, allowCascades); | 2678 if (inPlainSync) { |
| 2679 return parsePrimary(token); |
| 2680 } else { |
| 2681 return parseAwaitExpression(token, allowCascades); |
| 2682 } |
2635 } else if (identical(value, '+')) { | 2683 } else if (identical(value, '+')) { |
2636 // Dart no longer allows prefix-plus. | 2684 // Dart no longer allows prefix-plus. |
2637 reportRecoverableError(token, ErrorKind.UnsupportedPrefixPlus); | 2685 reportRecoverableError(token, ErrorKind.UnsupportedPrefixPlus); |
2638 return parseUnaryExpression(token.next, allowCascades); | 2686 return parseUnaryExpression(token.next, allowCascades); |
2639 } else if ((identical(value, '!')) || | 2687 } else if ((identical(value, '!')) || |
2640 (identical(value, '-')) || | 2688 (identical(value, '-')) || |
2641 (identical(value, '~'))) { | 2689 (identical(value, '~'))) { |
2642 Token operator = token; | 2690 Token operator = token; |
2643 // Right associative, so we recurse at the same precedence | 2691 // Right associative, so we recurse at the same precedence |
2644 // level. | 2692 // level. |
2645 token = parsePrecedenceExpression( | 2693 token = parsePrecedenceExpression( |
2646 token.next, POSTFIX_PRECEDENCE, allowCascades); | 2694 token.next, POSTFIX_PRECEDENCE, allowCascades); |
2647 listener.handleUnaryPrefixExpression(operator); | 2695 listener.handleUnaryPrefixExpression(operator); |
| 2696 return token; |
2648 } else if ((identical(value, '++')) || identical(value, '--')) { | 2697 } else if ((identical(value, '++')) || identical(value, '--')) { |
2649 // TODO(ahe): Validate this is used correctly. | 2698 // TODO(ahe): Validate this is used correctly. |
2650 Token operator = token; | 2699 Token operator = token; |
2651 // Right associative, so we recurse at the same precedence | 2700 // Right associative, so we recurse at the same precedence |
2652 // level. | 2701 // level. |
2653 token = parsePrecedenceExpression( | 2702 token = parsePrecedenceExpression( |
2654 token.next, POSTFIX_PRECEDENCE, allowCascades); | 2703 token.next, POSTFIX_PRECEDENCE, allowCascades); |
2655 listener.handleUnaryPrefixAssignmentExpression(operator); | 2704 listener.handleUnaryPrefixAssignmentExpression(operator); |
| 2705 return token; |
2656 } else { | 2706 } else { |
2657 token = parsePrimary(token); | 2707 return parsePrimary(token); |
2658 } | 2708 } |
2659 return token; | |
2660 } | 2709 } |
2661 | 2710 |
2662 Token parseArgumentOrIndexStar(Token token) { | 2711 Token parseArgumentOrIndexStar(Token token) { |
2663 Token beginToken = token; | 2712 Token beginToken = token; |
2664 while (true) { | 2713 while (true) { |
2665 if (optional('[', token)) { | 2714 if (optional('[', token)) { |
2666 Token openSquareBracket = token; | 2715 Token openSquareBracket = token; |
2667 bool old = mayParseFunctionExpressions; | 2716 bool old = mayParseFunctionExpressions; |
2668 mayParseFunctionExpressions = true; | 2717 mayParseFunctionExpressions = true; |
2669 token = parseExpression(token.next); | 2718 token = parseExpression(token.next); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2702 } else if (identical(value, "this")) { | 2751 } else if (identical(value, "this")) { |
2703 return parseThisExpression(token); | 2752 return parseThisExpression(token); |
2704 } else if (identical(value, "super")) { | 2753 } else if (identical(value, "super")) { |
2705 return parseSuperExpression(token); | 2754 return parseSuperExpression(token); |
2706 } else if (identical(value, "new")) { | 2755 } else if (identical(value, "new")) { |
2707 return parseNewExpression(token); | 2756 return parseNewExpression(token); |
2708 } else if (identical(value, "const")) { | 2757 } else if (identical(value, "const")) { |
2709 return parseConstExpression(token); | 2758 return parseConstExpression(token); |
2710 } else if (identical(value, "void")) { | 2759 } else if (identical(value, "void")) { |
2711 return parseFunctionExpression(token); | 2760 return parseFunctionExpression(token); |
2712 } else if (asyncState != AsyncModifier.Sync && | 2761 } else if (!inPlainSync && |
2713 (identical(value, "yield") || identical(value, "async"))) { | 2762 (identical(value, "yield") || identical(value, "async"))) { |
2714 return expressionExpected(token); | 2763 return expressionExpected(token); |
2715 } else if (token.isIdentifier()) { | 2764 } else if (token.isIdentifier()) { |
2716 return parseSendOrFunctionLiteral(token); | 2765 return parseSendOrFunctionLiteral(token); |
2717 } else { | 2766 } else { |
2718 return expressionExpected(token); | 2767 return expressionExpected(token); |
2719 } | 2768 } |
2720 } else if (kind == OPEN_PAREN_TOKEN) { | 2769 } else if (kind == OPEN_PAREN_TOKEN) { |
2721 return parseParenthesizedExpressionOrFunctionLiteral(token); | 2770 return parseParenthesizedExpressionOrFunctionLiteral(token); |
2722 } else if (kind == OPEN_SQUARE_BRACKET_TOKEN || optional('[]', token)) { | 2771 } else if (kind == OPEN_SQUARE_BRACKET_TOKEN || optional('[]', token)) { |
(...skipping 632 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3355 ++statementCount; | 3404 ++statementCount; |
3356 } | 3405 } |
3357 listener.endBlock(statementCount, begin, token); | 3406 listener.endBlock(statementCount, begin, token); |
3358 return expect('}', token); | 3407 return expect('}', token); |
3359 } | 3408 } |
3360 | 3409 |
3361 Token parseAwaitExpression(Token token, bool allowCascades) { | 3410 Token parseAwaitExpression(Token token, bool allowCascades) { |
3362 Token awaitToken = token; | 3411 Token awaitToken = token; |
3363 listener.beginAwaitExpression(awaitToken); | 3412 listener.beginAwaitExpression(awaitToken); |
3364 token = expect('await', token); | 3413 token = expect('await', token); |
| 3414 if (!inAsync) { |
| 3415 reportRecoverableError(awaitToken, ErrorKind.AwaitNotAsync); |
| 3416 } |
3365 token = parsePrecedenceExpression(token, POSTFIX_PRECEDENCE, allowCascades); | 3417 token = parsePrecedenceExpression(token, POSTFIX_PRECEDENCE, allowCascades); |
3366 listener.endAwaitExpression(awaitToken, token); | 3418 listener.endAwaitExpression(awaitToken, token); |
3367 return token; | 3419 return token; |
3368 } | 3420 } |
3369 | 3421 |
3370 Token parseThrowExpression(Token token, bool allowCascades) { | 3422 Token parseThrowExpression(Token token, bool allowCascades) { |
3371 Token throwToken = token; | 3423 Token throwToken = token; |
3372 listener.beginThrowExpression(throwToken); | 3424 listener.beginThrowExpression(throwToken); |
3373 token = expect('throw', token); | 3425 token = expect('throw', token); |
3374 token = allowCascades | 3426 token = allowCascades |
(...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3644 break; | 3696 break; |
3645 } | 3697 } |
3646 if (isRecoverable) { | 3698 if (isRecoverable) { |
3647 listener.handleRecoverableError(token, kind, arguments); | 3699 listener.handleRecoverableError(token, kind, arguments); |
3648 return null; | 3700 return null; |
3649 } else { | 3701 } else { |
3650 return listener.handleUnrecoverableError(token, kind, arguments); | 3702 return listener.handleUnrecoverableError(token, kind, arguments); |
3651 } | 3703 } |
3652 } | 3704 } |
3653 } | 3705 } |
OLD | NEW |