@@ -104,27 +104,14 @@ impl VisitMut for ClassFieldsUseSet {
104
104
}
105
105
106
106
fn visit_mut_class ( & mut self , n : & mut Class ) {
107
+ // visit inner classes first
107
108
n. visit_mut_children_with ( self ) ;
108
109
109
- let mut fields_handler = FieldsHandler :: default ( ) ;
110
- n. visit_mut_with ( & mut fields_handler) ;
111
-
112
- let FieldsHandler {
113
- constructor_inits,
114
- constructor_found,
115
- ..
116
- } = fields_handler;
117
-
118
- if constructor_inits. is_empty ( ) {
119
- return ;
120
- }
121
-
122
- let mut constructor_handler = ConstructorHandler {
110
+ let mut fields_handler = FieldsHandler {
123
111
has_super : n. super_class . is_some ( ) ,
124
- constructor_inits,
125
- constructor_found,
126
112
} ;
127
- n. visit_mut_with ( & mut constructor_handler) ;
113
+
114
+ n. body . visit_mut_with ( & mut fields_handler) ;
128
115
}
129
116
}
130
117
@@ -170,113 +157,105 @@ impl ClassFieldsUseSet {
170
157
}
171
158
}
172
159
173
- #[ derive( Debug , Default ) ]
160
+ #[ derive( Debug ) ]
174
161
struct FieldsHandler {
175
- constructor_inits : Vec < Box < Expr > > ,
176
- constructor_found : bool ,
162
+ has_super : bool ,
177
163
}
178
164
179
165
impl VisitMut for FieldsHandler {
180
166
noop_visit_mut_type ! ( ) ;
181
167
182
- fn visit_mut_class ( & mut self , n : & mut Class ) {
183
- n. body . visit_mut_with ( self ) ;
168
+ fn visit_mut_class ( & mut self , _: & mut Class ) {
169
+ // skip inner classes
170
+ // In fact, FieldsHandler does not visit children recursively.
171
+ // We call FieldsHandler with the class.body as the only entry point.
172
+ // The FieldsHandler actually operates in a iterative way.
184
173
}
185
174
186
- fn visit_mut_class_member ( & mut self , n : & mut ClassMember ) {
187
- match n {
188
- ClassMember :: Constructor ( ..) => self . constructor_found = true ,
189
- ClassMember :: ClassProp ( ClassProp {
190
- ref span,
191
- ref is_static,
192
- key,
193
- value,
194
- ..
195
- } ) => {
196
- if let Some ( value) = value. take ( ) {
197
- let init_expr: Expr = AssignExpr {
198
- span : * span,
199
- op : op ! ( "=" ) ,
200
- left : MemberExpr {
201
- span : DUMMY_SP ,
202
- obj : ThisExpr :: dummy ( ) . into ( ) ,
203
- prop : prop_name_to_member_prop ( key. take ( ) ) ,
204
- }
205
- . into ( ) ,
206
- right : value,
207
- }
208
- . into ( ) ;
209
-
210
- if * is_static {
211
- * n = StaticBlock {
212
- span : DUMMY_SP ,
213
- body : BlockStmt {
175
+ fn visit_mut_class_members ( & mut self , n : & mut Vec < ClassMember > ) {
176
+ let mut constructor_inits = vec ! [ ] ;
177
+
178
+ for member in n. iter_mut ( ) {
179
+ match member {
180
+ ClassMember :: ClassProp ( ClassProp {
181
+ ref span,
182
+ ref is_static,
183
+ key,
184
+ value,
185
+ ..
186
+ } ) => {
187
+ if let Some ( value) = value. take ( ) {
188
+ let init_expr: Expr = AssignExpr {
189
+ span : * span,
190
+ op : op ! ( "=" ) ,
191
+ left : MemberExpr {
214
192
span : DUMMY_SP ,
215
- stmts : vec ! [ init_expr. into_stmt( ) ] ,
216
- } ,
193
+ obj : ThisExpr :: dummy ( ) . into ( ) ,
194
+ prop : prop_name_to_member_prop ( key. take ( ) ) ,
195
+ }
196
+ . into ( ) ,
197
+ right : value,
217
198
}
218
199
. into ( ) ;
219
200
220
- return ;
221
- } else {
222
- self . constructor_inits . push ( init_expr. into ( ) ) ;
201
+ if * is_static {
202
+ * member = StaticBlock {
203
+ span : DUMMY_SP ,
204
+ body : BlockStmt {
205
+ span : DUMMY_SP ,
206
+ stmts : vec ! [ init_expr. into_stmt( ) ] ,
207
+ } ,
208
+ }
209
+ . into ( ) ;
210
+
211
+ continue ;
212
+ } else {
213
+ constructor_inits. push ( init_expr. into ( ) ) ;
214
+ }
223
215
}
224
- }
225
216
226
- n. take ( ) ;
227
- }
228
- ClassMember :: PrivateProp ( PrivateProp {
229
- ref span,
230
- is_static : false ,
231
- key,
232
- value,
233
- ..
234
- } ) => {
235
- if let Some ( value) = value. take ( ) {
236
- let init_expr: Expr = AssignExpr {
237
- span : * span,
238
- op : op ! ( "=" ) ,
239
- left : MemberExpr {
240
- span : DUMMY_SP ,
241
- obj : ThisExpr :: dummy ( ) . into ( ) ,
242
- prop : MemberProp :: PrivateName ( key. clone ( ) ) ,
217
+ member. take ( ) ;
218
+ }
219
+ ClassMember :: PrivateProp ( PrivateProp {
220
+ ref span,
221
+ is_static : false ,
222
+ key,
223
+ value,
224
+ ..
225
+ } ) => {
226
+ if let Some ( value) = value. take ( ) {
227
+ let init_expr: Expr = AssignExpr {
228
+ span : * span,
229
+ op : op ! ( "=" ) ,
230
+ left : MemberExpr {
231
+ span : DUMMY_SP ,
232
+ obj : ThisExpr :: dummy ( ) . into ( ) ,
233
+ prop : MemberProp :: PrivateName ( key. clone ( ) ) ,
234
+ }
235
+ . into ( ) ,
236
+ right : value,
243
237
}
244
- . into ( ) ,
245
- right : value,
246
- }
247
- . into ( ) ;
238
+ . into ( ) ;
248
239
249
- self . constructor_inits . push ( init_expr. into ( ) ) ;
240
+ constructor_inits. push ( init_expr. into ( ) ) ;
241
+ }
250
242
}
243
+ _ => { }
251
244
}
252
- _ => { }
253
245
}
254
- }
255
- }
256
-
257
- #[ derive( Debug , Default ) ]
258
- struct ConstructorHandler {
259
- has_super : bool ,
260
- constructor_inits : Vec < Box < Expr > > ,
261
- constructor_found : bool ,
262
- }
263
246
264
- impl VisitMut for ConstructorHandler {
265
- noop_visit_mut_type ! ( ) ;
247
+ if constructor_inits. is_empty ( ) {
248
+ return ;
249
+ }
266
250
267
- fn visit_mut_class ( & mut self , n : & mut Class ) {
268
- if !self . constructor_found {
269
- let mut constructor = default_constructor ( self . has_super ) ;
270
- constructor. visit_mut_with ( self ) ;
271
- n. body . push ( constructor. into ( ) ) ;
251
+ if let Some ( c) = n. iter_mut ( ) . find_map ( |m| m. as_mut_constructor ( ) ) {
252
+ inject_after_super ( c, constructor_inits. take ( ) ) ;
272
253
} else {
273
- n. body . visit_mut_children_with ( self ) ;
254
+ let mut c = default_constructor ( self . has_super ) ;
255
+ inject_after_super ( & mut c, constructor_inits. take ( ) ) ;
256
+ n. push ( c. into ( ) ) ;
274
257
}
275
258
}
276
-
277
- fn visit_mut_constructor ( & mut self , n : & mut Constructor ) {
278
- inject_after_super ( n, self . constructor_inits . take ( ) ) ;
279
- }
280
259
}
281
260
282
261
#[ derive( Debug ) ]
0 commit comments