refactor(linter): add capability of adding semantic data to module record (#7561)

closes #5814
closes #5816
This commit is contained in:
Boshen 2024-12-01 08:14:43 +00:00
parent 123b5b7f38
commit 0f3f67a05a
5 changed files with 38 additions and 36 deletions

View file

@ -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

View file

@ -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(),

View file

@ -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)
}

View file

@ -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() {

View file

@ -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)));
},
);