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

Unified Diff: pkg/analyzer/lib/src/generated/parser.dart

Issue 2809773005: Fix parsing of generic function types as return types (Closed)
Patch Set: remove test Created 3 years, 8 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 | « no previous file | pkg/analyzer/test/generated/parser_test.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/analyzer/lib/src/generated/parser.dart
diff --git a/pkg/analyzer/lib/src/generated/parser.dart b/pkg/analyzer/lib/src/generated/parser.dart
index 26ee60613be6b5055b1191e563a1bf34cab90f24..ea555a569a305cacc769e3b6a14d38730087a094 100644
--- a/pkg/analyzer/lib/src/generated/parser.dart
+++ b/pkg/analyzer/lib/src/generated/parser.dart
@@ -1234,9 +1234,19 @@ class Parser {
CommentAndMetadata commentAndMetadata = parseCommentAndMetadata();
Modifiers modifiers = parseModifiers();
Keyword keyword = _currentToken.keyword;
- if (keyword == Keyword.VOID) {
- TypeName returnType = astFactory.typeName(
- astFactory.simpleIdentifier(getAndAdvance()), null);
+ if (keyword == Keyword.VOID ||
+ _atGenericFunctionTypeAfterReturnType(_currentToken)) {
+ TypeAnnotation returnType;
+ if (keyword == Keyword.VOID) {
+ if (_atGenericFunctionTypeAfterReturnType(_peek())) {
+ returnType = parseTypeAnnotation(false);
+ } else {
+ returnType = astFactory.typeName(
+ astFactory.simpleIdentifier(getAndAdvance()), null);
+ }
+ } else {
+ returnType = parseTypeAnnotation(false);
+ }
keyword = _currentToken.keyword;
Token next = _peek();
bool isFollowedByIdentifier = _tokenMatchesIdentifier(next);
@@ -2031,9 +2041,19 @@ class Parser {
} else if (keyword == Keyword.ENUM) {
_validateModifiersForEnum(modifiers);
return parseEnumDeclaration(commentAndMetadata);
- } else if (keyword == Keyword.VOID) {
- TypeName returnType = astFactory.typeName(
- astFactory.simpleIdentifier(getAndAdvance()), null);
+ } else if (keyword == Keyword.VOID ||
+ _atGenericFunctionTypeAfterReturnType(_currentToken)) {
+ TypeAnnotation returnType;
+ if (keyword == Keyword.VOID) {
+ if (_atGenericFunctionTypeAfterReturnType(next)) {
+ returnType = parseTypeAnnotation(false);
+ } else {
+ returnType = astFactory.typeName(
+ astFactory.simpleIdentifier(getAndAdvance()), null);
+ }
+ } else {
+ returnType = parseTypeAnnotation(false);
+ }
keyword = _currentToken.keyword;
next = _peek();
if ((keyword == Keyword.GET || keyword == Keyword.SET) &&
@@ -4019,8 +4039,13 @@ class Parser {
return parseVariableDeclarationStatementAfterMetadata(
commentAndMetadata);
} else if (keyword == Keyword.VOID) {
- TypeName returnType = astFactory.typeName(
- astFactory.simpleIdentifier(getAndAdvance()), null);
+ TypeAnnotation returnType;
+ if (_atGenericFunctionTypeAfterReturnType(_peek())) {
+ returnType = parseTypeAnnotation(false);
+ } else {
+ returnType = astFactory.typeName(
+ astFactory.simpleIdentifier(getAndAdvance()), null);
+ }
Token next = _currentToken.next;
if (_matchesIdentifier() &&
next.matchesAny(const <TokenType>[
@@ -4101,6 +4126,48 @@ class Parser {
return astFactory
.emptyStatement(_createSyntheticToken(TokenType.SEMICOLON));
}
+ } else if (_atGenericFunctionTypeAfterReturnType(_currentToken)) {
+ TypeAnnotation returnType = parseTypeAnnotation(false);
+ Token next = _currentToken.next;
+ if (_matchesIdentifier() &&
+ next.matchesAny(const <TokenType>[
+ TokenType.OPEN_PAREN,
+ TokenType.OPEN_CURLY_BRACKET,
+ TokenType.FUNCTION,
+ TokenType.LT
+ ])) {
+ return _parseFunctionDeclarationStatementAfterReturnType(
+ commentAndMetadata, returnType);
+ } else {
+ //
+ // We have found an error of some kind. Try to recover.
+ //
+ if (_matchesIdentifier()) {
+ if (next.matchesAny(const <TokenType>[
+ TokenType.EQ,
+ TokenType.COMMA,
+ TokenType.SEMICOLON
+ ])) {
+ //
+ // We appear to have a variable declaration with a type of "void".
+ //
+ _reportErrorForNode(ParserErrorCode.VOID_VARIABLE, returnType);
+ return parseVariableDeclarationStatementAfterMetadata(
+ commentAndMetadata);
+ }
+ } else if (_matches(TokenType.CLOSE_CURLY_BRACKET)) {
+ //
+ // We appear to have found an incomplete statement at the end of a
+ // block. Parse it as a variable declaration.
+ //
+ return _parseVariableDeclarationStatementAfterType(
+ commentAndMetadata, null, returnType);
+ }
+ _reportErrorForCurrentToken(ParserErrorCode.MISSING_STATEMENT);
+ // TODO(brianwilkerson) Recover from this error.
+ return astFactory
+ .emptyStatement(_createSyntheticToken(TokenType.SEMICOLON));
+ }
} else if (_inGenerator && _matchesKeyword(Keyword.YIELD)) {
return parseYieldStatement();
} else if (_inAsync && _matchesKeyword(Keyword.AWAIT)) {
@@ -4618,8 +4685,12 @@ class Parser {
*/
TypeAnnotation parseReturnType(bool inExpression) {
if (_currentToken.keyword == Keyword.VOID) {
- return astFactory.typeName(
- astFactory.simpleIdentifier(getAndAdvance()), null);
+ if (_atGenericFunctionTypeAfterReturnType(_peek())) {
+ return parseTypeAnnotation(false);
+ } else {
+ return astFactory.typeName(
+ astFactory.simpleIdentifier(getAndAdvance()), null);
+ }
} else {
return parseTypeAnnotation(inExpression);
}
@@ -5480,6 +5551,9 @@ class Parser {
*/
Token skipReturnType(Token startToken) {
if (_tokenMatchesKeyword(startToken, Keyword.VOID)) {
+ if (_atGenericFunctionTypeAfterReturnType(_peek())) {
+ return skipTypeAnnotation(startToken);
+ }
return startToken.next;
} else {
return skipTypeAnnotation(startToken);
@@ -7148,6 +7222,9 @@ class Parser {
}
Keyword keyword = _currentToken.keyword;
if (keyword == Keyword.VOID) {
+ if (_atGenericFunctionTypeAfterReturnType(_peek())) {
+ return parseTypeAnnotation(false);
+ }
return astFactory.typeName(
astFactory.simpleIdentifier(getAndAdvance()), null);
} else if (_matchesIdentifier()) {
« no previous file with comments | « no previous file | pkg/analyzer/test/generated/parser_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698