From 26badc686fe99b539410966f844b59de8e456834 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Fri, 12 Dec 2014 11:38:05 -0800 Subject: [PATCH] Avoid lookahead when parsing a statement. If a statement started with an identifier, then we'd normally lookahead to see if the next token was a colon. Lookahead is expensive (as it has to rescan tokens). Instead, we do the same thing we do for arrow-functions. We just parse out the identifier, and afterwards we check if there is a colon as the current token. Now, no lookahead is required. --- src/compiler/parser.ts | 42 +++++++++++++++++++----------------------- 1 file changed, 19 insertions(+), 23 deletions(-) diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index e75b195d776..38a1e4bb451 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -3123,27 +3123,25 @@ module ts { return finishNode(node); } - function isLabel(): boolean { - return isIdentifier() && lookAhead(nextTokenIsColonToken); - } + function parseExpressionOrLabeledStatement(): ExpressionStatement | LabeledStatement { + // Avoiding having to do the lookahead for a labeled statement by just trying to parse + // out an expression, seeing if it is identifier and then seeing if it is followed by + // a colon. + var fullStart = scanner.getStartPos(); + var expression = allowInAnd(parseExpression); - function nextTokenIsColonToken() { - return nextToken() === SyntaxKind.ColonToken; - } - - function parseLabeledStatement(): LabeledStatement { - var node = createNode(SyntaxKind.LabeledStatement); - node.label = parseIdentifier(); - parseExpected(SyntaxKind.ColonToken); - node.statement = parseStatement(); - return finishNode(node); - } - - function parseExpressionStatement(): ExpressionStatement { - var node = createNode(SyntaxKind.ExpressionStatement); - node.expression = allowInAnd(parseExpression); - parseSemicolon(); - return finishNode(node); + if (expression.kind === SyntaxKind.Identifier && parseOptional(SyntaxKind.ColonToken)) { + var labeledStatement = createNode(SyntaxKind.LabeledStatement, fullStart); + labeledStatement.label = expression; + labeledStatement.statement = parseStatement(); + return finishNode(labeledStatement); + } + else { + var expressionStatement = createNode(SyntaxKind.ExpressionStatement, fullStart); + expressionStatement.expression = expression; + parseSemicolon(); + return finishNode(expressionStatement); + } } function isStatement(inErrorRecovery: boolean): boolean { @@ -3264,9 +3262,7 @@ module ts { } // Else parse it like identifier - fall through default: - return isLabel() - ? parseLabeledStatement() - : parseExpressionStatement(); + return parseExpressionOrLabeledStatement(); } }