Skip to content

Commit 03ba760

Browse files
authoredApr 7, 2025··
fix(linter): jsdoc/require-param: skip rule if any doc has @type tag (#10282)
- fixes #10253 We had a correct skip for this rule already, but it only accounted for a single JSDoc block. Now, if there is any `@type` tag in any JSDoc for a given function node, we will skip the rule. I also took this opportunity to extract a diagnostic function for this rule and simplify the labeled span creation.
1 parent 6c9b094 commit 03ba760

File tree

1 file changed

+26
-12
lines changed

1 file changed

+26
-12
lines changed
 

Diff for: ‎crates/oxc_linter/src/rules/jsdoc/require_param.rs

+26-12
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,12 @@ use std::sync::{
33
};
44

55
use lazy_regex::Regex;
6+
use oxc_span::Span;
67
use rustc_hash::{FxHashMap, FxHashSet};
78
use serde::Deserialize;
89

910
use oxc_ast::{AstKind, ast::MethodDefinitionKind};
10-
use oxc_diagnostics::{LabeledSpan, OxcDiagnostic};
11+
use oxc_diagnostics::OxcDiagnostic;
1112
use oxc_macros::declare_oxc_lint;
1213
use oxc_semantic::{AstNode, JSDoc};
1314

@@ -20,6 +21,12 @@ use crate::{
2021
},
2122
};
2223

24+
fn require_param_diagnostic(violations: Vec<Span>) -> OxcDiagnostic {
25+
OxcDiagnostic::warn("Missing JSDoc `@param` declaration for function parameters.")
26+
.with_help("Add `@param` tag with name.")
27+
.with_labels(violations)
28+
}
29+
2330
#[derive(Debug, Default, Clone)]
2431
pub struct RequireParam(Box<RequireParamConfig>);
2532

@@ -149,10 +156,14 @@ impl Rule for RequireParam {
149156
}
150157
}
151158

159+
// If there is a `@type` tag for this function, then `@param` is not required
160+
if jsdocs.iter().any(has_type_tag) {
161+
return;
162+
}
163+
152164
// If JSDoc is found but safely ignored, skip
153165
if jsdocs
154166
.iter()
155-
.filter(|jsdoc| !should_ignore_as_custom_skip(jsdoc))
156167
.filter(|jsdoc| !should_ignore_as_avoid(jsdoc, settings, &config.exempted_by))
157168
.filter(|jsdoc| !should_ignore_as_private(jsdoc, settings))
158169
.filter(|jsdoc| !should_ignore_as_internal(jsdoc, settings))
@@ -175,6 +186,7 @@ impl Rule for RequireParam {
175186
});
176187

177188
let mut violations = vec![];
189+
178190
for (idx, param) in params_to_check.iter().enumerate() {
179191
match param {
180192
ParamKind::Single(param) => {
@@ -246,15 +258,7 @@ impl Rule for RequireParam {
246258
}
247259

248260
if !violations.is_empty() {
249-
let labels = violations
250-
.iter()
251-
.map(|span| LabeledSpan::new_with_span(None, *span))
252-
.collect::<Vec<_>>();
253-
ctx.diagnostic(
254-
OxcDiagnostic::warn("Missing JSDoc `@param` declaration for function parameters.")
255-
.with_help("Add `@param` tag with name.")
256-
.with_labels(labels),
257-
);
261+
ctx.diagnostic(require_param_diagnostic(violations));
258262
}
259263
}
260264
}
@@ -286,7 +290,8 @@ fn collect_tags<'a>(
286290
collected
287291
}
288292

289-
fn should_ignore_as_custom_skip(jsdoc: &JSDoc) -> bool {
293+
/// Returns true if the JSDoc has a `@type` tag in it
294+
fn has_type_tag(jsdoc: &JSDoc) -> bool {
290295
jsdoc.tags().iter().any(|tag| "type" == tag.kind.parsed())
291296
}
292297

@@ -747,6 +752,15 @@ fn test() {
747752
return a + b;
748753
}
749754
", None, None), // { "parser": typescriptEslintParser, }
755+
// https://github.com/oxc-project/oxc/issues/10253
756+
("
757+
/** @typedef {import('../types.d.ts').FileURL} FileURL */
758+
759+
/**
760+
* @type {import('node:module').ResolveHook}
761+
*/
762+
async function resolveJSONC(specifier, ctx, nextResolve) {}
763+
", None, None)
750764
];
751765

752766
let fail = vec![

0 commit comments

Comments
 (0)
Please sign in to comment.