diff --git a/crates/oxc_language_server/src/linter.rs b/crates/oxc_language_server/src/linter.rs index 6722198902f20..01c5f4998c497 100644 --- a/crates/oxc_language_server/src/linter.rs +++ b/crates/oxc_language_server/src/linter.rs @@ -290,9 +290,9 @@ impl IsolatedLintHandler { return Some(Self::wrap_diagnostics(path, &source_text, reports, start)); }; - let module_record = Arc::new(ModuleRecord::new(path, &ret.module_record)); let mut semantic = semantic_ret.semantic; semantic.set_irregular_whitespaces(ret.irregular_whitespaces); + let module_record = Arc::new(ModuleRecord::new(path, &ret.module_record, &semantic)); let result = self.linter.run(path, Rc::new(semantic), module_record); let reports = result diff --git a/crates/oxc_linter/src/module_record.rs b/crates/oxc_linter/src/module_record.rs index a3a3d27eb82c6..d10ab4982fa6a 100644 --- a/crates/oxc_linter/src/module_record.rs +++ b/crates/oxc_linter/src/module_record.rs @@ -9,6 +9,7 @@ use std::{ use dashmap::DashMap; use rustc_hash::{FxBuildHasher, FxHashMap}; +use oxc_semantic::Semantic; use oxc_span::{CompactStr, Span}; pub use oxc_syntax::module_record::RequestedModule; @@ -435,7 +436,11 @@ impl<'a> From<&oxc_syntax::module_record::ExportLocalName<'a>> for ExportLocalNa } impl ModuleRecord { - pub fn new(path: &Path, other: &oxc_syntax::module_record::ModuleRecord) -> Self { + pub fn new( + path: &Path, + other: &oxc_syntax::module_record::ModuleRecord, + _semantic: &Semantic, + ) -> Self { Self { not_esm: other.not_esm, resolved_absolute_path: path.to_path_buf(), diff --git a/crates/oxc_linter/src/service/runtime.rs b/crates/oxc_linter/src/service/runtime.rs index ac7e0d6cb6295..443b016d01e8e 100644 --- a/crates/oxc_linter/src/service/runtime.rs +++ b/crates/oxc_linter/src/service/runtime.rs @@ -211,12 +211,25 @@ impl Runtime { }; }; - let module_record = Arc::new(ModuleRecord::new(path, &ret.module_record)); + let semantic_ret = SemanticBuilder::new() + .with_cfg(true) + .with_scope_tree_child_ids(true) + .with_build_jsdoc(true) + .with_check_syntax_error(check_syntax_errors) + .build(&ret.program); + + if !semantic_ret.errors.is_empty() { + return semantic_ret.errors.into_iter().map(|err| Message::new(err, None)).collect(); + }; + + let mut semantic = semantic_ret.semantic; + semantic.set_irregular_whitespaces(ret.irregular_whitespaces); + + let module_record = Arc::new(ModuleRecord::new(path, &ret.module_record, &semantic)); // If import plugin is enabled. if self.resolver.is_some() { self.modules.add_resolved_module(path, Arc::clone(&module_record)); - // Retrieve all dependent modules from this module. let dir = path.parent().unwrap(); module_record @@ -230,18 +243,14 @@ impl Runtime { .for_each_with(tx_error, |tx_error, (specifier, resolution)| { let path = resolution.path(); self.process_path(path, tx_error); - let Some(target_module_record_ref) = self.modules.get(path) else { - return; - }; - let ModuleState::Resolved(target_module_record) = - target_module_record_ref.value() - else { - return; - }; // Append target_module to loaded_modules - module_record - .loaded_modules - .insert(specifier.clone(), Arc::clone(target_module_record)); + if let Some(target_ref) = self.modules.get(path) { + if let ModuleState::Resolved(target_module_record) = target_ref.value() { + module_record + .loaded_modules + .insert(specifier.clone(), Arc::clone(target_module_record)); + } + }; }); // The thread is blocked here until all dependent modules are resolved. @@ -256,7 +265,6 @@ impl Runtime { continue; }; let remote_module_record = remote_module_record_ref.value(); - // 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 @@ -282,19 +290,6 @@ impl Runtime { } } - let semantic_ret = SemanticBuilder::new() - .with_cfg(true) - .with_scope_tree_child_ids(true) - .with_build_jsdoc(true) - .with_check_syntax_error(check_syntax_errors) - .build(&ret.program); - - if !semantic_ret.errors.is_empty() { - return semantic_ret.errors.into_iter().map(|err| Message::new(err, None)).collect(); - }; - - let mut semantic = semantic_ret.semantic; - semantic.set_irregular_whitespaces(ret.irregular_whitespaces); self.linter.run(path, Rc::new(semantic), Arc::clone(&module_record)) } @@ -302,7 +297,6 @@ impl Runtime { if self.resolver.is_none() { return false; } - self.modules.init_cache_state(path) } diff --git a/crates/oxc_wasm/src/lib.rs b/crates/oxc_wasm/src/lib.rs index 6bd7a08a097f3..e7f02b14dfe15 100644 --- a/crates/oxc_wasm/src/lib.rs +++ b/crates/oxc_wasm/src/lib.rs @@ -215,10 +215,11 @@ impl Oxc { } let semantic_ret = semantic_builder.with_check_syntax_error(true).with_cfg(true).build(&program); + let semantic = semantic_ret.semantic; - self.control_flow_graph = semantic_ret.semantic.cfg().map_or_else(String::default, |cfg| { + self.control_flow_graph = semantic.cfg().map_or_else(String::default, |cfg| { cfg.debug_dot(DebugDotContext::new( - semantic_ret.semantic.nodes(), + semantic.nodes(), control_flow_options.verbose.unwrap_or_default(), )) }); @@ -228,12 +229,12 @@ impl Oxc { ); } - let module_record = Arc::new(ModuleRecord::new(&path, &module_record)); + let module_record = Arc::new(ModuleRecord::new(&path, &module_record, &semantic)); self.run_linter(&run_options, &path, &program, &module_record); self.run_prettier(&run_options, source_text, source_type); - let (symbols, scopes) = semantic_ret.semantic.into_symbol_table_and_scope_tree(); + let (symbols, scopes) = semantic.into_symbol_table_and_scope_tree(); if !source_type.is_typescript_definition() { if run_options.scope.unwrap_or_default() { diff --git a/tasks/benchmark/benches/linter.rs b/tasks/benchmark/benches/linter.rs index 67daf08687d86..9b51eef628f36 100644 --- a/tasks/benchmark/benches/linter.rs +++ b/tasks/benchmark/benches/linter.rs @@ -37,9 +37,11 @@ fn bench_linter(criterion: &mut Criterion) { .with_scope_tree_child_ids(true) .with_cfg(true) .build(&ret.program); + let semantic = semantic_ret.semantic; + let module_record = + Arc::new(ModuleRecord::new(path, &ret.module_record, &semantic)); + let semantic = Rc::new(semantic); let linter = LinterBuilder::all().with_fix(FixKind::All).build(); - let semantic = Rc::new(semantic_ret.semantic); - let module_record = Arc::new(ModuleRecord::new(path, &ret.module_record)); b.iter(|| linter.run(path, Rc::clone(&semantic), Arc::clone(&module_record))); }, );