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

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

Issue 2985673002: Parse type variables of local functions before return type. (Closed)
Patch Set: 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/front_end/lib/src/fasta/parser/listener.dart ('k') | no next file » | 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 8ff84bbd67275d6faad324a2b93e364b48d592c8..c2c49517661540064ba3c8df8283d1b95682ef98 100644
--- a/pkg/front_end/lib/src/fasta/parser/parser.dart
+++ b/pkg/front_end/lib/src/fasta/parser/parser.dart
@@ -1176,14 +1176,8 @@ class Parser {
}
if (looksLikeType && token.isIdentifier) {
- // If the identifier token has a type substitution comment /*=T*/,
- // then the set of tokens type tokens should be replaced with the
- // tokens parsed from the comment.
Token afterId = token.next;
- begin =
- listener.replaceTokenWithGenericCommentTypeAssign(begin, token);
ahe 2017/07/21 16:02:19 This has already been called when we analyze the t
-
int afterIdKind = afterId.kind;
if (looksLikeVariableDeclarationEnd(afterIdKind)) {
// We are looking at `type identifier` followed by
@@ -1197,18 +1191,44 @@ class Parser {
if (looksLikeFunctionBody(closeBraceTokenFor(afterId).next)) {
// We are looking at `type identifier '(' ... ')'` followed
// `( '{' | '=>' | 'async' | 'sync' )`.
- return parseLocalFunctionDeclaration(begin);
+
+ // Although it looks like there are no type variables here, they
+ // may get injected from a comment.
+ Token formals = parseTypeVariablesOpt(afterId);
+
+ listener.beginLocalFunctionDeclaration(begin);
+ listener.handleModifiers(0);
+ if (voidToken != null) {
+ listener.handleVoidKeyword(voidToken);
+ } else {
+ commitType();
+ }
+ listener.beginFunctionName(token);
+ token = parseIdentifier(
+ token, IdentifierContext.localFunctionDeclaration);
+ listener.endFunctionName(begin, token);
+ return parseLocalFunctionDeclarationFromFormals(formals);
}
} else if (identical(afterIdKind, LT_TOKEN)) {
// We are looking at `type identifier '<'`.
- Token afterTypeVariables = closeBraceTokenFor(afterId)?.next;
- if (afterTypeVariables != null &&
- optional("(", afterTypeVariables)) {
- if (looksLikeFunctionBody(
- closeBraceTokenFor(afterTypeVariables).next)) {
+ Token formals = closeBraceTokenFor(afterId)?.next;
+ if (formals != null && optional("(", formals)) {
+ if (looksLikeFunctionBody(closeBraceTokenFor(formals).next)) {
// We are looking at "type identifier '<' ... '>' '(' ... ')'"
// followed by '{', '=>', 'async', or 'sync'.
- return parseLocalFunctionDeclaration(begin);
+ parseTypeVariablesOpt(afterId);
+ listener.beginLocalFunctionDeclaration(begin);
+ listener.handleModifiers(0);
+ if (voidToken != null) {
+ listener.handleVoidKeyword(voidToken);
+ } else {
+ commitType();
+ }
+ listener.beginFunctionName(token);
+ token = parseIdentifier(
+ token, IdentifierContext.localFunctionDeclaration);
+ listener.endFunctionName(begin, token);
+ return parseLocalFunctionDeclarationFromFormals(formals);
}
}
}
@@ -1219,7 +1239,21 @@ class Parser {
return parseLabeledStatement(token);
} else if (optional('(', token.next)) {
if (looksLikeFunctionBody(closeBraceTokenFor(token.next).next)) {
- return parseLocalFunctionDeclaration(token);
+ // We are looking at `identifier '(' ... ')'` followed by `'{'`,
+ // `'=>'`, `'async'`, or `'sync'`.
+
+ // Although it looks like there are no type variables here, they
+ // may get injected from a comment.
+ Token formals = parseTypeVariablesOpt(token.next);
+
+ listener.beginLocalFunctionDeclaration(token);
+ listener.handleModifiers(0);
+ listener.handleNoType(token);
+ listener.beginFunctionName(token);
+ token = parseIdentifier(
+ token, IdentifierContext.localFunctionDeclaration);
+ listener.endFunctionName(begin, token);
+ return parseLocalFunctionDeclarationFromFormals(formals);
}
} else if (optional('<', token.next)) {
Token afterTypeVariables = closeBraceTokenFor(token.next)?.next;
@@ -1227,7 +1261,18 @@ class Parser {
optional("(", afterTypeVariables)) {
if (looksLikeFunctionBody(
closeBraceTokenFor(afterTypeVariables).next)) {
- return parseLocalFunctionDeclaration(token);
+ // We are looking at `identifier '<' ... '>' '(' ... ')'`
+ // followed by `'{'`, `'=>'`, `'async'`, or `'sync'`.
+ parseTypeVariablesOpt(token.next);
+ listener.beginLocalFunctionDeclaration(token);
+ listener.handleModifiers(0);
+ listener.handleNoType(token);
+ listener.beginFunctionName(token);
danrubel 2017/07/21 17:11:20 From this line down to the return statement looks
ahe 2017/08/07 11:45:27 You inspired me to go a bit further, and I decided
+ token = parseIdentifier(
+ token, IdentifierContext.localFunctionDeclaration);
+ listener.endFunctionName(begin, token);
+ return parseLocalFunctionDeclarationFromFormals(
+ afterTypeVariables);
}
}
// Fall through to expression statement.
@@ -2335,16 +2380,17 @@ class Parser {
return isBlock ? token.next : token;
}
- Token parseLocalFunctionDeclaration(Token token) {
- listener.beginLocalFunctionDeclaration(token);
- Token beginToken = token;
- token = parseModifiers(token, MemberKind.Local);
- listener.beginFunctionName(token);
- token = parseIdentifier(token, IdentifierContext.localFunctionDeclaration);
- token = parseQualifiedRestOpt(
- token, IdentifierContext.localFunctionDeclarationContinuation);
- listener.endFunctionName(beginToken, token);
- token = parseTypeVariablesOpt(token);
+ /// Parses the rest of a local function declaration starting from formal
+ /// parameters.
+ ///
+ /// Precondition: the parser has previously generated these events:
+ ///
+ /// - Type variables.
+ /// - beginLocalFunctionDeclaration.
+ /// - Modifiers.
+ /// - Return type.
+ /// - Function name.
+ Token parseLocalFunctionDeclarationFromFormals(Token token) {
token = parseFormalParametersOpt(token, MemberKind.Local);
token = parseInitializersOpt(token);
AsyncModifier savedAsyncModifier = asyncState;
« no previous file with comments | « pkg/front_end/lib/src/fasta/parser/listener.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698