Skip to content

Commit

Permalink
refactor(linter): add capability of adding semantic data to module re…
Browse files Browse the repository at this point in the history
…cord (#7561)

closes #5814
closes #5816
  • Loading branch information
Boshen committed Dec 1, 2024
1 parent 123b5b7 commit 0f3f67a
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 36 deletions.
2 changes: 1 addition & 1 deletion crates/oxc_language_server/src/linter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
7 changes: 6 additions & 1 deletion crates/oxc_linter/src/module_record.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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(),
Expand Down
50 changes: 22 additions & 28 deletions crates/oxc_linter/src/service/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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.
Expand All @@ -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
Expand All @@ -282,27 +290,13 @@ 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))
}

pub(super) fn init_cache_state(&self, path: &Path) -> bool {
if self.resolver.is_none() {
return false;
}

self.modules.init_cache_state(path)
}

Expand Down
9 changes: 5 additions & 4 deletions crates/oxc_wasm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
))
});
Expand All @@ -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() {
Expand Down
6 changes: 4 additions & 2 deletions tasks/benchmark/benches/linter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)));
},
);
Expand Down

0 comments on commit 0f3f67a

Please sign in to comment.