feat(linter): add fixer for unicorn prefer-string-replace-all (#4801)

This commit is contained in:
camc314 2024-08-10 14:46:12 +00:00
parent 504ac0b178
commit 070ae53ad6
2 changed files with 63 additions and 10 deletions

View file

@ -6,6 +6,8 @@ use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_span::{CompactStr, Span};
use oxc_span::GetSpan;
use crate::{ast_util::extract_regex_flags, context::LintContext, rule::Rule, AstNode};
fn string_literal(span0: Span, x1: &str) -> OxcDiagnostic {
@ -45,7 +47,8 @@ declare_oxc_lint!(
/// foo.replace(pattern, bar)
/// ```
PreferStringReplaceAll,
pedantic
pedantic,
fix
);
impl Rule for PreferStringReplaceAll {
@ -76,11 +79,17 @@ impl Rule for PreferStringReplaceAll {
match method_name_str {
"replaceAll" => {
if let Some(k) = get_pattern_replacement(pattern) {
ctx.diagnostic(string_literal(static_member_expr.property.span, &k));
ctx.diagnostic_with_fix(string_literal(pattern.span(), &k), |fixer| {
// foo.replaceAll(/hello world/g, bar) => foo.replaceAll("hello world", bar)
fixer.replace(pattern.span(), format!("{k:?}"))
});
}
}
"replace" if is_reg_exp_with_global_flag(pattern) => {
ctx.diagnostic(use_replace_all(static_member_expr.property.span));
ctx.diagnostic_with_fix(
use_replace_all(static_member_expr.property.span),
|fixer| fixer.replace(static_member_expr.property.span, "replaceAll"),
);
}
_ => {}
}
@ -213,5 +222,10 @@ fn test() {
r#""Hello world".replaceAll(/world/g, 'world!');"#,
];
Tester::new(PreferStringReplaceAll::NAME, pass, fail).test_and_snapshot();
let fix = vec![
("foo.replace(/a/g, bar)", "foo.replaceAll(/a/g, bar)"),
("foo.replaceAll(/a/g, bar)", "foo.replaceAll(\"a\", bar)"),
];
Tester::new(PreferStringReplaceAll::NAME, pass, fail).expect_fix(fix).test_and_snapshot();
}

View file

@ -6,231 +6,270 @@ source: crates/oxc_linter/src/tester.rs
1 │ foo.replace(/a/g, bar)
· ───────
╰────
help: Replace `replace` with `replaceAll`.
⚠ eslint-plugin-unicorn(prefer-string-replace-all): Prefer `String#replaceAll()` over `String#replace()` when using a regex with the global flag.
╭─[prefer_string_replace_all.tsx:1:5]
1 │ foo.replace(/"'/g, '\'')
· ───────
╰────
help: Replace `replace` with `replaceAll`.
⚠ eslint-plugin-unicorn(prefer-string-replace-all): Prefer `String#replaceAll()` over `String#replace()` when using a regex with the global flag.
╭─[prefer_string_replace_all.tsx:1:5]
1 │ foo.replace(/\./g, bar)
· ───────
╰────
help: Replace `replace` with `replaceAll`.
⚠ eslint-plugin-unicorn(prefer-string-replace-all): Prefer `String#replaceAll()` over `String#replace()` when using a regex with the global flag.
╭─[prefer_string_replace_all.tsx:1:5]
1 │ foo.replace(/\\\./g, bar)
· ───────
╰────
help: Replace `replace` with `replaceAll`.
⚠ eslint-plugin-unicorn(prefer-string-replace-all): Prefer `String#replaceAll()` over `String#replace()` when using a regex with the global flag.
╭─[prefer_string_replace_all.tsx:1:5]
1 │ foo.replace(/\|/g, bar)
· ───────
╰────
help: Replace `replace` with `replaceAll`.
⚠ eslint-plugin-unicorn(prefer-string-replace-all): Prefer `String#replaceAll()` over `String#replace()` when using a regex with the global flag.
╭─[prefer_string_replace_all.tsx:1:5]
1 │ foo.replace(/a/gu, bar)
· ───────
╰────
help: Replace `replace` with `replaceAll`.
⚠ eslint-plugin-unicorn(prefer-string-replace-all): Prefer `String#replaceAll()` over `String#replace()` when using a regex with the global flag.
╭─[prefer_string_replace_all.tsx:1:5]
1 │ foo.replace(/a/ug, bar)
· ───────
╰────
help: Replace `replace` with `replaceAll`.
⚠ eslint-plugin-unicorn(prefer-string-replace-all): Prefer `String#replaceAll()` over `String#replace()` when using a regex with the global flag.
╭─[prefer_string_replace_all.tsx:1:5]
1 │ foo.replace(/[a]/g, bar)
· ───────
╰────
help: Replace `replace` with `replaceAll`.
⚠ eslint-plugin-unicorn(prefer-string-replace-all): Prefer `String#replaceAll()` over `String#replace()` when using a regex with the global flag.
╭─[prefer_string_replace_all.tsx:1:5]
1 │ foo.replace(/a?/g, bar)
· ───────
╰────
help: Replace `replace` with `replaceAll`.
⚠ eslint-plugin-unicorn(prefer-string-replace-all): Prefer `String#replaceAll()` over `String#replace()` when using a regex with the global flag.
╭─[prefer_string_replace_all.tsx:1:5]
1 │ foo.replace(/.*/g, bar)
· ───────
╰────
help: Replace `replace` with `replaceAll`.
⚠ eslint-plugin-unicorn(prefer-string-replace-all): Prefer `String#replaceAll()` over `String#replace()` when using a regex with the global flag.
╭─[prefer_string_replace_all.tsx:1:5]
1 │ foo.replace(/a|b/g, bar)
· ───────
╰────
help: Replace `replace` with `replaceAll`.
⚠ eslint-plugin-unicorn(prefer-string-replace-all): Prefer `String#replaceAll()` over `String#replace()` when using a regex with the global flag.
╭─[prefer_string_replace_all.tsx:1:5]
1 │ foo.replace(/\W/g, bar)
· ───────
╰────
help: Replace `replace` with `replaceAll`.
⚠ eslint-plugin-unicorn(prefer-string-replace-all): Prefer `String#replaceAll()` over `String#replace()` when using a regex with the global flag.
╭─[prefer_string_replace_all.tsx:1:5]
1 │ foo.replace(/\u{61}/g, bar)
· ───────
╰────
help: Replace `replace` with `replaceAll`.
⚠ eslint-plugin-unicorn(prefer-string-replace-all): Prefer `String#replaceAll()` over `String#replace()` when using a regex with the global flag.
╭─[prefer_string_replace_all.tsx:1:5]
1 │ foo.replace(/\u{61}/gu, bar)
· ───────
╰────
help: Replace `replace` with `replaceAll`.
⚠ eslint-plugin-unicorn(prefer-string-replace-all): Prefer `String#replaceAll()` over `String#replace()` when using a regex with the global flag.
╭─[prefer_string_replace_all.tsx:1:5]
1 │ foo.replace(/\u{61}/gv, bar)
· ───────
╰────
help: Replace `replace` with `replaceAll`.
⚠ eslint-plugin-unicorn(prefer-string-replace-all): Prefer `String#replaceAll()` over `String#replace()` when using a regex with the global flag.
╭─[prefer_string_replace_all.tsx:1:5]
1 │ foo.replace(/]/g, "bar")
· ───────
╰────
help: Replace `replace` with `replaceAll`.
⚠ eslint-plugin-unicorn(prefer-string-replace-all): Prefer `String#replaceAll()` over `String#replace()` when using a regex with the global flag.
╭─[prefer_string_replace_all.tsx:1:5]
1 │ foo.replace(/a/gi, bar)
· ───────
╰────
help: Replace `replace` with `replaceAll`.
⚠ eslint-plugin-unicorn(prefer-string-replace-all): Prefer `String#replaceAll()` over `String#replace()` when using a regex with the global flag.
╭─[prefer_string_replace_all.tsx:1:5]
1 │ foo.replace(/a/gui, bar)
· ───────
╰────
help: Replace `replace` with `replaceAll`.
⚠ eslint-plugin-unicorn(prefer-string-replace-all): Prefer `String#replaceAll()` over `String#replace()` when using a regex with the global flag.
╭─[prefer_string_replace_all.tsx:1:5]
1 │ foo.replace(/a/uig, bar)
· ───────
╰────
help: Replace `replace` with `replaceAll`.
⚠ eslint-plugin-unicorn(prefer-string-replace-all): Prefer `String#replaceAll()` over `String#replace()` when using a regex with the global flag.
╭─[prefer_string_replace_all.tsx:1:5]
1 │ foo.replace(/a/vig, bar)
· ───────
╰────
help: Replace `replace` with `replaceAll`.
⚠ eslint-plugin-unicorn(prefer-string-replace-all): Prefer `String#replaceAll()` over `String#replace()` when using a regex with the global flag.
╭─[prefer_string_replace_all.tsx:1:5]
1 │ foo.replace(new RegExp("foo", "g"), bar)
· ───────
╰────
help: Replace `replace` with `replaceAll`.
⚠ eslint-plugin-unicorn(prefer-string-replace-all): Prefer `String#replaceAll()` over `String#replace()` when using a regex with the global flag.
╭─[prefer_string_replace_all.tsx:1:5]
1 │ foo.replace(/a]/g, _)
· ───────
╰────
help: Replace `replace` with `replaceAll`.
⚠ eslint-plugin-unicorn(prefer-string-replace-all): Prefer `String#replaceAll()` over `String#replace()` when using a regex with the global flag.
╭─[prefer_string_replace_all.tsx:1:5]
1 │ foo.replace(/[a]/g, _)
· ───────
╰────
help: Replace `replace` with `replaceAll`.
⚠ eslint-plugin-unicorn(prefer-string-replace-all): Prefer `String#replaceAll()` over `String#replace()` when using a regex with the global flag.
╭─[prefer_string_replace_all.tsx:1:5]
1 │ foo.replace(/a{1/g, _)
· ───────
╰────
help: Replace `replace` with `replaceAll`.
⚠ eslint-plugin-unicorn(prefer-string-replace-all): Prefer `String#replaceAll()` over `String#replace()` when using a regex with the global flag.
╭─[prefer_string_replace_all.tsx:1:5]
1 │ foo.replace(/a{1}/g, _)
· ───────
╰────
help: Replace `replace` with `replaceAll`.
⚠ eslint-plugin-unicorn(prefer-string-replace-all): Prefer `String#replaceAll()` over `String#replace()` when using a regex with the global flag.
╭─[prefer_string_replace_all.tsx:1:5]
1 │ foo.replace(/\u0022/g, _)
· ───────
╰────
help: Replace `replace` with `replaceAll`.
⚠ eslint-plugin-unicorn(prefer-string-replace-all): Prefer `String#replaceAll()` over `String#replace()` when using a regex with the global flag.
╭─[prefer_string_replace_all.tsx:1:5]
1 │ foo.replace(/\u0027/g, _)
· ───────
╰────
help: Replace `replace` with `replaceAll`.
⚠ eslint-plugin-unicorn(prefer-string-replace-all): Prefer `String#replaceAll()` over `String#replace()` when using a regex with the global flag.
╭─[prefer_string_replace_all.tsx:1:5]
1 │ foo.replace(/\cM\cj/g, _)
· ───────
╰────
help: Replace `replace` with `replaceAll`.
⚠ eslint-plugin-unicorn(prefer-string-replace-all): Prefer `String#replaceAll()` over `String#replace()` when using a regex with the global flag.
╭─[prefer_string_replace_all.tsx:1:5]
1 │ foo.replace(/\x22/g, _)
· ───────
╰────
help: Replace `replace` with `replaceAll`.
⚠ eslint-plugin-unicorn(prefer-string-replace-all): Prefer `String#replaceAll()` over `String#replace()` when using a regex with the global flag.
╭─[prefer_string_replace_all.tsx:1:5]
1 │ foo.replace(/\x27/g, _)
· ───────
╰────
help: Replace `replace` with `replaceAll`.
⚠ eslint-plugin-unicorn(prefer-string-replace-all): Prefer `String#replaceAll()` over `String#replace()` when using a regex with the global flag.
╭─[prefer_string_replace_all.tsx:1:5]
1 │ foo.replace(/\uD83D\ude00/g, _)
· ───────
╰────
help: Replace `replace` with `replaceAll`.
⚠ eslint-plugin-unicorn(prefer-string-replace-all): Prefer `String#replaceAll()` over `String#replace()` when using a regex with the global flag.
╭─[prefer_string_replace_all.tsx:1:5]
1 │ foo.replace(/\u{1f600}/gu, _)
· ───────
╰────
help: Replace `replace` with `replaceAll`.
⚠ eslint-plugin-unicorn(prefer-string-replace-all): Prefer `String#replaceAll()` over `String#replace()` when using a regex with the global flag.
╭─[prefer_string_replace_all.tsx:1:5]
1 │ foo.replace(/\n/g, _)
· ───────
╰────
help: Replace `replace` with `replaceAll`.
⚠ eslint-plugin-unicorn(prefer-string-replace-all): Prefer `String#replaceAll()` over `String#replace()` when using a regex with the global flag.
╭─[prefer_string_replace_all.tsx:1:5]
1 │ foo.replace(/\u{20}/gu, _)
· ───────
╰────
help: Replace `replace` with `replaceAll`.
⚠ eslint-plugin-unicorn(prefer-string-replace-all): Prefer `String#replaceAll()` over `String#replace()` when using a regex with the global flag.
╭─[prefer_string_replace_all.tsx:1:5]
1 │ foo.replace(/\u{20}/gv, _)
· ───────
╰────
help: Replace `replace` with `replaceAll`.
⚠ eslint-plugin-unicorn(prefer-string-replace-all): This pattern can be replaced with `a]`.
╭─[prefer_string_replace_all.tsx:1:5]
╭─[prefer_string_replace_all.tsx:1:16]
1 │ foo.replaceAll(/a]/g, _)
· ──────────
· ─────
╰────
help: Replace `/a]/g` with `"a]"`.
⚠ eslint-plugin-unicorn(prefer-string-replace-all): This pattern can be replaced with `a very very very very very very very very very very very very very very very very very very very very very very very very very very very very very long string`.
╭─[prefer_string_replace_all.tsx:1:5]
╭─[prefer_string_replace_all.tsx:1:16]
1 │ foo.replaceAll(/a very very very very very very very very very very very very very very very very very very very very very very very very very very very very very long string/g, _)
· ──────────
· ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
╰────
help: Replace `/a very very very very very very very very very very very very very very very very very very very very very very very very very very very very very long string/g` with `"a very very very very very very very very very very very very very very very very very very very very very very very very very very very very very long string"`.
⚠ eslint-plugin-unicorn(prefer-string-replace-all): Prefer `String#replaceAll()` over `String#replace()` when using a regex with the global flag.
╭─[prefer_string_replace_all.tsx:1:5]
1 │ foo.replace(/(?!a)+/g, "")
· ───────
╰────
help: Replace `replace` with `replaceAll`.
⚠ eslint-plugin-unicorn(prefer-string-replace-all): This pattern can be replaced with `world`.
╭─[prefer_string_replace_all.tsx:1:15]
╭─[prefer_string_replace_all.tsx:1:26]
1 │ "Hello world".replaceAll(/world/g, 'world!');
· ──────────
· ────────
╰────
help: Replace `/world/g` with `"world"`.