Skip to content

Commit da1c85f

Browse files
committed
feat(require-param-type, require-param-description): add exemptDestructuredRootsFromChecks setting; fixes #752
Also: - feat(`require-param-type`): add `setDefaultDestructuredRootType` and `defaultDestructuredRootType` options - feat(`require-param-description`): add `setDefaultDestructuredRootDescription` and `defaultDestructuredRootDescription` options
1 parent 36f6f9c commit da1c85f

File tree

8 files changed

+511
-4
lines changed

8 files changed

+511
-4
lines changed

.README/rules/require-param-description.md

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,26 @@
22

33
Requires that each `@param` tag has a `description` value.
44

5+
Will exempt destructured roots and their children if
6+
`settings.exemptDestructuredRootsFromChecks` is set to `true` (e.g.,
7+
`@param {object} props` will be exempted from requiring a description given
8+
`function someFunc ({child1, child2})`).
9+
510
#### Options
611

12+
##### `setDefaultDestructuredRootDescription`
13+
14+
Whether to set a default destructured root description. For example, you may
15+
wish to avoid manually having to set the description for a `@param`
16+
corresponding to a destructured root object as it should always be the same
17+
type of object. Uses `defaultDestructuredRootDescription` for the description
18+
string. Defaults to `false`.
19+
20+
##### `defaultDestructuredRootDescription`
21+
22+
The description string to set by default for destructured roots. Defaults to
23+
"The root object".
24+
725
##### `contexts`
826

