Skip to content

Commit b76cb41

Browse files
authored
feat(linter): implement useExplicitFunctionReturnType (#3990)
1 parent 83626d9 commit b76cb41

File tree

14 files changed

+647
-13
lines changed

14 files changed

+647
-13
lines changed

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

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

crates/biome_cli/tests/snapshots/main_commands_check/top_level_all_down_level_not_all.snap

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,25 @@ check ━━━━━━━━━━━━━━━━━━━━━━━━
4040

4141
# Emitted Messages
4242

43+
```block
44+
fix.js:1:1 lint/nursery/useExplicitFunctionReturnType ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
45+
46+
! Missing return type on function.
47+
48+
> 1 │
49+
50+
> 2 │ function f() {arguments;}
51+
│ ^^^^^^^^^^
52+
3 │ const FOO = "FOO";
53+
4 │ var x, y;
54+
55+
i Declaring the return type makes the code self-documenting and can speed up TypeScript type checking.
56+
57+
i Add a return type annotation.
58+
59+
60+
```
61+
4362
```block
4463
fix.js:2:14 lint/correctness/noUnusedVariables ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
4564
@@ -151,5 +170,5 @@ fix.js format ━━━━━━━━━━━━━━━━━━━━━━
151170
```block
152171
Checked 1 file in <TIME>. No fixes applied.
153172
Found 1 error.
154-
Found 4 warnings.
173+
Found 5 warnings.
155174
```

crates/biome_cli/tests/snapshots/main_commands_lint/top_level_all_true_group_level_all_false.snap

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,25 @@ expression: content
2929

3030
# Emitted Messages
3131

32+
```block
33+
fix.js:1:1 lint/nursery/useExplicitFunctionReturnType ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
34+
35+
! Missing return type on function.
36+
37+
> 1 │
38+
39+
> 2 │ function f() {arguments;}
40+
│ ^^^^^^^^^^
41+
3 │ const FOO = "FOO";
42+
4 │ var x, y;
43+
44+
i Declaring the return type makes the code self-documenting and can speed up TypeScript type checking.
45+
46+
i Add a return type annotation.
47+
48+
49+
```
50+
3251
```block
3352
fix.js:2:14 lint/correctness/noUnusedVariables ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
3453
@@ -119,5 +138,5 @@ fix.js:4:12 lint/correctness/noUnusedVariables FIXABLE ━━━━━━━
119138

120139
```block
121140
Checked 1 file in <TIME>. No fixes applied.
122-
Found 4 warnings.
141+
Found 5 warnings.
123142
```

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

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3368,6 +3368,10 @@ pub struct Nursery {
33683368
#[serde(skip_serializing_if = "Option::is_none")]
33693369
pub use_deprecated_reason:
33703370
Option<RuleConfiguration<biome_graphql_analyze::options::UseDeprecatedReason>>,
3371+
#[doc = "Require explicit return types on functions and class methods."]
3372+
#[serde(skip_serializing_if = "Option::is_none")]
3373+
pub use_explicit_function_return_type:
3374+
Option<RuleConfiguration<biome_js_analyze::options::UseExplicitFunctionReturnType>>,
33713375
#[doc = "Disallows package private imports."]
33723376
#[serde(skip_serializing_if = "Option::is_none")]
33733377
pub use_import_restrictions:
@@ -3431,6 +3435,7 @@ impl Nursery {
34313435
"useConsistentCurlyBraces",
34323436
"useConsistentMemberAccessibility",
34333437
"useDeprecatedReason",
3438+
"useExplicitFunctionReturnType",
34343439
"useImportRestrictions",
34353440
"useSortedClasses",
34363441
"useStrictMode",
@@ -3461,7 +3466,7 @@ impl Nursery {
34613466
RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[21]),
34623467
RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[24]),
34633468
RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[25]),
3464-
RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[28]),
3469+
RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[29]),
34653470
];
34663471
const ALL_RULES_AS_FILTERS: &'static [RuleFilter<'static>] = &[
34673472
RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[0]),
@@ -3495,6 +3500,7 @@ impl Nursery {
34953500
RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[28]),
34963501
RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[29]),
34973502
RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[30]),
3503+
RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[31]),
34983504
];
34993505
#[doc = r" Retrieves the recommended rules"]
35003506
pub(crate) fn is_recommended_true(&self) -> bool {
@@ -3641,31 +3647,36 @@ impl Nursery {
36413647
index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[25]));
36423648
}
36433649
}
3644-
if let Some(rule) = self.use_import_restrictions.as_ref() {
3650+
if let Some(rule) = self.use_explicit_function_return_type.as_ref() {
36453651
if rule.is_enabled() {
36463652
index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[26]));
36473653
}
36483654
}
3649-
if let Some(rule) = self.use_sorted_classes.as_ref() {
3655+
if let Some(rule) = self.use_import_restrictions.as_ref() {
36503656
if rule.is_enabled() {
36513657
index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[27]));
36523658
}
36533659
}
3654-
if let Some(rule) = self.use_strict_mode.as_ref() {
3660+
if let Some(rule) = self.use_sorted_classes.as_ref() {
36553661
if rule.is_enabled() {
36563662
index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[28]));
36573663
}
36583664
}
3659-
if let Some(rule) = self.use_trim_start_end.as_ref() {
3665+
if let Some(rule) = self.use_strict_mode.as_ref() {
36603666
if rule.is_enabled() {
36613667
index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[29]));
36623668
}
36633669
}
3664-
if let Some(rule) = self.use_valid_autocomplete.as_ref() {
3670+
if let Some(rule) = self.use_trim_start_end.as_ref() {
36653671
if rule.is_enabled() {
36663672
index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[30]));
36673673
}
36683674
}
3675+
if let Some(rule) = self.use_valid_autocomplete.as_ref() {
3676+
if rule.is_enabled() {
3677+
index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[31]));
3678+
}
3679+
}
36693680
index_set
36703681
}
36713682
pub(crate) fn get_disabled_rules(&self) -> FxHashSet<RuleFilter<'static>> {
@@ -3800,31 +3811,36 @@ impl Nursery {
38003811
index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[25]));
38013812
}
38023813
}
3803-
if let Some(rule) = self.use_import_restrictions.as_ref() {
3814+
if let Some(rule) = self.use_explicit_function_return_type.as_ref() {
38043815
if rule.is_disabled() {
38053816
index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[26]));
38063817
}
38073818
}
3808-
if let Some(rule) = self.use_sorted_classes.as_ref() {
3819+
if let Some(rule) = self.use_import_restrictions.as_ref() {
38093820
if rule.is_disabled() {
38103821
index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[27]));
38113822
}
38123823
}
3813-
if let Some(rule) = self.use_strict_mode.as_ref() {
3824+
if let Some(rule) = self.use_sorted_classes.as_ref() {
38143825
if rule.is_disabled() {
38153826
index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[28]));
38163827
}
38173828
}
3818-
if let Some(rule) = self.use_trim_start_end.as_ref() {
3829+
if let Some(rule) = self.use_strict_mode.as_ref() {
38193830
if rule.is_disabled() {
38203831
index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[29]));
38213832
}
38223833
}
3823-
if let Some(rule) = self.use_valid_autocomplete.as_ref() {
3834+
if let Some(rule) = self.use_trim_start_end.as_ref() {
38243835
if rule.is_disabled() {
38253836
index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[30]));
38263837
}
38273838
}
3839+
if let Some(rule) = self.use_valid_autocomplete.as_ref() {
3840+
if rule.is_disabled() {
3841+
index_set.insert(RuleFilter::Rule(Self::GROUP_NAME, Self::GROUP_RULES[31]));
3842+
}
3843+
}
38283844
index_set
38293845
}
38303846
#[doc = r" Checks if, given a rule name, matches one of the rules contained in this category"]
@@ -3965,6 +3981,10 @@ impl Nursery {
39653981
.use_deprecated_reason
39663982
.as_ref()
39673983
.map(|conf| (conf.level(), conf.get_options())),
3984+
"useExplicitFunctionReturnType" => self
3985+
.use_explicit_function_return_type
3986+
.as_ref()
3987+
.map(|conf| (conf.level(), conf.get_options())),
39683988
"useImportRestrictions" => self
39693989
.use_import_restrictions
39703990
.as_ref()

crates/biome_diagnostics_categories/src/categories.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@ define_categories! {
180180
"lint/nursery/useConsistentCurlyBraces": "https://biomejs.dev/linter/rules/use-consistent-curly-braces",
181181
"lint/nursery/useConsistentMemberAccessibility": "https://biomejs.dev/linter/rules/use-consistent-member-accessibility",
182182
"lint/nursery/useDeprecatedReason": "https://biomejs.dev/linter/rules/use-deprecated-reason",
183+
"lint/nursery/useExplicitFunctionReturnType": "https://biomejs.dev/linter/rules/use-explicit-function-return-type",
183184
"lint/nursery/useImportRestrictions": "https://biomejs.dev/linter/rules/use-import-restrictions",
184185
"lint/nursery/useJsxCurlyBraceConvention": "https://biomejs.dev/linter/rules/use-jsx-curly-brace-convention",
185186
"lint/nursery/useSortedClasses": "https://biomejs.dev/linter/rules/use-sorted-classes",

crates/biome_js_analyze/src/lint/nursery.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ pub mod use_aria_props_supported_by_role;
2121
pub mod use_component_export_only_modules;
2222
pub mod use_consistent_curly_braces;
2323
pub mod use_consistent_member_accessibility;
24+
pub mod use_explicit_function_return_type;
2425
pub mod use_import_restrictions;
2526
pub mod use_sorted_classes;
2627
pub mod use_strict_mode;
@@ -50,6 +51,7 @@ declare_lint_group! {
5051
self :: use_component_export_only_modules :: UseComponentExportOnlyModules ,
5152
self :: use_consistent_curly_braces :: UseConsistentCurlyBraces ,
5253
self :: use_consistent_member_accessibility :: UseConsistentMemberAccessibility ,
54+
self :: use_explicit_function_return_type :: UseExplicitFunctionReturnType ,
5355
self :: use_import_restrictions :: UseImportRestrictions ,
5456
self :: use_sorted_classes :: UseSortedClasses ,
5557
self :: use_strict_mode :: UseStrictMode ,

0 commit comments

Comments
 (0)