mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
fix emit for super calls that has preceding prologue directives
This commit is contained in:
@@ -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 = (<ExpressionStatement>statement).expression;
|
||||
if (expression.kind === SyntaxKind.CallExpression) {
|
||||
if ((<CallExpression>expression).expression.kind === SyntaxKind.SuperKeyword) {
|
||||
return <ExpressionStatement>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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user