Skip to content

Commit d7a20f5

Browse files
authored
Port 10404 : optimize emit default constructor for subclass (#10598)
* Port 10404 : optimize emit default constructor for subclass * Address PR
1 parent 153666f commit d7a20f5

5 files changed

+30
-24
lines changed

src/compiler/transformers/ts.ts

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -821,7 +821,7 @@ namespace ts {
821821
return visitEachChild(constructor, visitor, context);
822822
}
823823

824-
const parameters = transformConstructorParameters(constructor, hasExtendsClause);
824+
const parameters = transformConstructorParameters(constructor);
825825
const body = transformConstructorBody(node, constructor, hasExtendsClause, parameters);
826826

827827
// constructor(${parameters}) {
@@ -848,10 +848,25 @@ namespace ts {
848848
* @param constructor The constructor declaration.
849849
* @param hasExtendsClause A value indicating whether the class has an extends clause.
850850
*/
851-
function transformConstructorParameters(constructor: ConstructorDeclaration, hasExtendsClause: boolean) {
851+
function transformConstructorParameters(constructor: ConstructorDeclaration) {
852+
// The ES2015 spec specifies in 14.5.14. Runtime Semantics: ClassDefinitionEvaluation:
853+
// If constructor is empty, then
854+
// If ClassHeritag_eopt is present and protoParent is not null, then
855+
// Let constructor be the result of parsing the source text
856+
// constructor(...args) { super (...args);}
857+
// using the syntactic grammar with the goal symbol MethodDefinition[~Yield].
858+
// Else,
859+
// Let constructor be the result of parsing the source text
860+
// constructor( ){ }
861+
// using the syntactic grammar with the goal symbol MethodDefinition[~Yield].
862+
//
863+
// While we could emit the '...args' rest parameter, certain later tools in the pipeline might
864+
// downlevel the '...args' portion less efficiently by naively copying the contents of 'arguments' to an array.
865+
// Instead, we'll avoid using a rest parameter and spread into the super call as
866+
// 'super(...arguments)' instead of 'super(...args)', as you can see in "transformConstructorBody".
852867
return constructor
853868
? visitNodes(constructor.parameters, visitor, isParameter)
854-
: hasExtendsClause ? [createRestParameter("args")] : [];
869+
: <ParameterDeclaration[]>[];
855870
}
856871

857872
/**
@@ -889,18 +904,16 @@ namespace ts {
889904
addRange(statements, map(propertyAssignments, transformParameterWithPropertyAssignment));
890905
}
891906
else if (hasExtendsClause) {
892-
Debug.assert(parameters.length === 1 && isIdentifier(parameters[0].name));
893-
894907
// Add a synthetic `super` call:
895908
//
896-
// super(...args);
909+
// super(...arguments);
897910
//
898911
statements.push(
899912
createStatement(
900913
createCall(
901914
createSuper(),
902915
/*typeArguments*/ undefined,
903-
[createSpread(<Identifier>parameters[0].name)]
916+
[createSpread(createIdentifier("arguments"))]
904917
)
905918
)
906919
);

tests/baselines/reference/classExpressionES63.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,13 @@ let C = class extends class extends class {
1212
this.a = 1;
1313
}
1414
} {
15-
constructor(...args) {
16-
super(...args);
15+
constructor() {
16+
super(...arguments);
1717
this.b = 2;
1818
}
1919
} {
20-
constructor(...args) {
21-
super(...args);
20+
constructor() {
21+
super(...arguments);
2222
this.c = 3;
2323
}
2424
};

tests/baselines/reference/emitClassDeclarationWithPropertyAssignmentInES6.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ class D {
3737
}
3838
}
3939
class E extends D {
40-
constructor(...args) {
41-
super(...args);
40+
constructor() {
41+
super(...arguments);
4242
this.z = true;
4343
}
4444
}

tests/baselines/reference/sourceMapValidationClassWithDefaultConstructorAndExtendsClause.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/baselines/reference/sourceMapValidationClassWithDefaultConstructorAndExtendsClause.sourcemap.txt

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -82,27 +82,20 @@ sourceFile:sourceMapValidationClassWithDefaultConstructorAndExtendsClause.ts
8282
1 >Emitted(13, 5) Source(4, 1) + SourceIndex(0)
8383
---
8484
>>> _super.apply(this, arguments);
85-
1->^^^^^^^^
86-
2 > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
87-
1->class Greeter extends
88-
2 > AbstractGreeter
89-
1->Emitted(14, 9) Source(4, 23) + SourceIndex(0)
90-
2 >Emitted(14, 39) Source(4, 38) + SourceIndex(0)
91-
---
9285
>>> this.a = 10;
93-
1 >^^^^^^^^
86+
1->^^^^^^^^
9487
2 > ^^^^^^
9588
3 > ^^^
9689
4 > ^^
9790
5 > ^
9891
6 > ^^^^^^^^->
99-
1 > {
92+
1->class Greeter extends AbstractGreeter {
10093
> public
10194
2 > a
10295
3 > =
10396
4 > 10
10497
5 > ;
105-
1 >Emitted(15, 9) Source(5, 12) + SourceIndex(0)
98+
1->Emitted(15, 9) Source(5, 12) + SourceIndex(0)
10699
2 >Emitted(15, 15) Source(5, 13) + SourceIndex(0)
107100
3 >Emitted(15, 18) Source(5, 16) + SourceIndex(0)
108101
4 >Emitted(15, 20) Source(5, 18) + SourceIndex(0)

0 commit comments

Comments
 (0)