@@ -40,8 +40,10 @@ pub struct Scanner<'a> {
4040 current_stmt_info : StmtInfo ,
4141 result : ScanResult ,
4242 esm_export_keyword : Option < Span > ,
43- cjs_export_keyword : Option < Span > ,
43+ esm_import_keyword : Option < Span > ,
4444 pub namespace_symbol : SymbolRef ,
45+ used_exports_ref : bool ,
46+ used_module_ref : bool ,
4547}
4648
4749impl < ' ast > Scanner < ' ast > {
@@ -68,45 +70,49 @@ impl<'ast> Scanner<'ast> {
6870 current_stmt_info : StmtInfo :: default ( ) ,
6971 result,
7072 esm_export_keyword : None ,
71- cjs_export_keyword : None ,
73+ esm_import_keyword : None ,
7274 module_type,
7375 namespace_symbol : namespace_ref,
76+ used_exports_ref : false ,
77+ used_module_ref : false ,
7478 }
7579 }
7680
7781 pub fn scan ( mut self , program : & Program < ' ast > ) -> ScanResult {
7882 self . visit_program ( program) ;
79- self . result
80- }
83+ let mut exports_kind = ExportsKind :: None ;
8184
82- fn set_esm_export_keyword ( & mut self , span : Span ) {
83- if self . esm_export_keyword . is_none ( ) {
84- self . esm_export_keyword = Some ( span) ;
85+ if self . esm_export_keyword . is_some ( ) {
86+ exports_kind = ExportsKind :: Esm ;
87+ } else if self . used_exports_ref || self . used_module_ref {
88+ exports_kind = ExportsKind :: CommonJs ;
89+ } else {
90+ // TODO(hyf0): need review this. Why `ModuleType` doesn't have higher priority?
91+ match self . module_type {
92+ ModuleType :: CJS | ModuleType :: CjsPackageJson => {
93+ exports_kind = ExportsKind :: CommonJs ;
94+ }
95+ ModuleType :: EsmMjs | ModuleType :: EsmPackageJson => {
96+ exports_kind = ExportsKind :: Esm ;
97+ }
98+ ModuleType :: Unknown => {
99+ if self . esm_import_keyword . is_some ( ) {
100+ exports_kind = ExportsKind :: Esm ;
101+ }
102+ }
103+ }
85104 }
105+
106+ self . result . exports_kind = exports_kind;
107+ self . result
86108 }
87109
88110 fn is_unresolved_reference ( & self , ident_ref : & IdentifierReference ) -> bool {
89111 self . scope . is_unresolved ( ident_ref. reference_id . get ( ) . unwrap ( ) )
90112 }
91113
92- fn set_cjs_export_keyword ( & mut self , span : Span ) {
93- if self . cjs_export_keyword . is_none ( ) {
94- self . cjs_export_keyword = Some ( span) ;
95- }
96- }
97-
98- fn set_exports_kind ( & mut self ) {
99- if self . esm_export_keyword . is_some ( ) {
100- self . result . exports_kind = ExportsKind :: Esm ;
101- } else if self . cjs_export_keyword . is_some ( ) {
102- self . result . exports_kind = ExportsKind :: CommonJs ;
103- } else if self . module_type . is_esm ( ) {
104- self . result . exports_kind = ExportsKind :: Esm ;
105- } else if self . module_type . is_commonjs ( ) {
106- self . result . exports_kind = ExportsKind :: CommonJs ;
107- } else {
108- self . result . exports_kind = ExportsKind :: Esm ;
109- }
114+ fn set_esm_export_keyword ( & mut self , span : Span ) {
115+ self . esm_export_keyword . get_or_insert ( span) ;
110116 }
111117
112118 fn add_declared_id ( & mut self , id : SymbolId ) {
@@ -276,6 +282,8 @@ impl<'ast> Scanner<'ast> {
276282 fn scan_module_decl ( & mut self , decl : & ModuleDeclaration ) {
277283 match decl {
278284 oxc:: ast:: ast:: ModuleDeclaration :: ImportDeclaration ( decl) => {
285+ // TODO: this should be the span of `import` keyword, while now it is the span of the whole import declaration.
286+ self . esm_import_keyword . get_or_insert ( decl. span ) ;
279287 self . scan_import_decl ( decl) ;
280288 }
281289 oxc:: ast:: ast:: ModuleDeclaration :: ExportAllDeclaration ( decl) => {
@@ -311,7 +319,6 @@ impl<'ast> Visit<'ast> for Scanner<'ast> {
311319 self . visit_statement ( stmt) ;
312320 self . result . stmt_infos . add_stmt_info ( std:: mem:: take ( & mut self . current_stmt_info ) ) ;
313321 }
314- self . set_exports_kind ( ) ;
315322 }
316323
317324 fn visit_binding_identifier ( & mut self , ident : & oxc:: ast:: ast:: BindingIdentifier ) {
@@ -327,14 +334,15 @@ impl<'ast> Visit<'ast> for Scanner<'ast> {
327334 Some ( symbol_id) if self . is_top_level ( symbol_id) => {
328335 self . add_referenced_symbol ( symbol_id) ;
329336 }
330- _ => { }
331- }
332- if ident . name == "module" || ident . name == "exports" {
333- if let Some ( refs ) = self . scope . root_unresolved_references ( ) . get ( & ident . name ) {
334- if refs . iter ( ) . any ( |r| ( * r ) . eq ( & ident. reference_id . get ( ) . unwrap ( ) ) ) {
335- self . set_cjs_export_keyword ( ident . span ) ;
337+ None => {
338+ if ident . name == "module" {
339+ self . used_module_ref = true ;
340+ }
341+ if ident. name == "exports" {
342+ self . used_exports_ref = true ;
336343 }
337344 }
345+ _ => { }
338346 }
339347 }
340348
0 commit comments