diff --git a/crates/oxc_linter/src/rules/eslint/no_mixed_operators.rs b/crates/oxc_linter/src/rules/eslint/no_mixed_operators.rs index c178bb279..64e73a8db 100644 --- a/crates/oxc_linter/src/rules/eslint/no_mixed_operators.rs +++ b/crates/oxc_linter/src/rules/eslint/no_mixed_operators.rs @@ -147,7 +147,7 @@ impl NoMixedOperators { }; // Since we don't store the exact span of the operators, approximate that span to be between the lhs // and rhs of the expression. - let node_operator_span = Span::new(node_left_span.end + 1, node_right_span.start - 1); + let node_operator_span = get_op_span(node_left_span, node_right_span, node_operator, ctx); let (parent_operator, parent_left_span, parent_right_span) = match parent { AstKind::BinaryExpression(expr) => { @@ -162,7 +162,8 @@ impl NoMixedOperators { } _ => unreachable!(), }; - let parent_operator_span = Span::new(parent_left_span.end + 1, parent_right_span.start - 1); + let parent_operator_span = + get_op_span(parent_left_span, parent_right_span, parent_operator, ctx); let (node_operator, node_precedence) = operator_and_precedence(node_operator).unwrap(); let (parent_operator, parent_precedence) = @@ -236,6 +237,26 @@ fn operator_and_precedence(operator: &str) -> Option<(&'static str, u8)> { OPERATORS.iter().position(|op| *op == operator).map(|idx| (OPERATORS[idx], PRECEDENCES[idx])) } +#[allow(clippy::cast_possible_truncation)] +fn get_op_span( + node_left_span: Span, + node_right_span: Span, + node_operator: &str, + ctx: &LintContext<'_>, +) -> Span { + Span::new(node_left_span.end, node_right_span.start) + .source_text(ctx.source_text()) + .find(node_operator) + .map_or_else( + || Span::new(node_left_span.end, node_right_span.start), + |v| { + let length = node_operator.len() as u32; + let length = if length == 1 { 0 } else { length }; + Span::new(node_left_span.end + v as u32, node_left_span.end + v as u32 + length) + }, + ) +} + #[test] fn test() { use serde_json::json; @@ -295,6 +316,12 @@ fn test() { ("x ? 0 : a && b", Some(json!([{ "groups": [["&&", "||", "?:"]] }]))), ("a + b ?? c", Some(json!([{ "groups": [["+", "??"]] }]))), ("a in b ?? c", Some(json!([{ "groups": [["in", "??"]] }]))), + ("var y = 1.0 - 1/65536.0;", None), + ("var y = 1.0 - 1 /65536.0;", None), + ("var y = 1.0 - 1/ 65536.0;", None), + ("var y = 1.0- 1 / 65536.0;", None), + ("var y = 1.0 -1 / 65536.0;", None), + ("var y = 1.0-1 / 65536.0;", None), ]; Tester::new(NoMixedOperators::NAME, pass, fail).test_and_snapshot(); diff --git a/crates/oxc_linter/src/snapshots/no_mixed_operators.snap b/crates/oxc_linter/src/snapshots/no_mixed_operators.snap index d1c19773b..8e6f753d8 100644 --- a/crates/oxc_linter/src/snapshots/no_mixed_operators.snap +++ b/crates/oxc_linter/src/snapshots/no_mixed_operators.snap @@ -19,7 +19,7 @@ expression: no_mixed_operators ⚠ eslint(no-mixed-operators): Unexpected mix of > with && ╭─[no_mixed_operators.tsx:1:1] 1 │ a && b > 0 || c - · ── ─ + · ── ▲ ╰──── help: Use parentheses to clarify the intended order of operations. @@ -40,7 +40,7 @@ expression: no_mixed_operators ⚠ eslint(no-mixed-operators): Unexpected mix of / with - ╭─[no_mixed_operators.tsx:1:1] 1 │ a && b + c - d / e || f - · ─ ─ + · ▲ ▲ ╰──── help: Use parentheses to clarify the intended order of operations. @@ -54,56 +54,56 @@ expression: no_mixed_operators ⚠ eslint(no-mixed-operators): Unexpected mix of / with - ╭─[no_mixed_operators.tsx:1:1] 1 │ a && b + c - d / e || f - · ─ ─ + · ▲ ▲ ╰──── help: Use parentheses to clarify the intended order of operations. ⚠ eslint(no-mixed-operators): Unexpected mix of + with - ╭─[no_mixed_operators.tsx:1:1] 1 │ a + b - c - · ─ ─ + · ▲ ▲ ╰──── help: Use parentheses to clarify the intended order of operations. ⚠ eslint(no-mixed-operators): Unexpected mix of * with / ╭─[no_mixed_operators.tsx:1:1] 1 │ a * b / c - · ─ ─ + · ▲ ▲ ╰──── help: Use parentheses to clarify the intended order of operations. ⚠ eslint(no-mixed-operators): Unexpected mix of || with ?: ╭─[no_mixed_operators.tsx:1:1] 1 │ a || b ? c : d - · ── ───── + · ── ─────── ╰──── help: Use parentheses to clarify the intended order of operations. ⚠ eslint(no-mixed-operators): Unexpected mix of && with ?: ╭─[no_mixed_operators.tsx:1:1] 1 │ a && b ? 1 : 2 - · ── ───── + · ── ─────── ╰──── help: Use parentheses to clarify the intended order of operations. ⚠ eslint(no-mixed-operators): Unexpected mix of && with ?: ╭─[no_mixed_operators.tsx:1:1] 1 │ x ? a && b : 0 - · ─────────── + · ───────────── ╰──── help: Use parentheses to clarify the intended order of operations. ⚠ eslint(no-mixed-operators): Unexpected mix of && with ?: ╭─[no_mixed_operators.tsx:1:1] 1 │ x ? 0 : a && b - · ───── ── + · ─────── ── ╰──── help: Use parentheses to clarify the intended order of operations. ⚠ eslint(no-mixed-operators): Unexpected mix of + with ?? ╭─[no_mixed_operators.tsx:1:1] 1 │ a + b ?? c - · ─ ── + · ▲ ── ╰──── help: Use parentheses to clarify the intended order of operations. @@ -114,4 +114,46 @@ expression: no_mixed_operators ╰──── help: Use parentheses to clarify the intended order of operations. + ⚠ eslint(no-mixed-operators): Unexpected mix of / with - + ╭─[no_mixed_operators.tsx:1:1] + 1 │ var y = 1.0 - 1/65536.0; + · ▲ ▲ + ╰──── + help: Use parentheses to clarify the intended order of operations. + + ⚠ eslint(no-mixed-operators): Unexpected mix of / with - + ╭─[no_mixed_operators.tsx:1:1] + 1 │ var y = 1.0 - 1 /65536.0; + · ▲ ▲ + ╰──── + help: Use parentheses to clarify the intended order of operations. + + ⚠ eslint(no-mixed-operators): Unexpected mix of / with - + ╭─[no_mixed_operators.tsx:1:1] + 1 │ var y = 1.0 - 1/ 65536.0; + · ▲ ▲ + ╰──── + help: Use parentheses to clarify the intended order of operations. + + ⚠ eslint(no-mixed-operators): Unexpected mix of / with - + ╭─[no_mixed_operators.tsx:1:1] + 1 │ var y = 1.0- 1 / 65536.0; + · ▲ ▲ + ╰──── + help: Use parentheses to clarify the intended order of operations. + + ⚠ eslint(no-mixed-operators): Unexpected mix of / with - + ╭─[no_mixed_operators.tsx:1:1] + 1 │ var y = 1.0 -1 / 65536.0; + · ▲ ▲ + ╰──── + help: Use parentheses to clarify the intended order of operations. + + ⚠ eslint(no-mixed-operators): Unexpected mix of / with - + ╭─[no_mixed_operators.tsx:1:1] + 1 │ var y = 1.0-1 / 65536.0; + · ▲ ▲ + ╰──── + help: Use parentheses to clarify the intended order of operations. +