diff --git a/crates/oxc_linter/src/rules/eslint/no_nonoctal_decimal_escape.rs b/crates/oxc_linter/src/rules/eslint/no_nonoctal_decimal_escape.rs index 17a4730be23c4..d846fa0596686 100644 --- a/crates/oxc_linter/src/rules/eslint/no_nonoctal_decimal_escape.rs +++ b/crates/oxc_linter/src/rules/eslint/no_nonoctal_decimal_escape.rs @@ -12,7 +12,9 @@ use crate::{ }; fn no_nonoctal_decimal_escape_diagnostic(escape_sequence: &str, span: Span) -> OxcDiagnostic { - OxcDiagnostic::warn(format!("Don't use '{escape_sequence}' escape sequence.")).with_label(span) + OxcDiagnostic::warn(format!("Don't use '{escape_sequence}' escape sequence.")) + .with_help("Use the actual character or a valid escape sequence instead.") + .with_label(span) } #[derive(Debug, Default, Clone)] diff --git a/crates/oxc_linter/src/rules/eslint/operator_assignment.rs b/crates/oxc_linter/src/rules/eslint/operator_assignment.rs index 026e70a56544f..487b755c95073 100644 --- a/crates/oxc_linter/src/rules/eslint/operator_assignment.rs +++ b/crates/oxc_linter/src/rules/eslint/operator_assignment.rs @@ -15,13 +15,28 @@ use serde_json::Value; use crate::{AstNode, context::LintContext, rule::Rule, utils::is_same_member_expression}; -fn operator_assignment_diagnostic(mode: Mode, span: Span, operator: &str) -> OxcDiagnostic { +fn operator_assignment_diagnostic( + mode: Mode, + span: Span, + operator: &str, + can_fix: bool, +) -> OxcDiagnostic { let msg = if Mode::Never == mode { format!("Unexpected operator assignment ({operator}) shorthand.") } else { format!("Assignment (=) can be replaced with operator assignment ({operator}).") }; - OxcDiagnostic::warn(msg).with_label(span) + let mut diagnostic = OxcDiagnostic::warn(msg).with_label(span); + + if !can_fix { + diagnostic = diagnostic.with_note(if Mode::Never == mode { + format!("Replace '{operator}' with a regular '=' assignment.") + } else { + format!("Use '{operator}' shorthand instead of '='.") + }); + } + + diagnostic } #[derive(Debug, Default, PartialEq, Clone, Copy, Serialize, JsonSchema)] @@ -129,7 +144,7 @@ fn verify(expr: &AssignmentExpression, mode: Mode, ctx: &LintContext) { let replace_operator = format!("{}=", binary_operator.as_str()); if check_is_same_reference(left, &binary_expr.left, ctx) { ctx.diagnostic_with_fix( - operator_assignment_diagnostic(mode, expr.span, &replace_operator), + operator_assignment_diagnostic(mode, expr.span, &replace_operator, true), |fixer| { if !can_be_fixed(left) { return fixer.noop(); @@ -162,7 +177,12 @@ fn verify(expr: &AssignmentExpression, mode: Mode, ctx: &LintContext) { ); } else if check_is_same_reference(left, &binary_expr.right, ctx) && is_commutative_operator { - ctx.diagnostic(operator_assignment_diagnostic(mode, expr.span, &replace_operator)); + ctx.diagnostic(operator_assignment_diagnostic( + mode, + expr.span, + &replace_operator, + false, + )); } } } @@ -170,7 +190,7 @@ fn verify(expr: &AssignmentExpression, mode: Mode, ctx: &LintContext) { fn prohibit(expr: &AssignmentExpression, mode: Mode, ctx: &LintContext) { if !expr.operator.is_assign() && !expr.operator.is_logical() { ctx.diagnostic_with_dangerous_fix( -operator_assignment_diagnostic(mode, expr.span, expr.operator.as_str()), +operator_assignment_diagnostic(mode, expr.span, expr.operator.as_str(), true), |fixer| { if !can_be_fixed(&expr.left) { return fixer.noop(); diff --git a/crates/oxc_linter/src/snapshots/eslint_no_nonoctal_decimal_escape.snap b/crates/oxc_linter/src/snapshots/eslint_no_nonoctal_decimal_escape.snap index 041d5d750640d..2dd6727cb2a8c 100644 --- a/crates/oxc_linter/src/snapshots/eslint_no_nonoctal_decimal_escape.snap +++ b/crates/oxc_linter/src/snapshots/eslint_no_nonoctal_decimal_escape.snap @@ -7,210 +7,245 @@ source: crates/oxc_linter/src/tester.rs 1 │ '\8' · ── ╰──── + help: Use the actual character or a valid escape sequence instead. ⚠ eslint(no-nonoctal-decimal-escape): Don't use '\9' escape sequence. ╭─[no_nonoctal_decimal_escape.tsx:1:2] 1 │ '\9' · ── ╰──── + help: Use the actual character or a valid escape sequence instead. ⚠ eslint(no-nonoctal-decimal-escape): Don't use '\8' escape sequence. ╭─[no_nonoctal_decimal_escape.tsx:1:2] 1 │ "\8" · ── ╰──── + help: Use the actual character or a valid escape sequence instead. ⚠ eslint(no-nonoctal-decimal-escape): Don't use '\9' escape sequence. ╭─[no_nonoctal_decimal_escape.tsx:1:3] 1 │ 'f\9' · ── ╰──── + help: Use the actual character or a valid escape sequence instead. ⚠ eslint(no-nonoctal-decimal-escape): Don't use '\9' escape sequence. ╭─[no_nonoctal_decimal_escape.tsx:1:4] 1 │ 'xo\9' · ── ╰──── + help: Use the actual character or a valid escape sequence instead. ⚠ eslint(no-nonoctal-decimal-escape): Don't use '\9' escape sequence. ╭─[no_nonoctal_decimal_escape.tsx:1:5] 1 │ 'foo\9' · ── ╰──── + help: Use the actual character or a valid escape sequence instead. ⚠ eslint(no-nonoctal-decimal-escape): Don't use '\8' escape sequence. ╭─[no_nonoctal_decimal_escape.tsx:1:5] 1 │ 'foo\8bar' · ── ╰──── + help: Use the actual character or a valid escape sequence instead. ⚠ eslint(no-nonoctal-decimal-escape): Don't use '\8' escape sequence. ╭─[no_nonoctal_decimal_escape.tsx:1:6] 1 │ '👍\8' · ── ╰──── + help: Use the actual character or a valid escape sequence instead. ⚠ eslint(no-nonoctal-decimal-escape): Don't use '\8' escape sequence. ╭─[no_nonoctal_decimal_escape.tsx:1:4] 1 │ '\\\8' · ── ╰──── + help: Use the actual character or a valid escape sequence instead. ⚠ eslint(no-nonoctal-decimal-escape): Don't use '\9' escape sequence. ╭─[no_nonoctal_decimal_escape.tsx:1:6] 1 │ '\\\\\9' · ── ╰──── + help: Use the actual character or a valid escape sequence instead. ⚠ eslint(no-nonoctal-decimal-escape): Don't use '\8' escape sequence. ╭─[no_nonoctal_decimal_escape.tsx:1:7] 1 │ 'foo\\\8' · ── ╰──── + help: Use the actual character or a valid escape sequence instead. ⚠ eslint(no-nonoctal-decimal-escape): Don't use '\8' escape sequence. ╭─[no_nonoctal_decimal_escape.tsx:1:4] 1 │ '\ \8' · ── ╰──── + help: Use the actual character or a valid escape sequence instead. ⚠ eslint(no-nonoctal-decimal-escape): Don't use '\9' escape sequence. ╭─[no_nonoctal_decimal_escape.tsx:1:4] 1 │ '\1\9' · ── ╰──── + help: Use the actual character or a valid escape sequence instead. ⚠ eslint(no-nonoctal-decimal-escape): Don't use '\9' escape sequence. ╭─[no_nonoctal_decimal_escape.tsx:1:7] 1 │ 'foo\1\9' · ── ╰──── + help: Use the actual character or a valid escape sequence instead. ⚠ eslint(no-nonoctal-decimal-escape): Don't use '\8' escape sequence. ╭─[no_nonoctal_decimal_escape.tsx:1:6] 1 │ '\n\n\8\n' · ── ╰──── + help: Use the actual character or a valid escape sequence instead. ⚠ eslint(no-nonoctal-decimal-escape): Don't use '\8' escape sequence. ╭─[no_nonoctal_decimal_escape.tsx:1:7] 1 │ '\n.\n\8\n' · ── ╰──── + help: Use the actual character or a valid escape sequence instead. ⚠ eslint(no-nonoctal-decimal-escape): Don't use '\8' escape sequence. ╭─[no_nonoctal_decimal_escape.tsx:1:8] 1 │ '\n.\nn\8\n' · ── ╰──── + help: Use the actual character or a valid escape sequence instead. ⚠ eslint(no-nonoctal-decimal-escape): Don't use '\8' escape sequence. ╭─[no_nonoctal_decimal_escape.tsx:1:7] 1 │ '\👍\8' · ── ╰──── + help: Use the actual character or a valid escape sequence instead. ⚠ eslint(no-nonoctal-decimal-escape): Don't use '\9' escape sequence. ╭─[no_nonoctal_decimal_escape.tsx:1:5] 1 │ '\\8\9' · ── ╰──── + help: Use the actual character or a valid escape sequence instead. ⚠ eslint(no-nonoctal-decimal-escape): Don't use '\8' escape sequence. ╭─[no_nonoctal_decimal_escape.tsx:1:2] 1 │ '\8\\9' · ── ╰──── + help: Use the actual character or a valid escape sequence instead. ⚠ eslint(no-nonoctal-decimal-escape): Don't use '\8' escape sequence. ╭─[no_nonoctal_decimal_escape.tsx:1:2] 1 │ '\8 \\9' · ── ╰──── + help: Use the actual character or a valid escape sequence instead. ⚠ eslint(no-nonoctal-decimal-escape): Don't use '\8' escape sequence. ╭─[no_nonoctal_decimal_escape.tsx:1:2] 1 │ '\8\8' · ── ╰──── + help: Use the actual character or a valid escape sequence instead. ⚠ eslint(no-nonoctal-decimal-escape): Don't use '\8' escape sequence. ╭─[no_nonoctal_decimal_escape.tsx:1:4] 1 │ '\8\8' · ── ╰──── + help: Use the actual character or a valid escape sequence instead. ⚠ eslint(no-nonoctal-decimal-escape): Don't use '\9' escape sequence. ╭─[no_nonoctal_decimal_escape.tsx:1:2] 1 │ '\9\8' · ── ╰──── + help: Use the actual character or a valid escape sequence instead. ⚠ eslint(no-nonoctal-decimal-escape): Don't use '\8' escape sequence. ╭─[no_nonoctal_decimal_escape.tsx:1:4] 1 │ '\9\8' · ── ╰──── + help: Use the actual character or a valid escape sequence instead. ⚠ eslint(no-nonoctal-decimal-escape): Don't use '\8' escape sequence. ╭─[no_nonoctal_decimal_escape.tsx:1:5] 1 │ 'foo\8bar\9baz' · ── ╰──── + help: Use the actual character or a valid escape sequence instead. ⚠ eslint(no-nonoctal-decimal-escape): Don't use '\9' escape sequence. ╭─[no_nonoctal_decimal_escape.tsx:1:10] 1 │ 'foo\8bar\9baz' · ── ╰──── + help: Use the actual character or a valid escape sequence instead. ⚠ eslint(no-nonoctal-decimal-escape): Don't use '\8' escape sequence. ╭─[no_nonoctal_decimal_escape.tsx:1:2] 1 │ '\8\1\9' · ── ╰──── + help: Use the actual character or a valid escape sequence instead. ⚠ eslint(no-nonoctal-decimal-escape): Don't use '\9' escape sequence. ╭─[no_nonoctal_decimal_escape.tsx:1:6] 1 │ '\8\1\9' · ── ╰──── + help: Use the actual character or a valid escape sequence instead. ⚠ eslint(no-nonoctal-decimal-escape): Don't use '\9' escape sequence. ╭─[no_nonoctal_decimal_escape.tsx:1:2] 1 │ '\9\n9\\9\9' · ── ╰──── + help: Use the actual character or a valid escape sequence instead. ⚠ eslint(no-nonoctal-decimal-escape): Don't use '\9' escape sequence. ╭─[no_nonoctal_decimal_escape.tsx:1:10] 1 │ '\9\n9\\9\9' · ── ╰──── + help: Use the actual character or a valid escape sequence instead. ⚠ eslint(no-nonoctal-decimal-escape): Don't use '\8' escape sequence. ╭─[no_nonoctal_decimal_escape.tsx:1:2] 1 │ '\8\\\9' · ── ╰──── + help: Use the actual character or a valid escape sequence instead. ⚠ eslint(no-nonoctal-decimal-escape): Don't use '\9' escape sequence. ╭─[no_nonoctal_decimal_escape.tsx:1:6] 1 │ '\8\\\9' · ── ╰──── + help: Use the actual character or a valid escape sequence instead. ⚠ eslint(no-nonoctal-decimal-escape): Don't use '\8' escape sequence. ╭─[no_nonoctal_decimal_escape.tsx:1:12] 1 │ var foo = '\8'; bar('\9') · ── ╰──── + help: Use the actual character or a valid escape sequence instead. ⚠ eslint(no-nonoctal-decimal-escape): Don't use '\9' escape sequence. ╭─[no_nonoctal_decimal_escape.tsx:1:22] 1 │ var foo = '\8'; bar('\9') · ── ╰──── + help: Use the actual character or a valid escape sequence instead. × Invalid Unicode escape sequence ╭─[no_nonoctal_decimal_escape.tsx:1:15] @@ -230,99 +265,116 @@ source: crates/oxc_linter/src/tester.rs 1 │ '\\n\8' · ── ╰──── + help: Use the actual character or a valid escape sequence instead. ⚠ eslint(no-nonoctal-decimal-escape): Don't use '\9' escape sequence. ╭─[no_nonoctal_decimal_escape.tsx:1:5] 1 │ '\\n\9' · ── ╰──── + help: Use the actual character or a valid escape sequence instead. ⚠ eslint(no-nonoctal-decimal-escape): Don't use '\8' escape sequence. ╭─[no_nonoctal_decimal_escape.tsx:1:7] 1 │ '\\\\n\8' · ── ╰──── + help: Use the actual character or a valid escape sequence instead. ⚠ eslint(no-nonoctal-decimal-escape): Don't use '\9' escape sequence. ╭─[no_nonoctal_decimal_escape.tsx:1:11] 1 │ 'foo\\nbar\9baz' · ── ╰──── + help: Use the actual character or a valid escape sequence instead. ⚠ eslint(no-nonoctal-decimal-escape): Don't use '\8' escape sequence. ╭─[no_nonoctal_decimal_escape.tsx:1:4] 1 │ '\0\8' · ── ╰──── + help: Use the actual character or a valid escape sequence instead. ⚠ eslint(no-nonoctal-decimal-escape): Don't use '\9' escape sequence. ╭─[no_nonoctal_decimal_escape.tsx:1:7] 1 │ 'foo\0\9bar' · ── ╰──── + help: Use the actual character or a valid escape sequence instead. ⚠ eslint(no-nonoctal-decimal-escape): Don't use '\8' escape sequence. ╭─[no_nonoctal_decimal_escape.tsx:1:6] 1 │ '\1\0\8' · ── ╰──── + help: Use the actual character or a valid escape sequence instead. ⚠ eslint(no-nonoctal-decimal-escape): Don't use '\8' escape sequence. ╭─[no_nonoctal_decimal_escape.tsx:1:4] 1 │ '\0\8\9' · ── ╰──── + help: Use the actual character or a valid escape sequence instead. ⚠ eslint(no-nonoctal-decimal-escape): Don't use '\9' escape sequence. ╭─[no_nonoctal_decimal_escape.tsx:1:6] 1 │ '\0\8\9' · ── ╰──── + help: Use the actual character or a valid escape sequence instead. ⚠ eslint(no-nonoctal-decimal-escape): Don't use '\8' escape sequence. ╭─[no_nonoctal_decimal_escape.tsx:1:2] 1 │ '\8\0\9' · ── ╰──── + help: Use the actual character or a valid escape sequence instead. ⚠ eslint(no-nonoctal-decimal-escape): Don't use '\9' escape sequence. ╭─[no_nonoctal_decimal_escape.tsx:1:6] 1 │ '\8\0\9' · ── ╰──── + help: Use the actual character or a valid escape sequence instead. ⚠ eslint(no-nonoctal-decimal-escape): Don't use '\8' escape sequence. ╭─[no_nonoctal_decimal_escape.tsx:1:3] 1 │ '0\8' · ── ╰──── + help: Use the actual character or a valid escape sequence instead. ⚠ eslint(no-nonoctal-decimal-escape): Don't use '\8' escape sequence. ╭─[no_nonoctal_decimal_escape.tsx:1:5] 1 │ '\\0\8' · ── ╰──── + help: Use the actual character or a valid escape sequence instead. ⚠ eslint(no-nonoctal-decimal-escape): Don't use '\8' escape sequence. ╭─[no_nonoctal_decimal_escape.tsx:1:5] 1 │ '\0 \8' · ── ╰──── + help: Use the actual character or a valid escape sequence instead. ⚠ eslint(no-nonoctal-decimal-escape): Don't use '\8' escape sequence. ╭─[no_nonoctal_decimal_escape.tsx:1:5] 1 │ '\01\8' · ── ╰──── + help: Use the actual character or a valid escape sequence instead. ⚠ eslint(no-nonoctal-decimal-escape): Don't use '\8' escape sequence. ╭─[no_nonoctal_decimal_escape.tsx:1:6] 1 │ '\0\1\8' · ── ╰──── + help: Use the actual character or a valid escape sequence instead. ⚠ eslint(no-nonoctal-decimal-escape): Don't use '\8' escape sequence. ╭─[no_nonoctal_decimal_escape.tsx:1:7] 1 │ '\0\\n\8' · ── ╰──── + help: Use the actual character or a valid escape sequence instead. diff --git a/crates/oxc_linter/src/snapshots/eslint_operator_assignment.snap b/crates/oxc_linter/src/snapshots/eslint_operator_assignment.snap index f96b715e90060..e479a60abfb52 100644 --- a/crates/oxc_linter/src/snapshots/eslint_operator_assignment.snap +++ b/crates/oxc_linter/src/snapshots/eslint_operator_assignment.snap @@ -28,12 +28,14 @@ source: crates/oxc_linter/src/tester.rs 1 │ x = y * x · ───────── ╰──── + note: Use '*=' shorthand instead of '='. ⚠ eslint(operator-assignment): Assignment (=) can be replaced with operator assignment (*=). ╭─[operator_assignment.tsx:1:1] 1 │ x = (y * z) * x · ─────────────── ╰──── + note: Use '*=' shorthand instead of '='. ⚠ eslint(operator-assignment): Assignment (=) can be replaced with operator assignment (/=). ╭─[operator_assignment.tsx:1:1]