From a2235fe429ffe0f204901945762cf789dd8a0948 Mon Sep 17 00:00:00 2001 From: Sean Poulter Date: Tue, 20 Feb 2024 22:44:28 -0500 Subject: [PATCH 1/9] feat(check-param-names): Add disableMissingParamChecks option --- .README/rules/check-param-names.md | 6 +++- docs/rules/check-param-names.md | 8 +++++- src/rules/checkParamNames.js | 9 +++++- test/rules/assertions/checkParamNames.js | 36 ++++++++++++++++++++++++ 4 files changed, 56 insertions(+), 3 deletions(-) diff --git a/.README/rules/check-param-names.md b/.README/rules/check-param-names.md index dcea0efa0..cd8a5d0a1 100644 --- a/.README/rules/check-param-names.md +++ b/.README/rules/check-param-names.md @@ -81,12 +81,16 @@ item at the same level is destructured as destructuring will prevent other access and this option is only intended to permit documenting extra properties that are available and actually used in the function. +### `disableMissingParamChecks` + +Whether to check for missing `@param` definitions. Defaults to `false`. Change to `true` if you want to be able to omit properties. + ## Context and settings ||| |---|---| |Context|`ArrowFunctionExpression`, `FunctionDeclaration`, `FunctionExpression`| -|Options|`allowExtraTrailingParamDocs`, `checkDestructured`, `checkRestProperty`, `checkTypesPattern`, `disableExtraPropertyReporting`, `enableFixer`, `useDefaultObjectProperties`| +|Options|`allowExtraTrailingParamDocs`, `checkDestructured`, `checkRestProperty`, `checkTypesPattern`, `disableExtraPropertyReporting`, `disableMissingParamChecks`, `enableFixer`, `useDefaultObjectProperties`| |Tags|`param`| |Aliases|`arg`, `argument`| |Recommended|true| diff --git a/docs/rules/check-param-names.md b/docs/rules/check-param-names.md index cca4fbd4b..9182f8baa 100644 --- a/docs/rules/check-param-names.md +++ b/docs/rules/check-param-names.md @@ -116,6 +116,12 @@ item at the same level is destructured as destructuring will prevent other access and this option is only intended to permit documenting extra properties that are available and actually used in the function. + + +### disableMissingParamChecks + +Whether to check for missing `@param` definitions. Defaults to `false`. Change to `true` if you want to be able to omit properties. + ## Context and settings @@ -123,7 +129,7 @@ that are available and actually used in the function. ||| |---|---| |Context|`ArrowFunctionExpression`, `FunctionDeclaration`, `FunctionExpression`| -|Options|`allowExtraTrailingParamDocs`, `checkDestructured`, `checkRestProperty`, `checkTypesPattern`, `disableExtraPropertyReporting`, `enableFixer`, `useDefaultObjectProperties`| +|Options|`allowExtraTrailingParamDocs`, `checkDestructured`, `checkRestProperty`, `checkTypesPattern`, `disableExtraPropertyReporting`, `disableMissingParamChecks`, `enableFixer`, `useDefaultObjectProperties`| |Tags|`param`| |Aliases|`arg`, `argument`| |Recommended|true| diff --git a/src/rules/checkParamNames.js b/src/rules/checkParamNames.js index 7837c6e6d..e98be8a18 100644 --- a/src/rules/checkParamNames.js +++ b/src/rules/checkParamNames.js @@ -7,6 +7,7 @@ import iterateJsdoc from '../iterateJsdoc.js'; * @param {boolean} checkRestProperty * @param {RegExp} checkTypesRegex * @param {boolean} disableExtraPropertyReporting + * @param {boolean} disableMissingParamChecks * @param {boolean} enableFixer * @param {import('../jsdocUtils.js').ParamNameInfo[]} functionParameterNames * @param {import('comment-parser').Block} jsdoc @@ -21,6 +22,7 @@ const validateParameterNames = ( checkRestProperty, checkTypesRegex, disableExtraPropertyReporting, + disableMissingParamChecks, enableFixer, functionParameterNames, jsdoc, utils, report, ) => { @@ -225,7 +227,7 @@ const validateParameterNames = ( funcParamName = functionParameterName; } - if (funcParamName !== tag.name.trim()) { + if (funcParamName !== tag.name.trim() && !disableMissingParamChecks) { // Todo: Improve for array or object child items const actualNames = paramTagsNonNested.map(([ , { @@ -329,6 +331,7 @@ export default iterateJsdoc(({ enableFixer = false, useDefaultObjectProperties = false, disableExtraPropertyReporting = false, + disableMissingParamChecks = false, } = context.options[0] || {}; const checkTypesRegex = utils.getRegexFromString(checkTypesPattern); @@ -349,6 +352,7 @@ export default iterateJsdoc(({ checkRestProperty, checkTypesRegex, disableExtraPropertyReporting, + disableMissingParamChecks, enableFixer, functionParameterNames, jsdoc, @@ -389,6 +393,9 @@ export default iterateJsdoc(({ disableExtraPropertyReporting: { type: 'boolean', }, + disableMissingParamChecks: { + type: 'boolean', + }, enableFixer: { type: 'boolean', }, diff --git a/test/rules/assertions/checkParamNames.js b/test/rules/assertions/checkParamNames.js index a666ff877..c7784499e 100644 --- a/test/rules/assertions/checkParamNames.js +++ b/test/rules/assertions/checkParamNames.js @@ -1183,6 +1183,27 @@ export default { parser: typescriptEslintParser }, }, + { + code: ` + /** + * @param foo + * @param foo.bar + */ + function quux (bar, foo) { + } + `, + options: [ + { + disableMissingParamChecks: false, + }, + ], + errors: [ + { + line: 3, + message: 'Expected @param names to be "bar, foo". Got "foo".', + }, + ], + } ], valid: [ { @@ -1835,5 +1856,20 @@ export default { parser: typescriptEslintParser }, }, + { + code: ` + /** + * @param foo + * @param foo.bar + */ + function quux (bar, foo) { + } + `, + options: [ + { + disableMissingParamChecks: true, + }, + ], + } ], }; From bc4c4f76c0b3d169cf2cf1d13d9c0e0322e98c68 Mon Sep 17 00:00:00 2001 From: Sean Poulter Date: Tue, 20 Feb 2024 23:26:25 -0500 Subject: [PATCH 2/9] test(require-param): Add missing line numbers in errors --- test/rules/assertions/requireParam.js | 30 +++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/test/rules/assertions/requireParam.js b/test/rules/assertions/requireParam.js index 70c04cb7c..9a2fa0f13 100644 --- a/test/rules/assertions/requireParam.js +++ b/test/rules/assertions/requireParam.js @@ -292,6 +292,7 @@ export default { `, errors: [ { + line: 2, message: 'Missing JSDoc @param "options.foo" declaration.', }, ], @@ -1783,6 +1784,7 @@ export default { `, errors: [ { + line: 2, message: 'Missing JSDoc @param "options.foo" declaration.', }, ], @@ -1828,6 +1830,7 @@ export default { `, errors: [ { + line: 3, message: 'Missing JSDoc @param "options.permissions" declaration.', }, ], @@ -1943,6 +1946,7 @@ export default { `, errors: [ { + line: 2, message: 'Missing JSDoc @param "cfg.extra" declaration.', }, ], @@ -1976,6 +1980,7 @@ export default { `, errors: [ { + line: 2, message: 'Missing JSDoc @param "cfg.opts.extra" declaration.', }, ], @@ -2010,6 +2015,7 @@ export default { `, errors: [ { + line: 2, message: 'Missing JSDoc @param "cfg."1"" declaration.', }, ], @@ -2067,15 +2073,19 @@ export default { `, errors: [ { + line: 2, message: 'Missing JSDoc @param "bbox.x" declaration.', }, { + line: 2, message: 'Missing JSDoc @param "bbox.y" declaration.', }, { + line: 2, message: 'Missing JSDoc @param "bbox.width" declaration.', }, { + line: 2, message: 'Missing JSDoc @param "bbox.height" declaration.', }, ], @@ -2110,15 +2120,19 @@ export default { `, errors: [ { + line: 2, message: 'Missing JSDoc @param "bbox.x" declaration.', }, { + line: 2, message: 'Missing JSDoc @param "bbox.y" declaration.', }, { + line: 2, message: 'Missing JSDoc @param "bbox.width" declaration.', }, { + line: 2, message: 'Missing JSDoc @param "bbox.height" declaration.', }, ], @@ -2149,9 +2163,11 @@ export default { `, errors: [ { + line: 3, message: 'Missing JSDoc @param "fetchOptions.url" declaration.', }, { + line: 3, message: 'Missing JSDoc @param "fetchOptions.options" declaration.', }, ], @@ -2218,6 +2234,7 @@ export default { `, errors: [ { + line: 2, message: 'Missing JSDoc @param "options.foo.bar" declaration.', }, ], @@ -2242,6 +2259,7 @@ export default { `, errors: [ { + line: 2, message: 'Missing JSDoc @param "options.foo.bar" declaration.', }, ], @@ -2271,9 +2289,11 @@ export default { `, errors: [ { + line: 2, message: 'Missing JSDoc @param "options.foo" declaration.', }, { + line: 2, message: 'Missing JSDoc @param "options.foo.bar" declaration.', }, ], @@ -2299,6 +2319,7 @@ export default { `, errors: [ { + line: 2, message: 'Missing JSDoc @param "options.foo.bar" declaration.', }, ], @@ -2324,6 +2345,7 @@ export default { `, errors: [ { + line: 2, message: 'Missing JSDoc @param "options.foo.bar.baz" declaration.', }, ], @@ -2351,9 +2373,11 @@ export default { `, errors: [ { + line: 2, message: 'Missing JSDoc @param "props.prop.a" declaration.', }, { + line: 2, message: 'Missing JSDoc @param "props.prop.b" declaration.', }, ], @@ -2385,12 +2409,15 @@ export default { `, errors: [ { + line: 2, message: 'Missing JSDoc @param "a" declaration.', }, { + line: 2, message: 'Missing JSDoc @param "b" declaration.', }, { + line: 2, message: 'Missing JSDoc @param "c" declaration.', }, ], @@ -2414,6 +2441,7 @@ export default { `, errors: [ { + line: 2, message: 'Missing JSDoc @param "baz" declaration.', }, ], @@ -2455,6 +2483,7 @@ export default { `, errors: [ { + line: 2, message: 'Missing JSDoc @param "verbose" declaration.', }, ], @@ -2502,6 +2531,7 @@ export default { `, errors: [ { + line: 6, message: 'Missing JSDoc @param "btnState" declaration.', }, ], From 091fe5f40b9ed59c6285642080fc60c4256c741d Mon Sep 17 00:00:00 2001 From: Sean Poulter Date: Tue, 20 Feb 2024 23:50:00 -0500 Subject: [PATCH 3/9] Revert "test(require-param): Add missing line numbers in errors" This reverts commit bc4c4f76c0b3d169cf2cf1d13d9c0e0322e98c68. --- test/rules/assertions/requireParam.js | 30 --------------------------- 1 file changed, 30 deletions(-) diff --git a/test/rules/assertions/requireParam.js b/test/rules/assertions/requireParam.js index 9a2fa0f13..70c04cb7c 100644 --- a/test/rules/assertions/requireParam.js +++ b/test/rules/assertions/requireParam.js @@ -292,7 +292,6 @@ export default { `, errors: [ { - line: 2, message: 'Missing JSDoc @param "options.foo" declaration.', }, ], @@ -1784,7 +1783,6 @@ export default { `, errors: [ { - line: 2, message: 'Missing JSDoc @param "options.foo" declaration.', }, ], @@ -1830,7 +1828,6 @@ export default { `, errors: [ { - line: 3, message: 'Missing JSDoc @param "options.permissions" declaration.', }, ], @@ -1946,7 +1943,6 @@ export default { `, errors: [ { - line: 2, message: 'Missing JSDoc @param "cfg.extra" declaration.', }, ], @@ -1980,7 +1976,6 @@ export default { `, errors: [ { - line: 2, message: 'Missing JSDoc @param "cfg.opts.extra" declaration.', }, ], @@ -2015,7 +2010,6 @@ export default { `, errors: [ { - line: 2, message: 'Missing JSDoc @param "cfg."1"" declaration.', }, ], @@ -2073,19 +2067,15 @@ export default { `, errors: [ { - line: 2, message: 'Missing JSDoc @param "bbox.x" declaration.', }, { - line: 2, message: 'Missing JSDoc @param "bbox.y" declaration.', }, { - line: 2, message: 'Missing JSDoc @param "bbox.width" declaration.', }, { - line: 2, message: 'Missing JSDoc @param "bbox.height" declaration.', }, ], @@ -2120,19 +2110,15 @@ export default { `, errors: [ { - line: 2, message: 'Missing JSDoc @param "bbox.x" declaration.', }, { - line: 2, message: 'Missing JSDoc @param "bbox.y" declaration.', }, { - line: 2, message: 'Missing JSDoc @param "bbox.width" declaration.', }, { - line: 2, message: 'Missing JSDoc @param "bbox.height" declaration.', }, ], @@ -2163,11 +2149,9 @@ export default { `, errors: [ { - line: 3, message: 'Missing JSDoc @param "fetchOptions.url" declaration.', }, { - line: 3, message: 'Missing JSDoc @param "fetchOptions.options" declaration.', }, ], @@ -2234,7 +2218,6 @@ export default { `, errors: [ { - line: 2, message: 'Missing JSDoc @param "options.foo.bar" declaration.', }, ], @@ -2259,7 +2242,6 @@ export default { `, errors: [ { - line: 2, message: 'Missing JSDoc @param "options.foo.bar" declaration.', }, ], @@ -2289,11 +2271,9 @@ export default { `, errors: [ { - line: 2, message: 'Missing JSDoc @param "options.foo" declaration.', }, { - line: 2, message: 'Missing JSDoc @param "options.foo.bar" declaration.', }, ], @@ -2319,7 +2299,6 @@ export default { `, errors: [ { - line: 2, message: 'Missing JSDoc @param "options.foo.bar" declaration.', }, ], @@ -2345,7 +2324,6 @@ export default { `, errors: [ { - line: 2, message: 'Missing JSDoc @param "options.foo.bar.baz" declaration.', }, ], @@ -2373,11 +2351,9 @@ export default { `, errors: [ { - line: 2, message: 'Missing JSDoc @param "props.prop.a" declaration.', }, { - line: 2, message: 'Missing JSDoc @param "props.prop.b" declaration.', }, ], @@ -2409,15 +2385,12 @@ export default { `, errors: [ { - line: 2, message: 'Missing JSDoc @param "a" declaration.', }, { - line: 2, message: 'Missing JSDoc @param "b" declaration.', }, { - line: 2, message: 'Missing JSDoc @param "c" declaration.', }, ], @@ -2441,7 +2414,6 @@ export default { `, errors: [ { - line: 2, message: 'Missing JSDoc @param "baz" declaration.', }, ], @@ -2483,7 +2455,6 @@ export default { `, errors: [ { - line: 2, message: 'Missing JSDoc @param "verbose" declaration.', }, ], @@ -2531,7 +2502,6 @@ export default { `, errors: [ { - line: 6, message: 'Missing JSDoc @param "btnState" declaration.', }, ], From 03db300ca63edc310cdb1f73c48df06791a0b05e Mon Sep 17 00:00:00 2001 From: Sean Poulter Date: Wed, 21 Feb 2024 00:22:52 -0500 Subject: [PATCH 4/9] Add invalid test case for disableMissingParamChecks = true --- src/rules/checkParamNames.js | 16 +++++++-- test/rules/assertions/checkParamNames.js | 41 ++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 3 deletions(-) diff --git a/src/rules/checkParamNames.js b/src/rules/checkParamNames.js index e98be8a18..1cf2f0670 100644 --- a/src/rules/checkParamNames.js +++ b/src/rules/checkParamNames.js @@ -227,7 +227,7 @@ const validateParameterNames = ( funcParamName = functionParameterName; } - if (funcParamName !== tag.name.trim() && !disableMissingParamChecks) { + if (funcParamName !== tag.name.trim()) { // Todo: Improve for array or object child items const actualNames = paramTagsNonNested.map(([ , { @@ -247,10 +247,20 @@ const validateParameterNames = ( return item; }).filter((item) => { return item !== 'this'; - }).join(', '); + }); + + // When disableMissingParamChecks is true tag names can be omitted. + // Report when the tag names do not match the expected names or they are used out of order. + if (disableMissingParamChecks) { + const usedExpectedNames = expectedNames.map(a => a?.toString()).filter(expectedName => !!expectedName && actualNames.includes(expectedName)); + const usedInOrder = actualNames.every((actualName, idx) => actualName === usedExpectedNames[idx]); + if (usedInOrder) { + return false; + } + } report( - `Expected @${targetTagName} names to be "${expectedNames}". Got "${actualNames.join(', ')}".`, + `Expected @${targetTagName} names to be "${expectedNames.join(', ')}". Got "${actualNames.join(', ')}".`, null, tag, ); diff --git a/test/rules/assertions/checkParamNames.js b/test/rules/assertions/checkParamNames.js index c7784499e..7db762dc9 100644 --- a/test/rules/assertions/checkParamNames.js +++ b/test/rules/assertions/checkParamNames.js @@ -1203,6 +1203,47 @@ export default { message: 'Expected @param names to be "bar, foo". Got "foo".', }, ], + }, + { + code: ` + /** + * @param foo + */ + function quux (bar, baz) { + } + `, + options: [ + { + disableMissingParamChecks: true, + }, + ], + errors: [ + { + line: 3, + message: 'Expected @param names to be "bar, baz". Got "foo".', + }, + ], + }, + { + code: ` + /** + * @param bar + * @param foo + */ + function quux (foo, bar) { + } + `, + options: [ + { + disableMissingParamChecks: true, + }, + ], + errors: [ + { + line: 3, + message: 'Expected @param names to be "foo, bar". Got "bar, foo".', + }, + ], } ], valid: [ From 55e5fc296a2644bf595d87686787b8c36cc3dee9 Mon Sep 17 00:00:00 2001 From: Sean Poulter Date: Wed, 21 Feb 2024 10:47:04 -0500 Subject: [PATCH 5/9] Add test case for extra, unexpected tag --- test/rules/assertions/checkParamNames.js | 45 +++++++++++++++++++++--- 1 file changed, 40 insertions(+), 5 deletions(-) diff --git a/test/rules/assertions/checkParamNames.js b/test/rules/assertions/checkParamNames.js index 7db762dc9..4a9b75eb8 100644 --- a/test/rules/assertions/checkParamNames.js +++ b/test/rules/assertions/checkParamNames.js @@ -1244,7 +1244,28 @@ export default { message: 'Expected @param names to be "foo, bar". Got "bar, foo".', }, ], - } + }, + { + code: ` + /** + * @param foo + * @param bar + */ + function quux (foo) { + } + `, + options: [ + { + disableMissingParamChecks: true, + }, + ], + errors: [ + { + line: 4, + message: '@param "bar" does not match an existing function parameter.', + }, + ], + }, ], valid: [ { @@ -1900,10 +1921,9 @@ export default { { code: ` /** - * @param foo - * @param foo.bar + * Documentation */ - function quux (bar, foo) { + function quux (foo, bar) { } `, options: [ @@ -1911,6 +1931,21 @@ export default { disableMissingParamChecks: true, }, ], - } + }, + { + code: ` + /** + * @param bar + * @param bar.baz + */ + function quux (foo, bar) { + } + `, + options: [ + { + disableMissingParamChecks: true, + }, + ], + }, ], }; From b752b5990addc54578178adc24d7b03f30ea11fb Mon Sep 17 00:00:00 2001 From: Sean Poulter Date: Wed, 21 Feb 2024 15:03:52 -0500 Subject: [PATCH 6/9] Add test case --- test/rules/assertions/checkParamNames.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/test/rules/assertions/checkParamNames.js b/test/rules/assertions/checkParamNames.js index 4a9b75eb8..0148603d8 100644 --- a/test/rules/assertions/checkParamNames.js +++ b/test/rules/assertions/checkParamNames.js @@ -1947,5 +1947,19 @@ export default { }, ], }, + { + code: ` + /** + * @param foo + */ + function quux (foo, bar) { + } + `, + options: [ + { + disableMissingParamChecks: true, + }, + ], + }, ], }; From d3a248dfd89c9b722db9f2ef216298cccfbdac2c Mon Sep 17 00:00:00 2001 From: Sean Poulter Date: Thu, 22 Feb 2024 06:53:16 -0500 Subject: [PATCH 7/9] Update src/rules/checkParamNames.js Co-authored-by: Brett Zamir --- src/rules/checkParamNames.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rules/checkParamNames.js b/src/rules/checkParamNames.js index 1cf2f0670..a94390b9a 100644 --- a/src/rules/checkParamNames.js +++ b/src/rules/checkParamNames.js @@ -252,7 +252,7 @@ const validateParameterNames = ( // When disableMissingParamChecks is true tag names can be omitted. // Report when the tag names do not match the expected names or they are used out of order. if (disableMissingParamChecks) { - const usedExpectedNames = expectedNames.map(a => a?.toString()).filter(expectedName => !!expectedName && actualNames.includes(expectedName)); + const usedExpectedNames = expectedNames.map(a => a?.toString()).filter(expectedName => Boolean(expectedName) && actualNames.includes(expectedName)); const usedInOrder = actualNames.every((actualName, idx) => actualName === usedExpectedNames[idx]); if (usedInOrder) { return false; From 133befa4c260277a41ca83f165630e6c1617ca8d Mon Sep 17 00:00:00 2001 From: Sean Poulter Date: Thu, 22 Feb 2024 06:53:26 -0500 Subject: [PATCH 8/9] Update .README/rules/check-param-names.md Co-authored-by: Brett Zamir --- .README/rules/check-param-names.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.README/rules/check-param-names.md b/.README/rules/check-param-names.md index cd8a5d0a1..7cb8b8296 100644 --- a/.README/rules/check-param-names.md +++ b/.README/rules/check-param-names.md @@ -83,7 +83,7 @@ that are available and actually used in the function. ### `disableMissingParamChecks` -Whether to check for missing `@param` definitions. Defaults to `false`. Change to `true` if you want to be able to omit properties. +Whether to avoid checks for missing `@param` definitions. Defaults to `false`. Change to `true` if you want to be able to omit properties. ## Context and settings From 5d57b1ea86935d1cfe033b8546d5c8b9370530c4 Mon Sep 17 00:00:00 2001 From: Brett Zamir Date: Thu, 22 Feb 2024 21:40:20 +0800 Subject: [PATCH 9/9] Update src/rules/checkParamNames.js --- src/rules/checkParamNames.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rules/checkParamNames.js b/src/rules/checkParamNames.js index a94390b9a..3569efcd5 100644 --- a/src/rules/checkParamNames.js +++ b/src/rules/checkParamNames.js @@ -252,7 +252,7 @@ const validateParameterNames = ( // When disableMissingParamChecks is true tag names can be omitted. // Report when the tag names do not match the expected names or they are used out of order. if (disableMissingParamChecks) { - const usedExpectedNames = expectedNames.map(a => a?.toString()).filter(expectedName => Boolean(expectedName) && actualNames.includes(expectedName)); + const usedExpectedNames = expectedNames.map(a => a?.toString()).filter(expectedName => expectedName && actualNames.includes(expectedName)); const usedInOrder = actualNames.every((actualName, idx) => actualName === usedExpectedNames[idx]); if (usedInOrder) { return false;