From c267691d8a967edda1cd58b3d340c64412efa3d0 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Wed, 2 Mar 2016 16:45:14 -0800 Subject: [PATCH] Fixed labels --- src/compiler/factory.ts | 4 +++ src/compiler/printer.ts | 17 ++++++++++- src/compiler/transformers/es6.ts | 13 +++++++++ src/compiler/transformers/generators.ts | 39 ++++++++++++++++++++----- 4 files changed, 65 insertions(+), 8 deletions(-) diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index e12a7730703..a39919ce681 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -1498,6 +1498,10 @@ namespace ts { } export function parenthesizeExpressionForList(expression: Expression) { + if (expression.kind === SyntaxKind.OmittedExpression) { + return expression; + } + const expressionPrecedence = getExpressionPrecedence(expression); const commaPrecedence = getOperatorPrecedence(SyntaxKind.BinaryExpression, SyntaxKind.CommaToken); return expressionPrecedence > commaPrecedence diff --git a/src/compiler/printer.ts b/src/compiler/printer.ts index 6d7cb9ab4ba..7040362fa8f 100644 --- a/src/compiler/printer.ts +++ b/src/compiler/printer.ts @@ -827,6 +827,13 @@ const _super = (function (geti, seti) { else { write(text); } + + if (node.kind === SyntaxKind.NumericLiteral) { + const trailingComment = (node).trailingComment; + if (trailingComment) { + write(` /*${trailingComment}*/`); + } + } } // @@ -1893,7 +1900,7 @@ const _super = (function (geti, seti) { } function emitCaseOrDefaultClauseStatements(parentNode: Node, statements: NodeArray) { - if (statements.length === 1 && rangeStartPositionsAreOnSameLine(parentNode, statements[0])) { + if (statements.length === 1 && shouldEmitCaseOrDefaultClauseStatementOnSameLine(parentNode, statements[0])) { write(" "); emit(statements[0]); } @@ -1902,6 +1909,14 @@ const _super = (function (geti, seti) { } } + function shouldEmitCaseOrDefaultClauseStatementOnSameLine(parentNode: Node, statement: Statement) { + if (statement.startsOnNewLine || nodeIsSynthesized(parentNode)) { + return false; + } + + return nodeIsSynthesized(statement) || rangeStartPositionsAreOnSameLine(parentNode, statement); + } + function emitHeritageClause(node: HeritageClause) { emitStart(node); write(" "); diff --git a/src/compiler/transformers/es6.ts b/src/compiler/transformers/es6.ts index ee887546512..a1e370e2394 100644 --- a/src/compiler/transformers/es6.ts +++ b/src/compiler/transformers/es6.ts @@ -163,6 +163,9 @@ namespace ts { case SyntaxKind.TemplateExpression: return visitTemplateExpression(node); + case SyntaxKind.YieldExpression: + return visitYieldExpression(node); + case SyntaxKind.SuperKeyword: return visitSuperKeyword(node); @@ -1496,6 +1499,16 @@ namespace ts { ); } + /** + * Visits a YieldExpression node. + * + * @param node A YieldExpression node. + */ + function visitYieldExpression(node: YieldExpression): Expression { + // `yield` expressions are transformed using the generators transformer. + return visitEachChild(node, visitor, context); + } + /** * Visits an ArrayLiteralExpression that contains a spread element. * diff --git a/src/compiler/transformers/generators.ts b/src/compiler/transformers/generators.ts index 8fd9a9e1c63..073cf50c90a 100644 --- a/src/compiler/transformers/generators.ts +++ b/src/compiler/transformers/generators.ts @@ -283,6 +283,7 @@ namespace ts { // let blockIndex = 0; // The index of the current block. let labelNumber = 0; // The current label number. + let labelNumbers: number[][]; let lastOperationWasAbrupt: boolean; // Indicates whether the last operation was abrupt (break/continue). let lastOperationWasCompletion: boolean; // Indicates whether the last operation was a completion (return/throw). let clauses: CaseClause[]; // The case clauses generated for labels. @@ -391,7 +392,7 @@ namespace ts { case SyntaxKind.SetAccessor: return visitAccessorDeclaration(node); default: - if (node.transformFlags & TransformFlags.ContainsGenerators) { + if (node.transformFlags & TransformFlags.ContainsGenerators || containsYield(node)) { return visitEachChild(node, visitor, context); } else { @@ -2497,6 +2498,7 @@ namespace ts { function build() { blockIndex = 0; labelNumber = 0; + labelNumbers = undefined; lastOperationWasAbrupt = false; lastOperationWasCompletion = false; clauses = undefined; @@ -2537,7 +2539,6 @@ namespace ts { flushFinalLabel(0); } - if (clauses) { const state = getState(); const labelExpression = createPropertyAccess(state, "label"); @@ -2590,6 +2591,8 @@ namespace ts { if (statements && clauses) { appendLabel(/*markLabelEnd*/ false); } + + updateLabelExpressions(); } /** @@ -2674,11 +2677,33 @@ namespace ts { for (let label = 0; label < labelOffsets.length; label++) { if (labelOffsets[label] === operationIndex) { flushLabel(); - if (labelExpressions !== undefined) { - const expressions = labelExpressions[label]; - if (expressions !== undefined) { - for (const expression of expressions) { - expression.text = String(labelNumber); + if (labelNumbers === undefined) { + labelNumbers = []; + } + if (labelNumbers[labelNumber] === undefined) { + labelNumbers[labelNumber] = [label] + } + else { + labelNumbers[labelNumber].push(label); + } + } + } + } + + /** + * Updates literal expressions for labels with actual label numbers. + */ + function updateLabelExpressions() { + if (labelExpressions !== undefined && labelNumbers !== undefined) { + for (let labelNumber = 0; labelNumber < labelNumbers.length; labelNumber++) { + const labels = labelNumbers[labelNumber]; + if (labels !== undefined) { + for (const label of labels) { + const expressions = labelExpressions[label]; + if (expressions !== undefined) { + for (const expression of expressions) { + expression.text = String(labelNumber); + } } } }