Skip to content

Removed lookahead for simple arrow function expressions. #460

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 15, 2014
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 20 additions & 40 deletions src/compiler/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1554,11 +1554,11 @@ module ts {
// Note: for ease of implementation we treat productions '2' and '3' as the same thing.
// (i.e. they're both BinaryExpressions with an assignment operator in it).

// First, check if we have production '4' (an arrow function). Note that if we do, we
// must *not* recurse for productsion 1, 2 or 3. An ArrowFunction is not a
// LeftHandSideExpression, nor does it start a ConditionalExpression. So we are done
// First, check if we have an arrow function (production '4') that starts with a parenthesized
// parameter list. If we do, we must *not* recurse for productsion 1, 2 or 3. An ArrowFunction is
// not a LeftHandSideExpression, nor does it start a ConditionalExpression. So we are done
// with AssignmentExpression if we see one.
var arrowExpression = tryParseArrowFunctionExpression();
var arrowExpression = tryParseParenthesizedArrowFunctionExpression();
if (arrowExpression) {
return arrowExpression;
}
Expand All @@ -1567,6 +1567,13 @@ module ts {
// including a conditional expression.
var expr = parseConditionalExpression(noIn);

// To avoid a look-ahead, we did not handle the case of an arrow function with a single un-parenthesized
// parameter ('x => ...') above. We handle it here by checking if the parsed expression was a single
// identifier and the current token is an arrow.
if (expr.kind === SyntaxKind.Identifier && token === SyntaxKind.EqualsGreaterThanToken) {
return parseSimpleArrowFunctionExpression(<Identifier>expr);
}

// Now see if we might be in cases '2' or '3'.
// If the expression was a LHS expression, and we have an assignment operator, then
// we're in '2' or '3'. Consume the assignment and return.
Expand Down Expand Up @@ -1613,39 +1620,7 @@ module ts {
return false;
}

function tryParseArrowFunctionExpression(): Expression {
return isSimpleArrowFunctionExpression()
? parseSimpleArrowFunctionExpression()
: tryParseParenthesizedArrowFunctionExpression();
}

function isSimpleArrowFunctionExpression(): boolean {
if (token === SyntaxKind.EqualsGreaterThanToken) {
// ERROR RECOVERY TWEAK:
// If we see a standalone => try to parse it as an arrow function expression as that's
// likely whatthe user intended to write.
return true;
}

if (token === SyntaxKind.Identifier) {
// if we see: a =>
// then this is clearly an arrow function expression.
return lookAhead(() => {
return nextToken() === SyntaxKind.EqualsGreaterThanToken;
});
}

// Definitely not a simple arrow function expression.
return false;
}

function parseSimpleArrowFunctionExpression(): Expression {
Debug.assert(token === SyntaxKind.Identifier || token === SyntaxKind.EqualsGreaterThanToken);

// Get the identifier for the simple arrow. If one isn't there then we'll report a useful
// message that it is missing.
var identifier = parseIdentifier();

function parseSimpleArrowFunctionExpression(identifier: Identifier): Expression {
Debug.assert(token === SyntaxKind.EqualsGreaterThanToken, "parseSimpleArrowFunctionExpression should only have been called if we had a =>");
parseExpected(SyntaxKind.EqualsGreaterThanToken);

Expand All @@ -1664,15 +1639,15 @@ module ts {
}

function tryParseParenthesizedArrowFunctionExpression(): Expression {
var pos = getNodePos();

// Indicates whether we are certain that we should parse an arrow expression.
var triState = isParenthesizedArrowFunctionExpression();

if (triState === Tristate.False) {
return undefined;
}

var pos = getNodePos();

if (triState === Tristate.True) {
var sig = parseSignature(SyntaxKind.CallSignature, SyntaxKind.ColonToken);

Expand Down Expand Up @@ -1765,7 +1740,12 @@ module ts {
}
});
}

if (token === SyntaxKind.EqualsGreaterThanToken) {
// ERROR RECOVERY TWEAK:
// If we see a standalone => try to parse it as an arrow function expression as that's
// likely whatthe user intended to write.
return Tristate.True;
}
// Definitely not a parenthesized arrow function.
return Tristate.False;
}
Expand Down