mirror of
https://github.com/danbulant/oxc
synced 2026-05-19 12:19:15 +00:00
feat(linter/eslint): add fixer to no-var (#5144)
This commit is contained in:
parent
4641034710
commit
a58e44845f
1 changed files with 53 additions and 4 deletions
|
|
@ -1,4 +1,7 @@
|
|||
use oxc_ast::{ast::VariableDeclarationKind, AstKind};
|
||||
use oxc_ast::{
|
||||
ast::{BindingPattern, BindingPatternKind, VariableDeclarationKind},
|
||||
AstKind,
|
||||
};
|
||||
use oxc_diagnostics::OxcDiagnostic;
|
||||
use oxc_macros::declare_oxc_lint;
|
||||
use oxc_span::Span;
|
||||
|
|
@ -41,19 +44,57 @@ declare_oxc_lint!(
|
|||
/// ```
|
||||
NoVar,
|
||||
restriction,
|
||||
pending // TODO: add suggestion that replaces `var` with `let` or `const` depending on if its written to
|
||||
fix
|
||||
);
|
||||
|
||||
impl Rule for NoVar {
|
||||
fn run<'a>(&self, node: &AstNode<'a>, ctx: &LintContext<'a>) {
|
||||
if let AstKind::VariableDeclaration(dec) = node.kind() {
|
||||
if dec.kind == VariableDeclarationKind::Var {
|
||||
ctx.diagnostic(no_var_diagnostic(Span::new(dec.span.start, dec.span.start + 3)));
|
||||
let is_written_to = dec.declarations.iter().any(|v| is_written_to(&v.id, ctx));
|
||||
|
||||
ctx.diagnostic_with_fix(
|
||||
no_var_diagnostic(Span::new(dec.span.start, dec.span.start + 3)),
|
||||
|fixer| {
|
||||
fixer.replace(
|
||||
Span::new(dec.span.start, dec.span.start + 3),
|
||||
if is_written_to { "let" } else { "const" },
|
||||
)
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn is_written_to(binding_pat: &BindingPattern, ctx: &LintContext) -> bool {
|
||||
match &binding_pat.kind {
|
||||
BindingPatternKind::BindingIdentifier(binding_ident) => ctx
|
||||
.semantic()
|
||||
.symbol_references(binding_ident.symbol_id.get().expect("symbol id should be set"))
|
||||
.any(oxc_semantic::Reference::is_write),
|
||||
BindingPatternKind::ObjectPattern(object_pat) => {
|
||||
if object_pat.properties.iter().any(|prop| is_written_to(&prop.value, ctx)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if let Some(rest) = &object_pat.rest {
|
||||
is_written_to(&rest.argument, ctx)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
BindingPatternKind::AssignmentPattern(_) => true,
|
||||
BindingPatternKind::ArrayPattern(array_pat) => array_pat.elements.iter().any(|elem| {
|
||||
if let Some(elem) = elem {
|
||||
is_written_to(elem, ctx)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test() {
|
||||
use crate::tester::Tester;
|
||||
|
|
@ -109,5 +150,13 @@ fn test() {
|
|||
("var bar = function () { foo(); }; var foo = function() {};", None),
|
||||
];
|
||||
|
||||
Tester::new(NoVar::NAME, pass, fail).test_and_snapshot();
|
||||
let fix = vec![
|
||||
("var foo", "const foo"),
|
||||
("var foo; foo += 1", "let foo; foo += 1"),
|
||||
("var foo,bar; bar = 'que'", "let foo,bar; bar = 'que'"),
|
||||
("var { a } = {}; a = fn()", "let { a } = {}; a = fn()"),
|
||||
("var { a } = {}; let b = a", "const { a } = {}; let b = a"),
|
||||
];
|
||||
|
||||
Tester::new(NoVar::NAME, pass, fail).expect_fix(fix).test_and_snapshot();
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue