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

Unified Diff: pkg/front_end/lib/src/fasta/parser/parser.dart

Issue 2759663002: Improve parsing of async and generator methods. (Closed)
Patch Set: Ignore some error messages already handled by dart2js. Created 3 years, 9 months 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « pkg/front_end/lib/src/fasta/parser/error_kind.dart ('k') | pkg/front_end/lib/src/fasta/scanner/token.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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;
« no previous file with comments | « pkg/front_end/lib/src/fasta/parser/error_kind.dart ('k') | pkg/front_end/lib/src/fasta/scanner/token.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698