@@ -22,7 +22,7 @@ use oxc_allocator::Allocator;
22
22
#[ allow( clippy:: wildcard_imports) ]
23
23
use oxc_ast:: { ast:: * , AstBuilder , Visit } ;
24
24
use oxc_diagnostics:: OxcDiagnostic ;
25
- use oxc_span:: { SourceType , SPAN } ;
25
+ use oxc_span:: { Atom , SourceType , SPAN } ;
26
26
27
27
use crate :: scope:: ScopeTree ;
28
28
@@ -86,27 +86,16 @@ impl<'a> IsolatedDeclarations<'a> {
86
86
if has_import_or_export {
87
87
self . transform_statements_on_demand ( & program. body )
88
88
} else {
89
- self . transform_program_without_module_declaration ( program)
90
- }
91
- }
92
-
93
- pub fn modifiers_declare ( & self ) -> Modifiers < ' a > {
94
- if self . scope . is_ts_module_block_flag ( ) {
95
- // If we are in a module block, we don't need to add declare
96
- Modifiers :: empty ( )
97
- } else {
98
- Modifiers :: new (
99
- self . ast . new_vec_single ( Modifier { span : SPAN , kind : ModifierKind :: Declare } ) ,
100
- )
89
+ self . transform_program_without_module_declaration ( & program. body )
101
90
}
102
91
}
103
92
104
93
pub fn transform_program_without_module_declaration (
105
94
& mut self ,
106
- program : & Program < ' a > ,
95
+ stmts : & oxc_allocator :: Vec < ' a , Statement < ' a > > ,
107
96
) -> oxc_allocator:: Vec < ' a , Statement < ' a > > {
108
97
let mut new_ast_stmts = self . ast . new_vec :: < Statement < ' a > > ( ) ;
109
- for stmt in & program . body {
98
+ for stmt in Self :: remove_function_overloads_implementation ( self . ast . copy ( stmts ) ) {
110
99
if let Some ( decl) = stmt. as_declaration ( ) {
111
100
if let Some ( decl) = self . transform_declaration ( decl, false ) {
112
101
new_ast_stmts. push ( Statement :: from ( decl) ) ;
@@ -130,68 +119,75 @@ impl<'a> IsolatedDeclarations<'a> {
130
119
// 2. Transform export declarations
131
120
// 3. Collect all bindings / reference from module declarations
132
121
// 4. Collect transformed indexes
133
- stmts. iter ( ) . for_each ( |stmt| match stmt {
134
- match_declaration ! ( Statement ) => {
135
- match stmt. to_declaration ( ) {
136
- Declaration :: VariableDeclaration ( decl) => {
137
- variables_declarations. push_back (
138
- self . ast . copy ( & decl. declarations ) . into_iter ( ) . collect :: < Vec < _ > > ( ) ,
139
- ) ;
140
- variable_transformed_indexes. push_back ( Vec :: default ( ) ) ;
141
- }
142
- Declaration :: UsingDeclaration ( decl) => {
143
- variables_declarations. push_back (
144
- self . ast . copy ( & decl. declarations ) . into_iter ( ) . collect :: < Vec < _ > > ( ) ,
145
- ) ;
146
- variable_transformed_indexes. push_back ( Vec :: default ( ) ) ;
122
+ for stmt in Self :: remove_function_overloads_implementation ( self . ast . copy ( stmts) ) {
123
+ match stmt {
124
+ match_declaration ! ( Statement ) => {
125
+ match stmt. to_declaration ( ) {
126
+ Declaration :: VariableDeclaration ( decl) => {
127
+ variables_declarations. push_back (
128
+ self . ast . copy ( & decl. declarations ) . into_iter ( ) . collect :: < Vec < _ > > ( ) ,
129
+ ) ;
130
+ variable_transformed_indexes. push_back ( Vec :: default ( ) ) ;
131
+ }
132
+ Declaration :: UsingDeclaration ( decl) => {
133
+ variables_declarations. push_back (
134
+ self . ast . copy ( & decl. declarations ) . into_iter ( ) . collect :: < Vec < _ > > ( ) ,
135
+ ) ;
136
+ variable_transformed_indexes. push_back ( Vec :: default ( ) ) ;
137
+ }
138
+ _ => { }
147
139
}
148
- _ => { }
140
+ new_stmts . push ( stmt ) ;
149
141
}
150
- new_stmts. push ( self . ast . copy ( stmt) ) ;
151
- }
152
- match_module_declaration ! ( Statement ) => {
153
- transformed_indexes. push ( new_stmts. len ( ) ) ;
154
- match stmt. to_module_declaration ( ) {
155
- ModuleDeclaration :: ExportDefaultDeclaration ( decl) => {
156
- if let Some ( ( var_decl, new_decl) ) =
157
- self . transform_export_default_declaration ( decl)
158
- {
159
- if let Some ( var_decl) = var_decl {
160
- self . scope . visit_variable_declaration ( & var_decl) ;
161
- new_stmts
162
- . push ( Statement :: VariableDeclaration ( self . ast . alloc ( var_decl) ) ) ;
163
- transformed_indexes. push ( new_stmts. len ( ) ) ;
142
+ match_module_declaration ! ( Statement ) => {
143
+ transformed_indexes. push ( new_stmts. len ( ) ) ;
144
+ match stmt. to_module_declaration ( ) {
145
+ ModuleDeclaration :: ExportDefaultDeclaration ( decl) => {
146
+ if let Some ( ( var_decl, new_decl) ) =
147
+ self . transform_export_default_declaration ( decl)
148
+ {
149
+ if let Some ( var_decl) = var_decl {
150
+ self . scope . visit_variable_declaration ( & var_decl) ;
151
+ new_stmts. push ( Statement :: VariableDeclaration (
152
+ self . ast . alloc ( var_decl) ,
153
+ ) ) ;
154
+ transformed_indexes. push ( new_stmts. len ( ) ) ;
155
+ }
156
+
157
+ self . scope . visit_export_default_declaration ( & new_decl) ;
158
+ new_stmts. push ( Statement :: ExportDefaultDeclaration (
159
+ self . ast . alloc ( new_decl) ,
160
+ ) ) ;
161
+ continue ;
164
162
}
165
163
166
- self . scope . visit_export_default_declaration ( & new_decl) ;
167
- new_stmts. push ( Statement :: ExportDefaultDeclaration (
168
- self . ast . alloc ( new_decl) ,
169
- ) ) ;
170
- return ;
164
+ self . scope . visit_export_default_declaration ( decl) ;
171
165
}
172
166
173
- self . scope . visit_export_default_declaration ( decl) ;
174
- }
175
- ModuleDeclaration :: ExportNamedDeclaration ( decl) => {
176
- if let Some ( new_decl) = self . transform_export_named_declaration ( decl) {
177
- self . scope . visit_declaration (
178
- new_decl. declaration . as_ref ( ) . unwrap_or_else ( || unreachable ! ( ) ) ,
179
- ) ;
167
+ ModuleDeclaration :: ExportNamedDeclaration ( decl) => {
168
+ if let Some ( new_decl) = self . transform_export_named_declaration ( decl) {
169
+ self . scope . visit_declaration (
170
+ new_decl. declaration . as_ref ( ) . unwrap_or_else ( || unreachable ! ( ) ) ,
171
+ ) ;
180
172
181
- new_stmts
182
- . push ( Statement :: ExportNamedDeclaration ( self . ast . alloc ( new_decl) ) ) ;
183
- return ;
184
- }
173
+ new_stmts. push ( Statement :: ExportNamedDeclaration (
174
+ self . ast . alloc ( new_decl) ,
175
+ ) ) ;
176
+ continue ;
177
+ }
185
178
186
- self . scope . visit_export_named_declaration ( decl) ;
179
+ self . scope . visit_export_named_declaration ( decl) ;
180
+ }
181
+ module_declaration => {
182
+ self . scope . visit_module_declaration ( module_declaration) ;
183
+ }
187
184
}
188
- module_declaration => self . scope . visit_module_declaration ( module_declaration) ,
189
- }
190
185
191
- new_stmts. push ( self . ast . copy ( stmt) ) ;
186
+ new_stmts. push ( stmt) ;
187
+ }
188
+ _ => { }
192
189
}
193
- _ => { }
194
- } ) ;
190
+ }
195
191
196
192
// 5. Transform statements until no more transformation can be done
197
193
let mut last_reference_len = 0 ;
@@ -201,13 +197,11 @@ impl<'a> IsolatedDeclarations<'a> {
201
197
let mut variables_declarations_iter = variables_declarations. iter_mut ( ) ;
202
198
let mut variable_transformed_indexes_iter = variable_transformed_indexes. iter_mut ( ) ;
203
199
204
- ( 0 .. new_stmts. len ( ) ) . for_each ( |i| {
200
+ for ( i , stmt ) in new_stmts. iter_mut ( ) . enumerate ( ) {
205
201
if transformed_indexes. contains ( & i) {
206
- return ;
202
+ continue ;
207
203
}
208
- let Some ( decl) = new_stmts[ i] . as_declaration ( ) else {
209
- return ;
210
- } ;
204
+ let Some ( decl) = stmt. as_declaration ( ) else { continue } ;
211
205
212
206
if let Declaration :: VariableDeclaration ( _) | Declaration :: UsingDeclaration ( _) = decl
213
207
{
@@ -219,25 +213,23 @@ impl<'a> IsolatedDeclarations<'a> {
219
213
unreachable ! ( )
220
214
} ;
221
215
222
- ( 0 .. cur_variable_declarations. len ( ) ) . for_each ( |ii| {
216
+ for ( ii , declarator ) in cur_variable_declarations. iter_mut ( ) . enumerate ( ) {
223
217
if cur_transformed_indexes. contains ( & ii) {
224
- return ;
218
+ continue ;
225
219
}
226
220
227
- if let Some ( decl) =
228
- self . transform_variable_declarator ( & cur_variable_declarations[ ii] , true )
229
- {
221
+ if let Some ( decl) = self . transform_variable_declarator ( declarator, true ) {
230
222
self . scope . visit_variable_declarator ( & decl) ;
231
223
cur_transformed_indexes. push ( ii) ;
232
- cur_variable_declarations [ ii ] = decl;
224
+ * declarator = decl;
233
225
}
234
- } ) ;
226
+ }
235
227
} else if let Some ( decl) = self . transform_declaration ( decl, true ) {
236
228
self . scope . visit_declaration ( & decl) ;
237
229
transformed_indexes. push ( i) ;
238
- new_stmts [ i ] = Statement :: from ( decl) ;
230
+ * stmt = Statement :: from ( decl) ;
239
231
}
240
- } ) ;
232
+ }
241
233
}
242
234
243
235
// 6. Transform variable/using declarations, import statements, remove unused imports
@@ -304,4 +296,67 @@ impl<'a> IsolatedDeclarations<'a> {
304
296
305
297
new_ast_stmts
306
298
}
299
+
300
+ pub fn remove_function_overloads_implementation (
301
+ stmts : oxc_allocator:: Vec < ' a , Statement < ' a > > ,
302
+ ) -> impl Iterator < Item = Statement < ' a > > + ' _ {
303
+ let mut last_function_name: Option < Atom < ' a > > = None ;
304
+
305
+ stmts. into_iter ( ) . filter_map ( move |stmt| match stmt {
306
+ Statement :: FunctionDeclaration ( ref func) => {
307
+ let name = & func
308
+ . id
309
+ . as_ref ( )
310
+ . unwrap_or_else ( || {
311
+ unreachable ! (
312
+ "Only export default function declaration is allowed to have no name"
313
+ )
314
+ } )
315
+ . name ;
316
+ if last_function_name. as_ref ( ) . is_some_and ( |last_name| last_name == name)
317
+ && func. body . is_some ( )
318
+ {
319
+ None
320
+ } else {
321
+ last_function_name = Some ( name. clone ( ) ) ;
322
+ Some ( stmt)
323
+ }
324
+ }
325
+ Statement :: ExportNamedDeclaration ( ref decl) => {
326
+ if let Some ( Declaration :: FunctionDeclaration ( ref func) ) = decl. declaration {
327
+ let name = & func
328
+ . id
329
+ . as_ref ( )
330
+ . unwrap_or_else ( || {
331
+ unreachable ! (
332
+ "Only export default function declaration is allowed to have no name"
333
+ )
334
+ } )
335
+ . name ;
336
+ if last_function_name. as_ref ( ) . is_some_and ( |last_name| last_name == name)
337
+ && func. body . is_some ( )
338
+ {
339
+ None
340
+ } else {
341
+ last_function_name = Some ( name. clone ( ) ) ;
342
+ Some ( stmt)
343
+ }
344
+ } else {
345
+ Some ( stmt)
346
+ }
347
+ }
348
+ _ => Some ( stmt) ,
349
+ } )
350
+ }
351
+
352
+ pub fn modifiers_declare ( & self ) -> Modifiers < ' a > {
353
+ if self . scope . is_ts_module_block_flag ( ) {
354
+ // If we are in a module block, we don't need to add declare
355
+ Modifiers :: empty ( )
356
+ } else {
357
+ Modifiers :: new (
358
+ self . ast . new_vec_single ( Modifier { span : SPAN , kind : ModifierKind :: Declare } ) ,
359
+ )
360
+ }
361
+ }
307
362
}
0 commit comments