From 774babb7f2c9a36a12804d76c4c9b6b5684569bb Mon Sep 17 00:00:00 2001 From: Boshen <1430279+Boshen@users.noreply.github.com> Date: Sun, 22 Dec 2024 08:41:42 +0000 Subject: [PATCH] refactor(linter): read `exported_bindings_from_star_export` lazily (#8062) --- crates/oxc_linter/src/module_record.rs | 37 ++++++++++++++++++- crates/oxc_linter/src/rules/import/named.rs | 4 +- .../oxc_linter/src/rules/import/namespace.rs | 4 +- crates/oxc_linter/src/service/runtime.rs | 31 ---------------- 4 files changed, 37 insertions(+), 39 deletions(-) diff --git a/crates/oxc_linter/src/module_record.rs b/crates/oxc_linter/src/module_record.rs index 6efd6e814813c..996032d5fc104 100644 --- a/crates/oxc_linter/src/module_record.rs +++ b/crates/oxc_linter/src/module_record.rs @@ -3,7 +3,7 @@ use std::{ fmt, path::{Path, PathBuf}, - sync::{Arc, RwLock}, + sync::{Arc, OnceLock, RwLock}, }; use rustc_hash::FxHashMap; @@ -78,7 +78,7 @@ pub struct ModuleRecord { /// Reexported bindings from `export * from 'specifier'` /// Keyed by resolved path - pub exported_bindings_from_star_export: RwLock>>, + exported_bindings_from_star_export: OnceLock>>, /// `export default name` /// ^^^^^^^ span @@ -491,4 +491,37 @@ impl ModuleRecord { ..ModuleRecord::default() } } + + pub(crate) fn exported_bindings_from_star_export( + &self, + ) -> &FxHashMap> { + self.exported_bindings_from_star_export.get_or_init(|| { + let mut exported_bindings_from_star_export: FxHashMap> = + FxHashMap::default(); + let loaded_modules = self.loaded_modules.read().unwrap(); + for export_entry in &self.star_export_entries { + let Some(module_request) = &export_entry.module_request else { + continue; + }; + let Some(remote_module_record) = loaded_modules.get(module_request.name()) else { + continue; + }; + // Append both remote `bindings` and `exported_bindings_from_star_export` + let remote_exported_bindings_from_star_export = remote_module_record + .exported_bindings_from_star_export() + .iter() + .flat_map(|(_, value)| value.clone()); + let remote_bindings = remote_module_record + .exported_bindings + .keys() + .cloned() + .chain(remote_exported_bindings_from_star_export); + exported_bindings_from_star_export + .entry(remote_module_record.resolved_absolute_path.clone()) + .or_default() + .extend(remote_bindings); + } + exported_bindings_from_star_export + }) + } } diff --git a/crates/oxc_linter/src/rules/import/named.rs b/crates/oxc_linter/src/rules/import/named.rs index 0e0b903cfc48f..72033bf068038 100644 --- a/crates/oxc_linter/src/rules/import/named.rs +++ b/crates/oxc_linter/src/rules/import/named.rs @@ -117,9 +117,7 @@ impl Rule for Named { } // check re-export if remote_module_record - .exported_bindings_from_star_export - .read() - .unwrap() + .exported_bindings_from_star_export() .iter() .any(|(_, value)| value.contains(&import_name.name)) { diff --git a/crates/oxc_linter/src/rules/import/namespace.rs b/crates/oxc_linter/src/rules/import/namespace.rs index e8786cfa68961..5e84692fd8fde 100644 --- a/crates/oxc_linter/src/rules/import/namespace.rs +++ b/crates/oxc_linter/src/rules/import/namespace.rs @@ -356,9 +356,7 @@ fn check_binding_exported( if module.exported_bindings.contains_key(name) || (name == "default" && module.export_default.is_some()) || module - .exported_bindings_from_star_export - .read() - .unwrap() + .exported_bindings_from_star_export() .iter() .any(|(_, value)| value.iter().any(|s| s.as_str() == name)) { diff --git a/crates/oxc_linter/src/service/runtime.rs b/crates/oxc_linter/src/service/runtime.rs index 26768fc58adc2..62b4060c4f896 100644 --- a/crates/oxc_linter/src/service/runtime.rs +++ b/crates/oxc_linter/src/service/runtime.rs @@ -264,37 +264,6 @@ impl Runtime { // The thread is blocked here until all dependent modules are resolved. - // Resolve and append `star_export_bindings` - for export_entry in &module_record.star_export_entries { - let Some(module_request) = &export_entry.module_request else { - continue; - }; - let loaded_modules = module_record.loaded_modules.read().unwrap(); - let Some(remote_module_record) = loaded_modules.get(module_request.name()) else { - continue; - }; - // Append both remote `bindings` and `exported_bindings_from_star_export` - let remote_exported_bindings_from_star_export = - remote_module_record.exported_bindings_from_star_export.read().unwrap(); - let remote_exported_bindings_from_star_export = - remote_exported_bindings_from_star_export - .iter() - .flat_map(|(_, value)| value.clone()); - let remote_bindings = remote_module_record - .exported_bindings - .keys() - .cloned() - .chain(remote_exported_bindings_from_star_export) - .collect::>(); - module_record - .exported_bindings_from_star_export - .write() - .unwrap() - .entry(remote_module_record.resolved_absolute_path.clone()) - .or_default() - .extend(remote_bindings); - } - // Stop if the current module is not marked for lint. if !self.paths.contains(path) { return vec![];