Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion crates/oxc_linter/src/rules/eslint/no_await_in_loop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ use oxc_span::{GetSpan, Span};
use crate::{AstNode, context::LintContext, rule::Rule};

fn no_await_in_loop_diagnostic(span: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("Unexpected `await` inside a loop.").with_label(span)
OxcDiagnostic::warn("Unexpected `await` inside a loop.")
.with_help("Collect all promises into an array and use `Promise.all()` to run them in parallel, rather than awaiting each one sequentially inside the loop.")
.with_label(span)
}

#[derive(Debug, Default, Clone)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ use oxc_span::Span;
use crate::{AstNode, context::LintContext, rule::Rule};

fn no_case_declarations_diagnostic(span: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("Unexpected lexical declaration in case block.").with_label(span)
OxcDiagnostic::warn("Unexpected lexical declaration in case block.")
.with_help("Wrap the case body in braces `{}` to create an explicit block scope for the lexical declaration.")
.with_label(span)
}

#[derive(Debug, Default, Clone)]
Expand Down
1 change: 1 addition & 0 deletions crates/oxc_linter/src/rules/eslint/no_const_assign.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use crate::{context::LintContext, rule::Rule};

fn no_const_assign_diagnostic(name: &str, decl_span: Span, assign_span: Span) -> OxcDiagnostic {
OxcDiagnostic::warn(format!("Unexpected re-assignment of `const` variable {name}."))
.with_help("Use `let` instead of `const` if you need to reassign this variable.")
.with_labels([
decl_span.label(format!("{name} is declared here as `const`.")),
assign_span.label(format!("{name} is re-assigned here.")),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ use oxc_span::Span;
use crate::{AstNode, context::LintContext, rule::Rule};

fn no_constructor_return_diagnostic(span: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("Unexpected return statement in constructor.").with_label(span)
OxcDiagnostic::warn("Unexpected return statement in constructor.")
.with_help("Remove the return statement from the constructor. If you need early exit, use a bare `return;` with no value.")
.with_label(span)
}

#[derive(Debug, Default, Clone)]
Expand Down
4 changes: 3 additions & 1 deletion crates/oxc_linter/src/rules/eslint/no_delete_var.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ use oxc_syntax::operator::UnaryOperator;
use crate::{AstNode, context::LintContext, rule::Rule};

fn no_delete_var_diagnostic(span: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("Variables should not be deleted").with_label(span)
OxcDiagnostic::warn("Variables should not be deleted")
.with_help("Assign `undefined` to the variable instead of using `delete`. The `delete` operator is intended for removing properties from objects, not for variables.")
.with_label(span)
}

#[derive(Debug, Default, Clone)]
Expand Down
4 changes: 3 additions & 1 deletion crates/oxc_linter/src/rules/eslint/no_eval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ use crate::{
};

fn no_eval_diagnostic(span: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("eval can be harmful.").with_label(span)
OxcDiagnostic::warn("eval can be harmful.")
.with_help("Avoid eval(). For JSON parsing use JSON.parse(); for dynamic property access use bracket notation (obj[key]); for other cases refactor to avoid evaluating strings as code.")
.with_label(span)
}

#[derive(Debug, Clone, JsonSchema, Deserialize)]
Expand Down
8 changes: 6 additions & 2 deletions crates/oxc_linter/src/rules/eslint/no_lone_blocks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,15 @@ use oxc_span::{GetSpan, Span};
use crate::{AstNode, context::LintContext, rule::Rule};

fn no_lone_blocks_diagnostic(span: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("Block is unnecessary.").with_label(span)
OxcDiagnostic::warn("Block is unnecessary.")
.with_help("Remove the unnecessary block statement. If you need to limit variable scope, consider using a function or module instead.")
.with_label(span)
}

fn no_nested_lone_blocks_diagnostic(span: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("Nested block is redundant.").with_label(span)
OxcDiagnostic::warn("Nested block is redundant.")
.with_help("Remove the redundant nested block statement.")
.with_label(span)
}

#[derive(Debug, Default, Clone)]
Expand Down
4 changes: 3 additions & 1 deletion crates/oxc_linter/src/rules/eslint/require_yield.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ use oxc_span::Span;
use crate::{AstNode, context::LintContext, rule::Rule};

fn require_yield_diagnostic(span: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("This generator function does not have `yield`").with_label(span)
OxcDiagnostic::warn("This generator function does not have `yield`")
.with_help("Add a `yield` expression inside the generator body, or convert it to a regular function if iteration behavior is not needed.")
.with_label(span)
}

#[derive(Debug, Default, Clone)]
Expand Down
17 changes: 17 additions & 0 deletions crates/oxc_linter/src/snapshots/eslint_no_await_in_loop.snap
Original file line number Diff line number Diff line change
Expand Up @@ -7,99 +7,116 @@ source: crates/oxc_linter/src/tester.rs
1 │ async function foo() { while (baz) { await bar; } }
· ─────
╰────
help: Collect all promises into an array and use `Promise.all()` to run them in parallel, rather than awaiting each one sequentially inside the loop.

⚠ eslint(no-await-in-loop): Unexpected `await` inside a loop.
╭─[no_await_in_loop.tsx:1:31]
1 │ async function foo() { while (await foo()) { } }
· ─────
╰────
help: Collect all promises into an array and use `Promise.all()` to run them in parallel, rather than awaiting each one sequentially inside the loop.

⚠ eslint(no-await-in-loop): Unexpected `await` inside a loop.
╭─[no_await_in_loop.tsx:1:42]
1 │ async function foo() { while (baz) { for await (x of xs); } }
· ─────
╰────
help: Collect all promises into an array and use `Promise.all()` to run them in parallel, rather than awaiting each one sequentially inside the loop.

⚠ eslint(no-await-in-loop): Unexpected `await` inside a loop.
╭─[no_await_in_loop.tsx:1:47]
1 │ async function foo() { for (var bar of baz) { await bar; } }
· ─────
╰────
help: Collect all promises into an array and use `Promise.all()` to run them in parallel, rather than awaiting each one sequentially inside the loop.

⚠ eslint(no-await-in-loop): Unexpected `await` inside a loop.
╭─[no_await_in_loop.tsx:1:45]
1 │ async function foo() { for (var bar of baz) await bar; }
· ─────
╰────
help: Collect all promises into an array and use `Promise.all()` to run them in parallel, rather than awaiting each one sequentially inside the loop.

⚠ eslint(no-await-in-loop): Unexpected `await` inside a loop.
╭─[no_await_in_loop.tsx:1:47]
1 │ async function foo() { for (var bar in baz) { await bar; } }
· ─────
╰────
help: Collect all promises into an array and use `Promise.all()` to run them in parallel, rather than awaiting each one sequentially inside the loop.

⚠ eslint(no-await-in-loop): Unexpected `await` inside a loop.
╭─[no_await_in_loop.tsx:1:50]
1 │ async function foo() { for (var i; i < n; i++) { await bar; } }
· ─────
╰────
help: Collect all promises into an array and use `Promise.all()` to run them in parallel, rather than awaiting each one sequentially inside the loop.

⚠ eslint(no-await-in-loop): Unexpected `await` inside a loop.
╭─[no_await_in_loop.tsx:1:36]
1 │ async function foo() { for (var i; await foo(i); i++) { } }
· ─────
╰────
help: Collect all promises into an array and use `Promise.all()` to run them in parallel, rather than awaiting each one sequentially inside the loop.

⚠ eslint(no-await-in-loop): Unexpected `await` inside a loop.
╭─[no_await_in_loop.tsx:1:47]
1 │ async function foo() { for (var i; i < n; i = await bar) { } }
· ─────
╰────
help: Collect all promises into an array and use `Promise.all()` to run them in parallel, rather than awaiting each one sequentially inside the loop.

⚠ eslint(no-await-in-loop): Unexpected `await` inside a loop.
╭─[no_await_in_loop.tsx:1:29]
1 │ async function foo() { do { await bar; } while (baz); }
· ─────
╰────
help: Collect all promises into an array and use `Promise.all()` to run them in parallel, rather than awaiting each one sequentially inside the loop.

⚠ eslint(no-await-in-loop): Unexpected `await` inside a loop.
╭─[no_await_in_loop.tsx:1:38]
1 │ async function foo() { do { } while (await bar); }
· ─────
╰────
help: Collect all promises into an array and use `Promise.all()` to run them in parallel, rather than awaiting each one sequentially inside the loop.

⚠ eslint(no-await-in-loop): Unexpected `await` inside a loop.
╭─[no_await_in_loop.tsx:1:54]
1 │ async function foo() { while (true) { if (bar) { foo(await bar); } } }
· ─────
╰────
help: Collect all promises into an array and use `Promise.all()` to run them in parallel, rather than awaiting each one sequentially inside the loop.

⚠ eslint(no-await-in-loop): Unexpected `await` inside a loop.
╭─[no_await_in_loop.tsx:1:42]
1 │ async function foo() { while (xyz || 5 > await x) { } }
· ─────
╰────
help: Collect all promises into an array and use `Promise.all()` to run them in parallel, rather than awaiting each one sequentially inside the loop.

⚠ eslint(no-await-in-loop): Unexpected `await` inside a loop.
╭─[no_await_in_loop.tsx:1:60]
1 │ async function foo() { for await (var x of xs) { while (1) await f(x) } }
· ─────
╰────
help: Collect all promises into an array and use `Promise.all()` to run them in parallel, rather than awaiting each one sequentially inside the loop.

⚠ eslint(no-await-in-loop): Unexpected `await` inside a loop.
╭─[no_await_in_loop.tsx:1:16]
1 │ while (true) { await using resource = getResource(); }
· ─────
╰────
help: Collect all promises into an array and use `Promise.all()` to run them in parallel, rather than awaiting each one sequentially inside the loop.

⚠ eslint(no-await-in-loop): Unexpected `await` inside a loop.
╭─[no_await_in_loop.tsx:1:12]
1 │ for (;;) { await using resource = getResource(); }
· ─────
╰────
help: Collect all promises into an array and use `Promise.all()` to run them in parallel, rather than awaiting each one sequentially inside the loop.

⚠ eslint(no-await-in-loop): Unexpected `await` inside a loop.
╭─[no_await_in_loop.tsx:1:6]
1 │ for (await using resource of resources) {}
· ─────
╰────
help: Collect all promises into an array and use `Promise.all()` to run them in parallel, rather than awaiting each one sequentially inside the loop.
Original file line number Diff line number Diff line change
Expand Up @@ -7,48 +7,56 @@ source: crates/oxc_linter/src/tester.rs
1 │ switch (a) { case 1: let x = 1; break; }
· ───
╰────
help: Wrap the case body in braces `{}` to create an explicit block scope for the lexical declaration.

⚠ eslint(no-case-declarations): Unexpected lexical declaration in case block.
╭─[no_case_declarations.tsx:1:23]
1 │ switch (a) { default: let x = 2; break; }
· ───
╰────
help: Wrap the case body in braces `{}` to create an explicit block scope for the lexical declaration.

⚠ eslint(no-case-declarations): Unexpected lexical declaration in case block.
╭─[no_case_declarations.tsx:1:22]
1 │ switch (a) { case 1: const x = 1; break; }
· ─────
╰────
help: Wrap the case body in braces `{}` to create an explicit block scope for the lexical declaration.

⚠ eslint(no-case-declarations): Unexpected lexical declaration in case block.
╭─[no_case_declarations.tsx:1:23]
1 │ switch (a) { default: const x = 2; break; }
· ─────
╰────
help: Wrap the case body in braces `{}` to create an explicit block scope for the lexical declaration.

⚠ eslint(no-case-declarations): Unexpected lexical declaration in case block.
╭─[no_case_declarations.tsx:1:22]
1 │ switch (a) { case 1: function f() {} break; }
· ────────
╰────
help: Wrap the case body in braces `{}` to create an explicit block scope for the lexical declaration.

⚠ eslint(no-case-declarations): Unexpected lexical declaration in case block.
╭─[no_case_declarations.tsx:1:23]
1 │ switch (a) { default: function f() {} break; }
· ────────
╰────
help: Wrap the case body in braces `{}` to create an explicit block scope for the lexical declaration.

⚠ eslint(no-case-declarations): Unexpected lexical declaration in case block.
╭─[no_case_declarations.tsx:1:22]
1 │ switch (a) { case 1: class C {} break; }
· ─────
╰────
help: Wrap the case body in braces `{}` to create an explicit block scope for the lexical declaration.

⚠ eslint(no-case-declarations): Unexpected lexical declaration in case block.
╭─[no_case_declarations.tsx:1:23]
1 │ switch (a) { default: class C {} break; }
· ─────
╰────
help: Wrap the case body in braces `{}` to create an explicit block scope for the lexical declaration.

× Using declaration cannot appear in the bare case statement.
╭─[no_case_declarations.tsx:1:23]
Expand Down
Loading
Loading