| Index: pkg/front_end/lib/src/fasta/parser/parser.dart
|
| diff --git a/pkg/front_end/lib/src/fasta/parser/parser.dart b/pkg/front_end/lib/src/fasta/parser/parser.dart
|
| index 1650fd13741f968bf9c9dcf4490551b62159aa60..149b86c599880b840fa52a95003d254246d53757 100644
|
| --- a/pkg/front_end/lib/src/fasta/parser/parser.dart
|
| +++ b/pkg/front_end/lib/src/fasta/parser/parser.dart
|
| @@ -135,6 +135,8 @@ class Parser {
|
| asyncState == AsyncModifier.AsyncStar;
|
| }
|
|
|
| + bool get inPlainSync => asyncState == AsyncModifier.Sync;
|
| +
|
| Token parseUnit(Token token) {
|
| listener.beginCompilationUnit(token);
|
| int count = 0;
|
| @@ -909,6 +911,14 @@ class Parser {
|
| } else if (!optional("dynamic", token)) {
|
| reportRecoverableError(token, ErrorKind.BuiltInIdentifierAsType);
|
| }
|
| + } else if (!inPlainSync && token.isPseudo) {
|
| + if (optional('await', token)) {
|
| + reportRecoverableError(token, ErrorKind.AwaitAsIdentifier);
|
| + } else if (optional('yield', token)) {
|
| + reportRecoverableError(token, ErrorKind.YieldAsIdentifier);
|
| + } else if (optional('async', token)) {
|
| + reportRecoverableError(token, ErrorKind.AsyncAsIdentifier);
|
| + }
|
| }
|
| listener.handleIdentifier(token, context);
|
| return token.next;
|
| @@ -1315,7 +1325,11 @@ class Parser {
|
| }
|
| token = parseFormalParametersOpt(token);
|
| AsyncModifier savedAsyncModifier = asyncState;
|
| + Token asyncToken = token;
|
| token = parseAsyncModifier(token);
|
| + if (getOrSet != null && !inPlainSync && optional("set", getOrSet)) {
|
| + reportRecoverableError(asyncToken, ErrorKind.SetterNotSync);
|
| + }
|
| token = parseFunctionBody(token, false, externalModifier != null);
|
| asyncState = savedAsyncModifier;
|
| Token endToken = token;
|
| @@ -1873,7 +1887,11 @@ class Parser {
|
| token = parseFormalParametersOpt(token);
|
| token = parseInitializersOpt(token);
|
| AsyncModifier savedAsyncModifier = asyncState;
|
| + Token asyncToken = token;
|
| token = parseAsyncModifier(token);
|
| + if (getOrSet != null && !inPlainSync && optional("set", getOrSet)) {
|
| + reportRecoverableError(asyncToken, ErrorKind.SetterNotSync);
|
| + }
|
| if (optional('=', token)) {
|
| token = parseRedirectingFactoryBody(token);
|
| } else {
|
| @@ -1903,7 +1921,11 @@ class Parser {
|
| token = expect('factory', token);
|
| token = parseConstructorReference(token);
|
| token = parseFormalParameters(token);
|
| + Token asyncToken = token;
|
| token = parseAsyncModifier(token);
|
| + if (!inPlainSync) {
|
| + reportRecoverableError(asyncToken, ErrorKind.FactoryNotSync);
|
| + }
|
| if (optional('=', token)) {
|
| token = parseRedirectingFactoryBody(token);
|
| } else {
|
| @@ -2168,6 +2190,11 @@ class Parser {
|
| }
|
| }
|
| listener.handleAsyncModifier(async, star);
|
| + if (inGenerator && optional('=>', token)) {
|
| + reportRecoverableError(token, ErrorKind.GeneratorReturnsValue);
|
| + } else if (!inPlainSync && optional(';', token)) {
|
| + reportRecoverableError(token, ErrorKind.AbstractNotSync);
|
| + }
|
| return token;
|
| }
|
|
|
| @@ -2196,12 +2223,11 @@ class Parser {
|
| return parseVariablesDeclaration(token);
|
| } else if (identical(value, 'if')) {
|
| return parseIfStatement(token);
|
| - } else if (asyncState != AsyncModifier.Sync && identical(value, 'await')) {
|
| - if (identical(token.next.stringValue, 'for')) {
|
| - return parseForStatement(token, token.next);
|
| - } else {
|
| - return parseExpressionStatement(token);
|
| + } else if (identical(value, 'await') && optional('for', token.next)) {
|
| + if (!inAsync) {
|
| + reportRecoverableError(token, ErrorKind.AwaitForNotAsync);
|
| }
|
| + return parseForStatement(token, token.next);
|
| } else if (identical(value, 'for')) {
|
| return parseForStatement(null, token);
|
| } else if (identical(value, 'rethrow')) {
|
| @@ -2227,8 +2253,20 @@ class Parser {
|
| return parseAssertStatement(token);
|
| } else if (identical(value, ';')) {
|
| return parseEmptyStatement(token);
|
| - } else if (asyncState != AsyncModifier.Sync && identical(value, 'yield')) {
|
| - return parseYieldStatement(token);
|
| + } else if (identical(value, 'yield')) {
|
| + switch (asyncState) {
|
| + case AsyncModifier.Sync:
|
| + return parseExpressionStatementOrDeclaration(token);
|
| +
|
| + case AsyncModifier.SyncStar:
|
| + case AsyncModifier.AsyncStar:
|
| + return parseYieldStatement(token);
|
| +
|
| + case AsyncModifier.Async:
|
| + reportRecoverableError(token, ErrorKind.YieldNotGenerator);
|
| + return parseYieldStatement(token);
|
| + }
|
| + throw "Internal error: Unknown asyncState: '$asyncState'.";
|
| } else if (identical(value, 'const')) {
|
| return parseExpressionStatementOrConstDeclaration(token);
|
| } else if (token.isIdentifier()) {
|
| @@ -2262,6 +2300,9 @@ class Parser {
|
| listener.endReturnStatement(false, begin, token);
|
| } else {
|
| token = parseExpression(token);
|
| + if (inGenerator) {
|
| + reportRecoverableError(begin.next, ErrorKind.GeneratorReturnsValue);
|
| + }
|
| listener.endReturnStatement(true, begin, token);
|
| }
|
| return expectSemicolon(token);
|
| @@ -2291,6 +2332,9 @@ class Parser {
|
| }
|
|
|
| Token parseExpressionStatementOrDeclaration(Token token) {
|
| + if (!inPlainSync && optional("await", token)) {
|
| + return parseExpressionStatement(token);
|
| + }
|
| assert(token.isIdentifier() || identical(token.stringValue, 'void'));
|
| Token identifier = peekIdentifierAfterType(token);
|
| if (identifier != null) {
|
| @@ -2630,8 +2674,12 @@ class Parser {
|
| Token parseUnaryExpression(Token token, bool allowCascades) {
|
| String value = token.stringValue;
|
| // Prefix:
|
| - if (asyncState != AsyncModifier.Sync && optional('await', token)) {
|
| - return parseAwaitExpression(token, allowCascades);
|
| + if (optional('await', token)) {
|
| + if (inPlainSync) {
|
| + return parsePrimary(token);
|
| + } else {
|
| + return parseAwaitExpression(token, allowCascades);
|
| + }
|
| } else if (identical(value, '+')) {
|
| // Dart no longer allows prefix-plus.
|
| reportRecoverableError(token, ErrorKind.UnsupportedPrefixPlus);
|
| @@ -2645,6 +2693,7 @@ class Parser {
|
| token = parsePrecedenceExpression(
|
| token.next, POSTFIX_PRECEDENCE, allowCascades);
|
| listener.handleUnaryPrefixExpression(operator);
|
| + return token;
|
| } else if ((identical(value, '++')) || identical(value, '--')) {
|
| // TODO(ahe): Validate this is used correctly.
|
| Token operator = token;
|
| @@ -2653,10 +2702,10 @@ class Parser {
|
| token = parsePrecedenceExpression(
|
| token.next, POSTFIX_PRECEDENCE, allowCascades);
|
| listener.handleUnaryPrefixAssignmentExpression(operator);
|
| + return token;
|
| } else {
|
| - token = parsePrimary(token);
|
| + return parsePrimary(token);
|
| }
|
| - return token;
|
| }
|
|
|
| Token parseArgumentOrIndexStar(Token token) {
|
| @@ -2709,7 +2758,7 @@ class Parser {
|
| return parseConstExpression(token);
|
| } else if (identical(value, "void")) {
|
| return parseFunctionExpression(token);
|
| - } else if (asyncState != AsyncModifier.Sync &&
|
| + } else if (!inPlainSync &&
|
| (identical(value, "yield") || identical(value, "async"))) {
|
| return expressionExpected(token);
|
| } else if (token.isIdentifier()) {
|
| @@ -3362,6 +3411,9 @@ class Parser {
|
| Token awaitToken = token;
|
| listener.beginAwaitExpression(awaitToken);
|
| token = expect('await', token);
|
| + if (!inAsync) {
|
| + reportRecoverableError(awaitToken, ErrorKind.AwaitNotAsync);
|
| + }
|
| token = parsePrecedenceExpression(token, POSTFIX_PRECEDENCE, allowCascades);
|
| listener.endAwaitExpression(awaitToken, token);
|
| return token;
|
|
|