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

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: Update unittests 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 void checkStarredModifier(Token token, Token star, String name) {
floitsch 2014/11/03 17:55:54 Add comment what exactly this checks.
Johnni Winther 2014/11/04 12:24:33 Done.
1412 if (star.charOffset > token.charOffset + token.charCount) {
1413 listener.reportError(new TokenPair(token, star),
1414 MessageKind.INVALID_STARRED_KEYWORD, {'keyword': name});
1415 }
1416 }
1417
1418 Token parseAsyncModifier(Token token) {
1419 Token async;
1420 Token star;
1421 awaitIsKeyword = false;
1422 yieldIsKeyword = false;
1423 if (optional('async', token)) {
1424 awaitIsKeyword = true;
1425 async = token;
1426 token = token.next;
1427 if (optional('*', token)) {
1428 yieldIsKeyword = true;
1429 star = token;
1430 token = token.next;
1431 checkStarredModifier(async, star, 'async*');
1432 }
1433 } else if (optional('sync', token)) {
1434 async = token;
1435 token = token.next;
1436 if (optional('*', token)) {
1437 yieldIsKeyword = true;
1438 star = token;
1439 token = token.next;
1440
1441 checkStarredModifier(async, star, 'sync*');
1442 } else {
1443 listener.reportError(async,
1444 MessageKind.INVALID_SYNC_MODIFIER);
1445 }
1446 }
1447 listener.handleAsyncModifier(async, star);
1448 return token;
1449 }
1450
1381 Token parseStatement(Token token) { 1451 Token parseStatement(Token token) {
1382 final value = token.stringValue; 1452 final value = token.stringValue;
1383 if (identical(token.kind, IDENTIFIER_TOKEN)) { 1453 if (identical(token.kind, IDENTIFIER_TOKEN)) {
1384 return parseExpressionStatementOrDeclaration(token); 1454 return parseExpressionStatementOrDeclaration(token);
1385 } else if (identical(value, '{')) { 1455 } else if (identical(value, '{')) {
1386 return parseBlock(token); 1456 return parseBlock(token);
1387 } else if (identical(value, 'return')) { 1457 } else if (identical(value, 'return')) {
1388 return parseReturnStatement(token); 1458 return parseReturnStatement(token);
1389 } else if (identical(value, 'var') || identical(value, 'final')) { 1459 } else if (identical(value, 'var') || identical(value, 'final')) {
1390 return parseVariablesDeclaration(token); 1460 return parseVariablesDeclaration(token);
1391 } else if (identical(value, 'if')) { 1461 } else if (identical(value, 'if')) {
1392 return parseIfStatement(token); 1462 return parseIfStatement(token);
1463 } else if (awaitIsKeyword && identical(value, 'await')) {
1464 if (identical(token.next.stringValue, 'for')) {
1465 return parseForStatement(token, token.next);
1466 } else {
1467 return parseExpressionStatement(token);
1468 }
1393 } else if (identical(value, 'for')) { 1469 } else if (identical(value, 'for')) {
1394 return parseForStatement(token); 1470 return parseForStatement(null, token);
1395 } else if (identical(value, 'rethrow')) { 1471 } else if (identical(value, 'rethrow')) {
1396 return parseRethrowStatement(token); 1472 return parseRethrowStatement(token);
1397 } else if (identical(value, 'throw') && optional(';', token.next)) { 1473 } else if (identical(value, 'throw') && optional(';', token.next)) {
1398 // TODO(kasperl): Stop dealing with throw here. 1474 // TODO(kasperl): Stop dealing with throw here.
1399 return parseRethrowStatement(token); 1475 return parseRethrowStatement(token);
1400 } else if (identical(value, 'void')) { 1476 } else if (identical(value, 'void')) {
1401 return parseExpressionStatementOrDeclaration(token); 1477 return parseExpressionStatementOrDeclaration(token);
1402 } else if (identical(value, 'while')) { 1478 } else if (identical(value, 'while')) {
1403 return parseWhileStatement(token); 1479 return parseWhileStatement(token);
1404 } else if (identical(value, 'do')) { 1480 } else if (identical(value, 'do')) {
1405 return parseDoWhileStatement(token); 1481 return parseDoWhileStatement(token);
1406 } else if (identical(value, 'try')) { 1482 } else if (identical(value, 'try')) {
1407 return parseTryStatement(token); 1483 return parseTryStatement(token);
1408 } else if (identical(value, 'switch')) { 1484 } else if (identical(value, 'switch')) {
1409 return parseSwitchStatement(token); 1485 return parseSwitchStatement(token);
1410 } else if (identical(value, 'break')) { 1486 } else if (identical(value, 'break')) {
1411 return parseBreakStatement(token); 1487 return parseBreakStatement(token);
1412 } else if (identical(value, 'continue')) { 1488 } else if (identical(value, 'continue')) {
1413 return parseContinueStatement(token); 1489 return parseContinueStatement(token);
1414 } else if (identical(value, 'assert')) { 1490 } else if (identical(value, 'assert')) {
1415 return parseAssertStatement(token); 1491 return parseAssertStatement(token);
1416 } else if (identical(value, ';')) { 1492 } else if (identical(value, ';')) {
1417 return parseEmptyStatement(token); 1493 return parseEmptyStatement(token);
1494 } else if (yieldIsKeyword && identical(value, 'yield')) {
1495 return parseYieldStatement(token);
1418 } else if (identical(value, 'const')) { 1496 } else if (identical(value, 'const')) {
1419 return parseExpressionStatementOrConstDeclaration(token); 1497 return parseExpressionStatementOrConstDeclaration(token);
1420 } else if (token.isIdentifier()) { 1498 } else if (token.isIdentifier()) {
1421 return parseExpressionStatementOrDeclaration(token); 1499 return parseExpressionStatementOrDeclaration(token);
1422 } else { 1500 } else {
1423 return parseExpressionStatement(token); 1501 return parseExpressionStatement(token);
1424 } 1502 }
1425 } 1503 }
1426 1504
1505 Token parseYieldStatement(Token token) {
1506 Token begin = token;
1507 listener.beginYieldStatement(begin);
1508 assert(identical('yield', token.stringValue));
1509 token = token.next;
1510 Token starToken;
1511 if (optional('*', token)) {
1512 starToken = token;
1513 token = token.next;
1514 checkStarredModifier(begin, starToken, 'yield*');
1515 }
1516 token = parseExpression(token);
1517 listener.endYieldStatement(begin, starToken, token);
1518 return expectSemicolon(token);
1519 }
1520
1521
1427 Token parseReturnStatement(Token token) { 1522 Token parseReturnStatement(Token token) {
1428 Token begin = token; 1523 Token begin = token;
1429 listener.beginReturnStatement(begin); 1524 listener.beginReturnStatement(begin);
1430 assert(identical('return', token.stringValue)); 1525 assert(identical('return', token.stringValue));
1431 token = token.next; 1526 token = token.next;
1432 if (optional(';', token)) { 1527 if (optional(';', token)) {
1433 listener.endReturnStatement(false, begin, token); 1528 listener.endReturnStatement(false, begin, token);
1434 } else { 1529 } else {
1435 token = parseExpression(token); 1530 token = parseExpression(token);
1436 listener.endReturnStatement(true, begin, token); 1531 listener.endReturnStatement(true, begin, token);
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1471 if (identical(afterIdKind, EQ_TOKEN) || 1566 if (identical(afterIdKind, EQ_TOKEN) ||
1472 identical(afterIdKind, SEMICOLON_TOKEN) || 1567 identical(afterIdKind, SEMICOLON_TOKEN) ||
1473 identical(afterIdKind, COMMA_TOKEN)) { 1568 identical(afterIdKind, COMMA_TOKEN)) {
1474 // We are looking at "type identifier" followed by '=', ';', ','. 1569 // We are looking at "type identifier" followed by '=', ';', ','.
1475 return parseVariablesDeclaration(token); 1570 return parseVariablesDeclaration(token);
1476 } else if (identical(afterIdKind, OPEN_PAREN_TOKEN)) { 1571 } else if (identical(afterIdKind, OPEN_PAREN_TOKEN)) {
1477 // We are looking at "type identifier '('". 1572 // We are looking at "type identifier '('".
1478 BeginGroupToken beginParen = afterId; 1573 BeginGroupToken beginParen = afterId;
1479 Token endParen = beginParen.endGroup; 1574 Token endParen = beginParen.endGroup;
1480 Token afterParens = endParen.next; 1575 Token afterParens = endParen.next;
1481 if (optional('{', afterParens) || optional('=>', afterParens)) { 1576 if (optional('{', afterParens) ||
1577 optional('=>', afterParens) ||
1578 optional('async', afterParens) ||
1579 optional('sync', afterParens)) {
1482 // We are looking at "type identifier '(' ... ')'" followed 1580 // We are looking at "type identifier '(' ... ')'" followed
1483 // by '=>' or '{'. 1581 // by '=>' or '{'.
1484 return parseFunctionDeclaration(token); 1582 return parseFunctionDeclaration(token);
1485 } 1583 }
1486 } 1584 }
1487 // Fall-through to expression statement. 1585 // Fall-through to expression statement.
1488 } else { 1586 } else {
1489 if (optional(':', token.next)) { 1587 if (optional(':', token.next)) {
1490 return parseLabeledStatement(token); 1588 return parseLabeledStatement(token);
1491 } else if (optional('(', token.next)) { 1589 } else if (optional('(', token.next)) {
1492 BeginGroupToken begin = token.next; 1590 BeginGroupToken begin = token.next;
1493 String afterParens = begin.endGroup.next.stringValue; 1591 String afterParens = begin.endGroup.next.stringValue;
1494 if (identical(afterParens, '{') || identical(afterParens, '=>')) { 1592 if (identical(afterParens, '{') ||
1593 identical(afterParens, '=>') ||
1594 identical(afterParens, 'async') ||
1595 identical(afterParens, 'sync')) {
1495 return parseFunctionDeclaration(token); 1596 return parseFunctionDeclaration(token);
1496 } 1597 }
1497 } 1598 }
1498 } 1599 }
1499 return parseExpressionStatement(token); 1600 return parseExpressionStatement(token);
1500 } 1601 }
1501 1602
1502 Token parseExpressionStatementOrConstDeclaration(Token token) { 1603 Token parseExpressionStatementOrConstDeclaration(Token token) {
1503 assert(identical(token.stringValue, 'const')); 1604 assert(identical(token.stringValue, 'const'));
1504 if (isModifier(token.next)) { 1605 if (isModifier(token.next)) {
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
1665 token = parseExpressionWithoutCascade(token.next); 1766 token = parseExpressionWithoutCascade(token.next);
1666 listener.handleAssignmentExpression(assignment); 1767 listener.handleAssignmentExpression(assignment);
1667 } 1768 }
1668 listener.endCascade(); 1769 listener.endCascade();
1669 return token; 1770 return token;
1670 } 1771 }
1671 1772
1672 Token parseUnaryExpression(Token token, bool allowCascades) { 1773 Token parseUnaryExpression(Token token, bool allowCascades) {
1673 String value = token.stringValue; 1774 String value = token.stringValue;
1674 // Prefix: 1775 // Prefix:
1675 if (identical(value, '+')) { 1776 if (awaitIsKeyword && optional('await', token)) {
1777 return parseAwaitExpression(token, allowCascades);
1778 } else if (identical(value, '+')) {
1676 // Dart no longer allows prefix-plus. 1779 // Dart no longer allows prefix-plus.
1677 listener.reportError(token, MessageKind.UNSUPPORTED_PREFIX_PLUS); 1780 listener.reportError(token, MessageKind.UNSUPPORTED_PREFIX_PLUS);
1678 return parseUnaryExpression(token.next, allowCascades); 1781 return parseUnaryExpression(token.next, allowCascades);
1679 } else if ((identical(value, '!')) || 1782 } else if ((identical(value, '!')) ||
1680 (identical(value, '-')) || 1783 (identical(value, '-')) ||
1681 (identical(value, '~'))) { 1784 (identical(value, '~'))) {
1682 Token operator = token; 1785 Token operator = token;
1683 // Right associative, so we recurse at the same precedence 1786 // Right associative, so we recurse at the same precedence
1684 // level. 1787 // level.
1685 token = parsePrecedenceExpression(token.next, POSTFIX_PRECEDENCE, 1788 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)) || 1863 (identical(kind, OPEN_CURLY_BRACKET_TOKEN)) ||
1761 identical(token.stringValue, '[]')) { 1864 identical(token.stringValue, '[]')) {
1762 return parseLiteralListOrMap(token); 1865 return parseLiteralListOrMap(token);
1763 } else { 1866 } else {
1764 return listener.expectedExpression(token); 1867 return listener.expectedExpression(token);
1765 } 1868 }
1766 } 1869 }
1767 1870
1768 Token parseParenthesizedExpressionOrFunctionLiteral(Token token) { 1871 Token parseParenthesizedExpressionOrFunctionLiteral(Token token) {
1769 BeginGroupToken beginGroup = token; 1872 BeginGroupToken beginGroup = token;
1770 int kind = beginGroup.endGroup.next.kind; 1873 Token nextToken = beginGroup.endGroup.next;
1874 int kind = nextToken.kind;
1771 if (mayParseFunctionExpressions && 1875 if (mayParseFunctionExpressions &&
1772 (identical(kind, FUNCTION_TOKEN) 1876 (identical(kind, FUNCTION_TOKEN) ||
1773 || identical(kind, OPEN_CURLY_BRACKET_TOKEN))) { 1877 identical(kind, OPEN_CURLY_BRACKET_TOKEN) ||
1774 return parseUnamedFunction(token); 1878 (identical(kind, KEYWORD_TOKEN) &&
1879 (nextToken.value == 'async' || nextToken.value == 'sync')))) {
1880 return parseUnnamedFunction(token);
1775 } else { 1881 } else {
1776 bool old = mayParseFunctionExpressions; 1882 bool old = mayParseFunctionExpressions;
1777 mayParseFunctionExpressions = true; 1883 mayParseFunctionExpressions = true;
1778 token = parseParenthesizedExpression(token); 1884 token = parseParenthesizedExpression(token);
1779 mayParseFunctionExpressions = old; 1885 mayParseFunctionExpressions = old;
1780 return token; 1886 return token;
1781 } 1887 }
1782 } 1888 }
1783 1889
1784 Token parseParenthesizedExpression(Token token) { 1890 Token parseParenthesizedExpression(Token token) {
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
1886 return parseFunctionExpression(token); 1992 return parseFunctionExpression(token);
1887 } else { 1993 } else {
1888 return parseSend(token); 1994 return parseSend(token);
1889 } 1995 }
1890 } 1996 }
1891 1997
1892 bool isFunctionDeclaration(Token token) { 1998 bool isFunctionDeclaration(Token token) {
1893 if (optional('(', token)) { 1999 if (optional('(', token)) {
1894 BeginGroupToken begin = token; 2000 BeginGroupToken begin = token;
1895 String afterParens = begin.endGroup.next.stringValue; 2001 String afterParens = begin.endGroup.next.stringValue;
1896 if (identical(afterParens, '{') || identical(afterParens, '=>')) { 2002 if (identical(afterParens, '{') ||
2003 identical(afterParens, '=>') ||
2004 identical(afterParens, 'async') ||
2005 identical(afterParens, 'sync')) {
1897 return true; 2006 return true;
1898 } 2007 }
1899 } 2008 }
1900 return false; 2009 return false;
1901 } 2010 }
1902 2011
1903 Token parseRequiredArguments(Token token) { 2012 Token parseRequiredArguments(Token token) {
1904 if (optional('(', token)) { 2013 if (optional('(', token)) {
1905 token = parseArguments(token); 2014 token = parseArguments(token);
1906 } else { 2015 } else {
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after
2144 token = parseStatement(token); 2253 token = parseStatement(token);
2145 Token elseToken = null; 2254 Token elseToken = null;
2146 if (optional('else', token)) { 2255 if (optional('else', token)) {
2147 elseToken = token; 2256 elseToken = token;
2148 token = parseStatement(token.next); 2257 token = parseStatement(token.next);
2149 } 2258 }
2150 listener.endIfStatement(ifToken, elseToken); 2259 listener.endIfStatement(ifToken, elseToken);
2151 return token; 2260 return token;
2152 } 2261 }
2153 2262
2154 Token parseForStatement(Token token) { 2263 Token parseForStatement(Token awaitToken, Token token) {
2155 Token forToken = token; 2264 Token forToken = token;
2156 listener.beginForStatement(forToken); 2265 listener.beginForStatement(forToken);
2157 token = expect('for', token); 2266 token = expect('for', token);
2158 token = expect('(', token); 2267 token = expect('(', token);
2159 token = parseVariablesDeclarationOrExpressionOpt(token); 2268 token = parseVariablesDeclarationOrExpressionOpt(token);
2160 if (optional('in', token)) { 2269 if (optional('in', token)) {
2161 return parseForInRest(forToken, token); 2270 return parseForInRest(awaitToken, forToken, token);
2162 } else { 2271 } else {
2272 if (awaitToken != null) {
2273 listener.reportError(awaitToken, MessageKind.INVALID_AWAIT_FOR);
2274 }
2163 return parseForRest(forToken, token); 2275 return parseForRest(forToken, token);
2164 } 2276 }
2165 } 2277 }
2166 2278
2167 Token parseVariablesDeclarationOrExpressionOpt(Token token) { 2279 Token parseVariablesDeclarationOrExpressionOpt(Token token) {
2168 final String value = token.stringValue; 2280 final String value = token.stringValue;
2169 if (identical(value, ';')) { 2281 if (identical(value, ';')) {
2170 listener.handleNoExpression(token); 2282 listener.handleNoExpression(token);
2171 return token; 2283 return token;
2172 } else if ((identical(value, 'var')) || (identical(value, 'final'))) { 2284 } else if ((identical(value, 'var')) || (identical(value, 'final'))) {
(...skipping 26 matching lines...) Expand all
2199 } else { 2311 } else {
2200 break; 2312 break;
2201 } 2313 }
2202 } 2314 }
2203 token = expect(')', token); 2315 token = expect(')', token);
2204 token = parseStatement(token); 2316 token = parseStatement(token);
2205 listener.endForStatement(expressionCount, forToken, token); 2317 listener.endForStatement(expressionCount, forToken, token);
2206 return token; 2318 return token;
2207 } 2319 }
2208 2320
2209 Token parseForInRest(Token forToken, Token token) { 2321 Token parseForInRest(Token awaitToken, Token forToken, Token token) {
2210 assert(optional('in', token)); 2322 assert(optional('in', token));
2211 Token inKeyword = token; 2323 Token inKeyword = token;
2212 token = parseExpression(token.next); 2324 token = parseExpression(token.next);
2213 token = expect(')', token); 2325 token = expect(')', token);
2214 token = parseStatement(token); 2326 token = parseStatement(token);
2215 listener.endForIn(forToken, inKeyword, token); 2327 listener.endForIn(awaitToken, forToken, inKeyword, token);
2216 return token; 2328 return token;
2217 } 2329 }
2218 2330
2219 Token parseWhileStatement(Token token) { 2331 Token parseWhileStatement(Token token) {
2220 Token whileToken = token; 2332 Token whileToken = token;
2221 listener.beginWhileStatement(whileToken); 2333 listener.beginWhileStatement(whileToken);
2222 token = expect('while', token); 2334 token = expect('while', token);
2223 token = parseParenthesizedExpression(token); 2335 token = parseParenthesizedExpression(token);
2224 token = parseStatement(token); 2336 token = parseStatement(token);
2225 listener.endWhileStatement(whileToken, token); 2337 listener.endWhileStatement(whileToken, token);
(...skipping 18 matching lines...) Expand all
2244 int statementCount = 0; 2356 int statementCount = 0;
2245 token = expect('{', token); 2357 token = expect('{', token);
2246 while (notEofOrValue('}', token)) { 2358 while (notEofOrValue('}', token)) {
2247 token = parseStatement(token); 2359 token = parseStatement(token);
2248 ++statementCount; 2360 ++statementCount;
2249 } 2361 }
2250 listener.endBlock(statementCount, begin, token); 2362 listener.endBlock(statementCount, begin, token);
2251 return expect('}', token); 2363 return expect('}', token);
2252 } 2364 }
2253 2365
2366 Token parseAwaitExpression(Token token, bool allowCascades) {
2367 Token awaitToken = token;
2368 listener.beginAwaitExpression(awaitToken);
2369 token = expect('await', token);
2370 token = parseUnaryExpression(token, allowCascades);
2371 listener.endAwaitExpression(awaitToken, token);
2372 return token;
2373 }
2374
2254 Token parseThrowExpression(Token token, bool allowCascades) { 2375 Token parseThrowExpression(Token token, bool allowCascades) {
2255 Token throwToken = token; 2376 Token throwToken = token;
2256 listener.beginThrowExpression(throwToken); 2377 listener.beginThrowExpression(throwToken);
2257 token = expect('throw', token); 2378 token = expect('throw', token);
2258 token = allowCascades 2379 token = allowCascades
2259 ? parseExpression(token) 2380 ? parseExpression(token)
2260 : parseExpressionWithoutCascade(token); 2381 : parseExpressionWithoutCascade(token);
2261 listener.endThrowExpression(throwToken, token); 2382 listener.endThrowExpression(throwToken, token);
2262 return token; 2383 return token;
2263 } 2384 }
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after
2446 } 2567 }
2447 listener.handleContinueStatement(hasTarget, continueKeyword, token); 2568 listener.handleContinueStatement(hasTarget, continueKeyword, token);
2448 return expectSemicolon(token); 2569 return expectSemicolon(token);
2449 } 2570 }
2450 2571
2451 Token parseEmptyStatement(Token token) { 2572 Token parseEmptyStatement(Token token) {
2452 listener.handleEmptyStatement(token); 2573 listener.handleEmptyStatement(token);
2453 return expectSemicolon(token); 2574 return expectSemicolon(token);
2454 } 2575 }
2455 } 2576 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698