| 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 3f9ba43a21a420b69396315bfe9ef1d84c6dff30..6e5b81ba272497d32afad9a293666fdeda9febde 100644
|
| --- a/pkg/front_end/lib/src/fasta/parser/parser.dart
|
| +++ b/pkg/front_end/lib/src/fasta/parser/parser.dart
|
| @@ -1389,9 +1389,9 @@ class Parser {
|
| if (looksLikeType &&
|
| token.isIdentifier &&
|
| isFunctionDeclaration(token.next)) {
|
| - return parseFunctionExpression(begin);
|
| + return parseNamedFunctionExpression(begin);
|
| } else if (isFunctionDeclaration(begin.next)) {
|
| - return parseFunctionExpression(begin);
|
| + return parseNamedFunctionExpression(begin);
|
| }
|
| return parseSend(begin, continuationContext);
|
|
|
| @@ -2447,9 +2447,22 @@ class Parser {
|
| }
|
| }
|
|
|
| - Token parseFunction(Token token) {
|
| + Token parseFunctionExpression(Token token) {
|
| + Token beginToken = token;
|
| + listener.beginFunctionExpression(token);
|
| + token = parseFormalParameters(token, MemberKind.Local);
|
| + AsyncModifier savedAsyncModifier = asyncState;
|
| + token = parseAsyncModifier(token);
|
| + bool isBlock = optional('{', token);
|
| + token = parseFunctionBody(token, true, false);
|
| + asyncState = savedAsyncModifier;
|
| + listener.endFunctionExpression(beginToken, token);
|
| + return isBlock ? token.next : token;
|
| + }
|
| +
|
| + Token parseFunctionDeclaration(Token token) {
|
| + listener.beginFunctionDeclaration(token);
|
| Token beginToken = token;
|
| - listener.beginFunction(token);
|
| token = parseModifiers(token, MemberKind.Local);
|
| listener.beginFunctionName(token);
|
| token = parseIdentifier(token, IdentifierContext.localFunctionDeclaration);
|
| @@ -2463,37 +2476,27 @@ class Parser {
|
| token = parseAsyncModifier(token);
|
| token = parseFunctionBody(token, false, true);
|
| asyncState = savedAsyncModifier;
|
| - listener.endFunction(null, token);
|
| - return token.next;
|
| - }
|
| -
|
| - Token parseUnnamedFunction(Token token) {
|
| - Token beginToken = token;
|
| - listener.beginUnnamedFunction(token);
|
| - token = parseFormalParameters(token, MemberKind.Local);
|
| - AsyncModifier savedAsyncModifier = asyncState;
|
| - token = parseAsyncModifier(token);
|
| - bool isBlock = optional('{', token);
|
| - token = parseFunctionBody(token, true, false);
|
| - asyncState = savedAsyncModifier;
|
| - listener.endUnnamedFunction(beginToken, token);
|
| - return isBlock ? token.next : token;
|
| - }
|
| -
|
| - Token parseFunctionDeclaration(Token token) {
|
| - listener.beginFunctionDeclaration(token);
|
| - token = parseFunction(token);
|
| + token = token.next;
|
| listener.endFunctionDeclaration(token);
|
| return token;
|
| }
|
|
|
| - Token parseFunctionExpression(Token token) {
|
| + /// Parses a named function expression which isn't legal syntax in Dart.
|
| + /// Useful for recovering from Javascript code being pasted into a Dart
|
| + /// proram, as it will interpret `function foo() {}` as a named function
|
| + /// expression with return type `function` and name `foo`.
|
| + Token parseNamedFunctionExpression(Token token) {
|
| Token beginToken = token;
|
| - listener.beginFunction(token);
|
| + listener.beginNamedFunctionExpression(token);
|
| listener.handleModifiers(0);
|
| token = parseType(token, TypeContinuation.Optional);
|
| + if (token != beginToken) {
|
| + reportRecoverableError(token, fasta.messageReturnTypeFunctionExpression);
|
| + }
|
| listener.beginFunctionName(token);
|
| + Token nameToken = token;
|
| token = parseIdentifier(token, IdentifierContext.functionExpressionName);
|
| + reportRecoverableError(nameToken, fasta.messageNamedFunctionExpression);
|
| listener.endFunctionName(beginToken, token);
|
| token = parseTypeVariablesOpt(token);
|
| token = parseFormalParameters(token, MemberKind.Local);
|
| @@ -2503,7 +2506,7 @@ class Parser {
|
| bool isBlock = optional('{', token);
|
| token = parseFunctionBody(token, true, false);
|
| asyncState = savedAsyncModifier;
|
| - listener.endFunction(null, token);
|
| + listener.endNamedFunctionExpression(token);
|
| return isBlock ? token.next : token;
|
| }
|
|
|
| @@ -3115,7 +3118,7 @@ class Parser {
|
| } else if (identical(value, "const")) {
|
| return parseConstExpression(token);
|
| } else if (identical(value, "void")) {
|
| - return parseFunctionExpression(token);
|
| + return parseNamedFunctionExpression(token);
|
| } else if (!inPlainSync &&
|
| (identical(value, "yield") || identical(value, "async"))) {
|
| return expressionExpected(token);
|
| @@ -3160,7 +3163,7 @@ class Parser {
|
| (optional('async', nextToken) ||
|
| optional('sync', nextToken))))) {
|
| listener.handleNoTypeVariables(token);
|
| - return parseUnnamedFunction(token);
|
| + return parseFunctionExpression(token);
|
| } else {
|
| bool old = mayParseFunctionExpressions;
|
| mayParseFunctionExpressions = true;
|
| @@ -3280,7 +3283,7 @@ class Parser {
|
| identical(kind, OPEN_CURLY_BRACKET_TOKEN) ||
|
| (identical(kind, KEYWORD_TOKEN) &&
|
| (optional('async', nextToken) || optional('sync', nextToken)))) {
|
| - return parseUnnamedFunction(token);
|
| + return parseFunctionExpression(token);
|
| }
|
| // Fall through.
|
| }
|
|
|