| 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 |