-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
feat(lint/useIterableCallbackReturn): add allowImplicit option #9489
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
dde21d6
78b550c
e89b399
455711e
a742f34
629f724
fa7c864
3085183
f9327c2
6c22bb1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| --- | ||
| "@biomejs/biome": patch | ||
| --- | ||
|
|
||
| Added `allowImplicit` option to [`useIterableCallbackReturn`](https://biomejs.dev/linter/rules/use-iterable-callback-return/). When set to `true`, callbacks for methods like `map` and `filter` can use `return;` to implicitly return `undefined`. This matches ESLint's `allowImplicit` option for `array-callback-return`. | ||
| Original file line number | Diff line number | Diff line change | ||
|---|---|---|---|---|
|
|
@@ -85,7 +85,7 @@ declare_lint_rule! { | |||
| /// | ||||
| /// ### `checkForEach` | ||||
| /// | ||||
| /// **Since `v2.4.0** | ||||
| /// **Since `v2.4.0`** | ||||
| /// | ||||
| /// Default: `true` | ||||
| /// | ||||
|
|
@@ -107,7 +107,37 @@ declare_lint_rule! { | |||
| /// }); | ||||
| /// ``` | ||||
| /// | ||||
| /// When `checkForEach` is `false` (default), the above code will not trigger any diagnostic. | ||||
| /// When `checkForEach` is `false`, the above code will not trigger any diagnostic. | ||||
| /// | ||||
| /// ### `allowImplicit` | ||||
| /// | ||||
| /// Default: `false` | ||||
| /// | ||||
| /// When set to `true`, allows callbacks of methods that expect a return value | ||||
| /// (such as `map` or `filter`) to implicitly return `undefined` using `return;`. | ||||
| /// This is useful for patterns like mapping with early returns where some paths | ||||
| /// intentionally return `undefined`. | ||||
| /// | ||||
| /// This matches ESLint's [`allowImplicit`](https://eslint.org/docs/latest/rules/array-callback-return#allowimplicit) option. | ||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This information isn't needed
This comment was marked as low quality.
Sorry, something went wrong. |
||||
| /// | ||||
| /// ### Examples | ||||
| /// | ||||
| /// ```json,options | ||||
| /// { | ||||
| /// "options": { | ||||
| /// "allowImplicit": true | ||||
| /// } | ||||
| /// } | ||||
| /// ``` | ||||
| /// | ||||
| /// ```js,use_options | ||||
| /// [1, 2, 3].map((x) => { | ||||
| /// if (x > 2) return x; | ||||
| /// return; | ||||
| /// }); | ||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we have a snippet that is more real? For example we should a
This comment was marked as low quality.
Sorry, something went wrong. |
||||
| /// ``` | ||||
| /// | ||||
| /// When `allowImplicit` is `true`, the above code will not trigger any diagnostic. | ||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
That's implied by the infrastructure
This comment was marked as low quality.
Sorry, something went wrong. |
||||
| /// | ||||
| pub UseIterableCallbackReturn { | ||||
| version: "2.0.0", | ||||
|
|
@@ -180,22 +210,34 @@ impl Rule for UseIterableCallbackReturn { | |||
|
|
||||
| let returns_info = get_function_returns_info(cfg); | ||||
|
|
||||
| let allow_implicit = ctx.options().allow_implicit(); | ||||
| let mut problems: Vec<RuleProblemKind> = Vec::new(); | ||||
| let member_range = member_expression.member().ok()?.range(); | ||||
| if method_config.return_value_required { | ||||
| if returns_info.has_paths_without_returns { | ||||
| if returns_info.returns_with_value.is_empty() { | ||||
| if allow_implicit { | ||||
| // When allowImplicit is true, `return;` is accepted. | ||||
| // Only report if there are paths that fall through without any return at all. | ||||
| if returns_info.has_paths_without_returns | ||||
| && returns_info.returns_with_value.is_empty() | ||||
| && returns_info.returns_without_value.is_empty() | ||||
| { | ||||
| problems.push(RuleProblemKind::MissingReturnWithValue); | ||||
| } else { | ||||
| problems.push(RuleProblemKind::NotAllPathsReturnValue); | ||||
| } | ||||
| } else if !returns_info.returns_without_value.is_empty() { | ||||
| if !returns_info.returns_with_value.is_empty() { | ||||
| for return_range in returns_info.returns_without_value { | ||||
| problems.push(RuleProblemKind::UnexpectedEmptyReturn(return_range)); | ||||
| } else { | ||||
| if returns_info.has_paths_without_returns { | ||||
| if returns_info.returns_with_value.is_empty() { | ||||
| problems.push(RuleProblemKind::MissingReturnWithValue); | ||||
| } else { | ||||
| problems.push(RuleProblemKind::NotAllPathsReturnValue); | ||||
| } | ||||
| } else if !returns_info.returns_without_value.is_empty() { | ||||
|
coderabbitai[bot] marked this conversation as resolved.
|
||||
| if !returns_info.returns_with_value.is_empty() { | ||||
| for return_range in returns_info.returns_without_value { | ||||
| problems.push(RuleProblemKind::UnexpectedEmptyReturn(return_range)); | ||||
| } | ||||
| } else { | ||||
| problems.push(RuleProblemKind::MissingReturnWithValue); | ||||
| } | ||||
| } else { | ||||
| problems.push(RuleProblemKind::MissingReturnWithValue); | ||||
| } | ||||
| } | ||||
| } else { | ||||
|
|
||||
Uh oh!
There was an error while loading. Please reload this page.