From dcddb50f5b3d31b00cffb2904c5428e6f215d65f Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 15 Aug 2014 07:44:56 -0700 Subject: [PATCH] Removed lookahead for simple arrow function expressions. --- src/compiler/parser.ts | 60 ++++++++++++++---------------------------- 1 file changed, 20 insertions(+), 40 deletions(-) diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 74b3f59bbd1..8e26b2090b9 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -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; } @@ -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(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. @@ -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); @@ -1664,8 +1639,6 @@ module ts { } function tryParseParenthesizedArrowFunctionExpression(): Expression { - var pos = getNodePos(); - // Indicates whether we are certain that we should parse an arrow expression. var triState = isParenthesizedArrowFunctionExpression(); @@ -1673,6 +1646,8 @@ module ts { return undefined; } + var pos = getNodePos(); + if (triState === Tristate.True) { var sig = parseSignature(SyntaxKind.CallSignature, SyntaxKind.ColonToken); @@ -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; }