Skip to content

Commit 2f6c3b9

Browse files
heygscmysteryven
andauthored
feat(linter): add fixer for eslint/no-compare-neg-zero (#4748)
part of #4179 --------- Co-authored-by: wenzhe <mysteryven@gmail.com>
1 parent 6cf38cb commit 2f6c3b9

File tree

1 file changed

+55
-5
lines changed

1 file changed

+55
-5
lines changed

crates/oxc_linter/src/rules/eslint/no_compare_neg_zero.rs

+55-5
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use oxc_ast::{ast::Expression, AstKind};
22
use oxc_diagnostics::OxcDiagnostic;
33
use oxc_macros::declare_oxc_lint;
4-
use oxc_span::Span;
4+
use oxc_span::{GetSpan, Span};
55
use oxc_syntax::operator::{BinaryOperator, UnaryOperator};
66

77
use crate::{context::LintContext, rule::Rule, AstNode};
@@ -29,7 +29,8 @@ declare_oxc_lint!(
2929
/// if (x === -0) {}
3030
/// ```
3131
NoCompareNegZero,
32-
correctness
32+
correctness,
33+
conditional_suggestion_fix
3334
);
3435

3536
impl Rule for NoCompareNegZero {
@@ -39,8 +40,41 @@ impl Rule for NoCompareNegZero {
3940
};
4041
if Self::should_check(expr.operator) {
4142
let op = expr.operator.as_str();
42-
if is_neg_zero(&expr.left) || is_neg_zero(&expr.right) {
43-
ctx.diagnostic(no_compare_neg_zero_diagnostic(op, expr.span));
43+
let is_left_neg_zero = is_neg_zero(&expr.left);
44+
let is_right_neg_zero = is_neg_zero(&expr.right);
45+
if is_left_neg_zero || is_right_neg_zero {
46+
if expr.operator == BinaryOperator::StrictEquality {
47+
ctx.diagnostic_with_suggestion(
48+
no_compare_neg_zero_diagnostic(op, expr.span),
49+
|fixer| {
50+
// replace `x === -0` with `Object.is(x, -0)`
51+
let value = if is_left_neg_zero {
52+
ctx.source_range(expr.right.span())
53+
} else {
54+
ctx.source_range(expr.left.span())
55+
};
56+
fixer.replace(expr.span, format!("Object.is({value}, -0)"))
57+
},
58+
);
59+
} else {
60+
// <https://tc39.es/ecma262/#%E2%84%9D>
61+
// <https://tc39.es/ecma262/#sec-numeric-types-number-lessThan>
62+
// The mathematical value of +0𝔽 and -0𝔽 is the mathematical value 0.
63+
// It's safe to replace -0 with 0
64+
ctx.diagnostic_with_fix(
65+
no_compare_neg_zero_diagnostic(op, expr.span),
66+
|fixer| {
67+
let start = if is_left_neg_zero {
68+
expr.left.span().start
69+
} else {
70+
expr.right.span().start
71+
};
72+
let end = start + 1;
73+
let span = Span::new(start, end);
74+
fixer.delete(&span)
75+
},
76+
);
77+
}
4478
}
4579
}
4680
}
@@ -117,5 +151,21 @@ fn test() {
117151
("-0n <= x", None),
118152
];
119153

120-
Tester::new(NoCompareNegZero::NAME, pass, fail).test_and_snapshot();
154+
let fix = vec![
155+
("x === -0", "Object.is(x, -0)", None),
156+
("-0 === x", "Object.is(x, -0)", None),
157+
("x == -0", "x == 0", None),
158+
("-0 == x", "0 == x", None),
159+
("x > -0", "x > 0", None),
160+
("-0 > x", "0 > x", None),
161+
("x >= -0", "x >= 0", None),
162+
("-0 >= x", "0 >= x", None),
163+
("x < -0", "x < 0", None),
164+
("-0 < x", "0 < x", None),
165+
("x <= -0", "x <= 0", None),
166+
("-0 <= x", "0 <= x", None),
167+
("-0n <= x", "0n <= x", None),
168+
];
169+
170+
Tester::new(NoCompareNegZero::NAME, pass, fail).expect_fix(fix).test_and_snapshot();
121171
}

0 commit comments

Comments
 (0)