@@ -568,7 +568,7 @@ namespace ts {
568
568
/**
569
569
* Tests whether we should emit a __decorate call for a class declaration.
570
570
*/
571
- function shouldEmitDecorateCallForClass ( node : ClassDeclaration ) {
571
+ function shouldEmitDecorateCallForClass ( node : ClassDeclaration | ClassExpression ) {
572
572
if ( node . decorators && node . decorators . length > 0 ) {
573
573
return true ;
574
574
}
@@ -588,7 +588,7 @@ namespace ts {
588
588
return parameter . decorators !== undefined && parameter . decorators . length > 0 ;
589
589
}
590
590
591
- function getClassFacts ( node : ClassDeclaration , staticProperties : readonly PropertyDeclaration [ ] ) {
591
+ function getClassFacts ( node : ClassDeclaration | ClassExpression , staticProperties : readonly PropertyDeclaration [ ] ) {
592
592
let facts = ClassFacts . None ;
593
593
if ( some ( staticProperties ) ) facts |= ClassFacts . HasStaticInitializedProperties ;
594
594
const extendsClauseElement = getEffectiveBaseTypeNode ( node ) ;
@@ -634,8 +634,8 @@ namespace ts {
634
634
635
635
636
636
// Write any decorators of the node.
637
- addClassElementDecorationStatements ( statements , node , /*isStatic*/ false ) ;
638
- addClassElementDecorationStatements ( statements , node , /*isStatic*/ true ) ;
637
+ addClassElementDecorationStatements ( statements , createClassPrototype ( factory . getDeclarationName ( node ) ) , node , /*isStatic*/ false ) ;
638
+ addClassElementDecorationStatements ( statements , factory . getDeclarationName ( node ) , node , /*isStatic*/ true ) ;
639
639
addConstructorDecorationStatement ( statements , node ) ;
640
640
641
641
if ( facts & ClassFacts . UseImmediatelyInvokedFunctionExpression ) {
@@ -879,6 +879,9 @@ namespace ts {
879
879
return visitEachChild ( node , visitor , context ) ;
880
880
}
881
881
882
+ const staticProperties = getProperties ( node , /*requireInitializer*/ true , /*isStatic*/ true ) ;
883
+ const facts = getClassFacts ( node , staticProperties ) ;
884
+
882
885
const classExpression = factory . createClassExpression (
883
886
/*decorators*/ undefined ,
884
887
/*modifiers*/ undefined ,
@@ -888,6 +891,14 @@ namespace ts {
888
891
transformClassMembers ( node )
889
892
) ;
890
893
894
+ if ( facts & ClassFacts . HasMemberDecorators ) {
895
+ const temp = factory . createTempVariable ( hoistVariableDeclaration ) ;
896
+ const expressions : Expression [ ] = [ factory . createAssignment ( temp , classExpression ) ] ;
897
+ addClassElementDecorationExpressions ( expressions , createClassPrototype ( temp ) , node , /*isStatic*/ false ) ;
898
+ addClassElementDecorationExpressions ( expressions , temp , node , /*isStatic*/ true ) ;
899
+ return factory . inlineExpressions ( [ ...expressions , temp ] ) ;
900
+ }
901
+
891
902
setOriginalNode ( classExpression , node ) ;
892
903
setTextRange ( classExpression , node ) ;
893
904
@@ -1123,31 +1134,44 @@ namespace ts {
1123
1134
return decoratorExpressions ;
1124
1135
}
1125
1136
1137
+ /**
1138
+ * Generates expressions used to apply decorators to either the static or instance member of a class.
1139
+ *
1140
+ * @param target
1141
+ * @param node The class node.
1142
+ * @param isStatic A value indicating whether to generate expressions for static or instance members.
1143
+ */
1144
+ function addClassElementDecorationExpressions ( expressions : Expression [ ] , target : Identifier | PropertyAccessExpression , node : ClassLikeDeclaration , isStatic : boolean ) {
1145
+ addRange ( expressions , map ( generateClassElementDecorationExpressions ( target , node , isStatic ) , expression => expression ) ) ;
1146
+ }
1147
+
1126
1148
/**
1127
1149
* Generates statements used to apply decorators to either the static or instance members
1128
1150
* of a class.
1129
1151
*
1152
+ * @param target
1130
1153
* @param node The class node.
1131
1154
* @param isStatic A value indicating whether to generate statements for static or
1132
1155
* instance members.
1133
1156
*/
1134
- function addClassElementDecorationStatements ( statements : Statement [ ] , node : ClassDeclaration , isStatic : boolean ) {
1135
- addRange ( statements , map ( generateClassElementDecorationExpressions ( node , isStatic ) , expressionToStatement ) ) ;
1157
+ function addClassElementDecorationStatements ( statements : Statement [ ] , target : Identifier | PropertyAccessExpression , node : ClassLikeDeclaration , isStatic : boolean ) {
1158
+ addRange ( statements , map ( generateClassElementDecorationExpressions ( target , node , isStatic ) , expressionToStatement ) ) ;
1136
1159
}
1137
1160
1138
1161
/**
1139
1162
* Generates expressions used to apply decorators to either the static or instance members
1140
1163
* of a class.
1141
1164
*
1165
+ * @param target
1142
1166
* @param node The class node.
1143
1167
* @param isStatic A value indicating whether to generate expressions for static or
1144
1168
* instance members.
1145
1169
*/
1146
- function generateClassElementDecorationExpressions ( node : ClassExpression | ClassDeclaration , isStatic : boolean ) {
1170
+ function generateClassElementDecorationExpressions ( target : Identifier | PropertyAccessExpression , node : ClassExpression | ClassDeclaration , isStatic : boolean ) {
1147
1171
const members = getDecoratedClassElements ( node , isStatic ) ;
1148
1172
let expressions : Expression [ ] | undefined ;
1149
1173
for ( const member of members ) {
1150
- const expression = generateClassElementDecorationExpression ( node , member ) ;
1174
+ const expression = generateClassElementDecorationExpression ( target , node , member ) ;
1151
1175
if ( expression ) {
1152
1176
if ( ! expressions ) {
1153
1177
expressions = [ expression ] ;
@@ -1163,10 +1187,11 @@ namespace ts {
1163
1187
/**
1164
1188
* Generates an expression used to evaluate class element decorators at runtime.
1165
1189
*
1190
+ * @param target
1166
1191
* @param node The class node that contains the member.
1167
1192
* @param member The class member.
1168
1193
*/
1169
- function generateClassElementDecorationExpression ( node : ClassExpression | ClassDeclaration , member : ClassElement ) {
1194
+ function generateClassElementDecorationExpression ( target : Identifier | PropertyAccessExpression , node : ClassExpression | ClassDeclaration , member : ClassElement ) {
1170
1195
const allDecorators = getAllDecoratorsOfClassElement ( node , member ) ;
1171
1196
const decoratorExpressions = transformAllDecoratorsOfDeclaration ( member , node , allDecorators ) ;
1172
1197
if ( ! decoratorExpressions ) {
@@ -1204,7 +1229,6 @@ namespace ts {
1204
1229
// ], C.prototype, "prop");
1205
1230
//
1206
1231
1207
- const prefix = getClassMemberPrefix ( node , member ) ;
1208
1232
const memberName = getExpressionForPropertyName ( member , /*generateNameForComputedPropertyName*/ true ) ;
1209
1233
const descriptor = languageVersion > ScriptTarget . ES3
1210
1234
? member . kind === SyntaxKind . PropertyDeclaration
@@ -1219,7 +1243,7 @@ namespace ts {
1219
1243
1220
1244
const helper = emitHelpers ( ) . createDecorateHelper (
1221
1245
decoratorExpressions ,
1222
- prefix ,
1246
+ target ,
1223
1247
memberName ,
1224
1248
descriptor
1225
1249
) ;
@@ -3151,14 +3175,8 @@ namespace ts {
3151
3175
}
3152
3176
}
3153
3177
3154
- function getClassPrototype ( node : ClassExpression | ClassDeclaration ) {
3155
- return factory . createPropertyAccessExpression ( factory . getDeclarationName ( node ) , "prototype" ) ;
3156
- }
3157
-
3158
- function getClassMemberPrefix ( node : ClassExpression | ClassDeclaration , member : ClassElement ) {
3159
- return hasSyntacticModifier ( member , ModifierFlags . Static )
3160
- ? factory . getDeclarationName ( node )
3161
- : getClassPrototype ( node ) ;
3178
+ function createClassPrototype ( expression : Expression ) {
3179
+ return factory . createPropertyAccessExpression ( expression , "prototype" ) ;
3162
3180
}
3163
3181
3164
3182
function enableSubstitutionForNonQualifiedEnumMembers ( ) {
0 commit comments