@@ -68,26 +68,46 @@ namespace ts {
6868 function visitClassDeclaration ( node : ClassDeclaration ) : VisitResult < Statement > {
6969 if ( ! ( classOrConstructorParameterIsDecorated ( node ) || childIsDecorated ( node ) ) ) return visitEachChild ( node , visitor , context ) ;
7070
71- const classStatement = hasDecorators ( node ) ?
71+ const statements = hasDecorators ( node ) ?
7272 createClassDeclarationHeadWithDecorators ( node , node . name ) :
7373 createClassDeclarationHeadWithoutDecorators ( node , node . name ) ;
7474
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-
8275 if ( statements . length > 1 ) {
8376 // Add a DeclarationMarker as a marker for the end of the declaration
8477 statements . push ( factory . createEndOfDeclarationMarker ( node ) ) ;
85- setEmitFlags ( classStatement , getEmitFlags ( classStatement ) | EmitFlags . HasEndOfDeclarationMarker ) ;
78+ setEmitFlags ( statements [ 0 ] , getEmitFlags ( statements [ 0 ] ) | EmitFlags . HasEndOfDeclarationMarker ) ;
8679 }
8780
8881 return singleOrMany ( statements ) ;
8982 }
9083
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+
91111 /**
92112 * Transforms a non-decorated class declaration.
93113 *
@@ -99,14 +119,33 @@ namespace ts {
99119 // ${members}
100120 // }
101121
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 (
103140 node ,
104- visitNodes ( node . modifiers , modifierVisitor , isModifier ) ,
141+ modifiers ,
105142 name ,
106143 /*typeParameters*/ undefined ,
107- visitNodes ( node . heritageClauses , visitor , isHeritageClause ) ,
108- visitNodes ( node . members , visitor , isClassElement )
144+ heritageClauses ,
145+ members
109146 ) ;
147+
148+ return addRange ( [ updated ] , decorationStatements ) ;
110149 }
111150
112151 /**
@@ -213,8 +252,28 @@ namespace ts {
213252 // ${members}
214253 // }
215254 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+
218277 setOriginalNode ( classExpression , node ) ;
219278 setTextRange ( classExpression , location ) ;
220279
@@ -234,7 +293,11 @@ namespace ts {
234293 setOriginalNode ( statement , node ) ;
235294 setTextRange ( statement , location ) ;
236295 setCommentRange ( statement , node ) ;
237- return statement ;
296+
297+ const statements : Statement [ ] = [ statement ] ;
298+ addRange ( statements , decorationStatements ) ;
299+ addConstructorDecorationStatement ( statements , node ) ;
300+ return statements ;
238301 }
239302
240303 function visitClassExpression ( node : ClassExpression ) {
0 commit comments