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

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

Issue 2990703002: Implemented support for generalized void in analyzer. (Closed)
Patch Set: Updated status for co19 tests and language/syntax_test Created 3 years, 5 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/analyzer/lib/src/generated/error_verifier.dart ('k') | 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 9053bb0463cc7ff2c731d2a2f2c579b3cdac5eca..ba2d870e52e4e5603a1461e46d076f2a5f740385 100644
--- a/pkg/analyzer/lib/src/generated/parser.dart
+++ b/pkg/analyzer/lib/src/generated/parser.dart
@@ -351,7 +351,7 @@ class Parser {
bool get hasReturnTypeInTypeAlias {
// TODO(brianwilkerson) This is too expensive as implemented and needs to be
// re-implemented or removed.
- Token next = skipReturnType(_currentToken);
+ Token next = skipTypeAnnotation(_currentToken);
if (next == null) {
return false;
}
@@ -449,10 +449,7 @@ class Parser {
*/
bool isFunctionDeclaration() {
Keyword keyword = _currentToken.keyword;
- if (keyword == Keyword.VOID) {
- return true;
- }
- Token afterReturnType = skipTypeName(_currentToken);
+ Token afterReturnType = skipTypeWithoutFunction(_currentToken);
if (afterReturnType != null &&
_tokenMatchesKeyword(afterReturnType, Keyword.FUNCTION)) {
afterReturnType = skipGenericFunctionTypeAfterReturnType(afterReturnType);
@@ -1328,9 +1325,6 @@ class Parser {
TokenType.COMMA,
TokenType.SEMICOLON
])) {
- if (returnType is! GenericFunctionType) {
- _reportErrorForNode(ParserErrorCode.VOID_VARIABLE, returnType);
- }
return parseInitializedIdentifierList(
commentAndMetadata,
modifiers.staticKeyword,
@@ -2137,9 +2131,6 @@ class Parser {
TokenType.COMMA,
TokenType.SEMICOLON
])) {
- if (returnType is! GenericFunctionType) {
- _reportErrorForNode(ParserErrorCode.VOID_VARIABLE, returnType);
- }
return astFactory.topLevelVariableDeclaration(
commentAndMetadata.comment,
commentAndMetadata.metadata,
@@ -2217,7 +2208,7 @@ class Parser {
null, _validateModifiersForTopLevelVariable(modifiers), null),
_expect(TokenType.SEMICOLON));
}
- TypeAnnotation returnType = parseReturnType(false);
+ TypeAnnotation returnType = parseTypeAnnotation(false);
keyword = _currentToken.keyword;
next = _peek();
if ((keyword == Keyword.GET || keyword == Keyword.SET) &&
@@ -2892,7 +2883,7 @@ class Parser {
keywordToken = null;
}
} else if (_isTypedIdentifier(_currentToken)) {
- type = parseReturnType(false);
+ type = parseTypeAnnotation(false);
} else if (inFunctionType && _matchesIdentifier()) {
type = parseTypeAnnotation(false);
} else if (!optional) {
@@ -3414,7 +3405,7 @@ class Parser {
* | '(' normalParameterTypes ',' optionalParameterTypes ')' |
* | '(' optionalParameterTypes ')'
* normalParameterTypes ::=
- * normalParameterType (',' normalParameterType)*
+ * normalParameterType (',' normalParameterType)*
* normalParameterType ::=
* type | typedIdentifier
* optionalParameterTypes ::=
@@ -4137,9 +4128,6 @@ class Parser {
TokenType.COMMA,
TokenType.SEMICOLON
])) {
- if (returnType is! GenericFunctionType) {
- _reportErrorForNode(ParserErrorCode.VOID_VARIABLE, returnType);
- }
return _parseVariableDeclarationStatementAfterType(
commentAndMetadata, null, returnType);
} else {
@@ -4217,9 +4205,6 @@ class Parser {
TokenType.COMMA,
TokenType.SEMICOLON
])) {
- if (returnType is! GenericFunctionType) {
- _reportErrorForNode(ParserErrorCode.VOID_VARIABLE, returnType);
- }
return _parseVariableDeclarationStatementAfterType(
commentAndMetadata, null, returnType);
} else {
@@ -4365,15 +4350,10 @@ class Parser {
//_reportErrorForToken(ParserErrorCode.MISSING_PARAMETERS, typeParameters.endToken);
}
TypeAnnotation type = holder.type;
- if (type != null) {
- if (type is TypeName &&
- _tokenMatchesKeyword(type.name.beginToken, Keyword.VOID)) {
- _reportErrorForToken(
- ParserErrorCode.VOID_PARAMETER, type.name.beginToken);
- } else if (holder.keyword != null &&
- _tokenMatchesKeyword(holder.keyword, Keyword.VAR)) {
- _reportErrorForToken(ParserErrorCode.VAR_AND_TYPE, holder.keyword);
- }
+ if (type != null &&
+ holder.keyword != null &&
+ _tokenMatchesKeyword(holder.keyword, Keyword.VAR)) {
+ _reportErrorForToken(ParserErrorCode.VAR_AND_TYPE, holder.keyword);
}
if (thisKeyword != null) {
// TODO(brianwilkerson) If there are type parameters but no parameters,
@@ -4701,14 +4681,14 @@ class Parser {
if (keyword == Keyword.AS) {
Token asOperator = getAndAdvance();
return astFactory.asExpression(
- expression, asOperator, parseTypeAnnotation(true));
+ expression, asOperator, parseTypeNotVoid(true));
} else if (keyword == Keyword.IS) {
Token isOperator = getAndAdvance();
Token notOperator = null;
if (_matches(TokenType.BANG)) {
notOperator = getAndAdvance();
}
- TypeAnnotation type = parseTypeAnnotation(true);
+ TypeAnnotation type = parseTypeNotVoid(true);
return astFactory.isExpression(expression, isOperator, notOperator, type);
} else if (_currentToken.type.isRelationalOperator) {
Token operator = getAndAdvance();
@@ -4747,26 +4727,6 @@ class Parser {
return astFactory.returnStatement(returnKeyword, expression, semicolon);
}
- /**
- * Parse a return type. Return the return type that was parsed.
- *
- * returnType ::=
- * 'void'
- * | type
- */
- TypeAnnotation parseReturnType(bool inExpression) {
- if (_currentToken.keyword == Keyword.VOID) {
- if (_atGenericFunctionTypeAfterReturnType(_peek())) {
- return parseTypeAnnotation(false);
- } else {
- return astFactory.typeName(
- astFactory.simpleIdentifier(getAndAdvance()), null);
- }
- } else {
- return parseTypeAnnotation(inExpression);
- }
- }
-
/**
* Parse a setter. The [commentAndMetadata] is the documentation comment and
* metadata to be associated with the declaration. The [externalKeyword] is
@@ -5130,7 +5090,7 @@ class Parser {
TypeName exceptionType = null;
if (_matchesKeyword(Keyword.ON)) {
onKeyword = getAndAdvance();
- exceptionType = parseTypeAnnotation(false);
+ exceptionType = parseTypeNotVoid(false);
}
Token catchKeyword = null;
Token leftParenthesis = null;
@@ -5218,6 +5178,27 @@ class Parser {
* | functionType
*/
TypeAnnotation parseTypeAnnotation(bool inExpression) {
+ TypeAnnotation type = null;
+ if (_atGenericFunctionTypeAfterReturnType(_currentToken)) {
+ // Generic function type with no return type.
+ type = parseGenericFunctionTypeAfterReturnType(null);
+ } else {
+ type = parseTypeWithoutFunction(inExpression);
+ }
+ while (_atGenericFunctionTypeAfterReturnType(_currentToken)) {
+ type = parseGenericFunctionTypeAfterReturnType(type);
+ }
+ return type;
+ }
+
+ /**
+ * Parse a type which is not `void`.
+ *
+ * typeNotVoid ::=
+ * functionType
+ * | typeNotVoidWithoutFunction
+ */
+ TypeAnnotation parseTypeNotVoid(bool inExpression) {
TypeAnnotation type = null;
if (_atGenericFunctionTypeAfterReturnType(_currentToken)) {
// Generic function type with no return type.
@@ -5235,6 +5216,22 @@ class Parser {
return type;
}
+ /**
+ * Parse a type which is not a function type.
+ *
+ * typeWithoutFunction ::=
+ * `void`
+ * | typeNotVoidWithoutFunction
+ */
+ TypeAnnotation parseTypeWithoutFunction(bool inExpression) {
+ if (_currentToken.keyword == Keyword.VOID) {
+ return astFactory.typeName(
+ astFactory.simpleIdentifier(getAndAdvance()), null);
+ } else {
+ return parseTypeName(inExpression);
+ }
+ }
+
/**
* Parse a list of type arguments. Return the type argument list that was
* parsed.
@@ -5260,11 +5257,14 @@ class Parser {
}
/**
- * Parse a type name. Return the type name that was parsed.
+ * Parse a type which is not void and is not a function type. Return the type
+ * that was parsed.
*
- * type ::=
+ * typeNotVoidWithoutFunction ::=
* qualified typeArguments?
*/
+ // TODO(eernst): Rename this to `parseTypeNotVoidWithoutFunction`?
+ // Apparently, it was named `parseTypeName` before type arguments existed.
TypeName parseTypeName(bool inExpression) {
TypeName realType = _parseTypeName(inExpression);
// If this is followed by a generic method type comment, allow the comment
@@ -5290,7 +5290,7 @@ class Parser {
}
if (_matchesKeyword(Keyword.EXTENDS)) {
Token keyword = getAndAdvance();
- TypeAnnotation bound = parseTypeAnnotation(false);
+ TypeAnnotation bound = parseTypeNotVoid(false);
return astFactory.typeParameter(commentAndMetadata.comment,
commentAndMetadata.metadata, name, keyword, bound);
}
@@ -5620,29 +5620,6 @@ class Parser {
return null;
}
- /**
- * Parse a return type, starting at the [startToken], without actually
- * creating a return type or changing the current token. Return the token
- * following the return type that was parsed, or `null` if the given token is
- * not the first token in a valid return type.
- *
- * This method must be kept in sync with [parseReturnType].
- *
- * returnType ::=
- * 'void'
- * | type
- */
- Token skipReturnType(Token startToken) {
- if (_tokenMatchesKeyword(startToken, Keyword.VOID)) {
- if (_atGenericFunctionTypeAfterReturnType(_peek())) {
- return skipTypeAnnotation(startToken);
- }
- return startToken.next;
- } else {
- return skipTypeAnnotation(startToken);
- }
- }
-
/**
* Parse a simple identifier, starting at the [startToken], without actually
* creating a simple identifier or changing the current token. Return the
@@ -5701,12 +5678,10 @@ class Parser {
Token skipTypeAnnotation(Token startToken) {
Token next = null;
if (_atGenericFunctionTypeAfterReturnType(startToken)) {
+ // Generic function type with no return type.
next = skipGenericFunctionTypeAfterReturnType(startToken);
- } else if (startToken.keyword == Keyword.VOID &&
- _atGenericFunctionTypeAfterReturnType(startToken.next)) {
- next = startToken.next;
} else {
- next = skipTypeName(startToken);
+ next = skipTypeWithoutFunction(startToken);
}
while (next != null && _atGenericFunctionTypeAfterReturnType(next)) {
next = skipGenericFunctionTypeAfterReturnType(next);
@@ -5714,6 +5689,22 @@ class Parser {
return next;
}
+ /**
+ * Parse a typeWithoutFunction, starting at the [startToken], without actually
+ * creating a TypeAnnotation or changing the current token. Return the token
+ * following the typeWithoutFunction that was parsed, or `null` if the given
+ * token is not the first token in a valid typeWithoutFunction.
+ *
+ * This method must be kept in sync with [parseTypeWithoutFunction].
+ */
+ Token skipTypeWithoutFunction(Token startToken) {
+ if (startToken.keyword == Keyword.VOID) {
+ return startToken.next;
+ } else {
+ return skipTypeName(startToken);
+ }
+ }
+
/**
* Parse a list of type arguments, starting at the [startToken], without
* actually creating a type argument list or changing the current token.
@@ -5735,7 +5726,7 @@ class Parser {
!_injectGenericCommentTypeList()) {
return null;
}
- token = skipTypeName(token.next);
+ token = skipTypeAnnotation(token.next);
if (token == null) {
// If the start token '<' is followed by '>'
// then assume this should be type argument list but is missing a type
@@ -5746,7 +5737,7 @@ class Parser {
return null;
}
while (_tokenMatches(token, TokenType.COMMA)) {
- token = skipTypeName(token.next);
+ token = skipTypeAnnotation(token.next);
if (token == null) {
return null;
}
@@ -5933,7 +5924,7 @@ class Parser {
// This looks like the start of a function
return true;
}
- Token token = skipReturnType(_currentToken);
+ Token token = skipTypeAnnotation(_currentToken);
if (token == null) {
return false;
}
@@ -6321,7 +6312,7 @@ class Parser {
* name that is followed by a variable or field formal parameter.
*/
bool _isTypedIdentifier(Token startToken) {
- Token token = skipReturnType(startToken);
+ Token token = skipTypeAnnotation(startToken);
if (token == null) {
return false;
} else if (_tokenMatchesIdentifier(token)) {
@@ -6330,10 +6321,6 @@ class Parser {
_tokenMatches(token.next, TokenType.PERIOD) &&
_tokenMatchesIdentifier(token.next.next)) {
return true;
- } else if (_tokenMatchesKeyword(startToken, Keyword.VOID)) {
- // The keyword 'void' isn't a valid identifier, so it should be assumed to
- // be a type name.
- return true;
} else if (startToken.next != token &&
!_tokenMatches(token, TokenType.OPEN_PAREN)) {
// The type is more than a simple identifier, so it should be assumed to
@@ -7011,7 +6998,7 @@ class Parser {
CommentAndMetadata commentAndMetadata, Token keyword) {
TypeAnnotation returnType = null;
if (hasReturnTypeInTypeAlias) {
- returnType = parseReturnType(false);
+ returnType = parseTypeAnnotation(false);
}
SimpleIdentifier name = parseSimpleIdentifier(isDeclaration: true);
TypeParameterList typeParameters = null;
@@ -7326,7 +7313,7 @@ class Parser {
// type.
return null;
}
- return parseReturnType(false);
+ return parseTypeAnnotation(false);
}
Token next2 = next.next;
Token next3 = next2.next;
@@ -7334,7 +7321,7 @@ class Parser {
_tokenMatchesIdentifier(next2) &&
(_tokenMatchesIdentifier(next3) ||
_tokenMatches(next3, TokenType.LT))) {
- return parseReturnType(false);
+ return parseTypeAnnotation(false);
}
}
return null;
@@ -7879,7 +7866,7 @@ class Parser {
(_tokenMatchesIdentifier(next.next.next) ||
_tokenMatches(next.next.next, TokenType.LT) ||
_tokenMatchesKeyword(next.next.next, Keyword.THIS)))) {
- return skipReturnType(startToken);
+ return skipTypeAnnotation(startToken);
}
}
return null;
« no previous file with comments | « pkg/analyzer/lib/src/generated/error_verifier.dart ('k') | pkg/analyzer/test/generated/parser_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698