feat(linter/eslint): Implement no-div-regex (#3442)

Rule Detail:
[link](https://eslint.org/docs/latest/rules/no-div-regex)
This commit is contained in:
Jelle van der Waa 2024-05-28 03:13:11 +02:00 committed by GitHub
parent 6a322c9c96
commit b589fd612f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 79 additions and 0 deletions

View file

@ -52,6 +52,7 @@ mod eslint {
pub mod no_control_regex;
pub mod no_debugger;
pub mod no_delete_var;
pub mod no_div_regex;
pub mod no_dupe_class_members;
pub mod no_dupe_else_if;
pub mod no_dupe_keys;
@ -428,6 +429,7 @@ oxc_macros::declare_all_lint_rules! {
eslint::no_control_regex,
eslint::no_debugger,
eslint::no_delete_var,
eslint::no_div_regex,
eslint::no_dupe_class_members,
eslint::no_dupe_else_if,
eslint::no_dupe_keys,

View file

@ -0,0 +1,67 @@
use oxc_ast::AstKind;
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_span::Span;
use crate::{context::LintContext, fixer::Fix, rule::Rule, AstNode};
fn no_div_regex_diagnostic(span0: Span) -> OxcDiagnostic {
OxcDiagnostic::warn(
"eslint(no-div-regex): A regular expression literal can be confused with '/='.",
)
.with_help("Rewrite `/=` into `/[=]`")
.with_labels([span0.into()])
}
#[derive(Debug, Default, Clone)]
pub struct NoDivRegex;
declare_oxc_lint!(
/// ### What it does
///
/// Disallow equal signs explicitly at the beginning of regular expressions.
///
/// ### Why is this bad?
///
/// Characters /= at the beginning of a regular expression literal can be confused with a
/// division assignment operator.
///
/// ### Example
/// ```javascript
/// function bar() { return /=foo/; }
/// ```
NoDivRegex,
restriction,
);
impl Rule for NoDivRegex {
fn run<'a>(&self, node: &AstNode<'a>, ctx: &LintContext<'a>) {
if let AstKind::RegExpLiteral(lit) = node.kind() {
if lit.regex.pattern.starts_with('=') {
ctx.diagnostic_with_fix(no_div_regex_diagnostic(lit.span), || {
Fix::new("[=]", Span::new(lit.span.start + 1, lit.span.start + 2))
});
}
}
}
}
#[test]
fn test() {
use crate::tester::Tester;
let pass = vec![
"var f = function() { return /foo/ig.test('bar'); };",
"var f = function() { return /\\=foo/; };",
];
let fail = vec!["var f = function() { return /=foo/; };"];
let fix = vec![(
"var f = function() { return /=foo/; };",
"var f = function() { return /[=]foo/; };",
None,
)];
Tester::new(NoDivRegex::NAME, pass, fail).expect_fix(fix).test_and_snapshot();
}

View file

@ -0,0 +1,10 @@
---
source: crates/oxc_linter/src/tester.rs
expression: no_div_regex
---
⚠ eslint(no-div-regex): A regular expression literal can be confused with '/='.
╭─[no_div_regex.tsx:1:29]
1 │ var f = function() { return /=foo/; };
· ──────
╰────
help: Rewrite `/=` into `/[=]`