diff --git a/crates/oxc_linter/src/rules/jsdoc/require_param.rs b/crates/oxc_linter/src/rules/jsdoc/require_param.rs index d17a57378a5b0..98f372ab65b12 100644 --- a/crates/oxc_linter/src/rules/jsdoc/require_param.rs +++ b/crates/oxc_linter/src/rules/jsdoc/require_param.rs @@ -334,6 +334,21 @@ fn test() { } ", None, None), + ( + " + /** + * @param md + */ + const component = (md) => { + md.renderer.rules.fence = (...args) => { + const [tokens, index] = args; + return tokens[index]; + }; + }; + ", + None, + None, + ), (" /** * @param root0 diff --git a/crates/oxc_linter/src/rules/jsdoc/require_returns.rs b/crates/oxc_linter/src/rules/jsdoc/require_returns.rs index 341f9600bbbbc..f437fd8afe228 100644 --- a/crates/oxc_linter/src/rules/jsdoc/require_returns.rs +++ b/crates/oxc_linter/src/rules/jsdoc/require_returns.rs @@ -317,6 +317,21 @@ fn test() { None, None, ), + ( + " + /** + * @param md + */ + const component = (md) => { + md.renderer.rules.fence = (...args) => { + const [tokens, index] = args; + return tokens[index]; + }; + }; + ", + None, + None, + ), ( " /** diff --git a/crates/oxc_linter/src/utils/jsdoc.rs b/crates/oxc_linter/src/utils/jsdoc.rs index e8e0a2e92f8fa..b8db4a4415e53 100644 --- a/crates/oxc_linter/src/utils/jsdoc.rs +++ b/crates/oxc_linter/src/utils/jsdoc.rs @@ -60,11 +60,20 @@ pub fn get_function_nearest_jsdoc_node<'a, 'b>( semantic: &'b Semantic<'a>, ) -> Option<&'b AstNode<'a>> { let mut current_node = node; + let source_function_id = node.id(); // Whether the node has attached JSDoc or not is determined by `JSDocBuilder` while semantic.jsdoc().get_all_by_node(semantic.nodes(), current_node).is_none() { // Tie-breaker, otherwise every loop will end at `Program` node! // Maybe more checks should be added match current_node.kind() { + // Do not leak an outer function's JSDoc into nested function expressions. + // Keep walking only for the source function node itself, because function + // JSDoc can be attached on wrapper nodes like `VariableDeclaration`. + AstKind::Function(_) | AstKind::ArrowFunctionExpression(_) + if current_node.id() != source_function_id => + { + return None; + } AstKind::Program(_) => return None, AstKind::VariableDeclaration(_) | AstKind::MethodDefinition(_)