@@ -594,12 +594,11 @@ namespace ts {
594
594
emitLines ( node . statements ) ;
595
595
}
596
596
597
- // Return a temp variable name to be used in `export default` statements.
597
+ // Return a temp variable name to be used in `export default`/`export class ... extends` statements.
598
598
// The temp name will be of the form _default_counter.
599
599
// Note that export default is only allowed at most once in a module, so we
600
600
// do not need to keep track of created temp names.
601
- function getExportDefaultTempVariableName ( ) : string {
602
- const baseName = "_default" ;
601
+ function getExportTempVariableName ( baseName : string ) : string {
603
602
if ( ! currentIdentifiers . has ( baseName ) ) {
604
603
return baseName ;
605
604
}
@@ -613,24 +612,31 @@ namespace ts {
613
612
}
614
613
}
615
614
615
+ function emitTempVariableDeclaration ( expr : Expression , baseName : string , diagnostic : SymbolAccessibilityDiagnostic ) : string {
616
+ const tempVarName = getExportTempVariableName ( baseName ) ;
617
+ if ( ! noDeclare ) {
618
+ write ( "declare " ) ;
619
+ }
620
+ write ( "const " ) ;
621
+ write ( tempVarName ) ;
622
+ write ( ": " ) ;
623
+ writer . getSymbolAccessibilityDiagnostic = ( ) => diagnostic ;
624
+ resolver . writeTypeOfExpression ( expr , enclosingDeclaration , TypeFormatFlags . UseTypeOfFunction | TypeFormatFlags . UseTypeAliasValue , writer ) ;
625
+ write ( ";" ) ;
626
+ writeLine ( ) ;
627
+ return tempVarName ;
628
+ }
629
+
616
630
function emitExportAssignment ( node : ExportAssignment ) {
617
631
if ( node . expression . kind === SyntaxKind . Identifier ) {
618
632
write ( node . isExportEquals ? "export = " : "export default " ) ;
619
633
writeTextOfNode ( currentText , node . expression ) ;
620
634
}
621
635
else {
622
- // Expression
623
- const tempVarName = getExportDefaultTempVariableName ( ) ;
624
- if ( ! noDeclare ) {
625
- write ( "declare " ) ;
626
- }
627
- write ( "var " ) ;
628
- write ( tempVarName ) ;
629
- write ( ": " ) ;
630
- writer . getSymbolAccessibilityDiagnostic = getDefaultExportAccessibilityDiagnostic ;
631
- resolver . writeTypeOfExpression ( node . expression , enclosingDeclaration , TypeFormatFlags . UseTypeOfFunction | TypeFormatFlags . UseTypeAliasValue , writer ) ;
632
- write ( ";" ) ;
633
- writeLine ( ) ;
636
+ const tempVarName = emitTempVariableDeclaration ( node . expression , "_default" , {
637
+ diagnosticMessage : Diagnostics . Default_export_of_the_module_has_or_is_using_private_name_0 ,
638
+ errorNode : node
639
+ } ) ;
634
640
write ( node . isExportEquals ? "export = " : "export default " ) ;
635
641
write ( tempVarName ) ;
636
642
}
@@ -644,13 +650,6 @@ namespace ts {
644
650
// write each of these declarations asynchronously
645
651
writeAsynchronousModuleElements ( nodes ) ;
646
652
}
647
-
648
- function getDefaultExportAccessibilityDiagnostic ( ) : SymbolAccessibilityDiagnostic {
649
- return {
650
- diagnosticMessage : Diagnostics . Default_export_of_the_module_has_or_is_using_private_name_0 ,
651
- errorNode : node
652
- } ;
653
- }
654
653
}
655
654
656
655
function isModuleElementVisible ( node : Declaration ) {
@@ -1097,7 +1096,7 @@ namespace ts {
1097
1096
}
1098
1097
}
1099
1098
1100
- function emitHeritageClause ( className : Identifier , typeReferences : ExpressionWithTypeArguments [ ] , isImplementsList : boolean ) {
1099
+ function emitHeritageClause ( typeReferences : ExpressionWithTypeArguments [ ] , isImplementsList : boolean ) {
1101
1100
if ( typeReferences ) {
1102
1101
write ( isImplementsList ? " implements " : " extends " ) ;
1103
1102
emitCommaList ( typeReferences , emitTypeOfTypeReference ) ;
@@ -1110,12 +1109,6 @@ namespace ts {
1110
1109
else if ( ! isImplementsList && node . expression . kind === SyntaxKind . NullKeyword ) {
1111
1110
write ( "null" ) ;
1112
1111
}
1113
- else {
1114
- writer . getSymbolAccessibilityDiagnostic = getHeritageClauseVisibilityError ;
1115
- errorNameNode = className ;
1116
- resolver . writeBaseConstructorTypeOfClass ( < ClassLikeDeclaration > enclosingDeclaration , enclosingDeclaration , TypeFormatFlags . UseTypeOfFunction | TypeFormatFlags . UseTypeAliasValue , writer ) ;
1117
- errorNameNode = undefined ;
1118
- }
1119
1112
1120
1113
function getHeritageClauseVisibilityError ( ) : SymbolAccessibilityDiagnostic {
1121
1114
let diagnosticMessage : DiagnosticMessage ;
@@ -1151,23 +1144,43 @@ namespace ts {
1151
1144
}
1152
1145
}
1153
1146
1147
+ const prevEnclosingDeclaration = enclosingDeclaration ;
1148
+ enclosingDeclaration = node ;
1149
+ const baseTypeNode = getClassExtendsHeritageClauseElement ( node ) ;
1150
+ let tempVarName : string ;
1151
+ if ( baseTypeNode && ! isEntityNameExpression ( baseTypeNode . expression ) ) {
1152
+ tempVarName = baseTypeNode . expression . kind === SyntaxKind . NullKeyword ?
1153
+ "null" :
1154
+ emitTempVariableDeclaration ( baseTypeNode . expression , `${ node . name . text } _base` , {
1155
+ diagnosticMessage : Diagnostics . extends_clause_of_exported_class_0_has_or_is_using_private_name_1 ,
1156
+ errorNode : baseTypeNode ,
1157
+ typeName : node . name
1158
+ } ) ;
1159
+ }
1160
+
1154
1161
emitJsDocComments ( node ) ;
1155
1162
emitModuleElementDeclarationFlags ( node ) ;
1156
1163
if ( hasModifier ( node , ModifierFlags . Abstract ) ) {
1157
1164
write ( "abstract " ) ;
1158
1165
}
1159
-
1160
1166
write ( "class " ) ;
1161
1167
writeTextOfNode ( currentText , node . name ) ;
1162
- const prevEnclosingDeclaration = enclosingDeclaration ;
1163
- enclosingDeclaration = node ;
1164
1168
emitTypeParameters ( node . typeParameters ) ;
1165
- const baseTypeNode = getClassExtendsHeritageClauseElement ( node ) ;
1166
1169
if ( baseTypeNode ) {
1167
- node . name ;
1168
- emitHeritageClause ( node . name , [ baseTypeNode ] , /*isImplementsList*/ false ) ;
1170
+ if ( ! isEntityNameExpression ( baseTypeNode . expression ) ) {
1171
+ write ( " extends " ) ;
1172
+ write ( tempVarName ) ;
1173
+ if ( baseTypeNode . typeArguments ) {
1174
+ write ( "<" ) ;
1175
+ emitCommaList ( baseTypeNode . typeArguments , emitType ) ;
1176
+ write ( ">" ) ;
1177
+ }
1178
+ }
1179
+ else {
1180
+ emitHeritageClause ( [ baseTypeNode ] , /*isImplementsList*/ false ) ;
1181
+ }
1169
1182
}
1170
- emitHeritageClause ( node . name , getClassImplementsHeritageClauseElements ( node ) , /*isImplementsList*/ true ) ;
1183
+ emitHeritageClause ( getClassImplementsHeritageClauseElements ( node ) , /*isImplementsList*/ true ) ;
1171
1184
write ( " {" ) ;
1172
1185
writeLine ( ) ;
1173
1186
increaseIndent ( ) ;
@@ -1189,7 +1202,7 @@ namespace ts {
1189
1202
emitTypeParameters ( node . typeParameters ) ;
1190
1203
const interfaceExtendsTypes = filter ( getInterfaceBaseTypeNodes ( node ) , base => isEntityNameExpression ( base . expression ) ) ;
1191
1204
if ( interfaceExtendsTypes && interfaceExtendsTypes . length ) {
1192
- emitHeritageClause ( node . name , interfaceExtendsTypes , /*isImplementsList*/ false ) ;
1205
+ emitHeritageClause ( interfaceExtendsTypes , /*isImplementsList*/ false ) ;
1193
1206
}
1194
1207
write ( " {" ) ;
1195
1208
writeLine ( ) ;
0 commit comments