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; } /**