diff --git a/apps/oxlint/src/snapshots/fixtures__overrides_env_globals_-c .oxlintrc.json .@oxlint.snap b/apps/oxlint/src/snapshots/fixtures__overrides_env_globals_-c .oxlintrc.json .@oxlint.snap index f78300432e5ab..05633bf73c3cc 100644 --- a/apps/oxlint/src/snapshots/fixtures__overrides_env_globals_-c .oxlintrc.json .@oxlint.snap +++ b/apps/oxlint/src/snapshots/fixtures__overrides_env_globals_-c .oxlintrc.json .@oxlint.snap @@ -14,6 +14,7 @@ working directory: fixtures/overrides_env_globals : `-- Read-only global 'globalThis' should not be modified. 3 | $ = 'abc'; `---- + help: Use a local variable instead of modifying the global 'globalThis'. ! eslint(no-global-assign): Read-only global 'globalThis' should not be modified. ,-[test.js:2:1] @@ -23,6 +24,7 @@ working directory: fixtures/overrides_env_globals : `-- Read-only global 'globalThis' should not be modified. 3 | $ = 'abc'; `---- + help: Use a local variable instead of modifying the global 'globalThis'. ! eslint(no-global-assign): Read-only global '$' should not be modified. ,-[test.js:3:1] @@ -32,6 +34,7 @@ working directory: fixtures/overrides_env_globals : `-- Read-only global '$' should not be modified. 4 | `---- + help: Use a local variable instead of modifying the global '$'. ! eslint(no-global-assign): Read-only global 'Foo' should not be modified. ,-[test.js:6:1] @@ -40,6 +43,7 @@ working directory: fixtures/overrides_env_globals : ^|^ : `-- Read-only global 'Foo' should not be modified. `---- + help: Use a local variable instead of modifying the global 'Foo'. ! eslint(no-global-assign): Read-only global 'globalThis' should not be modified. ,-[test.ts:2:1] @@ -49,6 +53,7 @@ working directory: fixtures/overrides_env_globals : `-- Read-only global 'globalThis' should not be modified. 3 | $ = 'abc'; `---- + help: Use a local variable instead of modifying the global 'globalThis'. Found 5 warnings and 0 errors. Finished in ms on 3 files with 1 rules using 1 threads. diff --git a/crates/oxc_linter/src/rules/eslint/no_async_promise_executor.rs b/crates/oxc_linter/src/rules/eslint/no_async_promise_executor.rs index 1bfc0a33da278..359d4bd66d64e 100644 --- a/crates/oxc_linter/src/rules/eslint/no_async_promise_executor.rs +++ b/crates/oxc_linter/src/rules/eslint/no_async_promise_executor.rs @@ -9,7 +9,9 @@ use oxc_span::Span; use crate::{AstNode, context::LintContext, rule::Rule}; fn no_async_promise_executor_diagnostic(span: Span) -> OxcDiagnostic { - OxcDiagnostic::warn("Promise executor functions should not be `async`.").with_label(span) + OxcDiagnostic::warn("Promise executor functions should not be `async`.") + .with_help("Remove the `async` keyword from the Promise executor function.") + .with_label(span) } #[derive(Debug, Default, Clone)] diff --git a/crates/oxc_linter/src/rules/eslint/no_class_assign.rs b/crates/oxc_linter/src/rules/eslint/no_class_assign.rs index e3a4598251b75..c82a21ff4e8fb 100644 --- a/crates/oxc_linter/src/rules/eslint/no_class_assign.rs +++ b/crates/oxc_linter/src/rules/eslint/no_class_assign.rs @@ -7,10 +7,12 @@ use oxc_span::Span; use crate::{context::LintContext, rule::Rule}; fn no_class_assign_diagnostic(name: &str, decl_span: Span, assign_span: Span) -> OxcDiagnostic { - OxcDiagnostic::warn(format!("Unexpected re-assignment of class {name}")).with_labels([ - decl_span.label(format!("{name} is declared as class here")), - assign_span.label(format!("{name} is re-assigned here")), - ]) + OxcDiagnostic::warn(format!("Unexpected re-assignment of class {name}")) + .with_help("Use a different variable name instead of re-assigning the class declaration.") + .with_labels([ + decl_span.label(format!("{name} is declared as class here")), + assign_span.label(format!("{name} is re-assigned here")), + ]) } #[derive(Debug, Default, Clone)] diff --git a/crates/oxc_linter/src/rules/eslint/no_global_assign.rs b/crates/oxc_linter/src/rules/eslint/no_global_assign.rs index 5a68ad428f2e3..86577ac015bbc 100644 --- a/crates/oxc_linter/src/rules/eslint/no_global_assign.rs +++ b/crates/oxc_linter/src/rules/eslint/no_global_assign.rs @@ -12,6 +12,7 @@ use crate::{ fn no_global_assign_diagnostic(global_name: &str, span: Span) -> OxcDiagnostic { OxcDiagnostic::warn(format!("Read-only global '{global_name}' should not be modified.")) + .with_help(format!("Use a local variable instead of modifying the global '{global_name}'.")) .with_label(span.label(format!("Read-only global '{global_name}' should not be modified."))) } diff --git a/crates/oxc_linter/src/rules/eslint/no_throw_literal.rs b/crates/oxc_linter/src/rules/eslint/no_throw_literal.rs index e8a48e7cb61ed..7b360a6df70fc 100644 --- a/crates/oxc_linter/src/rules/eslint/no_throw_literal.rs +++ b/crates/oxc_linter/src/rules/eslint/no_throw_literal.rs @@ -9,7 +9,9 @@ fn no_throw_literal_diagnostic(span: Span, is_undef: bool) -> OxcDiagnostic { let message = if is_undef { "Do not throw undefined" } else { "Expected an error object to be thrown" }; - OxcDiagnostic::warn(message).with_label(span) + OxcDiagnostic::warn(message) + .with_help("Throwing literals or non-Error objects is not recommended. Use an Error object instead.") + .with_label(span) } #[derive(Debug, Default, Clone)] diff --git a/crates/oxc_linter/src/snapshots/eslint_no_async_promise_executor.snap b/crates/oxc_linter/src/snapshots/eslint_no_async_promise_executor.snap index 65747c521be48..3353312db4d96 100644 --- a/crates/oxc_linter/src/snapshots/eslint_no_async_promise_executor.snap +++ b/crates/oxc_linter/src/snapshots/eslint_no_async_promise_executor.snap @@ -7,15 +7,18 @@ source: crates/oxc_linter/src/tester.rs 1 │ new Promise(async function foo(resolve, reject) {}) · ───── ╰──── + help: Remove the `async` keyword from the Promise executor function. ⚠ eslint(no-async-promise-executor): Promise executor functions should not be `async`. ╭─[no_async_promise_executor.tsx:1:13] 1 │ new Promise(async (resolve, reject) => {}) · ───── ╰──── + help: Remove the `async` keyword from the Promise executor function. ⚠ eslint(no-async-promise-executor): Promise executor functions should not be `async`. ╭─[no_async_promise_executor.tsx:1:17] 1 │ new Promise(((((async () => {}))))) · ───── ╰──── + help: Remove the `async` keyword from the Promise executor function. diff --git a/crates/oxc_linter/src/snapshots/eslint_no_class_assign.snap b/crates/oxc_linter/src/snapshots/eslint_no_class_assign.snap index bc2357fdc747b..9227986ef4970 100644 --- a/crates/oxc_linter/src/snapshots/eslint_no_class_assign.snap +++ b/crates/oxc_linter/src/snapshots/eslint_no_class_assign.snap @@ -9,6 +9,7 @@ source: crates/oxc_linter/src/tester.rs · │ ╰── A is re-assigned here · ╰── A is declared as class here ╰──── + help: Use a different variable name instead of re-assigning the class declaration. ⚠ eslint(no-class-assign): Unexpected re-assignment of class A ╭─[no_class_assign.tsx:1:7] @@ -17,6 +18,7 @@ source: crates/oxc_linter/src/tester.rs · │ ╰── A is re-assigned here · ╰── A is declared as class here ╰──── + help: Use a different variable name instead of re-assigning the class declaration. ⚠ eslint(no-class-assign): Unexpected re-assignment of class A ╭─[no_class_assign.tsx:1:7] @@ -25,6 +27,7 @@ source: crates/oxc_linter/src/tester.rs · │ ╰── A is re-assigned here · ╰── A is declared as class here ╰──── + help: Use a different variable name instead of re-assigning the class declaration. ⚠ eslint(no-class-assign): Unexpected re-assignment of class A ╭─[no_class_assign.tsx:1:1] @@ -33,6 +36,7 @@ source: crates/oxc_linter/src/tester.rs · │ ╰── A is declared as class here · ╰── A is re-assigned here ╰──── + help: Use a different variable name instead of re-assigning the class declaration. ⚠ eslint(no-class-assign): Unexpected re-assignment of class A ╭─[no_class_assign.tsx:1:7] @@ -41,6 +45,7 @@ source: crates/oxc_linter/src/tester.rs · │ ╰── A is re-assigned here · ╰── A is declared as class here ╰──── + help: Use a different variable name instead of re-assigning the class declaration. ⚠ eslint(no-class-assign): Unexpected re-assignment of class A ╭─[no_class_assign.tsx:1:15] @@ -49,6 +54,7 @@ source: crates/oxc_linter/src/tester.rs · │ ╰── A is re-assigned here · ╰── A is declared as class here ╰──── + help: Use a different variable name instead of re-assigning the class declaration. ⚠ eslint(no-class-assign): Unexpected re-assignment of class A ╭─[no_class_assign.tsx:1:7] @@ -57,6 +63,7 @@ source: crates/oxc_linter/src/tester.rs · │ ╰── A is re-assigned here · ╰── A is declared as class here ╰──── + help: Use a different variable name instead of re-assigning the class declaration. ⚠ eslint(no-class-assign): Unexpected re-assignment of class A ╭─[no_class_assign.tsx:1:7] @@ -65,6 +72,7 @@ source: crates/oxc_linter/src/tester.rs · │ ╰── A is re-assigned here · ╰── A is declared as class here ╰──── + help: Use a different variable name instead of re-assigning the class declaration. ⚠ eslint(no-class-assign): Unexpected re-assignment of class A ╭─[no_class_assign.tsx:1:18] @@ -73,3 +81,4 @@ source: crates/oxc_linter/src/tester.rs · │ ╰── A is re-assigned here · ╰── A is declared as class here ╰──── + help: Use a different variable name instead of re-assigning the class declaration. diff --git a/crates/oxc_linter/src/snapshots/eslint_no_global_assign.snap b/crates/oxc_linter/src/snapshots/eslint_no_global_assign.snap index 4e51af072b0c3..c32a4d8ccc247 100644 --- a/crates/oxc_linter/src/snapshots/eslint_no_global_assign.snap +++ b/crates/oxc_linter/src/snapshots/eslint_no_global_assign.snap @@ -8,6 +8,7 @@ source: crates/oxc_linter/src/tester.rs · ───┬── · ╰── Read-only global 'String' should not be modified. ╰──── + help: Use a local variable instead of modifying the global 'String'. ⚠ eslint(no-global-assign): Read-only global 'String' should not be modified. ╭─[no_global_assign.tsx:1:1] @@ -15,6 +16,7 @@ source: crates/oxc_linter/src/tester.rs · ───┬── · ╰── Read-only global 'String' should not be modified. ╰──── + help: Use a local variable instead of modifying the global 'String'. ⚠ eslint(no-global-assign): Read-only global 'Object' should not be modified. ╭─[no_global_assign.tsx:1:3] @@ -22,6 +24,7 @@ source: crates/oxc_linter/src/tester.rs · ───┬── · ╰── Read-only global 'Object' should not be modified. ╰──── + help: Use a local variable instead of modifying the global 'Object'. ⚠ eslint(no-global-assign): Read-only global 'String' should not be modified. ╭─[no_global_assign.tsx:1:15] @@ -29,6 +32,7 @@ source: crates/oxc_linter/src/tester.rs · ───┬── · ╰── Read-only global 'String' should not be modified. ╰──── + help: Use a local variable instead of modifying the global 'String'. ⚠ eslint(no-global-assign): Read-only global 'top' should not be modified. ╭─[no_global_assign.tsx:1:1] @@ -36,6 +40,7 @@ source: crates/oxc_linter/src/tester.rs · ─┬─ · ╰── Read-only global 'top' should not be modified. ╰──── + help: Use a local variable instead of modifying the global 'top'. ⚠ eslint(no-global-assign): Read-only global 'require' should not be modified. ╭─[no_global_assign.tsx:1:1] @@ -43,6 +48,7 @@ source: crates/oxc_linter/src/tester.rs · ───┬─── · ╰── Read-only global 'require' should not be modified. ╰──── + help: Use a local variable instead of modifying the global 'require'. ⚠ eslint(no-global-assign): Read-only global 'Object' should not be modified. ╭─[no_global_assign.tsx:1:16] @@ -50,6 +56,7 @@ source: crates/oxc_linter/src/tester.rs · ───┬── · ╰── Read-only global 'Object' should not be modified. ╰──── + help: Use a local variable instead of modifying the global 'Object'. ⚠ eslint(no-global-assign): Read-only global 'a' should not be modified. ╭─[no_global_assign.tsx:1:1] @@ -57,6 +64,7 @@ source: crates/oxc_linter/src/tester.rs · ┬ · ╰── Read-only global 'a' should not be modified. ╰──── + help: Use a local variable instead of modifying the global 'a'. ⚠ eslint(no-global-assign): Read-only global 'Array' should not be modified. ╭─[no_global_assign.tsx:1:1] @@ -64,3 +72,4 @@ source: crates/oxc_linter/src/tester.rs · ──┬── · ╰── Read-only global 'Array' should not be modified. ╰──── + help: Use a local variable instead of modifying the global 'Array'. diff --git a/crates/oxc_linter/src/snapshots/eslint_no_throw_literal.snap b/crates/oxc_linter/src/snapshots/eslint_no_throw_literal.snap index 1ab65ff4c929a..6c76dcc7cf2b6 100644 --- a/crates/oxc_linter/src/snapshots/eslint_no_throw_literal.snap +++ b/crates/oxc_linter/src/snapshots/eslint_no_throw_literal.snap @@ -7,153 +7,175 @@ source: crates/oxc_linter/src/tester.rs 1 │ throw 'error'; · ─────── ╰──── - help: Replace `'error'` with `new Error('error')`. + help: Throwing literals or non-Error objects is not recommended. Use an Error object instead. ⚠ eslint(no-throw-literal): Expected an error object to be thrown ╭─[no_throw_literal.tsx:1:7] 1 │ throw 0; · ─ ╰──── + help: Throwing literals or non-Error objects is not recommended. Use an Error object instead. ⚠ eslint(no-throw-literal): Expected an error object to be thrown ╭─[no_throw_literal.tsx:1:7] 1 │ throw false; · ───── ╰──── + help: Throwing literals or non-Error objects is not recommended. Use an Error object instead. ⚠ eslint(no-throw-literal): Expected an error object to be thrown ╭─[no_throw_literal.tsx:1:7] 1 │ throw null; · ──── ╰──── + help: Throwing literals or non-Error objects is not recommended. Use an Error object instead. ⚠ eslint(no-throw-literal): Expected an error object to be thrown ╭─[no_throw_literal.tsx:1:7] 1 │ throw {}; · ── ╰──── + help: Throwing literals or non-Error objects is not recommended. Use an Error object instead. ⚠ eslint(no-throw-literal): Do not throw undefined ╭─[no_throw_literal.tsx:1:7] 1 │ throw undefined; · ───────── ╰──── + help: Throwing literals or non-Error objects is not recommended. Use an Error object instead. ⚠ eslint(no-throw-literal): Do not throw undefined ╭─[no_throw_literal.tsx:1:7] 1 │ throw Infinity; · ──────── ╰──── + help: Throwing literals or non-Error objects is not recommended. Use an Error object instead. ⚠ eslint(no-throw-literal): Do not throw undefined ╭─[no_throw_literal.tsx:1:7] 1 │ throw NaN; · ─── ╰──── + help: Throwing literals or non-Error objects is not recommended. Use an Error object instead. ⚠ eslint(no-throw-literal): Expected an error object to be thrown ╭─[no_throw_literal.tsx:1:7] 1 │ throw 'a' + 'b'; · ───────── ╰──── + help: Throwing literals or non-Error objects is not recommended. Use an Error object instead. ⚠ eslint(no-throw-literal): Expected an error object to be thrown ╭─[no_throw_literal.tsx:1:28] 1 │ var b = new Error(); throw 'a' + b; · ─────── ╰──── + help: Throwing literals or non-Error objects is not recommended. Use an Error object instead. ⚠ eslint(no-throw-literal): Expected an error object to be thrown ╭─[no_throw_literal.tsx:1:7] 1 │ throw foo = 'error'; · ───────────── ╰──── + help: Throwing literals or non-Error objects is not recommended. Use an Error object instead. ⚠ eslint(no-throw-literal): Expected an error object to be thrown ╭─[no_throw_literal.tsx:1:7] 1 │ throw foo += new Error(); · ────────────────── ╰──── + help: Throwing literals or non-Error objects is not recommended. Use an Error object instead. ⚠ eslint(no-throw-literal): Expected an error object to be thrown ╭─[no_throw_literal.tsx:1:7] 1 │ throw foo &= new Error(); · ────────────────── ╰──── + help: Throwing literals or non-Error objects is not recommended. Use an Error object instead. ⚠ eslint(no-throw-literal): Expected an error object to be thrown ╭─[no_throw_literal.tsx:1:7] 1 │ throw foo &&= 'literal' · ───────────────── ╰──── + help: Throwing literals or non-Error objects is not recommended. Use an Error object instead. ⚠ eslint(no-throw-literal): Expected an error object to be thrown ╭─[no_throw_literal.tsx:1:7] 1 │ throw new Error(), 1, 2, 3; · ──────────────────── ╰──── + help: Throwing literals or non-Error objects is not recommended. Use an Error object instead. ⚠ eslint(no-throw-literal): Expected an error object to be thrown ╭─[no_throw_literal.tsx:1:7] 1 │ throw 'literal' && 'not an Error'; · ─────────────────────────── ╰──── + help: Throwing literals or non-Error objects is not recommended. Use an Error object instead. ⚠ eslint(no-throw-literal): Expected an error object to be thrown ╭─[no_throw_literal.tsx:1:7] 1 │ throw foo && 'literal' · ──────────────── ╰──── + help: Throwing literals or non-Error objects is not recommended. Use an Error object instead. ⚠ eslint(no-throw-literal): Expected an error object to be thrown ╭─[no_throw_literal.tsx:1:7] 1 │ throw foo ? 'not an Error' : 'literal'; · ──────────────────────────────── ╰──── + help: Throwing literals or non-Error objects is not recommended. Use an Error object instead. ⚠ eslint(no-throw-literal): Expected an error object to be thrown ╭─[no_throw_literal.tsx:1:7] 1 │ throw `${err}`; · ──────── ╰──── - help: Replace ``${err}`` with `new Error(`${err}`)`. + help: Throwing literals or non-Error objects is not recommended. Use an Error object instead. ⚠ eslint(no-throw-literal): Expected an error object to be thrown ╭─[no_throw_literal.tsx:1:7] 1 │ throw 0 as number · ─ ╰──── + help: Throwing literals or non-Error objects is not recommended. Use an Error object instead. ⚠ eslint(no-throw-literal): Expected an error object to be thrown ╭─[no_throw_literal.tsx:1:7] 1 │ throw 'error' satisfies Error · ─────────────────────── ╰──── - help: Replace `'error' satisfies Error` with `new Error('error' satisfies Error)`. + help: Throwing literals or non-Error objects is not recommended. Use an Error object instead. ⚠ eslint(no-throw-literal): Expected an error object to be thrown ╭─[no_throw_literal.tsx:1:24] 1 │ let foo = 'foo'; throw foo; · ─── ╰──── + help: Throwing literals or non-Error objects is not recommended. Use an Error object instead. ⚠ eslint(no-throw-literal): Expected an error object to be thrown ╭─[no_throw_literal.tsx:1:44] 1 │ let foo = 'foo' as unknown as Error; throw foo; · ─── ╰──── + help: Throwing literals or non-Error objects is not recommended. Use an Error object instead. ⚠ eslint(no-throw-literal): Expected an error object to be thrown ╭─[no_throw_literal.tsx:1:26] 1 │ function foo() {}; throw foo; · ─── ╰──── + help: Throwing literals or non-Error objects is not recommended. Use an Error object instead. ⚠ eslint(no-throw-literal): Expected an error object to be thrown ╭─[no_throw_literal.tsx:1:29] 1 │ const foo = () => {}; throw foo; · ─── ╰──── + help: Throwing literals or non-Error objects is not recommended. Use an Error object instead. ⚠ eslint(no-throw-literal): Expected an error object to be thrown ╭─[no_throw_literal.tsx:2:7] @@ -161,21 +183,25 @@ source: crates/oxc_linter/src/tester.rs 2 │ throw Foo; · ─── ╰──── + help: Throwing literals or non-Error objects is not recommended. Use an Error object instead. ⚠ eslint(no-throw-literal): Expected an error object to be thrown ╭─[no_throw_literal.tsx:1:34] 1 │ function main(x: number) { throw x; } · ─ ╰──── + help: Throwing literals or non-Error objects is not recommended. Use an Error object instead. ⚠ eslint(no-throw-literal): Expected an error object to be thrown ╭─[no_throw_literal.tsx:1:34] 1 │ function main(x: string) { throw x; } · ─ ╰──── + help: Throwing literals or non-Error objects is not recommended. Use an Error object instead. ⚠ eslint(no-throw-literal): Expected an error object to be thrown ╭─[no_throw_literal.tsx:1:43] 1 │ function main(x: string | number) { throw x; } · ─ ╰──── + help: Throwing literals or non-Error objects is not recommended. Use an Error object instead.