@@ -19,11 +19,13 @@ mod types;
19
19
20
20
use std:: { cell:: RefCell , collections:: VecDeque , mem} ;
21
21
22
+ use diagnostics:: function_with_assigning_properties;
22
23
use oxc_allocator:: Allocator ;
23
24
#[ allow( clippy:: wildcard_imports) ]
24
25
use oxc_ast:: { ast:: * , AstBuilder , Visit } ;
25
26
use oxc_diagnostics:: OxcDiagnostic ;
26
27
use oxc_span:: { Atom , SourceType , SPAN } ;
28
+ use rustc_hash:: FxHashSet ;
27
29
28
30
use crate :: scope:: ScopeTree ;
29
31
@@ -105,6 +107,7 @@ impl<'a> IsolatedDeclarations<'a> {
105
107
}
106
108
}
107
109
}
110
+ self . report_error_for_expando_function ( stmts) ;
108
111
new_ast_stmts
109
112
}
110
113
@@ -119,6 +122,7 @@ impl<'a> IsolatedDeclarations<'a> {
119
122
let mut variables_declarations = VecDeque :: new ( ) ;
120
123
let mut variable_transformed_indexes = VecDeque :: new ( ) ;
121
124
let mut transformed_indexes = Vec :: new ( ) ;
125
+
122
126
// 1. Collect all declarations, module declarations
123
127
// 2. Transform export declarations
124
128
// 3. Collect all bindings / reference from module declarations
@@ -321,6 +325,7 @@ impl<'a> IsolatedDeclarations<'a> {
321
325
. push ( Statement :: from ( ModuleDeclaration :: ExportNamedDeclaration ( empty_export) ) ) ;
322
326
}
323
327
328
+ self . report_error_for_expando_function ( stmts) ;
324
329
new_ast_stmts
325
330
}
326
331
@@ -393,6 +398,85 @@ impl<'a> IsolatedDeclarations<'a> {
393
398
} )
394
399
}
395
400
401
+ pub fn report_error_for_expando_function ( & self , stmts : & oxc_allocator:: Vec < ' a , Statement < ' a > > ) {
402
+ let mut can_expando_function_names = FxHashSet :: default ( ) ;
403
+ for stmt in stmts {
404
+ match stmt {
405
+ Statement :: ExportNamedDeclaration ( decl) => match decl. declaration . as_ref ( ) {
406
+ Some ( Declaration :: FunctionDeclaration ( func) ) => {
407
+ if func. body . is_some ( ) {
408
+ if let Some ( id) = func. id . as_ref ( ) {
409
+ can_expando_function_names. insert ( id. name . clone ( ) ) ;
410
+ }
411
+ }
412
+ }
413
+ Some ( Declaration :: VariableDeclaration ( decl) ) => {
414
+ for declarator in & decl. declarations {
415
+ if declarator. id . type_annotation . is_none ( )
416
+ && declarator. init . as_ref ( ) . is_some_and ( Expression :: is_function)
417
+ {
418
+ if let Some ( name) = declarator. id . get_identifier ( ) {
419
+ can_expando_function_names. insert ( name. clone ( ) ) ;
420
+ }
421
+ }
422
+ }
423
+ }
424
+ _ => ( ) ,
425
+ } ,
426
+ Statement :: ExportDefaultDeclaration ( decl) => {
427
+ if let ExportDefaultDeclarationKind :: FunctionDeclaration ( func) =
428
+ & decl. declaration
429
+ {
430
+ if func. body . is_some ( ) {
431
+ if let Some ( id) = func. id . as_ref ( ) {
432
+ can_expando_function_names. insert ( id. name . clone ( ) ) ;
433
+ }
434
+ }
435
+ }
436
+ }
437
+ Statement :: FunctionDeclaration ( func) => {
438
+ if func. body . is_some ( ) {
439
+ if let Some ( id) = func. id . as_ref ( ) {
440
+ if self . scope . has_reference ( & id. name ) {
441
+ can_expando_function_names. insert ( id. name . clone ( ) ) ;
442
+ }
443
+ }
444
+ }
445
+ }
446
+ Statement :: VariableDeclaration ( decl) => {
447
+ for declarator in & decl. declarations {
448
+ if declarator. id . type_annotation . is_none ( )
449
+ && declarator. init . as_ref ( ) . is_some_and ( Expression :: is_function)
450
+ {
451
+ if let Some ( name) = declarator. id . get_identifier ( ) {
452
+ if self . scope . has_reference ( & name) {
453
+ can_expando_function_names. insert ( name. clone ( ) ) ;
454
+ }
455
+ }
456
+ }
457
+ }
458
+ }
459
+ Statement :: ExpressionStatement ( stmt) => {
460
+ if let Expression :: AssignmentExpression ( assignment) = & stmt. expression {
461
+ if let AssignmentTarget :: StaticMemberExpression ( static_member_expr) =
462
+ & assignment. left
463
+ {
464
+ if let Expression :: Identifier ( ident) = & static_member_expr. object {
465
+ if can_expando_function_names. contains ( & ident. name ) {
466
+ self . error ( function_with_assigning_properties (
467
+ static_member_expr. span ,
468
+ ) ) ;
469
+ }
470
+ }
471
+ }
472
+ }
473
+ }
474
+
475
+ _ => { }
476
+ }
477
+ }
478
+ }
479
+
396
480
pub fn is_declare ( & self ) -> bool {
397
481
// If we are in a module block, we don't need to add declare
398
482
!self . scope . is_ts_module_block_flag ( )
0 commit comments