From 83334fac18dff28a1a4984a5b18cf6d040dba825 Mon Sep 17 00:00:00 2001 From: Vladimir Matveev Date: Tue, 12 Apr 2016 09:58:57 -0700 Subject: [PATCH 1/4] fix emit for super calls that has preceding prologue directives --- src/compiler/transformers/ts.ts | 42 ++++++++++++++++++++++----------- 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index 0b8c11a66e2..0d2d5238638 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -762,19 +762,14 @@ namespace ts { * @param parameters The transformed parameters for the constructor. */ function transformConstructorBody(node: ClassExpression | ClassDeclaration, constructor: ConstructorDeclaration, hasExtendsClause: boolean, parameters: ParameterDeclaration[]) { - let hasSuperCall = false; const statements: Statement[] = []; + let indexOfFirstStatement = 0; // The body of a constructor is a new lexical environment startLexicalEnvironment(); if (constructor) { - const superCall = visitNode(findInitialSuperCall(constructor), visitor, isStatement); - if (superCall) { - // Adds the existing super call as the first line of the constructor. - addNode(statements, superCall); - hasSuperCall = true; - } + indexOfFirstStatement = addPrologueDirectivesAndInitialSuperCall(constructor, statements); // Add parameters with property assignments. Transforms this: // @@ -823,7 +818,7 @@ namespace ts { if (constructor) { // The class already had a constructor, so we should add the existing statements, skipping the initial super call. - addNodes(statements, visitNodes(constructor.body.statements, visitor, isStatement, hasSuperCall ? 1 : 0)); + addNodes(statements, visitNodes(constructor.body.statements, visitor, isStatement, indexOfFirstStatement)); } // End the lexical environment. @@ -841,25 +836,44 @@ namespace ts { } /** - * Finds the initial super-call for a constructor. + * Adds super call and preceding prologue directives into the list of statements. * * @param ctor The constructor node. + * @returns index of the statement that follows super call */ - function findInitialSuperCall(ctor: ConstructorDeclaration): ExpressionStatement { + function addPrologueDirectivesAndInitialSuperCall(ctor: ConstructorDeclaration, result: Statement[]): number { if (ctor.body) { const statements = ctor.body.statements; - const statement = firstOrUndefined(statements); - if (statement && statement.kind === SyntaxKind.ExpressionStatement) { + // find first statement that is not prologue directive + let indexOfFirstNonPrologueDirective = -1; + for (let i = 0; i < statements.length; i++) { + if (!isPrologueDirective(statements[i])) { + indexOfFirstNonPrologueDirective = i; + break; + } + } + + if (indexOfFirstNonPrologueDirective === -1) { + return 0; + } + + const statement = statements[indexOfFirstNonPrologueDirective]; + if (statement.kind === SyntaxKind.ExpressionStatement) { const expression = (statement).expression; if (expression.kind === SyntaxKind.CallExpression) { if ((expression).expression.kind === SyntaxKind.SuperKeyword) { - return statement; + for (let i = 0; i < indexOfFirstNonPrologueDirective; i++) { + // push all non-prologue directives + result.push(statements[i]); + } + result.push(visitNode(statement, visitor, isStatement)); + return indexOfFirstNonPrologueDirective + 1; } } } } - return undefined; + return 0; } /** From 9c545c63c28635c48104dbb169f82f00b9154b05 Mon Sep 17 00:00:00 2001 From: Vladimir Matveev Date: Wed, 13 Apr 2016 14:29:37 -0700 Subject: [PATCH 2/4] switch to use addPrologueDirectives function --- src/compiler/transformers/ts.ts | 26 +++++++++----------------- 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index 9bb227d9301..32c24c293ae 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -852,33 +852,25 @@ namespace ts { function addPrologueDirectivesAndInitialSuperCall(ctor: ConstructorDeclaration, result: Statement[]): number { if (ctor.body) { const statements = ctor.body.statements; - // find first statement that is not prologue directive - let indexOfFirstNonPrologueDirective = -1; - for (let i = 0; i < statements.length; i++) { - if (!isPrologueDirective(statements[i])) { - indexOfFirstNonPrologueDirective = i; - break; - } + // add prologue directives to the list (if any) + const index = addPrologueDirectives(result, statements); + if (index === statements.length) { + // list contains nothing but prologue directives (or empty) - exit + return index; } - if (indexOfFirstNonPrologueDirective === -1) { - return 0; - } - - const statement = statements[indexOfFirstNonPrologueDirective]; + const statement = statements[index]; if (statement.kind === SyntaxKind.ExpressionStatement) { const expression = (statement).expression; if (expression.kind === SyntaxKind.CallExpression) { if ((expression).expression.kind === SyntaxKind.SuperKeyword) { - for (let i = 0; i < indexOfFirstNonPrologueDirective; i++) { - // push all non-prologue directives - result.push(statements[i]); - } result.push(visitNode(statement, visitor, isStatement)); - return indexOfFirstNonPrologueDirective + 1; + return index + 1; } } } + + return index; } return 0; From 10616560da2f0cfd3749587836aaa927cb057eec Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Thu, 14 Apr 2016 11:32:33 -0700 Subject: [PATCH 3/4] Fix the incorrectly assigned arrow expression trailing comments Fixes #8041 --- src/compiler/printer.ts | 7 +++++-- src/compiler/transformers/es6.ts | 1 + .../reference/disallowLineTerminatorBeforeArrow.js | 4 +--- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/compiler/printer.ts b/src/compiler/printer.ts index e26a36233b7..451e002d5bf 100644 --- a/src/compiler/printer.ts +++ b/src/compiler/printer.ts @@ -1505,8 +1505,11 @@ const _super = (function (geti, seti) { const endingLine = writer.getLine(); emitLexicalEnvironment(endLexicalEnvironment(), /*newLine*/ startingLine !== endingLine); - const range = collapseRangeToEnd(body.statements); - emitLeadingComments(range, getLeadingComments(range)); + // Do not emit leading comments if the body belongs to arrow expression + if (!body.original || isBlock(body.original)) { + const range = collapseRangeToEnd(body.statements); + emitLeadingComments(range, getLeadingComments(range)); + } decreaseIndent(); } diff --git a/src/compiler/transformers/es6.ts b/src/compiler/transformers/es6.ts index 7b769889dca..0d0ab884cca 100644 --- a/src/compiler/transformers/es6.ts +++ b/src/compiler/transformers/es6.ts @@ -1271,6 +1271,7 @@ namespace ts { setNodeEmitFlags(block, NodeEmitFlags.SingleLine); } + setOriginalNode(block, node.body); return block; } diff --git a/tests/baselines/reference/disallowLineTerminatorBeforeArrow.js b/tests/baselines/reference/disallowLineTerminatorBeforeArrow.js index 55fba8115e0..1044146ccd0 100644 --- a/tests/baselines/reference/disallowLineTerminatorBeforeArrow.js +++ b/tests/baselines/reference/disallowLineTerminatorBeforeArrow.js @@ -110,9 +110,7 @@ var f8 = function (x, y, z) { var f9 = function (a) { return a; }; var f10 = function (a) { return a; }; var f11 = function (a) { return a; }; -var f12 = function (a) { - return a; -}; +var f12 = function (a) { return a; }; // Should be valid. var f11 = function (a) { return a; }; // Should be valid. From 487be624930771e9ef58e980c22a97a7d9f46a8c Mon Sep 17 00:00:00 2001 From: Vladimir Matveev Date: Fri, 15 Apr 2016 15:25:11 -0700 Subject: [PATCH 4/4] use existing 'isSuperCallExpression' function --- src/compiler/transformers/ts.ts | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index 32c24c293ae..6ff67ef90cb 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -860,14 +860,9 @@ namespace ts { } const statement = statements[index]; - if (statement.kind === SyntaxKind.ExpressionStatement) { - const expression = (statement).expression; - if (expression.kind === SyntaxKind.CallExpression) { - if ((expression).expression.kind === SyntaxKind.SuperKeyword) { - result.push(visitNode(statement, visitor, isStatement)); - return index + 1; - } - } + if (statement.kind === SyntaxKind.ExpressionStatement && isSuperCallExpression((statement).expression)) { + result.push(visitNode(statement, visitor, isStatement)); + return index + 1; } return index;