fix(linter/no-unused-vars): panic on UsingDeclarations (#5206)

Closes #5202
This commit is contained in:
DonIsaac 2024-08-25 21:26:45 +00:00
parent 982bd6ecb7
commit 8ff6f2cb86
3 changed files with 44 additions and 10 deletions

View file

@ -34,10 +34,26 @@ impl NoUnusedVars {
return fixer.noop();
}
let Some(AstKind::VariableDeclaration(declaration)) =
symbol.nodes().parent_node(decl_id).map(AstNode::kind)
else {
panic!("VariableDeclarator nodes should always be direct children of VariableDeclaration nodes");
let Some(parent) = symbol.nodes().parent_node(decl_id).map(AstNode::kind) else {
#[cfg(debug_assertions)]
panic!("VariableDeclarator nodes should always have a parent node");
#[cfg(not(debug_assertions))]
return fixer.noop();
};
let (span, declarations) = match parent {
AstKind::VariableDeclaration(decl) => (decl.span, &decl.declarations),
AstKind::UsingDeclaration(decl) => {
if decl.is_await {
return fixer.noop();
}
(decl.span, &decl.declarations)
}
_ => {
#[cfg(debug_assertions)]
panic!("VariableDeclarator nodes should always be direct children of VariableDeclaration or UsingDeclaration nodes");
#[cfg(not(debug_assertions))]
return fixer.noop();
}
};
// `true` even if references aren't considered a usage.
@ -48,18 +64,16 @@ impl NoUnusedVars {
// for `let x = 1;` or `const { x } = obj; the whole declaration can
// be removed, but for `const { x, y } = obj;` or `let x = 1, y = 2`
// we need to keep the other declarations
let has_neighbors = declaration.declarations.len() > 1;
debug_assert!(!declaration.declarations.is_empty());
let has_neighbors = declarations.len() > 1;
debug_assert!(!declarations.is_empty());
let binding_info = symbol.get_binding_info(&decl.id.kind);
match binding_info {
BindingInfo::SingleDestructure | BindingInfo::NotDestructure => {
if has_neighbors {
return symbol
.delete_from_list(fixer, &declaration.declarations, decl)
.dangerously();
return symbol.delete_from_list(fixer, declarations, decl).dangerously();
}
return fixer.delete(declaration).dangerously();
return fixer.delete_range(span).dangerously();
}
BindingInfo::MultiDestructure(mut span, is_object, is_last) => {
let source_after = &fixer.source_text()[(span.end as usize)..];

View file

@ -370,6 +370,16 @@ fn test_vars_catch() {
.test_and_snapshot();
}
#[test]
fn test_vars_using() {
let pass = vec![("using a = 1; console.log(a)", None)];
let fail = vec![("using a = 1;", None)];
Tester::new(NoUnusedVars::NAME, pass, fail)
.with_snapshot_suffix("oxc-vars-using")
.test_and_snapshot();
}
#[test]
fn test_functions() {
let pass = vec![

View file

@ -0,0 +1,10 @@
---
source: crates/oxc_linter/src/tester.rs
---
⚠ eslint(no-unused-vars): Variable 'a' is declared but never used.
╭─[no_unused_vars.tsx:1:7]
1 │ using a = 1;
· ┬
· ╰── 'a' is declared here
╰────
help: Consider removing this declaration.