Skip to content

Commit

Permalink
feat(require-param-type, require-param-description): add `exemptD…
Browse files Browse the repository at this point in the history
…estructuredRootsFromChecks` setting; fixes #752

Also:
- feat(`require-param-type`): add `setDefaultDestructuredRootType` and `defaultDestructuredRootType` options
- feat(`require-param-description`): add `setDefaultDestructuredRootDescription` and `defaultDestructuredRootDescription` options
  • Loading branch information
brettz9 committed Oct 29, 2022
1 parent 36f6f9c commit da1c85f
Show file tree
Hide file tree
Showing 8 changed files with 511 additions and 4 deletions.
21 changes: 20 additions & 1 deletion .README/rules/require-param-description.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,26 @@

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

Will exempt destructured roots and their children if
`settings.exemptDestructuredRootsFromChecks` is set to `true` (e.g.,
`@param {object} props` will be exempted from requiring a description given
`function someFunc ({child1, child2})`).

#### Options

##### `setDefaultDestructuredRootDescription`

Whether to set a default destructured root description. For example, you may
wish to avoid manually having to set the description for a `@param`
corresponding to a destructured root object as it should always be the same
type of object. Uses `defaultDestructuredRootDescription` for the description
string. Defaults to `false`.

##### `defaultDestructuredRootDescription`

The description string to set by default for destructured roots. Defaults to
"The root object".

##### `contexts`

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

<!-- assertions requireParamDescription -->
20 changes: 19 additions & 1 deletion .README/rules/require-param-type.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,25 @@

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

Will exempt destructured roots and their children if
`settings.exemptDestructuredRootsFromChecks` is set to `true` (e.g.,
`@param props` will be exempted from requiring a type given
`function someFunc ({child1, child2})`).

#### Options

##### `setDefaultDestructuredRootType`

Whether to set a default destructured root type. For example, you may wish
to avoid manually having to set the type for a `@param`
corresponding to a destructured root object as it is always going to be an
object. Uses `defaultDestructuredRootType` for the type string. Defaults to
`false`.

##### `defaultDestructuredRootType`

The type string to set by default for destructured roots. Defaults to "object".

##### `contexts`

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

<!-- assertions requireParamType -->
155 changes: 153 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14772,10 +14772,32 @@ class A {

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

Will exempt destructured roots and their children if
`settings.exemptDestructuredRootsFromChecks` is set to `true` (e.g.,
`@param {object} props` will be exempted from requiring a description given
`function someFunc ({child1, child2})`).

<a name="user-content-eslint-plugin-jsdoc-rules-require-param-description-options-29"></a>
<a name="eslint-plugin-jsdoc-rules-require-param-description-options-29"></a>
#### Options

<a name="user-content-eslint-plugin-jsdoc-rules-require-param-description-options-29-setdefaultdestructuredrootdescription"></a>
<a name="eslint-plugin-jsdoc-rules-require-param-description-options-29-setdefaultdestructuredrootdescription"></a>
##### <code>setDefaultDestructuredRootDescription</code>

Whether to set a default destructured root description. For example, you may
wish to avoid manually having to set the description for a `@param`
corresponding to a destructured root object as it should always be the same
type of object. Uses `defaultDestructuredRootDescription` for the description
string. Defaults to `false`.

<a name="user-content-eslint-plugin-jsdoc-rules-require-param-description-options-29-defaultdestructuredrootdescription"></a>
<a name="eslint-plugin-jsdoc-rules-require-param-description-options-29-defaultdestructuredrootdescription"></a>
##### <code>defaultDestructuredRootDescription</code>

The description string to set by default for destructured roots. Defaults to
"The root object".

<a name="user-content-eslint-plugin-jsdoc-rules-require-param-description-options-29-contexts-8"></a>
<a name="eslint-plugin-jsdoc-rules-require-param-description-options-29-contexts-8"></a>
##### <code>contexts</code>
Expand All @@ -14797,7 +14819,8 @@ section of our README for more on the expected format.
|Tags|`param`|
|Aliases|`arg`, `argument`|
|Recommended|true|
|Options|`contexts`|
|Options|`setDefaultDestructuredRootDescription`, `defaultDestructuredRootDescription`, `contexts`|
|Settings|`exemptDestructuredRootsFromChecks`|

The following patterns are considered problems:

Expand Down Expand Up @@ -14859,6 +14882,39 @@ function quux (foo) {
}
// "jsdoc/require-param-description": ["error"|"warn", {"contexts":[{"comment":"JsdocBlock:has(JsdocTag:not([name=props]))","context":"FunctionDeclaration"}]}]
// Message: Missing JSDoc @param "foo" description.

/**
* @param {number} foo Foo description
* @param {object} root
* @param {boolean} baz Baz description
*/
function quux (foo, {bar}, baz) {

}
// "jsdoc/require-param-description": ["error"|"warn", {"setDefaultDestructuredRootDescription":true}]
// Message: Missing root description for @param.

/**
* @param {number} foo Foo description
* @param {object} root
* @param {boolean} baz Baz description
*/
function quux (foo, {bar}, baz) {

}
// "jsdoc/require-param-description": ["error"|"warn", {"defaultDestructuredRootDescription":"Root description","setDefaultDestructuredRootDescription":true}]
// Message: Missing root description for @param.

/**
* @param {number} foo Foo description
* @param {object} root
* @param {boolean} baz Baz description
*/
function quux (foo, {bar}, baz) {

}
// "jsdoc/require-param-description": ["error"|"warn", {"setDefaultDestructuredRootDescription":false}]
// Message: Missing JSDoc @param "root" description.
````

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

}
// "jsdoc/require-param-description": ["error"|"warn", {"contexts":[{"comment":"JsdocBlock:has(JsdocTag:not([name=props]))","context":"FunctionDeclaration"}]}]

