Port 10404 : optimize emit default constructor for subclass (#10598)

* Port 10404 : optimize emit default constructor for subclass

* Address PR
This commit is contained in:
Yui
2016-09-01 15:34:39 -07:00
committed by GitHub
parent 153666f908
commit d7a20f5c6f
5 changed files with 30 additions and 24 deletions

View File

@@ -821,7 +821,7 @@ namespace ts {
return visitEachChild(constructor, visitor, context);
}
const parameters = transformConstructorParameters(constructor, hasExtendsClause);
const parameters = transformConstructorParameters(constructor);
const body = transformConstructorBody(node, constructor, hasExtendsClause, parameters);
// constructor(${parameters}) {
@@ -848,10 +848,25 @@ namespace ts {
* @param constructor The constructor declaration.
* @param hasExtendsClause A value indicating whether the class has an extends clause.
*/
function transformConstructorParameters(constructor: ConstructorDeclaration, hasExtendsClause: boolean) {
function transformConstructorParameters(constructor: ConstructorDeclaration) {
// The ES2015 spec specifies in 14.5.14. Runtime Semantics: ClassDefinitionEvaluation:
// If constructor is empty, then
// If ClassHeritag_eopt is present and protoParent is not null, then
// Let constructor be the result of parsing the source text
// constructor(...args) { super (...args);}
// using the syntactic grammar with the goal symbol MethodDefinition[~Yield].
// Else,
// Let constructor be the result of parsing the source text
// constructor( ){ }
// using the syntactic grammar with the goal symbol MethodDefinition[~Yield].
//
// While we could emit the '...args' rest parameter, certain later tools in the pipeline might
// downlevel the '...args' portion less efficiently by naively copying the contents of 'arguments' to an array.
// Instead, we'll avoid using a rest parameter and spread into the super call as
// 'super(...arguments)' instead of 'super(...args)', as you can see in "transformConstructorBody".
return constructor
? visitNodes(constructor.parameters, visitor, isParameter)
: hasExtendsClause ? [createRestParameter("args")] : [];
: <ParameterDeclaration[]>[];
}
/**
@@ -889,18 +904,16 @@ namespace ts {
addRange(statements, map(propertyAssignments, transformParameterWithPropertyAssignment));
}
else if (hasExtendsClause) {
Debug.assert(parameters.length === 1 && isIdentifier(parameters[0].name));
// Add a synthetic `super` call:
//
// super(...args);
// super(...arguments);
//
statements.push(
createStatement(
createCall(
createSuper(),
/*typeArguments*/ undefined,
[createSpread(<Identifier>parameters[0].name)]
[createSpread(createIdentifier("arguments"))]
)
)
);

View File

@@ -12,13 +12,13 @@ let C = class extends class extends class {
this.a = 1;
}
} {
constructor(...args) {
super(...args);
constructor() {
super(...arguments);
this.b = 2;
}
} {
constructor(...args) {
super(...args);
constructor() {
super(...arguments);
this.c = 3;
}
};

View File

@@ -37,8 +37,8 @@ class D {
}
}
class E extends D {
constructor(...args) {
super(...args);
constructor() {
super(...arguments);
this.z = true;
}
}

View File

@@ -1,2 +1,2 @@
//// [sourceMapValidationClassWithDefaultConstructorAndExtendsClause.js.map]
{"version":3,"file":"sourceMapValidationClassWithDefaultConstructorAndExtendsClause.js","sourceRoot":"","sources":["sourceMapValidationClassWithDefaultConstructorAndExtendsClause.ts"],"names":[],"mappings":";;;;;AAAA;IAAA;IACA,CAAC;IAAD,sBAAC;AAAD,CAAC,AADD,IACC;AAED;IAAsB,2BAAe;IAArC;QAAsB,8BAAe;QAC1B,MAAC,GAAG,EAAE,CAAC;QACP,UAAK,GAAG,KAAK,CAAC;IACzB,CAAC;IAAD,cAAC;AAAD,CAAC,AAHD,CAAsB,eAAe,GAGpC"}
{"version":3,"file":"sourceMapValidationClassWithDefaultConstructorAndExtendsClause.js","sourceRoot":"","sources":["sourceMapValidationClassWithDefaultConstructorAndExtendsClause.ts"],"names":[],"mappings":";;;;;AAAA;IAAA;IACA,CAAC;IAAD,sBAAC;AAAD,CAAC,AADD,IACC;AAED;IAAsB,2BAAe;IAArC;;QACW,MAAC,GAAG,EAAE,CAAC;QACP,UAAK,GAAG,KAAK,CAAC;IACzB,CAAC;IAAD,cAAC;AAAD,CAAC,AAHD,CAAsB,eAAe,GAGpC"}

View File

@@ -82,27 +82,20 @@ sourceFile:sourceMapValidationClassWithDefaultConstructorAndExtendsClause.ts
1 >Emitted(13, 5) Source(4, 1) + SourceIndex(0)
---
>>> _super.apply(this, arguments);
1->^^^^^^^^
2 > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1->class Greeter extends
2 > AbstractGreeter
1->Emitted(14, 9) Source(4, 23) + SourceIndex(0)
2 >Emitted(14, 39) Source(4, 38) + SourceIndex(0)
---
>>> this.a = 10;
1 >^^^^^^^^
1->^^^^^^^^
2 > ^^^^^^
3 > ^^^
4 > ^^
5 > ^
6 > ^^^^^^^^->
1 > {
1->class Greeter extends AbstractGreeter {
> public
2 > a
3 > =
4 > 10
5 > ;
1 >Emitted(15, 9) Source(5, 12) + SourceIndex(0)
1->Emitted(15, 9) Source(5, 12) + SourceIndex(0)
2 >Emitted(15, 15) Source(5, 13) + SourceIndex(0)
3 >Emitted(15, 18) Source(5, 16) + SourceIndex(0)
4 >Emitted(15, 20) Source(5, 18) + SourceIndex(0)