Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions docs/rules/require-param.md
Original file line number Diff line number Diff line change
Expand Up @@ -629,6 +629,15 @@ function quux ({ foo, bar: { baz }}) {
}
// Message: Missing JSDoc @param "root0" declaration.

/**
* @param root0
* @param root0.foo
* @param root0.bar.baz
*/
function quux ({ foo, bar: { baz }}) {
}
// Message: Missing JSDoc @param "root0.bar" declaration.

/**
*
*/
Expand Down
35 changes: 22 additions & 13 deletions src/rules/requireParam.js
Original file line number Diff line number Diff line change
Expand Up @@ -181,27 +181,36 @@ export default iterateJsdoc(({
* }}
*/
const findExpectedIndex = (jsdocTags, indexAtFunctionParams) => {
const remainingRoots = functionParameterNames.slice(indexAtFunctionParams || 0);
// Get the parameters that come after the current index in the flattened order
const remainingFlattenedRoots = flattenedRoots.slice((indexAtFunctionParams || 0) + 1);

// Find the first existing tag that comes after the current parameter in the flattened order
const foundIndex = jsdocTags.findIndex(({
name,
newAdd,
}) => {
return !newAdd && remainingRoots.some((remainingRoot) => {
if (Array.isArray(remainingRoot)) {
return (
/**
* @type {import('../jsdocUtils.js').FlattendRootInfo & {
* annotationParamName?: string|undefined;
* }}
*/ (remainingRoot[1]).names.includes(name)
);
if (newAdd) {
return false;
}

// Check if the tag name matches any of the remaining flattened roots
return remainingFlattenedRoots.some((flattenedRoot) => {
// The flattened roots don't have the root prefix (e.g., "bar", "bar.baz")
// but JSDoc tags do (e.g., "root0", "root0.bar", "root0.bar.baz")
// So we need to check if the tag name ends with the flattened root

// Check if tag name ends with ".<flattenedRoot>"
if (name.endsWith(`.${flattenedRoot}`)) {
return true;
}

if (typeof remainingRoot === 'object') {
return name === remainingRoot.name;
// Also check if tag name exactly matches the flattenedRoot
// (for single-level params)
if (name === flattenedRoot) {
return true;
}

return name === remainingRoot;
return false;
});
});

Expand Down
29 changes: 28 additions & 1 deletion test/rules/assertions/requireParam.js
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,33 @@ export default /** @type {import('../index.js').TestCases} */ ({
}
`,
},
{
code: `
/**
* @param root0
* @param root0.foo
* @param root0.bar.baz
*/
function quux ({ foo, bar: { baz }}) {
}
`,
errors: [
{
line: 2,
message: 'Missing JSDoc @param "root0.bar" declaration.',
},
],
output: `
/**
* @param root0
* @param root0.foo
* @param root0.bar
* @param root0.bar.baz
*/
function quux ({ foo, bar: { baz }}) {
}
`,
},
{
code: `
/**
Expand Down Expand Up @@ -2244,8 +2271,8 @@ export default /** @type {import('../index.js').TestCases} */ ({
/**
* Description.
* @param {Object} options
* @param options.foo
* @param {FooBar} foo
* @param options.foo
* @param options.foo.bar
*/
function quux ({ foo: { bar } }) {}
Expand Down
Loading