Skip to content

Commit bbb93b9

Browse files
authored
feat(lint): useCollapsedIf JS lint rule (#4179)
Signed-off-by: Naoki Ikeguchi <[email protected]>
1 parent 89d34b2 commit bbb93b9

File tree

12 files changed

+1534
-24
lines changed

12 files changed

+1534
-24
lines changed

crates/biome_cli/src/execute/migrate/eslint_any_rule_to_biome.rs

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/biome_configuration/src/analyzer/linter/rules.rs

Lines changed: 43 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3395,6 +3395,9 @@ pub struct Nursery {
33953395
#[doc = "Use at() instead of integer index access."]
33963396
#[serde(skip_serializing_if = "Option::is_none")]
33973397
pub use_at_index: Option<RuleFixConfiguration<biome_js_analyze::options::UseAtIndex>>,
3398+
#[doc = "Enforce using single if instead of nested if clauses."]
3399+
#[serde(skip_serializing_if = "Option::is_none")]
3400+
pub use_collapsed_if: Option<RuleFixConfiguration<biome_js_analyze::options::UseCollapsedIf>>,
33983401
#[doc = "Enforce declaring components only within modules that export React Components exclusively."]
33993402
#[serde(skip_serializing_if = "Option::is_none")]
34003403
pub use_component_export_only_modules:
@@ -3488,6 +3491,7 @@ impl Nursery {
34883491
"useAdjacentOverloadSignatures",
34893492
"useAriaPropsSupportedByRole",
34903493
"useAtIndex",
3494+
"useCollapsedIf",
34913495
"useComponentExportOnlyModules",
34923496
"useConsistentCurlyBraces",
34933497
"useConsistentMemberAccessibility",
@@ -3528,9 +3532,9 @@ impl Nursery {
35283532
RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[27]),
35293533
RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[28]),
35303534
RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[32]),
3531-
RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[36]),
35323535
RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[37]),
3533-
RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[42]),
3536+
RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[38]),
3537+
RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[43]),
35343538
];
35353539
const ALL_RULES_AS_FILTERS: &'static [RuleFilter<'static>] = &[
35363540
RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[0]),
@@ -3578,6 +3582,7 @@ impl Nursery {
35783582
RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[42]),
35793583
RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[43]),
35803584
RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[44]),
3585+
RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[45]),
35813586
];
35823587
#[doc = r" Retrieves the recommended rules"]
35833588
pub(crate) fn is_recommended_true(&self) -> bool {
@@ -3764,61 +3769,66 @@ impl Nursery {
37643769
index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[33]));
37653770
}
37663771
}
3767-
if let Some(rule) = self.use_component_export_only_modules.as_ref() {
3772+
if let Some(rule) = self.use_collapsed_if.as_ref() {
37683773
if rule.is_enabled() {
37693774
index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[34]));
37703775
}
37713776
}
3772-
if let Some(rule) = self.use_consistent_curly_braces.as_ref() {
3777+
if let Some(rule) = self.use_component_export_only_modules.as_ref() {
37733778
if rule.is_enabled() {
37743779
index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[35]));
37753780
}
37763781
}
3777-
if let Some(rule) = self.use_consistent_member_accessibility.as_ref() {
3782+
if let Some(rule) = self.use_consistent_curly_braces.as_ref() {
37783783
if rule.is_enabled() {
37793784
index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[36]));
37803785
}
37813786
}
3782-
if let Some(rule) = self.use_deprecated_reason.as_ref() {
3787+
if let Some(rule) = self.use_consistent_member_accessibility.as_ref() {
37833788
if rule.is_enabled() {
37843789
index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[37]));
37853790
}
37863791
}
3787-
if let Some(rule) = self.use_explicit_type.as_ref() {
3792+
if let Some(rule) = self.use_deprecated_reason.as_ref() {
37883793
if rule.is_enabled() {
37893794
index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[38]));
37903795
}
37913796
}
3792-
if let Some(rule) = self.use_guard_for_in.as_ref() {
3797+
if let Some(rule) = self.use_explicit_type.as_ref() {
37933798
if rule.is_enabled() {
37943799
index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[39]));
37953800
}
37963801
}
3797-
if let Some(rule) = self.use_import_restrictions.as_ref() {
3802+
if let Some(rule) = self.use_guard_for_in.as_ref() {
37983803
if rule.is_enabled() {
37993804
index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[40]));
38003805
}
38013806
}
3802-
if let Some(rule) = self.use_sorted_classes.as_ref() {
3807+
if let Some(rule) = self.use_import_restrictions.as_ref() {
38033808
if rule.is_enabled() {
38043809
index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[41]));
38053810
}
38063811
}
3807-
if let Some(rule) = self.use_strict_mode.as_ref() {
3812+
if let Some(rule) = self.use_sorted_classes.as_ref() {
38083813
if rule.is_enabled() {
38093814
index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[42]));
38103815
}
38113816
}
3812-
if let Some(rule) = self.use_trim_start_end.as_ref() {
3817+
if let Some(rule) = self.use_strict_mode.as_ref() {
38133818
if rule.is_enabled() {
38143819
index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[43]));
38153820
}
38163821
}
3817-
if let Some(rule) = self.use_valid_autocomplete.as_ref() {
3822+
if let Some(rule) = self.use_trim_start_end.as_ref() {
38183823
if rule.is_enabled() {
38193824
index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[44]));
38203825
}
38213826
}
3827+
if let Some(rule) = self.use_valid_autocomplete.as_ref() {
3828+
if rule.is_enabled() {
3829+
index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[45]));
3830+
}
3831+
}
38223832
index_set
38233833
}
38243834
pub(crate) fn get_disabled_rules(&self) -> FxHashSet<RuleFilter<'static>> {
@@ -3993,61 +4003,66 @@ impl Nursery {
39934003
index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[33]));
39944004
}
39954005
}
3996-
if let Some(rule) = self.use_component_export_only_modules.as_ref() {
4006+
if let Some(rule) = self.use_collapsed_if.as_ref() {
39974007
if rule.is_disabled() {
39984008
index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[34]));
39994009
}
40004010
}
4001-
if let Some(rule) = self.use_consistent_curly_braces.as_ref() {
4011+
if let Some(rule) = self.use_component_export_only_modules.as_ref() {
40024012
if rule.is_disabled() {
40034013
index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[35]));
40044014
}
40054015
}
4006-
if let Some(rule) = self.use_consistent_member_accessibility.as_ref() {
4016+
if let Some(rule) = self.use_consistent_curly_braces.as_ref() {
40074017
if rule.is_disabled() {
40084018
index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[36]));
40094019
}
40104020
}
4011-
if let Some(rule) = self.use_deprecated_reason.as_ref() {
4021+
if let Some(rule) = self.use_consistent_member_accessibility.as_ref() {
40124022
if rule.is_disabled() {
40134023
index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[37]));
40144024
}
40154025
}
4016-
if let Some(rule) = self.use_explicit_type.as_ref() {
4026+
if let Some(rule) = self.use_deprecated_reason.as_ref() {
40174027
if rule.is_disabled() {
40184028
index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[38]));
40194029
}
40204030
}
4021-
if let Some(rule) = self.use_guard_for_in.as_ref() {
4031+
if let Some(rule) = self.use_explicit_type.as_ref() {
40224032
if rule.is_disabled() {
40234033
index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[39]));
40244034
}
40254035
}
4026-
if let Some(rule) = self.use_import_restrictions.as_ref() {
4036+
if let Some(rule) = self.use_guard_for_in.as_ref() {
40274037
if rule.is_disabled() {
40284038
index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[40]));
40294039
}
40304040
}
4031-
if let Some(rule) = self.use_sorted_classes.as_ref() {
4041+
if let Some(rule) = self.use_import_restrictions.as_ref() {
40324042
if rule.is_disabled() {
40334043
index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[41]));
40344044
}
40354045
}
4036-
if let Some(rule) = self.use_strict_mode.as_ref() {
4046+
if let Some(rule) = self.use_sorted_classes.as_ref() {
40374047
if rule.is_disabled() {
40384048
index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[42]));
40394049
}
40404050
}
4041-
if let Some(rule) = self.use_trim_start_end.as_ref() {
4051+
if let Some(rule) = self.use_strict_mode.as_ref() {
40424052
if rule.is_disabled() {
40434053
index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[43]));
40444054
}
40454055
}
4046-
if let Some(rule) = self.use_valid_autocomplete.as_ref() {
4056+
if let Some(rule) = self.use_trim_start_end.as_ref() {
40474057
if rule.is_disabled() {
40484058
index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[44]));
40494059
}
40504060
}
4061+
if let Some(rule) = self.use_valid_autocomplete.as_ref() {
4062+
if rule.is_disabled() {
4063+
index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[45]));
4064+
}
4065+
}
40514066
index_set
40524067
}
40534068
#[doc = r" Checks if, given a rule name, matches one of the rules contained in this category"]
@@ -4220,6 +4235,10 @@ impl Nursery {
42204235
.use_at_index
42214236
.as_ref()
42224237
.map(|conf| (conf.level(), conf.get_options())),
4238+
"useCollapsedIf" => self
4239+
.use_collapsed_if
4240+
.as_ref()
4241+
.map(|conf| (conf.level(), conf.get_options())),
42234242
"useComponentExportOnlyModules" => self
42244243
.use_component_export_only_modules
42254244
.as_ref()

crates/biome_diagnostics_categories/src/categories.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ define_categories! {
188188
"lint/nursery/useAriaPropsSupportedByRole": "https://biomejs.dev/linter/rules/use-aria-props-supported-by-role",
189189
"lint/nursery/useAtIndex": "https://biomejs.dev/linter/rules/use-at-index",
190190
"lint/nursery/useBiomeSuppressionComment": "https://biomejs.dev/linter/rules/use-biome-suppression-comment",
191+
"lint/nursery/useCollapsedIf": "https://biomejs.dev/linter/rules/use-collapsed-if",
191192
"lint/nursery/useComponentExportOnlyModules": "https://biomejs.dev/linter/rules/use-components-only-module",
192193
"lint/nursery/useConsistentCurlyBraces": "https://biomejs.dev/linter/rules/use-consistent-curly-braces",
193194
"lint/nursery/useConsistentMemberAccessibility": "https://biomejs.dev/linter/rules/use-consistent-member-accessibility",

crates/biome_js_analyze/src/lint/nursery.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ pub mod no_useless_string_raw;
2727
pub mod use_adjacent_overload_signatures;
2828
pub mod use_aria_props_supported_by_role;
2929
pub mod use_at_index;
30+
pub mod use_collapsed_if;
3031
pub mod use_component_export_only_modules;
3132
pub mod use_consistent_curly_braces;
3233
pub mod use_consistent_member_accessibility;
@@ -67,6 +68,7 @@ declare_lint_group! {
6768
self :: use_adjacent_overload_signatures :: UseAdjacentOverloadSignatures ,
6869
self :: use_aria_props_supported_by_role :: UseAriaPropsSupportedByRole ,
6970
self :: use_at_index :: UseAtIndex ,
71+
self :: use_collapsed_if :: UseCollapsedIf ,
7072
self :: use_component_export_only_modules :: UseComponentExportOnlyModules ,
7173
self :: use_consistent_curly_braces :: UseConsistentCurlyBraces ,
7274
self :: use_consistent_member_accessibility :: UseConsistentMemberAccessibility ,

0 commit comments

Comments
 (0)