@@ -68,26 +68,46 @@ namespace ts {
68
68
function visitClassDeclaration ( node : ClassDeclaration ) : VisitResult < Statement > {
69
69
if ( ! ( classOrConstructorParameterIsDecorated ( node ) || childIsDecorated ( node ) ) ) return visitEachChild ( node , visitor , context ) ;
70
70
71
- const classStatement = hasDecorators ( node ) ?
71
+ const statements = hasDecorators ( node ) ?
72
72
createClassDeclarationHeadWithDecorators ( node , node . name ) :
73
73
createClassDeclarationHeadWithoutDecorators ( node , node . name ) ;
74
74
75
- const statements : Statement [ ] = [ classStatement ] ;
76
-
77
- // Write any decorators of the node.
78
- addClassElementDecorationStatements ( statements , node , /*isStatic*/ false ) ;
79
- addClassElementDecorationStatements ( statements , node , /*isStatic*/ true ) ;
80
- addConstructorDecorationStatement ( statements , node ) ;
81
-
82
75
if ( statements . length > 1 ) {
83
76
// Add a DeclarationMarker as a marker for the end of the declaration
84
77
statements . push ( factory . createEndOfDeclarationMarker ( node ) ) ;
85
- setEmitFlags ( classStatement , getEmitFlags ( classStatement ) | EmitFlags . HasEndOfDeclarationMarker ) ;
78
+ setEmitFlags ( statements [ 0 ] , getEmitFlags ( statements [ 0 ] ) | EmitFlags . HasEndOfDeclarationMarker ) ;
86
79
}
87
80
88
81
return singleOrMany ( statements ) ;
89
82
}
90
83
84
+ function containsDecoratedClassElementWithPrivateFieldAccess ( node : ClassDeclaration ) {
85
+ for ( const member of node . members ) {
86
+ if ( ! canHaveDecorators ( member ) ) continue ;
87
+ const decorators = getAllDecoratorsOfClassElement ( member , node ) ;
88
+ if ( decorators ?. decorators ) {
89
+ for ( const decorator of decorators . decorators ) {
90
+ if ( decorator . transformFlags & TransformFlags . ContainsPrivateIdentifierInExpression ) {
91
+ return true ;
92
+ }
93
+ }
94
+ }
95
+ if ( decorators ?. parameters ) {
96
+ for ( const parameterDecorators of decorators . parameters ) {
97
+ if ( parameterDecorators ) {
98
+ for ( const decorator of parameterDecorators ) {
99
+ if ( decorator . transformFlags & TransformFlags . ContainsPrivateIdentifierInExpression ) {
100
+ return true ;
101
+ }
102
+ }
103
+ }
104
+ }
105
+ }
106
+ }
107
+
108
+ return false ;
109
+ }
110
+
91
111
/**
92
112
* Transforms a non-decorated class declaration.
93
113
*
@@ -99,14 +119,33 @@ namespace ts {
99
119
// ${members}
100
120
// }
101
121
102
- return factory . updateClassDeclaration (
122
+ const modifiers = visitNodes ( node . modifiers , modifierVisitor , isModifier ) ;
123
+ const heritageClauses = visitNodes ( node . heritageClauses , visitor , isHeritageClause ) ;
124
+ let members = visitNodes ( node . members , visitor , isClassElement ) ;
125
+
126
+ let decorationStatements : Statement [ ] | undefined = [ ] ;
127
+ addClassElementDecorationStatements ( decorationStatements , node , /*isStatic*/ false ) ;
128
+ addClassElementDecorationStatements ( decorationStatements , node , /*isStatic*/ true ) ;
129
+ if ( containsDecoratedClassElementWithPrivateFieldAccess ( node ) ) {
130
+ members = setTextRange ( factory . createNodeArray ( [
131
+ ...members ,
132
+ factory . createClassStaticBlockDeclaration (
133
+ factory . createBlock ( decorationStatements , /*multiLine*/ true )
134
+ )
135
+ ] ) , members ) ;
136
+ decorationStatements = undefined ;
137
+ }
138
+
139
+ const updated = factory . updateClassDeclaration (
103
140
node ,
104
- visitNodes ( node . modifiers , modifierVisitor , isModifier ) ,
141
+ modifiers ,
105
142
name ,
106
143
/*typeParameters*/ undefined ,
107
- visitNodes ( node . heritageClauses , visitor , isHeritageClause ) ,
108
- visitNodes ( node . members , visitor , isClassElement )
144
+ heritageClauses ,
145
+ members
109
146
) ;
147
+
148
+ return addRange ( [ updated ] , decorationStatements ) ;
110
149
}
111
150
112
151
/**
@@ -213,8 +252,28 @@ namespace ts {
213
252
// ${members}
214
253
// }
215
254
const heritageClauses = visitNodes ( node . heritageClauses , visitor , isHeritageClause ) ;
216
- const members = visitNodes ( node . members , visitor , isClassElement ) ;
217
- const classExpression = factory . createClassExpression ( /*modifiers*/ undefined , name , /*typeParameters*/ undefined , heritageClauses , members ) ;
255
+ let members = visitNodes ( node . members , visitor , isClassElement ) ;
256
+
257
+ let decorationStatements : Statement [ ] | undefined = [ ] ;
258
+ addClassElementDecorationStatements ( decorationStatements , node , /*isStatic*/ false ) ;
259
+ addClassElementDecorationStatements ( decorationStatements , node , /*isStatic*/ true ) ;
260
+ if ( containsDecoratedClassElementWithPrivateFieldAccess ( node ) ) {
261
+ members = setTextRange ( factory . createNodeArray ( [
262
+ ...members ,
263
+ factory . createClassStaticBlockDeclaration (
264
+ factory . createBlock ( decorationStatements , /*multiLine*/ true )
265
+ )
266
+ ] ) , members ) ;
267
+ decorationStatements = undefined ;
268
+ }
269
+
270
+ const classExpression = factory . createClassExpression (
271
+ /*modifiers*/ undefined ,
272
+ name ,
273
+ /*typeParameters*/ undefined ,
274
+ heritageClauses ,
275
+ members ) ;
276
+
218
277
setOriginalNode ( classExpression , node ) ;
219
278
setTextRange ( classExpression , location ) ;
220
279
@@ -234,7 +293,11 @@ namespace ts {
234
293
setOriginalNode ( statement , node ) ;
235
294
setTextRange ( statement , location ) ;
236
295
setCommentRange ( statement , node ) ;
237
- return statement ;
296
+
297
+ const statements : Statement [ ] = [ statement ] ;
298
+ addRange ( statements , decorationStatements ) ;
299
+ addConstructorDecorationStatement ( statements , node ) ;
300
+ return statements ;
238
301
}
239
302
240
303
function visitClassExpression ( node : ClassExpression ) {
0 commit comments