Skip to content

Commit

Permalink
feat(linter) add fixer to no-var
Browse files Browse the repository at this point in the history
  • Loading branch information
camc314 committed Aug 23, 2024
1 parent 7eb052e commit 7961de5
Showing 1 changed file with 53 additions and 4 deletions.
57 changes: 53 additions & 4 deletions crates/oxc_linter/src/rules/eslint/no_var.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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();
}

0 comments on commit 7961de5

Please sign in to comment.