@@ -837,7 +837,6 @@ namespace ts {
837
837
startLexicalEnvironment ( ) ;
838
838
839
839
let statementOffset = - 1 ;
840
- let superCaptureStatus = SuperCaptureResult . NoReplacement ;
841
840
if ( hasSynthesizedSuper ) {
842
841
// If a super call has already been synthesized,
843
842
// we're going to assume that we should just transform everything after that.
@@ -854,12 +853,9 @@ namespace ts {
854
853
addRestParameterIfNeeded ( statements , constructor , hasSynthesizedSuper ) ;
855
854
Debug . assert ( statementOffset >= 0 , "statementOffset not initialized correctly!" ) ;
856
855
857
- superCaptureStatus = declareOrCaptureOrReturnThisForConstructorIfNeeded ( statements , constructor , ! ! extendsClauseElement , statementOffset ) ;
858
856
}
859
857
860
- if ( superCaptureStatus === SuperCaptureResult . NoReplacement ) {
861
- superCaptureStatus = addDefaultSuperCallIfNeeded ( statements , constructor , extendsClauseElement , hasSynthesizedSuper ) ;
862
- }
858
+ const superCaptureStatus = declareOrCaptureOrReturnThisForConstructorIfNeeded ( statements , constructor , ! ! extendsClauseElement , hasSynthesizedSuper , statementOffset ) ;
863
859
864
860
// The last statement expression was replaced. Skip it.
865
861
if ( superCaptureStatus === SuperCaptureResult . ReplaceSuperCapture || superCaptureStatus === SuperCaptureResult . ReplaceWithReturn ) {
@@ -929,61 +925,42 @@ namespace ts {
929
925
return false ;
930
926
}
931
927
932
- /**
933
- * Adds a synthesized call to `_super` if it is needed.
934
- *
935
- * @param statements The statements for the new constructor body.
936
- * @param constructor The constructor for the class.
937
- * @param extendsClauseElement The expression for the class `extends` clause.
938
- * @param hasSynthesizedSuper A value indicating whether the constructor starts with a
939
- * synthesized `super` call.
940
- */
941
- function addDefaultSuperCallIfNeeded ( statements : Statement [ ] , constructor : ConstructorDeclaration , extendsClauseElement : ExpressionWithTypeArguments , hasSynthesizedSuper : boolean ) {
942
- // If the TypeScript transformer needed to synthesize a constructor for property
943
- // initializers, it would have also added a synthetic `...args` parameter and
944
- // `super` call.
945
- // If this is the case, or if the class has an `extends` clause but no
946
- // constructor, we emit a synthesized call to `_super`.
947
- if ( constructor ? hasSynthesizedSuper : extendsClauseElement ) {
948
- const actualThis = createThis ( ) ;
949
- setNodeEmitFlags ( actualThis , NodeEmitFlags . NoSubstitution ) ;
950
- const superCall = createFunctionApply (
951
- createIdentifier ( "_super" ) ,
952
- actualThis ,
953
- createIdentifier ( "arguments" ) ,
954
- ) ;
955
- const superReturnValueOrThis = createLogicalOr ( superCall , actualThis ) ;
956
-
957
- if ( ! constructor ) {
958
- // We must be here because the user didn't write a constructor
959
- // but we needed to call 'super()' anyway - but if that's the case,
960
- // we can just immediately return the result of a 'super()' call.
961
- statements . push ( createReturn ( superReturnValueOrThis ) ) ;
962
- return SuperCaptureResult . ReplaceWithReturn ;
963
- }
964
-
965
- // The constructor was generated for some reason.
966
- // Create a captured '_this' variable.
967
- captureThisForNode ( statements , constructor , superReturnValueOrThis ) ;
968
- enableSubstitutionsForCapturedThis ( ) ;
969
- return SuperCaptureResult . ReplaceSuperCapture ;
970
- }
971
-
972
- return SuperCaptureResult . NoReplacement ;
973
- }
974
-
975
928
/**
976
929
* Declares a `_this` variable for derived classes and for when arrow functions capture `this`.
977
930
*
978
931
* @returns The new statement offset into the `statements` array.
979
932
*/
980
- function declareOrCaptureOrReturnThisForConstructorIfNeeded ( statements : Statement [ ] , ctor : ConstructorDeclaration , hasExtendsClause : boolean , statementOffset : number ) {
933
+ function declareOrCaptureOrReturnThisForConstructorIfNeeded (
934
+ statements : Statement [ ] ,
935
+ ctor : ConstructorDeclaration | undefined ,
936
+ hasExtendsClause : boolean ,
937
+ hasSynthesizedSuper : boolean ,
938
+ statementOffset : number ) {
981
939
// If this isn't a derived class, just capture 'this' for arrow functions if necessary.
982
940
if ( ! hasExtendsClause ) {
983
- addCaptureThisForNodeIfNeeded ( statements , ctor ) ;
941
+ if ( ctor ) {
942
+ addCaptureThisForNodeIfNeeded ( statements , ctor ) ;
943
+ }
984
944
return SuperCaptureResult . NoReplacement ;
985
945
}
986
946
947
+ // We must be here because the user didn't write a constructor
948
+ // but we needed to call 'super(...args)' anyway as per 14.5.14 of the ES2016 spec.
949
+ // If that's the case we can just immediately return the result of a 'super()' call.
950
+ if ( ! ctor ) {
951
+ statements . push ( createReturn ( createDefaultSuperCallOrThis ( ) ) ) ;
952
+ return SuperCaptureResult . ReplaceWithReturn ;
953
+ }
954
+
955
+ // The constructor exists, but it and the 'super()' call it contains were generated
956
+ // for something like property initializers.
957
+ // Create a captured '_this' variable and assume it will subsequently be used.
958
+ if ( hasSynthesizedSuper ) {
959
+ captureThisForNode ( statements , ctor , createDefaultSuperCallOrThis ( ) ) ;
960
+ enableSubstitutionsForCapturedThis ( ) ;
961
+ return SuperCaptureResult . ReplaceSuperCapture ;
962
+ }
963
+
987
964
// Most of the time, a 'super' call will be the first real statement in a constructor body.
988
965
// In these cases, we'd like to transform these into a *single* statement instead of a declaration
989
966
// followed by an assignment statement for '_this'. For instance, if we emitted without an initializer,
@@ -1034,6 +1011,17 @@ namespace ts {
1034
1011
return SuperCaptureResult . NoReplacement ;
1035
1012
}
1036
1013
1014
+ function createDefaultSuperCallOrThis ( ) {
1015
+ const actualThis = createThis ( ) ;
1016
+ setNodeEmitFlags ( actualThis , NodeEmitFlags . NoSubstitution ) ;
1017
+ const superCall = createFunctionApply (
1018
+ createIdentifier ( "_super" ) ,
1019
+ actualThis ,
1020
+ createIdentifier ( "arguments" ) ,
1021
+ ) ;
1022
+ return createLogicalOr ( superCall , actualThis ) ;
1023
+ }
1024
+
1037
1025
/**
1038
1026
* Visits a parameter declaration.
1039
1027
*
0 commit comments