/**
* @param {number} foo Foo description
* @param {object} root
* @param {boolean} baz Baz description
*/
function quux (foo, {bar}, baz) {

}
// Settings: {"jsdoc":{"exemptDestructuredRootsFromChecks":true}}

/**
* @param {number} foo Foo description
* @param {object} root
* @param {object} root.bar
*/
function quux (foo, {bar: {baz}}) {

}
// Settings: {"jsdoc":{"exemptDestructuredRootsFromChecks":true}}
````


Expand Down Expand Up @@ -15055,10 +15131,31 @@ function example(cb) {

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

Will exempt destructured roots and their children if
`settings.exemptDestructuredRootsFromChecks` is set to `true` (e.g.,
`@param props` will be exempted from requiring a type given
`function someFunc ({child1, child2})`).

<a name="user-content-eslint-plugin-jsdoc-rules-require-param-type-options-31"></a>
<a name="eslint-plugin-jsdoc-rules-require-param-type-options-31"></a>
#### Options

<a name="user-content-eslint-plugin-jsdoc-rules-require-param-type-options-31-setdefaultdestructuredroottype"></a>
<a name="eslint-plugin-jsdoc-rules-require-param-type-options-31-setdefaultdestructuredroottype"></a>
##### <code>setDefaultDestructuredRootType</code>

Whether to set a default destructured root type. For example, you may wish
to avoid manually having to set the type for a `@param`
corresponding to a destructured root object as it is always going to be an
object. Uses `defaultDestructuredRootType` for the type string. Defaults to
`false`.

<a name="user-content-eslint-plugin-jsdoc-rules-require-param-type-options-31-defaultdestructuredroottype"></a>
<a name="eslint-plugin-jsdoc-rules-require-param-type-options-31-defaultdestructuredroottype"></a>
##### <code>defaultDestructuredRootType</code>

The type string to set by default for destructured roots. Defaults to "object".

<a name="user-content-eslint-plugin-jsdoc-rules-require-param-type-options-31-contexts-10"></a>
<a name="eslint-plugin-jsdoc-rules-require-param-type-options-31-contexts-10"></a>
##### <code>contexts</code>
Expand All @@ -15080,7 +15177,8 @@ section of our README for more on the expected format.
|Tags|`param`|
|Aliases|`arg`, `argument`|
|Recommended|true|
|Options|`contexts`|
|Options|`setDefaultDestructuredRootType`, `defaultDestructuredRootType`, `contexts`|
|Settings|`exemptDestructuredRootsFromChecks`|

The following patterns are considered problems:

Expand Down Expand Up @@ -15140,6 +15238,39 @@ function quux (foo) {
}
// Settings: {"jsdoc":{"tagNamePreference":{"param":false}}}
// Message: Unexpected tag `@param`

/**
* @param {number} foo
* @param root
* @param {boolean} baz
*/
function quux (foo, {bar}, baz) {

}
// "jsdoc/require-param-type": ["error"|"warn", {"setDefaultDestructuredRootType":true}]
// Message: Missing root type for @param.

/**
* @param {number} foo
* @param root
* @param {boolean} baz
*/
function quux (foo, {bar}, baz) {

}
// "jsdoc/require-param-type": ["error"|"warn", {"defaultDestructuredRootType":"Object","setDefaultDestructuredRootType":true}]
// Message: Missing root type for @param.

/**
* @param {number} foo
* @param root
* @param {boolean} baz
*/
function quux (foo, {bar}, baz) {

}
// "jsdoc/require-param-type": ["error"|"warn", {"setDefaultDestructuredRootType":false}]
// Message: Missing JSDoc @param "root" type.
````

The following patterns are not considered problems:
Expand Down Expand Up @@ -15176,6 +15307,26 @@ function quux (foo) {
* @callback
* @param foo
*/

/**
* @param {number} foo
* @param root
* @param {boolean} baz
*/
function quux (foo, {bar}, baz) {

}
// Settings: {"jsdoc":{"exemptDestructuredRootsFromChecks":true}}

/**
* @param {number} foo
* @param root
* @param root.bar
*/
function quux (foo, {bar: {baz}}) {

}
// Settings: {"jsdoc":{"exemptDestructuredRootsFromChecks":true}}
````


Expand Down
3 changes: 3 additions & 0 deletions src/iterateJsdoc.js
Original file line number Diff line number Diff line change
Expand Up @@ -818,6 +818,9 @@ const getSettings = (context) => {
implementsReplacesDocs: context.settings.jsdoc?.implementsReplacesDocs,
augmentsExtendsReplacesDocs: context.settings.jsdoc?.augmentsExtendsReplacesDocs,

// `require-param-type`, `require-param-description`
exemptDestructuredRootsFromChecks: context.settings.jsdoc?.exemptDestructuredRootsFromChecks,

// Many rules, e.g., `check-tag-names`
mode: context.settings.jsdoc?.mode ??
(context.parserPath.includes('@typescript-eslint') ? 'typescript' : 'jsdoc'),
Expand Down
34 changes: 34 additions & 0 deletions src/rules/requireParamDescription.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,38 @@
import iterateJsdoc from '../iterateJsdoc';

export default iterateJsdoc(({
context,
report,
settings,
utils,
}) => {
const {
defaultDestructuredRootDescription = 'The root object',
setDefaultDestructuredRootDescription = false,
} = context.options[0] || {};

const functionParameterNames = utils.getFunctionParameterNames();

let rootCount = -1;
utils.forEachPreferredTag('param', (jsdocParameter, targetTagName) => {
rootCount += jsdocParameter.name.includes('.') ? 0 : 1;
if (!jsdocParameter.description.trim()) {
if (Array.isArray(functionParameterNames[rootCount])) {
if (settings.exemptDestructuredRootsFromChecks) {
return;
}

if (setDefaultDestructuredRootDescription) {
utils.reportJSDoc(`Missing root description for @${targetTagName}.`, jsdocParameter, () => {
utils.changeTag(jsdocParameter, {
description: defaultDestructuredRootDescription,
postName: ' ',
});
});
return;
}
}

report(
`Missing JSDoc @${targetTagName} "${jsdocParameter.name}" description.`,
null,
Expand All @@ -20,6 +47,7 @@ export default iterateJsdoc(({
description: 'Requires that each `@param` tag has a `description` value.',
url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-require-param-description',
},
fixable: 'code',
schema: [
{
additionalProperties: false,
Expand All @@ -46,6 +74,12 @@ export default iterateJsdoc(({
},
type: 'array',
},
defaultDestructuredRootDescription: {
type: 'string',
},
setDefaultDestructuredRootDescription: {
type: 'boolean',
},
},
type: 'object',
},
Expand Down

0 comments on commit da1c85f

Please sign in to comment.