Skip to content

Commit 1487271

Browse files
committed
docs(linter): Add config option docs for jsdoc/require-param and jsdoc/require-returns rules (#15857)
Part of #14743. I also refactored the default definitions a bit to make sure they were simple and matched the usual patterns in the app. Generated docs: ```md ## Configuration This rule accepts a configuration object with the following properties: ### checkConstructors type: `boolean` default: `false` Whether to check constructor methods. ### checkDestructured type: `boolean` default: `true` Whether to check destructured parameters. ### checkDestructuredRoots type: `boolean` default: `true` Whether to check destructured parameters when you have code like `function doSomething({ a, b }) { ... }`. Because there is no named parameter in this example, when this option is `true` you must have a `@param` tag that corresponds to `{a, b}`. ### checkGetters type: `boolean` default: `true` Whether to check getter methods. ### checkRestProperty type: `boolean` default: `false` Whether to check rest properties. ### checkSetters type: `boolean` default: `true` Whether to check setter methods. ### checkTypesPattern type: `string` default: `"^(?:[oO]bject|[aA]rray|PlainObject|Generic(?:Object|Array))$"` Regex pattern string to match types that exempt parameters from checking. ### exemptedBy type: `string[]` default: `["inheritdoc"]` List of JSDoc tags that exempt functions from `@param` checking. ``` ```md ## Configuration This rule accepts a configuration object with the following properties: ### checkConstructors type: `boolean` default: `false` Whether to check constructor methods. ### checkGetters type: `boolean` default: `true` Whether to check getter methods. ### exemptedBy type: `string[]` default: `["inheritdoc"]` Tags that exempt functions from requiring `@returns`. ### forceRequireReturn type: `boolean` default: `false` Whether to require a `@returns` tag even if the function doesn't return a value. ### forceReturnsWithAsync type: `boolean` default: `false` Whether to require a `@returns` tag for async functions. ```
1 parent eea6b26 commit 1487271

File tree

4 files changed

+171
-157
lines changed

4 files changed

+171
-157
lines changed

crates/oxc_linter/src/rules/jsdoc/require_param.rs

Lines changed: 62 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use std::sync::{
55
use lazy_regex::Regex;
66
use oxc_span::Span;
77
use rustc_hash::{FxHashMap, FxHashSet};
8+
use schemars::JsonSchema;
89
use serde::Deserialize;
910

1011
use oxc_ast::{AstKind, ast::MethodDefinitionKind};
@@ -16,8 +17,8 @@ use crate::{
1617
context::LintContext,
1718
rule::Rule,
1819
utils::{
19-
ParamKind, collect_params, default_true, get_function_nearest_jsdoc_node,
20-
should_ignore_as_avoid, should_ignore_as_internal, should_ignore_as_private,
20+
ParamKind, collect_params, get_function_nearest_jsdoc_node, should_ignore_as_avoid,
21+
should_ignore_as_internal, should_ignore_as_private,
2122
},
2223
};
2324

@@ -30,14 +31,58 @@ fn require_param_diagnostic(violations: Vec<Span>) -> OxcDiagnostic {
3031
#[derive(Debug, Default, Clone)]
3132
pub struct RequireParam(Box<RequireParamConfig>);
3233

34+
#[derive(Debug, Clone, Deserialize, JsonSchema)]
35+
#[serde(rename_all = "camelCase", default)]
36+
struct RequireParamConfig {
37+
/// List of JSDoc tags that exempt functions from `@param` checking.
38+
#[serde(default = "default_exempted_by")]
39+
exempted_by: Vec<String>,
40+
/// Whether to check constructor methods.
41+
check_constructors: bool,
42+
/// Whether to check getter methods.
43+
check_getters: bool,
44+
/// Whether to check setter methods.
45+
check_setters: bool,
46+
/// Whether to check destructured parameters when you have code like
47+
/// `function doSomething({ a, b }) { ... }`. Because there is no named
48+
/// parameter in this example, when this option is `true` you must
49+
/// have a `@param` tag that corresponds to `{a, b}`.
50+
check_destructured_roots: bool,
51+
/// Whether to check destructured parameters.
52+
check_destructured: bool,
53+
/// Whether to check rest properties.
54+
check_rest_property: bool,
55+
/// Regex pattern to match types that exempt parameters from checking.
56+
#[serde(default = "default_check_types_pattern")]
57+
check_types_pattern: String,
58+
// TODO: Support this config
59+
// use_default_object_properties: bool,
60+
}
61+
62+
impl Default for RequireParamConfig {
63+
fn default() -> Self {
64+
Self {
65+
exempted_by: default_exempted_by(),
66+
check_constructors: false,
67+
check_getters: true,
68+
check_setters: true,
69+
check_destructured_roots: true,
70+
check_destructured: true,
71+
check_rest_property: false,
72+
check_types_pattern: default_check_types_pattern(),
73+
}
74+
}
75+
}
76+
3377
declare_oxc_lint!(
3478
/// ### What it does
3579
///
3680
/// Requires that all function parameters are documented with JSDoc `@param` tags.
3781
///
3882
/// ### Why is this bad?
3983
///
40-
/// The rule is aimed at enforcing code quality and maintainability by requiring that all function parameters are documented.
84+
/// The rule is aimed at enforcing code quality and maintainability by requiring
85+
/// that all function parameters are documented.
4186
///
4287
/// ### Examples
4388
///
@@ -55,56 +100,9 @@ declare_oxc_lint!(
55100
RequireParam,
56101
jsdoc,
57102
pedantic,
103+
config = RequireParamConfig,
58104
);
59105

60-
#[derive(Debug, Clone, Deserialize)]
61-
struct RequireParamConfig {
62-
#[serde(default = "default_exempted_by", rename = "exemptedBy")]
63-
exempted_by: Vec<String>,
64-
#[serde(default = "default_true", rename = "checkConstructors")]
65-
check_constructors: bool,
66-
#[serde(default, rename = "checkGetters")]
67-
check_getters: bool,
68-
#[serde(default, rename = "checkSetters")]
69-
check_setters: bool,
70-
#[serde(default = "default_true", rename = "checkDestructuredRoots")]
71-
check_destructured_roots: bool,
72-
#[serde(default = "default_true", rename = "checkDestructured")]
73-
check_destructured: bool,
74-
#[serde(default, rename = "checkRestProperty")]
75-
check_rest_property: bool,
76-
#[serde(default = "default_check_types_pattern", rename = "checkTypesPattern")]
77-
check_types_pattern: String,
78-
// TODO: Support this config
79-
// #[serde(default, rename = "useDefaultObjectProperties")]
80-
// use_default_object_properties: bool,
81-
}
82-
impl Default for RequireParamConfig {
83-
fn default() -> Self {
84-
Self {
85-
exempted_by: default_exempted_by(),
86-
check_constructors: false,
87-
check_getters: default_true(),
88-
check_setters: default_true(),
89-
check_destructured_roots: default_true(),
90-
check_destructured: default_true(),
91-
check_rest_property: false,
92-
check_types_pattern: default_check_types_pattern(),
93-
}
94-
}
95-
}
96-
fn default_exempted_by() -> Vec<String> {
97-
vec!["inheritdoc".to_string()]
98-
}
99-
fn default_check_types_pattern() -> String {
100-
"^(?:[oO]bject|[aA]rray|PlainObject|Generic(?:Object|Array))$".to_string() // spellchecker:disable-line
101-
}
102-
103-
fn regex_cache() -> RwLockWriteGuard<'static, FxHashMap<String, Regex>> {
104-
static REGEX_CACHE: OnceLock<RwLock<FxHashMap<String, Regex>>> = OnceLock::new();
105-
REGEX_CACHE.get_or_init(|| RwLock::new(FxHashMap::default())).write().unwrap()
106-
}
107-
108106
impl Rule for RequireParam {
109107
fn from_configuration(value: serde_json::Value) -> Self {
110108
value
@@ -263,6 +261,19 @@ impl Rule for RequireParam {
263261
}
264262
}
265263

264+
fn default_exempted_by() -> Vec<String> {
265+
vec!["inheritdoc".to_string()]
266+
}
267+
268+
fn default_check_types_pattern() -> String {
269+
"^(?:[oO]bject|[aA]rray|PlainObject|Generic(?:Object|Array))$".to_string() // spellchecker:disable-line
270+
}
271+
272+
fn regex_cache() -> RwLockWriteGuard<'static, FxHashMap<String, Regex>> {
273+
static REGEX_CACHE: OnceLock<RwLock<FxHashMap<String, Regex>>> = OnceLock::new();
274+
REGEX_CACHE.get_or_init(|| RwLock::new(FxHashMap::default())).write().unwrap()
275+
}
276+
266277
fn collect_tags<'a>(
267278
jsdocs: &[JSDoc<'a>],
268279
resolved_param_tag_name: &str,

crates/oxc_linter/src/rules/jsdoc/require_returns.rs

Lines changed: 39 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -7,32 +7,61 @@ use oxc_macros::declare_oxc_lint;
77
use oxc_semantic::JSDoc;
88
use oxc_span::Span;
99
use rustc_hash::FxHashMap;
10+
use schemars::JsonSchema;
1011
use serde::Deserialize;
1112

1213
use crate::{
1314
context::LintContext,
1415
rule::Rule,
1516
utils::{
16-
default_true, get_function_nearest_jsdoc_node, is_duplicated_special_tag,
17-
is_missing_special_tag, should_ignore_as_avoid, should_ignore_as_custom_skip,
18-
should_ignore_as_internal, should_ignore_as_private,
17+
get_function_nearest_jsdoc_node, is_duplicated_special_tag, is_missing_special_tag,
18+
should_ignore_as_avoid, should_ignore_as_custom_skip, should_ignore_as_internal,
19+
should_ignore_as_private,
1920
},
2021
};
2122

2223
fn missing_returns_diagnostic(span: Span) -> OxcDiagnostic {
2324
OxcDiagnostic::warn("Missing JSDoc `@returns` declaration for function.")
24-
.with_help("Add `@returns` tag to the JSDoc comment.")
25+
.with_help("Add a `@returns` tag to the JSDoc comment.")
2526
.with_label(span)
2627
}
28+
2729
fn duplicate_returns_diagnostic(span: Span) -> OxcDiagnostic {
2830
OxcDiagnostic::warn("Duplicate `@returns` tags.")
29-
.with_help("Remove redundant `@returns` tag.")
31+
.with_help("Remove the redundant `@returns` tag.")
3032
.with_label(span)
3133
}
3234

3335
#[derive(Debug, Default, Clone)]
3436
pub struct RequireReturns(Box<RequireReturnsConfig>);
3537

38+
#[derive(Debug, Clone, Deserialize, JsonSchema)]
39+
#[serde(rename_all = "camelCase", default)]
40+
struct RequireReturnsConfig {
41+
/// Tags that exempt functions from requiring `@returns`.
42+
exempted_by: Vec<String>,
43+
/// Whether to check constructor methods.
44+
check_constructors: bool,
45+
/// Whether to check getter methods.
46+
check_getters: bool,
47+
/// Whether to require a `@returns` tag even if the function doesn't return a value.
48+
force_require_return: bool,
49+
/// Whether to require a `@returns` tag for async functions.
50+
force_returns_with_async: bool,
51+
}
52+
53+
impl Default for RequireReturnsConfig {
54+
fn default() -> Self {
55+
Self {
56+
exempted_by: default_exempted_by(),
57+
check_constructors: false,
58+
check_getters: true,
59+
force_require_return: false,
60+
force_returns_with_async: false,
61+
}
62+
}
63+
}
64+
3665
declare_oxc_lint!(
3766
/// ### What it does
3867
///
@@ -65,36 +94,9 @@ declare_oxc_lint!(
6594
RequireReturns,
6695
jsdoc,
6796
pedantic,
97+
config = RequireReturnsConfig,
6898
);
6999

70-
#[derive(Debug, Clone, Deserialize)]
71-
struct RequireReturnsConfig {
72-
#[serde(default = "default_exempted_by", rename = "exemptedBy")]
73-
exempted_by: Vec<String>,
74-
#[serde(default, rename = "checkConstructors")]
75-
check_constructors: bool,
76-
#[serde(default = "default_true", rename = "checkGetters")]
77-
check_getters: bool,
78-
#[serde(default, rename = "forceRequireReturn")]
79-
force_require_return: bool,
80-
#[serde(default, rename = "forceReturnsWithAsync")]
81-
force_returns_with_async: bool,
82-
}
83-
impl Default for RequireReturnsConfig {
84-
fn default() -> Self {
85-
Self {
86-
exempted_by: default_exempted_by(),
87-
check_constructors: false,
88-
check_getters: true,
89-
force_require_return: false,
90-
force_returns_with_async: false,
91-
}
92-
}
93-
}
94-
fn default_exempted_by() -> Vec<String> {
95-
vec!["inheritdoc".to_string()]
96-
}
97-
98100
impl Rule for RequireReturns {
99101
fn from_configuration(value: serde_json::Value) -> Self {
100102
value
@@ -243,6 +245,10 @@ impl Rule for RequireReturns {
243245
}
244246
}
245247

248+
fn default_exempted_by() -> Vec<String> {
249+
vec!["inheritdoc".to_string()]
250+
}
251+
246252
/// - Some(true): `Promise` with value
247253
/// - Some(false): `Promise` without value
248254
/// - None: Not a `Promise` but some other expression

0 commit comments

Comments
 (0)