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

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

Issue 2710973002: Revert "Add support for the new function-type syntax." (Closed)
Patch Set: Created 3 years, 10 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
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 a0119eb7b6f15ccea75e4f066a9b8259b10302af..19512820017d87d353339ceba1ae7bad30986160 100644
--- a/pkg/front_end/lib/src/fasta/parser/parser.dart
+++ b/pkg/front_end/lib/src/fasta/parser/parser.dart
@@ -100,7 +100,7 @@ class FormalParameterType {
* Subclasses of the class [Listener] are used to listen to events.
*
* Most methods of this class belong in one of two major categories:
- * parse methods and peek methods. Parse methods all have the prefix
+ * parse metods and peek methods. Parse methods all have the prefix
* parse, and peek methods all have the prefix peek.
*
* Parse methods generate events (by calling methods on [listener])
@@ -385,20 +385,11 @@ class Parser {
Token parseTypedef(Token token) {
Token typedefKeyword = token;
listener.beginFunctionTypeAlias(token);
- Token equals;
- if (optional('=', peekAfterNominalType(token.next))) {
- token = parseIdentifier(token.next);
- token = parseTypeVariablesOpt(token);
- equals = token;
- token = expect('=', token);
- token = parseType(token);
- } else {
- token = parseReturnTypeOpt(token.next);
- token = parseIdentifier(token);
- token = parseTypeVariablesOpt(token);
- token = parseFormalParameters(token);
- }
- listener.endFunctionTypeAlias(typedefKeyword, equals, token);
+ token = parseReturnTypeOpt(token.next);
+ token = parseIdentifier(token);
+ token = parseTypeVariablesOpt(token);
+ token = parseFormalParameters(token);
+ listener.endFunctionTypeAlias(typedefKeyword, token);
return expect(';', token);
}
@@ -413,12 +404,8 @@ class Parser {
Token parseReturnTypeOpt(Token token) {
if (identical(token.stringValue, 'void')) {
- if (isGeneralizedFunctionType(token.next)) {
- return parseType(token);
- } else {
- listener.handleVoidKeyword(token);
- return token.next;
- }
+ listener.handleVoidKeyword(token);
+ return token.next;
} else {
return parseTypeOpt(token);
}
@@ -450,11 +437,7 @@ class Parser {
return endToken.next;
}
- /// Parses the formal parameter list of a function.
- ///
- /// If [inFunctionType] is true, then the names may be omitted (except for
- /// named arguments). If it is false, then the types may be omitted.
- Token parseFormalParameters(Token token, {bool inFunctionType: false}) {
+ Token parseFormalParameters(Token token) {
Token begin = token;
listener.beginFormalParameters(begin);
expect('(', token);
@@ -467,23 +450,19 @@ class Parser {
++parameterCount;
String value = token.stringValue;
if (identical(value, '[')) {
- token = parseOptionalFormalParameters(
- token, false, inFunctionType: inFunctionType);
+ token = parseOptionalFormalParameters(token, false);
break;
} else if (identical(value, '{')) {
- token = parseOptionalFormalParameters(
- token, true, inFunctionType: inFunctionType);
+ token = parseOptionalFormalParameters(token, true);
break;
}
- token = parseFormalParameter(token, FormalParameterType.REQUIRED,
- inFunctionType: inFunctionType);
+ token = parseFormalParameter(token, FormalParameterType.REQUIRED);
} while (optional(',', token));
listener.endFormalParameters(parameterCount, begin, token);
return expect(')', token);
}
- Token parseFormalParameter(Token token, FormalParameterType type,
- {bool inFunctionType}) {
+ Token parseFormalParameter(Token token, FormalParameterType type) {
token = parseMetadataStar(token, forParameter: true);
listener.beginFormalParameter(token);
@@ -496,51 +475,26 @@ class Parser {
token = token.next;
}
token = parseModifiers(token);
- bool isNamedParameter = type == FormalParameterType.NAMED;
-
+ // TODO(ahe): Validate that there are formal parameters if void.
+ token = parseReturnTypeOpt(token);
Token thisKeyword = null;
- if (inFunctionType && isNamedParameter) {
- token = parseType(token);
- token = parseIdentifier(token);
- } else if (inFunctionType) {
- token = parseType(token);
- if (token.isIdentifier()) {
- token = parseIdentifier(token);
- } else {
- listener.handleNoName(token);
- }
- } else {
- token = parseReturnTypeOpt(token);
- if (optional('this', token)) {
- thisKeyword = token;
- token = expect('.', token.next);
- }
- token = parseIdentifier(token);
+ if (optional('this', token)) {
+ thisKeyword = token;
+ // TODO(ahe): Validate field initializers are only used in
+ // constructors, and not for function-typed arguments.
+ token = expect('.', token.next);
}
-
- // Generalized function types don't allow inline function types.
- // The following isn't allowed:
- // int Function(int bar(String x)).
+ token = parseIdentifier(token);
if (optional('(', token)) {
- Token inlineFunctionTypeStart = token;
listener.beginFunctionTypedFormalParameter(token);
listener.handleNoTypeVariables(token);
token = parseFormalParameters(token);
listener.endFunctionTypedFormalParameter(token);
- if (inFunctionType) {
- reportRecoverableError(
- inlineFunctionTypeStart, ErrorKind.InvalidInlineFunctionType);
- }
} else if (optional('<', token)) {
- Token inlineFunctionTypeStart = token;
listener.beginFunctionTypedFormalParameter(token);
token = parseTypeVariablesOpt(token);
token = parseFormalParameters(token);
listener.endFunctionTypedFormalParameter(token);
- if (inFunctionType) {
- reportRecoverableError(
- inlineFunctionTypeStart, ErrorKind.InvalidInlineFunctionType);
- }
}
String value = token.stringValue;
if ((identical('=', value)) || (identical(':', value))) {
@@ -560,8 +514,7 @@ class Parser {
return token;
}
- Token parseOptionalFormalParameters(Token token, bool isNamed,
- {bool inFunctionType}) {
+ Token parseOptionalFormalParameters(Token token, bool isNamed) {
Token begin = token;
listener.beginOptionalFormalParameters(begin);
assert((isNamed && optional('{', token)) || optional('[', token));
@@ -575,8 +528,7 @@ class Parser {
}
var type =
isNamed ? FormalParameterType.NAMED : FormalParameterType.POSITIONAL;
- token =
- parseFormalParameter(token, type, inFunctionType: inFunctionType);
+ token = parseFormalParameter(token, type);
++parameterCount;
} while (optional(',', token));
if (parameterCount == 0) {
@@ -595,10 +547,6 @@ class Parser {
}
Token parseTypeOpt(Token token) {
- if (isGeneralizedFunctionType(token)) {
- // Function type without return type.
- return parseType(token);
- }
Token peek = peekAfterIfType(token);
if (peek != null && (peek.isIdentifier() || optional('this', peek))) {
return parseType(token);
@@ -773,7 +721,7 @@ class Parser {
modifierCount++;
}
listener.handleModifiers(modifierCount);
- bool isMixinApplication = optional('=', peekAfterNominalType(token));
+ bool isMixinApplication = optional('=', peekAfterType(token));
Token name = token.next;
token = parseIdentifier(name);
@@ -812,7 +760,7 @@ class Parser {
Token extendsKeyword;
if (optional('extends', token)) {
extendsKeyword = token;
- if (optional('with', peekAfterNominalType(token.next))) {
+ if (optional('with', peekAfterType(token.next))) {
token = parseMixinApplication(token.next);
} else {
token = parseType(token.next);
@@ -904,52 +852,17 @@ class Parser {
!identical(value, token.stringValue);
}
- bool isGeneralizedFunctionType(Token token) {
- return optional('Function', token) &&
- (optional('<', token.next) || optional('(', token.next));
- }
-
Token parseType(Token token) {
Token begin = token;
- if (isGeneralizedFunctionType(token)) {
- // A function type without return type.
- // Push the non-existing return type first. The loop below will
- // generate the full type.
- listener.handleNoType(token);
- } else if (identical(token.stringValue, 'void') &&
- isGeneralizedFunctionType(token.next)) {
- listener.handleVoidKeyword(token);
- token = token.next;
+ if (isValidTypeReference(token)) {
+ token = parseIdentifier(token);
+ token = parseQualifiedRestOpt(token);
} else {
- if (isValidTypeReference(token)) {
- token = parseIdentifier(token);
- token = parseQualifiedRestOpt(token);
- } else {
- token = reportUnrecoverableError(token, ErrorKind.ExpectedType);
- listener.handleInvalidTypeReference(token);
- }
- token = parseTypeArgumentsOpt(token);
- listener.handleType(begin, token);
- }
-
- // While we see a `Function(` treat the pushed type as return type.
- // For example: `int Function() Function(int) Function(String x)`.
- while (isGeneralizedFunctionType(token)) {
- token = parseFunctionType(token);
+ token = reportUnrecoverableError(token, ErrorKind.ExpectedType);
+ listener.handleInvalidTypeReference(token);
}
- return token;
- }
-
- /// Parses a generalized function type.
- ///
- /// The return type must already be pushed.
- Token parseFunctionType(Token token) {
- assert(optional('Function', token));
- Token functionToken = token;
- token = token.next;
- token = parseTypeVariablesOpt(token);
- token = parseFormalParameters(token, inFunctionType: true);
- listener.handleFunctionType(functionToken, token);
+ token = parseTypeArgumentsOpt(token);
+ listener.endType(begin, token);
return token;
}
@@ -1169,8 +1082,7 @@ class Parser {
if (!hasType) {
listener.handleNoType(name);
- } else if (optional('void', type) &&
- !isGeneralizedFunctionType(type.next)) {
+ } else if (optional('void', type)) {
listener.handleNoType(name);
// TODO(ahe): This error is reported twice, second time is from
// [parseVariablesDeclarationMaybeSemicolon] via
@@ -1306,58 +1218,27 @@ class Parser {
hasName = true;
}
identifiers = identifiers.prepend(token);
-
- if (!isGeneralizedFunctionType(token)) {
- // Read a potential return type.
- if (isValidTypeReference(token)) {
- // type ...
- if (optional('.', token.next)) {
- // type '.' ...
- if (token.next.next.isIdentifier()) {
- // type '.' identifier
- token = token.next.next;
- }
- }
- if (optional('<', token.next)) {
- if (token.next is BeginGroupToken) {
- BeginGroupToken beginGroup = token.next;
- if (beginGroup.endGroup == null) {
- reportUnrecoverableError(beginGroup, ErrorKind.UnmatchedToken);
- } else {
- token = beginGroup.endGroup;
- }
- }
+ if (isValidTypeReference(token)) {
+ // type ...
+ if (optional('.', token.next)) {
+ // type '.' ...
+ if (token.next.next.isIdentifier()) {
+ // type '.' identifier
+ token = token.next.next;
}
}
- token = token.next;
- }
- while (isGeneralizedFunctionType(token)) {
- token = token.next;
- if (optional('<', token)) {
- if (token is BeginGroupToken) {
- BeginGroupToken beginGroup = token;
+ if (optional('<', token.next)) {
+ if (token.next is BeginGroupToken) {
+ BeginGroupToken beginGroup = token.next;
if (beginGroup.endGroup == null) {
reportUnrecoverableError(beginGroup, ErrorKind.UnmatchedToken);
} else {
- token = beginGroup.endGroup.next;
+ token = beginGroup.endGroup;
}
}
}
- if (!optional('(', token)) {
- if (optional(';', token)) {
- reportRecoverableError(token, ErrorKind.ExpectedOpenParens);
- }
- token = expect("(", token);
- }
- if (token is BeginGroupToken) {
- BeginGroupToken beginGroup = token;
- if (beginGroup.endGroup == null) {
- reportUnrecoverableError(beginGroup, ErrorKind.UnmatchedToken);
- } else {
- token = beginGroup.endGroup.next;
- }
- }
}
+ token = token.next;
}
return listener.handleMemberName(const Link<Token>());
}
@@ -1472,31 +1353,11 @@ class Parser {
/**
* Returns the first token after the type starting at [token].
- *
* This method assumes that [token] is an identifier (or void).
* Use [peekAfterIfType] if [token] isn't known to be an identifier.
*/
Token peekAfterType(Token token) {
// We are looking at "identifier ...".
- Token peek = token;
- if (!isGeneralizedFunctionType(token)) {
- peek = peekAfterNominalType(token);
- }
-
- // We might have just skipped over the return value of the function type.
- // Check again, if we are now at a function type position.
- while (isGeneralizedFunctionType(peek)) {
- peek = peekAfterFunctionType(peek.next);
- }
- return peek;
- }
-
- /**
- * Returns the first token after the nominal type starting at [token].
- *
- * This method assumes that [token] is an identifier (or void).
- */
- Token peekAfterNominalType(Token token) {
Token peek = token.next;
if (identical(peek.kind, PERIOD_TOKEN)) {
if (peek.next.isIdentifier()) {
@@ -1512,54 +1373,9 @@ class Parser {
Token gtToken = beginGroupToken.endGroup;
if (gtToken != null) {
// We are looking at "qualified '<' ... '>' ...".
- peek = gtToken.next;
- }
- }
- return peek;
- }
-
- /**
- * Returns the first token after the function type starting at [token].
- *
- * The token must be at the token *after* the `Function` token position. That
- * is, the return type and the `Function` token must have already been
- * skipped.
- *
- * This function only skips over one function type syntax.
- * If necessary, this function must be called multiple times.
- *
- * Example:
- * ```
- * int Function() Function<T>(int)
- * ^ ^
- * A call to this function must be either at `(` or at `<`.
- * If `token` pointed to the first `(`, then the returned
- * token points to the second `Function` token.
- */
- Token peekAfterFunctionType(Token token) {
- // Possible inputs are:
- // ( ... )
- // < ... >( ... )
-
- Token peek = token;
- // If there is a generic argument to the function, skip over that one first.
- if (identical(peek.kind, LT_TOKEN)) {
- BeginGroupToken beginGroupToken = peek;
- Token closeToken = beginGroupToken.endGroup;
- if (closeToken != null) {
- peek = closeToken.next;
+ return gtToken.next;
}
}
-
- // Now we just need to skip over the formals.
- expect('(', peek);
-
- BeginGroupToken beginGroupToken = peek;
- Token closeToken = beginGroupToken.endGroup;
- if (closeToken != null) {
- peek = closeToken.next;
- }
-
return peek;
}
« no previous file with comments | « pkg/front_end/lib/src/fasta/parser/listener.dart ('k') | pkg/front_end/lib/src/fasta/scanner/abstract_scanner.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698