mirror of
https://github.com/danbulant/oxc
synced 2026-05-19 04:08:41 +00:00
feat(linter): react/exhaustive-deps (#7151)
Firstly, a massive thanks to @alisnic for starting this (incredibly complicated) lint rule in https://github.com/oxc-project/oxc/pull/2637 ! still a draft. current state: 3x false positives (all todo with refs) 3x false negatives (TS will catch these 13x false negatvies todo with refs 1x false negative TODO closes #2637 relates to #2174
This commit is contained in:
parent
c5f4ee7a82
commit
3dcac1ae0b
7 changed files with 5750 additions and 1 deletions
|
|
@ -1,6 +1,6 @@
|
|||
use oxc_ast::{ast::BindingIdentifier, AstKind};
|
||||
use oxc_ecmascript::ToBoolean;
|
||||
use oxc_semantic::{AstNode, IsGlobalReference, NodeId, Semantic, SymbolId};
|
||||
use oxc_semantic::{AstNode, IsGlobalReference, NodeId, ReferenceId, Semantic, SymbolId};
|
||||
use oxc_span::{GetSpan, Span};
|
||||
use oxc_syntax::operator::{AssignmentOperator, BinaryOperator, LogicalOperator, UnaryOperator};
|
||||
|
||||
|
|
@ -282,6 +282,15 @@ pub fn get_declaration_of_variable<'a, 'b>(
|
|||
Some(semantic.nodes().get_node(symbol_table.get_declaration(symbol_id)))
|
||||
}
|
||||
|
||||
pub fn get_declaration_from_reference_id<'a, 'b>(
|
||||
reference_id: ReferenceId,
|
||||
semantic: &'b Semantic<'a>,
|
||||
) -> Option<&'b AstNode<'a>> {
|
||||
let symbol_table = semantic.symbols();
|
||||
let symbol_id = symbol_table.get_reference(reference_id).symbol_id()?;
|
||||
Some(semantic.nodes().get_node(symbol_table.get_declaration(symbol_id)))
|
||||
}
|
||||
|
||||
pub fn get_symbol_id_of_variable(
|
||||
ident: &IdentifierReference,
|
||||
semantic: &Semantic<'_>,
|
||||
|
|
|
|||
|
|
@ -505,6 +505,10 @@ mod node {
|
|||
pub mod no_new_require;
|
||||
}
|
||||
|
||||
mod react_hooks {
|
||||
pub mod exhaustive_deps;
|
||||
}
|
||||
|
||||
oxc_macros::declare_all_lint_rules! {
|
||||
// import::no_deprecated,
|
||||
// import::no_unused_modules,
|
||||
|
|
@ -956,4 +960,5 @@ oxc_macros::declare_all_lint_rules! {
|
|||
vitest::prefer_to_be_object,
|
||||
vitest::prefer_to_be_truthy,
|
||||
vitest::require_local_test_context_for_concurrent_snapshots,
|
||||
react_hooks::exhaustive_deps,
|
||||
}
|
||||
|
|
|
|||
3494
crates/oxc_linter/src/rules/react_hooks/exhaustive_deps.rs
Normal file
3494
crates/oxc_linter/src/rules/react_hooks/exhaustive_deps.rs
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -206,6 +206,7 @@ impl Runtime {
|
|||
// The semantic model is not built at this stage.
|
||||
let semantic_builder = SemanticBuilder::new()
|
||||
.with_cfg(true)
|
||||
.with_scope_tree_child_ids(true)
|
||||
.with_build_jsdoc(true)
|
||||
.with_check_syntax_error(check_syntax_errors)
|
||||
.build_module_record(path, &ret.program);
|
||||
|
|
|
|||
2224
crates/oxc_linter/src/snapshots/exhaustive_deps.snap
Normal file
2224
crates/oxc_linter/src/snapshots/exhaustive_deps.snap
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -289,6 +289,21 @@ impl ScopeTree {
|
|||
&self.child_ids[scope_id]
|
||||
}
|
||||
|
||||
pub fn iter_all_child_ids(&self, scope_id: ScopeId) -> impl Iterator<Item = ScopeId> + '_ {
|
||||
let mut stack = self.child_ids[scope_id].clone();
|
||||
let child_ids: &IndexVec<ScopeId, Vec<ScopeId>> = &self.child_ids;
|
||||
std::iter::from_fn(move || {
|
||||
if let Some(scope_id) = stack.pop() {
|
||||
if let Some(children) = child_ids.get(scope_id) {
|
||||
stack.extend(children.iter().copied());
|
||||
}
|
||||
Some(scope_id)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Get a mutable reference to a scope's children
|
||||
#[inline]
|
||||
pub fn get_child_ids_mut(&mut self, scope_id: ScopeId) -> &mut Vec<ScopeId> {
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ fn bench_linter(criterion: &mut Criterion) {
|
|||
let path = Path::new("");
|
||||
let semantic_ret = SemanticBuilder::new()
|
||||
.with_build_jsdoc(true)
|
||||
.with_scope_tree_child_ids(true)
|
||||
.with_cfg(true)
|
||||
.build_module_record(path, &ret.program)
|
||||
.build(&ret.program);
|
||||
|
|
|
|||
Loading…
Reference in a new issue