Skip to content

Commit eea8409

Browse files
committed
Merge pull request #460 from Microsoft/noArrowLookahead
Removed lookahead for simple arrow function expressions.
2 parents a52cdaf + dcddb50 commit eea8409

File tree

1 file changed

+20
-40
lines changed

1 file changed

+20
-40
lines changed

src/compiler/parser.ts

Lines changed: 20 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1554,11 +1554,11 @@ module ts {
15541554
// Note: for ease of implementation we treat productions '2' and '3' as the same thing.
15551555
// (i.e. they're both BinaryExpressions with an assignment operator in it).
15561556

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

1570+
// To avoid a look-ahead, we did not handle the case of an arrow function with a single un-parenthesized
1571+
// parameter ('x => ...') above. We handle it here by checking if the parsed expression was a single
1572+
// identifier and the current token is an arrow.
1573+
if (expr.kind === SyntaxKind.Identifier && token === SyntaxKind.EqualsGreaterThanToken) {
1574+
return parseSimpleArrowFunctionExpression(<Identifier>expr);
1575+
}
1576+
15701577
// Now see if we might be in cases '2' or '3'.
15711578
// If the expression was a LHS expression, and we have an assignment operator, then
15721579
// we're in '2' or '3'. Consume the assignment and return.
@@ -1613,39 +1620,7 @@ module ts {
16131620
return false;
16141621
}
16151622

1616-
function tryParseArrowFunctionExpression(): Expression {
1617-
return isSimpleArrowFunctionExpression()
1618-
? parseSimpleArrowFunctionExpression()
1619-
: tryParseParenthesizedArrowFunctionExpression();
1620-
}
1621-
1622-
function isSimpleArrowFunctionExpression(): boolean {
1623-
if (token === SyntaxKind.EqualsGreaterThanToken) {
1624-
// ERROR RECOVERY TWEAK:
1625-
// If we see a standalone => try to parse it as an arrow function expression as that's
1626-
// likely whatthe user intended to write.
1627-
return true;
1628-
}
1629-
1630-
if (token === SyntaxKind.Identifier) {
1631-
// if we see: a =>
1632-
// then this is clearly an arrow function expression.
1633-
return lookAhead(() => {
1634-
return nextToken() === SyntaxKind.EqualsGreaterThanToken;
1635-
});
1636-
}
1637-
1638-
// Definitely not a simple arrow function expression.
1639-
return false;
1640-
}
1641-
1642-
function parseSimpleArrowFunctionExpression(): Expression {
1643-
Debug.assert(token === SyntaxKind.Identifier || token === SyntaxKind.EqualsGreaterThanToken);
1644-
1645-
// Get the identifier for the simple arrow. If one isn't there then we'll report a useful
1646-
// message that it is missing.
1647-
var identifier = parseIdentifier();
1648-
1623+
function parseSimpleArrowFunctionExpression(identifier: Identifier): Expression {
16491624
Debug.assert(token === SyntaxKind.EqualsGreaterThanToken, "parseSimpleArrowFunctionExpression should only have been called if we had a =>");
16501625
parseExpected(SyntaxKind.EqualsGreaterThanToken);
16511626

@@ -1664,15 +1639,15 @@ module ts {
16641639
}
16651640

16661641
function tryParseParenthesizedArrowFunctionExpression(): Expression {
1667-
var pos = getNodePos();
1668-
16691642
// Indicates whether we are certain that we should parse an arrow expression.
16701643
var triState = isParenthesizedArrowFunctionExpression();
16711644

16721645
if (triState === Tristate.False) {
16731646
return undefined;
16741647
}
16751648

1649+
var pos = getNodePos();
1650+
16761651
if (triState === Tristate.True) {
16771652
var sig = parseSignature(SyntaxKind.CallSignature, SyntaxKind.ColonToken);
16781653

@@ -1765,7 +1740,12 @@ module ts {
17651740
}
17661741
});
17671742
}
1768-
1743+
if (token === SyntaxKind.EqualsGreaterThanToken) {
1744+
// ERROR RECOVERY TWEAK:
1745+
// If we see a standalone => try to parse it as an arrow function expression as that's
1746+
// likely whatthe user intended to write.
1747+
return Tristate.True;
1748+
}
17691749
// Definitely not a parenthesized arrow function.
17701750
return Tristate.False;
17711751
}

0 commit comments

Comments
 (0)