927
Set this to an array of strings representing the AST context (or an object with
@@ -23,6 +41,7 @@ section of our README for more on the expected format.
2341
|Tags|`param`|
2442
|Aliases|`arg`, `argument`|
2543
|Recommended|true|
26-
|Options|`contexts`|
44+
|Options|`setDefaultDestructuredRootDescription`, `defaultDestructuredRootDescription`, `contexts`|
45+
|Settings|`exemptDestructuredRootsFromChecks`|
2746

2847
<!-- assertions requireParamDescription -->

.README/rules/require-param-type.md

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,25 @@
22

33
Requires that each `@param` tag has a `type` value.
44

5+
Will exempt destructured roots and their children if
6+
`settings.exemptDestructuredRootsFromChecks` is set to `true` (e.g.,
7+
`@param props` will be exempted from requiring a type given
8+
`function someFunc ({child1, child2})`).
9+
510
#### Options
611

12+
##### `setDefaultDestructuredRootType`
13+
14+
Whether to set a default destructured root type. For example, you may wish
15+
to avoid manually having to set the type for a `@param`
16+
corresponding to a destructured root object as it is always going to be an
17+
object. Uses `defaultDestructuredRootType` for the type string. Defaults to
18+
`false`.
19+
20+
##### `defaultDestructuredRootType`
21+
22+
The type string to set by default for destructured roots. Defaults to "object".
23+
724
##### `contexts`
825

926
Set this to an array of strings representing the AST context (or an object with
@@ -23,6 +40,7 @@ section of our README for more on the expected format.
2340
|Tags|`param`|
2441
|Aliases|`arg`, `argument`|
2542
|Recommended|true|
26-
|Options|`contexts`|
43+
|Options|`setDefaultDestructuredRootType`, `defaultDestructuredRootType`, `contexts`|
44+
|Settings|`exemptDestructuredRootsFromChecks`|
2745

2846
<!-- assertions requireParamType -->

README.md

Lines changed: 153 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14772,10 +14772,32 @@ class A {
1477214772

1477314773
Requires that each `@param` tag has a `description` value.
1477414774

14775+
Will exempt destructured roots and their children if
14776+
`settings.exemptDestructuredRootsFromChecks` is set to `true` (e.g.,
14777+
`@param {object} props` will be exempted from requiring a description given
14778+
`function someFunc ({child1, child2})`).
14779+
1477514780
<a name="user-content-eslint-plugin-jsdoc-rules-require-param-description-options-29"></a>
1477614781
<a name="eslint-plugin-jsdoc-rules-require-param-description-options-29"></a>
1477714782
#### Options
1477814783

14784+
<a name="user-content-eslint-plugin-jsdoc-rules-require-param-description-options-29-setdefaultdestructuredrootdescription"></a>
14785+
<a name="eslint-plugin-jsdoc-rules-require-param-description-options-29-setdefaultdestructuredrootdescription"></a>
14786+
##### <code>setDefaultDestructuredRootDescription</code>
14787+
14788+
Whether to set a default destructured root description. For example, you may
14789+
wish to avoid manually having to set the description for a `@param`
14790+
corresponding to a destructured root object as it should always be the same
14791+
type of object. Uses `defaultDestructuredRootDescription` for the description
14792+
string. Defaults to `false`.
14793+
14794+
<a name="user-content-eslint-plugin-jsdoc-rules-require-param-description-options-29-defaultdestructuredrootdescription"></a>
14795+
<a name="eslint-plugin-jsdoc-rules-require-param-description-options-29-defaultdestructuredrootdescription"></a>
14796+
##### <code>defaultDestructuredRootDescription</code>
14797+
14798+
The description string to set by default for destructured roots. Defaults to
14799+
"The root object".
14800+
1477914801
<a name="user-content-eslint-plugin-jsdoc-rules-require-param-description-options-29-contexts-8"></a>
1478014802
<a name="eslint-plugin-jsdoc-rules-require-param-description-options-29-contexts-8"></a>
1478114803
##### <code>contexts</code>
@@ -14797,7 +14819,8 @@ section of our README for more on the expected format.
1479714819
|Tags|`param`|
1479814820
|Aliases|`arg`, `argument`|
1479914821
|Recommended|true|
14800-
|Options|`contexts`|
14822+
|Options|`setDefaultDestructuredRootDescription`, `defaultDestructuredRootDescription`, `contexts`|
14823+
|Settings|`exemptDestructuredRootsFromChecks`|
1480114824

1480214825
The following patterns are considered problems:
1480314826

@@ -14859,6 +14882,39 @@ function quux (foo) {
1485914882
}
1486014883
// "jsdoc/require-param-description": ["error"|"warn", {"contexts":[{"comment":"JsdocBlock:has(JsdocTag:not([name=props]))","context":"FunctionDeclaration"}]}]
1486114884
// Message: Missing JSDoc @param "foo" description.
14885+
14886+
/**
14887+
* @param {number} foo Foo description
14888+
* @param {object} root
14889+
* @param {boolean} baz Baz description
14890+
*/
14891+
function quux (foo, {bar}, baz) {
14892+
14893+
}
14894+
// "jsdoc/require-param-description": ["error"|"warn", {"setDefaultDestructuredRootDescription":true}]
14895+
// Message: Missing root description for @param.
14896+
14897+
/**
14898+
* @param {number} foo Foo description
14899+
* @param {object} root
14900+
* @param {boolean} baz Baz description
14901+
*/
14902+
function quux (foo, {bar}, baz) {
14903+
14904+
}
14905+
// "jsdoc/require-param-description": ["error"|"warn", {"defaultDestructuredRootDescription":"Root description","setDefaultDestructuredRootDescription":true}]
14906+
// Message: Missing root description for @param.
14907+
14908+
/**
14909+
* @param {number} foo Foo description
14910+
* @param {object} root
14911+
* @param {boolean} baz Baz description
14912+
*/
14913+
function quux (foo, {bar}, baz) {
14914+
14915+
}
14916+
// "jsdoc/require-param-description": ["error"|"warn", {"setDefaultDestructuredRootDescription":false}]
14917+
// Message: Missing JSDoc @param "root" description.
1486214918
````
1486314919

1486414920
The following patterns are not considered problems:
@@ -14903,6 +14959,26 @@ function quux (props) {
1490314959

1490414960
}
1490514961
// "jsdoc/require-param-description": ["error"|"warn", {"contexts":[{"comment":"JsdocBlock:has(JsdocTag:not([name=props]))","context":"FunctionDeclaration"}]}]
14962+
14963+
/**
14964+
* @param {number} foo Foo description
14965+
* @param {object} root
14966+
* @param {boolean} baz Baz description
14967+
*/
14968+
function quux (foo, {bar}, baz) {
14969+
14970+
}
14971+
// Settings: {"jsdoc":{"exemptDestructuredRootsFromChecks":true}}
14972+
14973+
/**
14974+
* @param {number} foo Foo description
14975+
* @param {object} root
14976+
* @param {object} root.bar
14977+
*/
14978+
function quux (foo, {bar: {baz}}) {
14979+
14980+
}
14981+
// Settings: {"jsdoc":{"exemptDestructuredRootsFromChecks":true}}
1490614982
````
1490714983

1490814984

@@ -15055,10 +15131,31 @@ function example(cb) {
1505515131

1505615132
Requires that each `@param` tag has a `type` value.
1505715133

15134+
Will exempt destructured roots and their children if
15135+
`settings.exemptDestructuredRootsFromChecks` is set to `true` (e.g.,
15136+
`@param props` will be exempted from requiring a type given
15137+
`function someFunc ({child1, child2})`).
15138+
1505815139
<a name="user-content-eslint-plugin-jsdoc-rules-require-param-type-options-31"></a>
1505915140
<a name="eslint-plugin-jsdoc-rules-require-param-type-options-31"></a>
1506015141
#### Options
1506115142

15143+
<a name="user-content-eslint-plugin-jsdoc-rules-require-param-type-options-31-setdefaultdestructuredroottype"></a>
15144+
<a name="eslint-plugin-jsdoc-rules-require-param-type-options-31-setdefaultdestructuredroottype"></a>
15145+
##### <code>setDefaultDestructuredRootType</code>
15146+
15147+
Whether to set a default destructured root type. For example, you may wish
15148+
to avoid manually having to set the type for a `@param`
15149+
corresponding to a destructured root object as it is always going to be an
15150+
object. Uses `defaultDestructuredRootType` for the type string. Defaults to
15151+
`false`.
15152+
15153+
<a name="user-content-eslint-plugin-jsdoc-rules-require-param-type-options-31-defaultdestructuredroottype"></a>
15154+
<a name="eslint-plugin-jsdoc-rules-require-param-type-options-31-defaultdestructuredroottype"></a>
15155+
##### <code>defaultDestructuredRootType</code>
15156+
15157+
The type string to set by default for destructured roots. Defaults to "object".
15158+
1506215159
<a name="user-content-eslint-plugin-jsdoc-rules-require-param-type-options-31-contexts-10"></a>
1506315160
<a name="eslint-plugin-jsdoc-rules-require-param-type-options-31-contexts-10"></a>
1506415161
##### <code>contexts</code>
@@ -15080,7 +15177,8 @@ section of our README for more on the expected format.
1508015177
|Tags|`param`|
1508115178
|Aliases|`arg`, `argument`|
1508215179
|Recommended|true|
15083-
|Options|`contexts`|
15180+
|Options|`setDefaultDestructuredRootType`, `defaultDestructuredRootType`, `contexts`|
15181+
|Settings|`exemptDestructuredRootsFromChecks`|
1508415182

1508515183
The following patterns are considered problems:
1508615184

@@ -15140,6 +15238,39 @@ function quux (foo) {
1514015238
}
1514115239
// Settings: {"jsdoc":{"tagNamePreference":{"param":false}}}
1514215240
// Message: Unexpected tag `@param`
15241+
15242+
/**
15243+
* @param {number} foo
15244+
* @param root
15245+
* @param {boolean} baz
15246+
*/
15247+
function quux (foo, {bar}, baz) {
15248+
15249+
}
15250+
// "jsdoc/require-param-type": ["error"|"warn", {"setDefaultDestructuredRootType":true}]
15251+
// Message: Missing root type for @param.
15252+
15253+
/**
15254+
* @param {number} foo
15255+
* @param root
15256+
* @param {boolean} baz
15257+
*/
15258+
function quux (foo, {bar}, baz) {
15259+
15260+
}
15261+
// "jsdoc/require-param-type": ["error"|"warn", {"defaultDestructuredRootType":"Object","setDefaultDestructuredRootType":true}]
15262+
// Message: Missing root type for @param.
15263+
15264+
/**
15265+
* @param {number} foo
15266+
* @param root
15267+
* @param {boolean} baz
15268+
*/
15269+
function quux (foo, {bar}, baz) {
15270+
15271+
}
15272+
// "jsdoc/require-param-type": ["error"|"warn", {"setDefaultDestructuredRootType":false}]
15273+
// Message: Missing JSDoc @param "root" type.
1514315274
````
1514415275

1514515276
The following patterns are not considered problems:
@@ -15176,6 +15307,26 @@ function quux (foo) {
1517615307
* @callback
1517715308
* @param foo
1517815309
*/
15310+
15311+
/**
15312+
* @param {number} foo
15313+
* @param root
15314+
* @param {boolean} baz
15315+
*/
15316+
function quux (foo, {bar}, baz) {
15317+
15318+
}
15319+
// Settings: {"jsdoc":{"exemptDestructuredRootsFromChecks":true}}
15320+
15321+
/**
15322+
* @param {number} foo
15323+
* @param root
15324+
* @param root.bar
15325+
*/
15326+
function quux (foo, {bar: {baz}}) {
15327+
15328+
}
15329+
// Settings: {"jsdoc":{"exemptDestructuredRootsFromChecks":true}}
1517915330
````
1518015331

1518115332

src/iterateJsdoc.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -818,6 +818,9 @@ const getSettings = (context) => {
818818
implementsReplacesDocs: context.settings.jsdoc?.implementsReplacesDocs,
819819
augmentsExtendsReplacesDocs: context.settings.jsdoc?.augmentsExtendsReplacesDocs,
820820

821+
// `require-param-type`, `require-param-description`
822+
exemptDestructuredRootsFromChecks: context.settings.jsdoc?.exemptDestructuredRootsFromChecks,
823+
821824
// Many rules, e.g., `check-tag-names`
822825
mode: context.settings.jsdoc?.mode ??
823826
(context.parserPath.includes('@typescript-eslint') ? 'typescript' : 'jsdoc'),

src/rules/requireParamDescription.js

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,38 @@
11
import iterateJsdoc from '../iterateJsdoc';
22

33
export default iterateJsdoc(({
4+
context,
45
report,
6+
settings,
57
utils,
68
}) => {
9+
const {
10+
defaultDestructuredRootDescription = 'The root object',
11+
setDefaultDestructuredRootDescription = false,
12+
} = context.options[0] || {};
13+
14+
const functionParameterNames = utils.getFunctionParameterNames();
15+
16+
let rootCount = -1;
717
utils.forEachPreferredTag('param', (jsdocParameter, targetTagName) => {
18+
rootCount += jsdocParameter.name.includes('.') ? 0 : 1;
819
if (!jsdocParameter.description.trim()) {
20+
if (Array.isArray(functionParameterNames[rootCount])) {
21+
if (settings.exemptDestructuredRootsFromChecks) {
22+
return;
23+
}
24+
25+
if (setDefaultDestructuredRootDescription) {
26+
utils.reportJSDoc(`Missing root description for @${targetTagName}.`, jsdocParameter, () => {
27+
utils.changeTag(jsdocParameter, {
28+
description: defaultDestructuredRootDescription,
29+
postName: ' ',
30+
});
31+
});
32+
return;
33+
}
34+
}
35+
936
report(
1037
`Missing JSDoc @${targetTagName} "${jsdocParameter.name}" description.`,
1138
null,
@@ -20,6 +47,7 @@ export default iterateJsdoc(({
2047
description: 'Requires that each `@param` tag has a `description` value.',
2148
url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-require-param-description',
2249
},
50+
fixable: 'code',
2351
schema: [
2452
{
2553
additionalProperties: false,
@@ -46,6 +74,12 @@ export default iterateJsdoc(({
4674
},
4775
type: 'array',
4876
},
77+
defaultDestructuredRootDescription: {
78+
type: 'string',
79+
},
80+
setDefaultDestructuredRootDescription: {
81+
type: 'boolean',
82+
},
4983
},
5084
type: 'object',
5185
},

0 commit comments

Comments
 (0)