Skip to content

fix(js-semantic): find_jsdoc may associate inner binding with outer declaration's JSDoc #9915

@coderabbitai

Description

@coderabbitai

Summary

The find_jsdoc helper in crates/biome_js_semantic/src/semantic_model/builder.rs walks all ancestors of a binding node and returns the first parseable JsdocComment it finds. This means an inner binding can inadvertently inherit the JSDoc comment that belongs to an outer declaration.

Example

/** JSDoc for outer */
export function outer() {
  const x = 1; // inner binding
}

When find_jsdoc is called for x, the ancestor walk reaches JsFunctionDeclaration (for outer) before finding a JSDoc, and returns /** JSDoc for outer */ — incorrectly associating it with x.

Expected behaviour

Each binding should only be associated with the JSDoc that directly precedes its own declaration (or its enclosing export statement). The traversal should stop at the binding's own declaration boundary and not continue to outer ancestors.

Suggested fix

fn find_jsdoc(node: &JsSyntaxNode) -> Option<JsdocComment> {
    let declaration = node.ancestors().find_map(AnyJsDeclaration::cast)?;

    JsdocComment::try_from(declaration.syntax()).ok().or_else(|| {
        declaration
            .syntax()
            .parent()
            .and_then(|parent| JsExport::cast_ref(&parent))
            .and_then(|export| JsdocComment::try_from(export.syntax()).ok())
    })
}

Notes

This was a pre-existing behaviour in crates/biome_module_graph/src/js_module_info/collector.rs before it was moved into the semantic model by PR #9905. It was identified during review of PR #9905 (comment: #9905 (comment)).

Backlink: #9905
Requested by: @ematipico

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions