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

Side by Side Diff: sdk/lib/_internal/compiler/implementation/scanner/parser.dart

Issue 675113002: Support async/await in the dart2js frontend. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Updated cf. comments Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 part of scanner; 5 part of scanner;
6 6
7 class FormalParameterType { 7 class FormalParameterType {
8 final String type; 8 final String type;
9 const FormalParameterType(this.type); 9 const FormalParameterType(this.type);
10 bool get isRequired => this == REQUIRED; 10 bool get isRequired => this == REQUIRED;
(...skipping 23 matching lines...) Expand all
34 * 34 *
35 * Parse methods are generally named parseGrammarProductionSuffix. The 35 * Parse methods are generally named parseGrammarProductionSuffix. The
36 * suffix can be one of "opt", or "star". "opt" means zero or one 36 * suffix can be one of "opt", or "star". "opt" means zero or one
37 * matches, "star" means zero or more matches. For example, 37 * matches, "star" means zero or more matches. For example,
38 * [parseMetadataStar] corresponds to this grammar snippet: [: 38 * [parseMetadataStar] corresponds to this grammar snippet: [:
39 * metadata* :], and [parseTypeOpt] corresponds to: [: type? :]. 39 * metadata* :], and [parseTypeOpt] corresponds to: [: type? :].
40 */ 40 */
41 class Parser { 41 class Parser {
42 final Listener listener; 42 final Listener listener;
43 bool mayParseFunctionExpressions = true; 43 bool mayParseFunctionExpressions = true;
44 bool yieldIsKeyword = false;
45 bool awaitIsKeyword = false;
44 46
45 Parser(this.listener); 47 Parser(this.listener);
46 48
47 Token parseUnit(Token token) { 49 Token parseUnit(Token token) {
48 listener.beginCompilationUnit(token); 50 listener.beginCompilationUnit(token);
49 int count = 0; 51 int count = 0;
50 while (!identical(token.kind, EOF_TOKEN)) { 52 while (!identical(token.kind, EOF_TOKEN)) {
51 token = parseTopLevelDeclaration(token); 53 token = parseTopLevelDeclaration(token);
52 listener.endTopLevelDeclaration(token); 54 listener.endTopLevelDeclaration(token);
53 count++; 55 count++;
(...skipping 803 matching lines...) Expand 10 before | Expand all | Expand 10 after
857 } 859 }
858 860
859 if (type == null) { 861 if (type == null) {
860 listener.handleNoType(name); 862 listener.handleNoType(name);
861 } else { 863 } else {
862 parseReturnTypeOpt(type); 864 parseReturnTypeOpt(type);
863 } 865 }
864 Token token = parseIdentifier(name); 866 Token token = parseIdentifier(name);
865 867
866 token = parseFormalParametersOpt(token); 868 token = parseFormalParametersOpt(token);
869 bool previousYieldIsKeyword = yieldIsKeyword;
870 bool previousAwaitIsKeyword = awaitIsKeyword;
871 token = parseAsyncModifier(token);
867 token = parseFunctionBody(token, false, externalModifier != null); 872 token = parseFunctionBody(token, false, externalModifier != null);
873 yieldIsKeyword = previousYieldIsKeyword;
874 awaitIsKeyword = previousAwaitIsKeyword;
868 listener.endTopLevelMethod(start, getOrSet, token); 875 listener.endTopLevelMethod(start, getOrSet, token);
869 return token.next; 876 return token.next;
870 } 877 }
871 878
872 Link<Token> findMemberName(Token token) { 879 Link<Token> findMemberName(Token token) {
873 Token start = token; 880 Token start = token;
874 Link<Token> identifiers = const Link<Token>(); 881 Link<Token> identifiers = const Link<Token>();
875 while (!identical(token.kind, EOF_TOKEN)) { 882 while (!identical(token.kind, EOF_TOKEN)) {
876 String value = token.stringValue; 883 String value = token.stringValue;
877 if ((identical(value, '(')) || (identical(value, '{')) 884 if ((identical(value, '(')) || (identical(value, '{'))
(...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after
1199 staticModifier, MessageKind.EXTRANEOUS_MODIFIER, 1206 staticModifier, MessageKind.EXTRANEOUS_MODIFIER,
1200 {'modifier': staticModifier}); 1207 {'modifier': staticModifier});
1201 } 1208 }
1202 } else { 1209 } else {
1203 token = parseIdentifier(name); 1210 token = parseIdentifier(name);
1204 } 1211 }
1205 1212
1206 token = parseQualifiedRestOpt(token); 1213 token = parseQualifiedRestOpt(token);
1207 token = parseFormalParametersOpt(token); 1214 token = parseFormalParametersOpt(token);
1208 token = parseInitializersOpt(token); 1215 token = parseInitializersOpt(token);
1216 bool previousYieldIsKeyword = yieldIsKeyword;
1217 bool previousAwaitIsKeyword = awaitIsKeyword;
1218 token = parseAsyncModifier(token);
1209 if (optional('=', token)) { 1219 if (optional('=', token)) {
1210 token = parseRedirectingFactoryBody(token); 1220 token = parseRedirectingFactoryBody(token);
1211 } else { 1221 } else {
1212 token = parseFunctionBody( 1222 token = parseFunctionBody(
1213 token, false, staticModifier == null || externalModifier != null); 1223 token, false, staticModifier == null || externalModifier != null);
1214 } 1224 }
1225 yieldIsKeyword = previousYieldIsKeyword;
1226 awaitIsKeyword = previousAwaitIsKeyword;
1215 listener.endMethod(getOrSet, start, token); 1227 listener.endMethod(getOrSet, start, token);
1216 return token.next; 1228 return token.next;
1217 } 1229 }
1218 1230
1219 Token parseFactoryMethod(Token token) { 1231 Token parseFactoryMethod(Token token) {
1220 assert(isFactoryDeclaration(token)); 1232 assert(isFactoryDeclaration(token));
1221 Token start = token; 1233 Token start = token;
1222 Token externalModifier; 1234 Token externalModifier;
1223 if (identical(token.stringValue, 'external')) { 1235 if (identical(token.stringValue, 'external')) {
1224 externalModifier = token; 1236 externalModifier = token;
1225 token = token.next; 1237 token = token.next;
1226 } 1238 }
1227 Token constKeyword = null; 1239 Token constKeyword = null;
1228 if (optional('const', token)) { 1240 if (optional('const', token)) {
1229 constKeyword = token; 1241 constKeyword = token;
1230 token = token.next; 1242 token = token.next;
1231 } 1243 }
1232 Token factoryKeyword = token; 1244 Token factoryKeyword = token;
1233 listener.beginFactoryMethod(factoryKeyword); 1245 listener.beginFactoryMethod(factoryKeyword);
1234 token = token.next; // Skip 'factory'. 1246 token = token.next; // Skip 'factory'.
1235 token = parseConstructorReference(token); 1247 token = parseConstructorReference(token);
1236 token = parseFormalParameters(token); 1248 token = parseFormalParameters(token);
1249 bool previousYieldIsKeyword = yieldIsKeyword;
1250 bool previousAwaitIsKeyword = awaitIsKeyword;
1251 token = parseAsyncModifier(token);
1237 if (optional('=', token)) { 1252 if (optional('=', token)) {
1238 token = parseRedirectingFactoryBody(token); 1253 token = parseRedirectingFactoryBody(token);
1239 } else { 1254 } else {
1240 token = parseFunctionBody(token, false, externalModifier != null); 1255 token = parseFunctionBody(token, false, externalModifier != null);
1241 } 1256 }
1242 listener.endFactoryMethod(start, token); 1257 listener.endFactoryMethod(start, token);
1243 return token.next; 1258 return token.next;
1244 } 1259 }
1245 1260
1246 Token parseOperatorName(Token token) { 1261 Token parseOperatorName(Token token) {
(...skipping 23 matching lines...) Expand all
1270 if (optional('operator', token)) { 1285 if (optional('operator', token)) {
1271 token = parseOperatorName(token); 1286 token = parseOperatorName(token);
1272 } else { 1287 } else {
1273 token = parseIdentifier(token); 1288 token = parseIdentifier(token);
1274 } 1289 }
1275 } 1290 }
1276 token = parseQualifiedRestOpt(token); 1291 token = parseQualifiedRestOpt(token);
1277 listener.endFunctionName(token); 1292 listener.endFunctionName(token);
1278 token = parseFormalParametersOpt(token); 1293 token = parseFormalParametersOpt(token);
1279 token = parseInitializersOpt(token); 1294 token = parseInitializersOpt(token);
1295 bool previousYieldIsKeyword = yieldIsKeyword;
1296 bool previousAwaitIsKeyword = awaitIsKeyword;
1297 token = parseAsyncModifier(token);
1280 if (optional('=', token)) { 1298 if (optional('=', token)) {
1281 token = parseRedirectingFactoryBody(token); 1299 token = parseRedirectingFactoryBody(token);
1282 } else { 1300 } else {
1283 token = parseFunctionBody(token, false, true); 1301 token = parseFunctionBody(token, false, true);
1284 } 1302 }
1303 yieldIsKeyword = previousYieldIsKeyword;
1304 awaitIsKeyword = previousAwaitIsKeyword;
1285 listener.endFunction(getOrSet, token); 1305 listener.endFunction(getOrSet, token);
1286 return token.next; 1306 return token.next;
1287 } 1307 }
1288 1308
1289 Token parseUnamedFunction(Token token) { 1309 Token parseUnnamedFunction(Token token) {
1290 listener.beginUnamedFunction(token); 1310 listener.beginUnnamedFunction(token);
1291 token = parseFormalParameters(token); 1311 token = parseFormalParameters(token);
1312 bool previousYieldIsKeyword = yieldIsKeyword;
1313 bool previousAwaitIsKeyword = awaitIsKeyword;
1314 token = parseAsyncModifier(token);
1292 bool isBlock = optional('{', token); 1315 bool isBlock = optional('{', token);
1293 token = parseFunctionBody(token, true, false); 1316 token = parseFunctionBody(token, true, false);
1294 listener.endUnamedFunction(token); 1317 yieldIsKeyword = previousYieldIsKeyword;
1318 awaitIsKeyword = previousAwaitIsKeyword;
1319 listener.endUnnamedFunction(token);
1295 return isBlock ? token.next : token; 1320 return isBlock ? token.next : token;
1296 } 1321 }
1297 1322
1298 Token parseFunctionDeclaration(Token token) { 1323 Token parseFunctionDeclaration(Token token) {
1299 listener.beginFunctionDeclaration(token); 1324 listener.beginFunctionDeclaration(token);
1300 token = parseFunction(token, null); 1325 token = parseFunction(token, null);
1301 listener.endFunctionDeclaration(token); 1326 listener.endFunctionDeclaration(token);
1302 return token; 1327 return token;
1303 } 1328 }
1304 1329
1305 Token parseFunctionExpression(Token token) { 1330 Token parseFunctionExpression(Token token) {
1306 listener.beginFunction(token); 1331 listener.beginFunction(token);
1307 listener.handleModifiers(0); 1332 listener.handleModifiers(0);
1308 token = parseReturnTypeOpt(token); 1333 token = parseReturnTypeOpt(token);
1309 listener.beginFunctionName(token); 1334 listener.beginFunctionName(token);
1310 token = parseIdentifier(token); 1335 token = parseIdentifier(token);
1311 listener.endFunctionName(token); 1336 listener.endFunctionName(token);
1312 token = parseFormalParameters(token); 1337 token = parseFormalParameters(token);
1313 listener.handleNoInitializers(); 1338 listener.handleNoInitializers();
1339 bool previousYieldIsKeyword = yieldIsKeyword;
1340 bool previousAwaitIsKeyword = awaitIsKeyword;
1341 token = parseAsyncModifier(token);
1314 bool isBlock = optional('{', token); 1342 bool isBlock = optional('{', token);
1315 token = parseFunctionBody(token, true, false); 1343 token = parseFunctionBody(token, true, false);
1344 yieldIsKeyword = previousYieldIsKeyword;
1345 awaitIsKeyword = previousAwaitIsKeyword;
1316 listener.endFunction(null, token); 1346 listener.endFunction(null, token);
1317 return isBlock ? token.next : token; 1347 return isBlock ? token.next : token;
1318 } 1348 }
1319 1349
1320 Token parseConstructorReference(Token token) { 1350 Token parseConstructorReference(Token token) {
1321 Token start = token; 1351 Token start = token;
1322 listener.beginConstructorReference(start); 1352 listener.beginConstructorReference(start);
1323 token = parseIdentifier(token); 1353 token = parseIdentifier(token);
1324 token = parseQualifiedRestOpt(token); 1354 token = parseQualifiedRestOpt(token);
1325 token = parseTypeArgumentsOpt(token); 1355 token = parseTypeArgumentsOpt(token);
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
1371 token = token.next; 1401 token = token.next;
1372 while (notEofOrValue('}', token)) { 1402 while (notEofOrValue('}', token)) {
1373 token = parseStatement(token); 1403 token = parseStatement(token);
1374 ++statementCount; 1404 ++statementCount;
1375 } 1405 }
1376 listener.endFunctionBody(statementCount, begin, token); 1406 listener.endFunctionBody(statementCount, begin, token);
1377 expect('}', token); 1407 expect('}', token);
1378 return token; 1408 return token;
1379 } 1409 }
1380 1410
1411 /// `async*` and `sync*` are parsed a two tokens, [token] and [star]. This
1412 /// method checks that there is no whitespace between [token] and [star].
1413 void checkStarredModifier(Token token, Token star, String name) {
1414 if (star.charOffset > token.charOffset + token.charCount) {
1415 listener.reportError(new TokenPair(token, star),
1416 MessageKind.INVALID_STARRED_KEYWORD, {'keyword': name});
1417 }
1418 }
1419
1420 Token parseAsyncModifier(Token token) {
1421 Token async;
1422 Token star;
1423 awaitIsKeyword = false;
1424 yieldIsKeyword = false;
1425 if (optional('async', token)) {
1426 awaitIsKeyword = true;
1427 async = token;
1428 token = token.next;
1429 if (optional('*', token)) {
1430 yieldIsKeyword = true;
1431 star = token;
1432 token = token.next;
1433 checkStarredModifier(async, star, 'async*');
1434 }
1435 } else if (optional('sync', token)) {
1436 async = token;
1437 token = token.next;
1438 if (optional('*', token)) {
1439 yieldIsKeyword = true;
1440 star = token;
1441 token = token.next;
1442
1443 checkStarredModifier(async, star, 'sync*');
1444 } else {
1445 listener.reportError(async,
1446 MessageKind.INVALID_SYNC_MODIFIER);
1447 }
1448 }
1449 listener.handleAsyncModifier(async, star);
1450 return token;
1451 }
1452
1381 Token parseStatement(Token token) { 1453 Token parseStatement(Token token) {
1382 final value = token.stringValue; 1454 final value = token.stringValue;
1383 if (identical(token.kind, IDENTIFIER_TOKEN)) { 1455 if (identical(token.kind, IDENTIFIER_TOKEN)) {
1384 return parseExpressionStatementOrDeclaration(token); 1456 return parseExpressionStatementOrDeclaration(token);
1385 } else if (identical(value, '{')) { 1457 } else if (identical(value, '{')) {
1386 return parseBlock(token); 1458 return parseBlock(token);
1387 } else if (identical(value, 'return')) { 1459 } else if (identical(value, 'return')) {
1388 return parseReturnStatement(token); 1460 return parseReturnStatement(token);
1389 } else if (identical(value, 'var') || identical(value, 'final')) { 1461 } else if (identical(value, 'var') || identical(value, 'final')) {
1390 return parseVariablesDeclaration(token); 1462 return parseVariablesDeclaration(token);
1391 } else if (identical(value, 'if')) { 1463 } else if (identical(value, 'if')) {
1392 return parseIfStatement(token); 1464 return parseIfStatement(token);
1465 } else if (awaitIsKeyword && identical(value, 'await')) {
1466 if (identical(token.next.stringValue, 'for')) {
1467 return parseForStatement(token, token.next);
1468 } else {
1469 return parseExpressionStatement(token);
1470 }
1393 } else if (identical(value, 'for')) { 1471 } else if (identical(value, 'for')) {
1394 return parseForStatement(token); 1472 return parseForStatement(null, token);
1395 } else if (identical(value, 'rethrow')) { 1473 } else if (identical(value, 'rethrow')) {
1396 return parseRethrowStatement(token); 1474 return parseRethrowStatement(token);
1397 } else if (identical(value, 'throw') && optional(';', token.next)) { 1475 } else if (identical(value, 'throw') && optional(';', token.next)) {
1398 // TODO(kasperl): Stop dealing with throw here. 1476 // TODO(kasperl): Stop dealing with throw here.
1399 return parseRethrowStatement(token); 1477 return parseRethrowStatement(token);
1400 } else if (identical(value, 'void')) { 1478 } else if (identical(value, 'void')) {
1401 return parseExpressionStatementOrDeclaration(token); 1479 return parseExpressionStatementOrDeclaration(token);
1402 } else if (identical(value, 'while')) { 1480 } else if (identical(value, 'while')) {
1403 return parseWhileStatement(token); 1481 return parseWhileStatement(token);
1404 } else if (identical(value, 'do')) { 1482 } else if (identical(value, 'do')) {
1405 return parseDoWhileStatement(token); 1483 return parseDoWhileStatement(token);
1406 } else if (identical(value, 'try')) { 1484 } else if (identical(value, 'try')) {
1407 return parseTryStatement(token); 1485 return parseTryStatement(token);
1408 } else if (identical(value, 'switch')) { 1486 } else if (identical(value, 'switch')) {
1409 return parseSwitchStatement(token); 1487 return parseSwitchStatement(token);
1410 } else if (identical(value, 'break')) { 1488 } else if (identical(value, 'break')) {
1411 return parseBreakStatement(token); 1489 return parseBreakStatement(token);
1412 } else if (identical(value, 'continue')) { 1490 } else if (identical(value, 'continue')) {
1413 return parseContinueStatement(token); 1491 return parseContinueStatement(token);
1414 } else if (identical(value, 'assert')) { 1492 } else if (identical(value, 'assert')) {
1415 return parseAssertStatement(token); 1493 return parseAssertStatement(token);
1416 } else if (identical(value, ';')) { 1494 } else if (identical(value, ';')) {
1417 return parseEmptyStatement(token); 1495 return parseEmptyStatement(token);
1496 } else if (yieldIsKeyword && identical(value, 'yield')) {
1497 return parseYieldStatement(token);
1418 } else if (identical(value, 'const')) { 1498 } else if (identical(value, 'const')) {
1419 return parseExpressionStatementOrConstDeclaration(token); 1499 return parseExpressionStatementOrConstDeclaration(token);
1420 } else if (token.isIdentifier()) { 1500 } else if (token.isIdentifier()) {
1421 return parseExpressionStatementOrDeclaration(token); 1501 return parseExpressionStatementOrDeclaration(token);
1422 } else { 1502 } else {
1423 return parseExpressionStatement(token); 1503 return parseExpressionStatement(token);
1424 } 1504 }
1425 } 1505 }
1426 1506
1507 Token parseYieldStatement(Token token) {
1508 Token begin = token;
1509 listener.beginYieldStatement(begin);
1510 assert(identical('yield', token.stringValue));
1511 token = token.next;
1512 Token starToken;
1513 if (optional('*', token)) {
1514 starToken = token;
1515 token = token.next;
1516 checkStarredModifier(begin, starToken, 'yield*');
1517 }
1518 token = parseExpression(token);
1519 listener.endYieldStatement(begin, starToken, token);
1520 return expectSemicolon(token);
1521 }
1522
1523
1427 Token parseReturnStatement(Token token) { 1524 Token parseReturnStatement(Token token) {
1428 Token begin = token; 1525 Token begin = token;
1429 listener.beginReturnStatement(begin); 1526 listener.beginReturnStatement(begin);
1430 assert(identical('return', token.stringValue)); 1527 assert(identical('return', token.stringValue));
1431 token = token.next; 1528 token = token.next;
1432 if (optional(';', token)) { 1529 if (optional(';', token)) {
1433 listener.endReturnStatement(false, begin, token); 1530 listener.endReturnStatement(false, begin, token);
1434 } else { 1531 } else {
1435 token = parseExpression(token); 1532 token = parseExpression(token);
1436 listener.endReturnStatement(true, begin, token); 1533 listener.endReturnStatement(true, begin, token);
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1471 if (identical(afterIdKind, EQ_TOKEN) || 1568 if (identical(afterIdKind, EQ_TOKEN) ||
1472 identical(afterIdKind, SEMICOLON_TOKEN) || 1569 identical(afterIdKind, SEMICOLON_TOKEN) ||
1473 identical(afterIdKind, COMMA_TOKEN)) { 1570 identical(afterIdKind, COMMA_TOKEN)) {
1474 // We are looking at "type identifier" followed by '=', ';', ','. 1571 // We are looking at "type identifier" followed by '=', ';', ','.
1475 return parseVariablesDeclaration(token); 1572 return parseVariablesDeclaration(token);
1476 } else if (identical(afterIdKind, OPEN_PAREN_TOKEN)) { 1573 } else if (identical(afterIdKind, OPEN_PAREN_TOKEN)) {
1477 // We are looking at "type identifier '('". 1574 // We are looking at "type identifier '('".
1478 BeginGroupToken beginParen = afterId; 1575 BeginGroupToken beginParen = afterId;
1479 Token endParen = beginParen.endGroup; 1576 Token endParen = beginParen.endGroup;
1480 Token afterParens = endParen.next; 1577 Token afterParens = endParen.next;
1481 if (optional('{', afterParens) || optional('=>', afterParens)) { 1578 if (optional('{', afterParens) ||
1579 optional('=>', afterParens) ||
1580 optional('async', afterParens) ||
1581 optional('sync', afterParens)) {
1482 // We are looking at "type identifier '(' ... ')'" followed 1582 // We are looking at "type identifier '(' ... ')'" followed
1483 // by '=>' or '{'. 1583 // by '=>' or '{'.
1484 return parseFunctionDeclaration(token); 1584 return parseFunctionDeclaration(token);
1485 } 1585 }
1486 } 1586 }
1487 // Fall-through to expression statement. 1587 // Fall-through to expression statement.
1488 } else { 1588 } else {
1489 if (optional(':', token.next)) { 1589 if (optional(':', token.next)) {
1490 return parseLabeledStatement(token); 1590 return parseLabeledStatement(token);
1491 } else if (optional('(', token.next)) { 1591 } else if (optional('(', token.next)) {
1492 BeginGroupToken begin = token.next; 1592 BeginGroupToken begin = token.next;
1493 String afterParens = begin.endGroup.next.stringValue; 1593 String afterParens = begin.endGroup.next.stringValue;
1494 if (identical(afterParens, '{') || identical(afterParens, '=>')) { 1594 if (identical(afterParens, '{') ||
1595 identical(afterParens, '=>') ||
1596 identical(afterParens, 'async') ||
1597 identical(afterParens, 'sync')) {
1495 return parseFunctionDeclaration(token); 1598 return parseFunctionDeclaration(token);
1496 } 1599 }
1497 } 1600 }
1498 } 1601 }
1499 return parseExpressionStatement(token); 1602 return parseExpressionStatement(token);
1500 } 1603 }
1501 1604
1502 Token parseExpressionStatementOrConstDeclaration(Token token) { 1605 Token parseExpressionStatementOrConstDeclaration(Token token) {
1503 assert(identical(token.stringValue, 'const')); 1606 assert(identical(token.stringValue, 'const'));
1504 if (isModifier(token.next)) { 1607 if (isModifier(token.next)) {
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
1665 token = parseExpressionWithoutCascade(token.next); 1768 token = parseExpressionWithoutCascade(token.next);
1666 listener.handleAssignmentExpression(assignment); 1769 listener.handleAssignmentExpression(assignment);
1667 } 1770 }
1668 listener.endCascade(); 1771 listener.endCascade();
1669 return token; 1772 return token;
1670 } 1773 }
1671 1774
1672 Token parseUnaryExpression(Token token, bool allowCascades) { 1775 Token parseUnaryExpression(Token token, bool allowCascades) {
1673 String value = token.stringValue; 1776 String value = token.stringValue;
1674 // Prefix: 1777 // Prefix:
1675 if (identical(value, '+')) { 1778 if (awaitIsKeyword && optional('await', token)) {
1779 return parseAwaitExpression(token, allowCascades);
1780 } else if (identical(value, '+')) {
1676 // Dart no longer allows prefix-plus. 1781 // Dart no longer allows prefix-plus.
1677 listener.reportError(token, MessageKind.UNSUPPORTED_PREFIX_PLUS); 1782 listener.reportError(token, MessageKind.UNSUPPORTED_PREFIX_PLUS);
1678 return parseUnaryExpression(token.next, allowCascades); 1783 return parseUnaryExpression(token.next, allowCascades);
1679 } else if ((identical(value, '!')) || 1784 } else if ((identical(value, '!')) ||
1680 (identical(value, '-')) || 1785 (identical(value, '-')) ||
1681 (identical(value, '~'))) { 1786 (identical(value, '~'))) {
1682 Token operator = token; 1787 Token operator = token;
1683 // Right associative, so we recurse at the same precedence 1788 // Right associative, so we recurse at the same precedence
1684 // level. 1789 // level.
1685 token = parsePrecedenceExpression(token.next, POSTFIX_PRECEDENCE, 1790 token = parsePrecedenceExpression(token.next, POSTFIX_PRECEDENCE,
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
1760 (identical(kind, OPEN_CURLY_BRACKET_TOKEN)) || 1865 (identical(kind, OPEN_CURLY_BRACKET_TOKEN)) ||
1761 identical(token.stringValue, '[]')) { 1866 identical(token.stringValue, '[]')) {
1762 return parseLiteralListOrMap(token); 1867 return parseLiteralListOrMap(token);
1763 } else { 1868 } else {
1764 return listener.expectedExpression(token); 1869 return listener.expectedExpression(token);
1765 } 1870 }
1766 } 1871 }
1767 1872
1768 Token parseParenthesizedExpressionOrFunctionLiteral(Token token) { 1873 Token parseParenthesizedExpressionOrFunctionLiteral(Token token) {
1769 BeginGroupToken beginGroup = token; 1874 BeginGroupToken beginGroup = token;
1770 int kind = beginGroup.endGroup.next.kind; 1875 Token nextToken = beginGroup.endGroup.next;
1876 int kind = nextToken.kind;
1771 if (mayParseFunctionExpressions && 1877 if (mayParseFunctionExpressions &&
1772 (identical(kind, FUNCTION_TOKEN) 1878 (identical(kind, FUNCTION_TOKEN) ||
1773 || identical(kind, OPEN_CURLY_BRACKET_TOKEN))) { 1879 identical(kind, OPEN_CURLY_BRACKET_TOKEN) ||
1774 return parseUnamedFunction(token); 1880 (identical(kind, KEYWORD_TOKEN) &&
1881 (nextToken.value == 'async' || nextToken.value == 'sync')))) {
1882 return parseUnnamedFunction(token);
1775 } else { 1883 } else {
1776 bool old = mayParseFunctionExpressions; 1884 bool old = mayParseFunctionExpressions;
1777 mayParseFunctionExpressions = true; 1885 mayParseFunctionExpressions = true;
1778 token = parseParenthesizedExpression(token); 1886 token = parseParenthesizedExpression(token);
1779 mayParseFunctionExpressions = old; 1887 mayParseFunctionExpressions = old;
1780 return token; 1888 return token;
1781 } 1889 }
1782 } 1890 }
1783 1891
1784 Token parseParenthesizedExpression(Token token) { 1892 Token parseParenthesizedExpression(Token token) {
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
1886 return parseFunctionExpression(token); 1994 return parseFunctionExpression(token);
1887 } else { 1995 } else {
1888 return parseSend(token); 1996 return parseSend(token);
1889 } 1997 }
1890 } 1998 }
1891 1999
1892 bool isFunctionDeclaration(Token token) { 2000 bool isFunctionDeclaration(Token token) {
1893 if (optional('(', token)) { 2001 if (optional('(', token)) {
1894 BeginGroupToken begin = token; 2002 BeginGroupToken begin = token;
1895 String afterParens = begin.endGroup.next.stringValue; 2003 String afterParens = begin.endGroup.next.stringValue;
1896 if (identical(afterParens, '{') || identical(afterParens, '=>')) { 2004 if (identical(afterParens, '{') ||
2005 identical(afterParens, '=>') ||
2006 identical(afterParens, 'async') ||
2007 identical(afterParens, 'sync')) {
1897 return true; 2008 return true;
1898 } 2009 }
1899 } 2010 }
1900 return false; 2011 return false;
1901 } 2012 }
1902 2013
1903 Token parseRequiredArguments(Token token) { 2014 Token parseRequiredArguments(Token token) {
1904 if (optional('(', token)) { 2015 if (optional('(', token)) {
1905 token = parseArguments(token); 2016 token = parseArguments(token);
1906 } else { 2017 } else {
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after
2144 token = parseStatement(token); 2255 token = parseStatement(token);
2145 Token elseToken = null; 2256 Token elseToken = null;
2146 if (optional('else', token)) { 2257 if (optional('else', token)) {
2147 elseToken = token; 2258 elseToken = token;
2148 token = parseStatement(token.next); 2259 token = parseStatement(token.next);
2149 } 2260 }
2150 listener.endIfStatement(ifToken, elseToken); 2261 listener.endIfStatement(ifToken, elseToken);
2151 return token; 2262 return token;
2152 } 2263 }
2153 2264
2154 Token parseForStatement(Token token) { 2265 Token parseForStatement(Token awaitToken, Token token) {
2155 Token forToken = token; 2266 Token forToken = token;
2156 listener.beginForStatement(forToken); 2267 listener.beginForStatement(forToken);
2157 token = expect('for', token); 2268 token = expect('for', token);
2158 token = expect('(', token); 2269 token = expect('(', token);
2159 token = parseVariablesDeclarationOrExpressionOpt(token); 2270 token = parseVariablesDeclarationOrExpressionOpt(token);
2160 if (optional('in', token)) { 2271 if (optional('in', token)) {
2161 return parseForInRest(forToken, token); 2272 return parseForInRest(awaitToken, forToken, token);
2162 } else { 2273 } else {
2274 if (awaitToken != null) {
2275 listener.reportError(awaitToken, MessageKind.INVALID_AWAIT_FOR);
2276 }
2163 return parseForRest(forToken, token); 2277 return parseForRest(forToken, token);
2164 } 2278 }
2165 } 2279 }
2166 2280
2167 Token parseVariablesDeclarationOrExpressionOpt(Token token) { 2281 Token parseVariablesDeclarationOrExpressionOpt(Token token) {
2168 final String value = token.stringValue; 2282 final String value = token.stringValue;
2169 if (identical(value, ';')) { 2283 if (identical(value, ';')) {
2170 listener.handleNoExpression(token); 2284 listener.handleNoExpression(token);
2171 return token; 2285 return token;
2172 } else if ((identical(value, 'var')) || (identical(value, 'final'))) { 2286 } else if ((identical(value, 'var')) || (identical(value, 'final'))) {
(...skipping 26 matching lines...) Expand all
2199 } else { 2313 } else {
2200 break; 2314 break;
2201 } 2315 }
2202 } 2316 }
2203 token = expect(')', token); 2317 token = expect(')', token);
2204 token = parseStatement(token); 2318 token = parseStatement(token);
2205 listener.endForStatement(expressionCount, forToken, token); 2319 listener.endForStatement(expressionCount, forToken, token);
2206 return token; 2320 return token;
2207 } 2321 }
2208 2322
2209 Token parseForInRest(Token forToken, Token token) { 2323 Token parseForInRest(Token awaitToken, Token forToken, Token token) {
2210 assert(optional('in', token)); 2324 assert(optional('in', token));
2211 Token inKeyword = token; 2325 Token inKeyword = token;
2212 token = parseExpression(token.next); 2326 token = parseExpression(token.next);
2213 token = expect(')', token); 2327 token = expect(')', token);
2214 token = parseStatement(token); 2328 token = parseStatement(token);
2215 listener.endForIn(forToken, inKeyword, token); 2329 listener.endForIn(awaitToken, forToken, inKeyword, token);
2216 return token; 2330 return token;
2217 } 2331 }
2218 2332
2219 Token parseWhileStatement(Token token) { 2333 Token parseWhileStatement(Token token) {
2220 Token whileToken = token; 2334 Token whileToken = token;
2221 listener.beginWhileStatement(whileToken); 2335 listener.beginWhileStatement(whileToken);
2222 token = expect('while', token); 2336 token = expect('while', token);
2223 token = parseParenthesizedExpression(token); 2337 token = parseParenthesizedExpression(token);
2224 token = parseStatement(token); 2338 token = parseStatement(token);
2225 listener.endWhileStatement(whileToken, token); 2339 listener.endWhileStatement(whileToken, token);
(...skipping 18 matching lines...) Expand all
2244 int statementCount = 0; 2358 int statementCount = 0;
2245 token = expect('{', token); 2359 token = expect('{', token);
2246 while (notEofOrValue('}', token)) { 2360 while (notEofOrValue('}', token)) {
2247 token = parseStatement(token); 2361 token = parseStatement(token);
2248 ++statementCount; 2362 ++statementCount;
2249 } 2363 }
2250 listener.endBlock(statementCount, begin, token); 2364 listener.endBlock(statementCount, begin, token);
2251 return expect('}', token); 2365 return expect('}', token);
2252 } 2366 }
2253 2367
2368 Token parseAwaitExpression(Token token, bool allowCascades) {
2369 Token awaitToken = token;
2370 listener.beginAwaitExpression(awaitToken);
2371 token = expect('await', token);
2372 token = parseUnaryExpression(token, allowCascades);
2373 listener.endAwaitExpression(awaitToken, token);
2374 return token;
2375 }
2376
2254 Token parseThrowExpression(Token token, bool allowCascades) { 2377 Token parseThrowExpression(Token token, bool allowCascades) {
2255 Token throwToken = token; 2378 Token throwToken = token;
2256 listener.beginThrowExpression(throwToken); 2379 listener.beginThrowExpression(throwToken);
2257 token = expect('throw', token); 2380 token = expect('throw', token);
2258 token = allowCascades 2381 token = allowCascades
2259 ? parseExpression(token) 2382 ? parseExpression(token)
2260 : parseExpressionWithoutCascade(token); 2383 : parseExpressionWithoutCascade(token);
2261 listener.endThrowExpression(throwToken, token); 2384 listener.endThrowExpression(throwToken, token);
2262 return token; 2385 return token;
2263 } 2386 }
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after
2446 } 2569 }
2447 listener.handleContinueStatement(hasTarget, continueKeyword, token); 2570 listener.handleContinueStatement(hasTarget, continueKeyword, token);
2448 return expectSemicolon(token); 2571 return expectSemicolon(token);
2449 } 2572 }
2450 2573
2451 Token parseEmptyStatement(Token token) { 2574 Token parseEmptyStatement(Token token) {
2452 listener.handleEmptyStatement(token); 2575 listener.handleEmptyStatement(token);
2453 return expectSemicolon(token); 2576 return expectSemicolon(token);
2454 } 2577 }
2455 } 2578 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698