Skip to content

Commit 492b814

Browse files
committed
feat(check-property-names): add rule to check for duplicated and improperly nested properties
BREAKING CHANGE: Adds new rule to `recommended`
1 parent e5f2a23 commit 492b814

File tree

11 files changed

+497
-63
lines changed

11 files changed

+497
-63
lines changed

.README/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,7 @@ only (e.g., to match `Array` if the type is `Array` vs. `Array.<string>`).
332332
{"gitdown": "include", "file": "./rules/check-examples.md"}
333333
{"gitdown": "include", "file": "./rules/check-indentation.md"}
334334
{"gitdown": "include", "file": "./rules/check-param-names.md"}
335+
{"gitdown": "include", "file": "./rules/check-property-names.md"}
335336
{"gitdown": "include", "file": "./rules/check-syntax.md"}
336337
{"gitdown": "include", "file": "./rules/check-tag-names.md"}
337338
{"gitdown": "include", "file": "./rules/check-types.md"}

.README/rules/check-property-names.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
### `check-property-names`
2+
3+
Ensures that property names in JSDoc are not duplicated on the same block
4+
and that nested properties have defined roots.
5+
6+
#### Options
7+
8+
|||
9+
|---|---|
10+
|Context|Everywhere|
11+
|Tags|`property`|
12+
13+
<!-- assertions checkPropertyNames -->

README.md

Lines changed: 145 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ JSDoc linting rules for ESLint.
2424
* [`check-examples`](#eslint-plugin-jsdoc-rules-check-examples)
2525
* [`check-indentation`](#eslint-plugin-jsdoc-rules-check-indentation)
2626
* [`check-param-names`](#eslint-plugin-jsdoc-rules-check-param-names)
27+
* [`check-property-names`](#eslint-plugin-jsdoc-rules-check-property-names)
2728
* [`check-syntax`](#eslint-plugin-jsdoc-rules-check-syntax)
2829
* [`check-tag-names`](#eslint-plugin-jsdoc-rules-check-tag-names)
2930
* [`check-types`](#eslint-plugin-jsdoc-rules-check-types)
@@ -1728,6 +1729,121 @@ function quux ({
17281729

17291730
Likewise for the pattern `[a, b]` which is an [`ArrayPattern`](https://github.com/estree/estree/blob/master/es2015.md#arraypattern).
17301731

1732+
<a name="eslint-plugin-jsdoc-rules-check-property-names"></a>
1733+
### <code>check-property-names</code>
1734+
1735+
Ensures that property names in JSDoc are not duplicated on the same block
1736+
and that nested properties have defined roots.
1737+
1738+
<a name="eslint-plugin-jsdoc-rules-check-property-names-options-4"></a>
1739+
#### Options
1740+
1741+
|||
1742+
|---|---|
1743+
|Context|Everywhere|
1744+
|Tags|`property`|
1745+
1746+
The following patterns are considered problems:
1747+
1748+
````js
1749+
/**
1750+
* @typedef (SomeType) SomeTypedef
1751+
* @property Foo.Bar
1752+
*/
1753+
// Message: @property path declaration ("Foo.Bar") appears before any real property.
1754+
1755+
/**
1756+
* @typedef (SomeType) SomeTypedef
1757+
* @property foo
1758+
* @property Foo.Bar
1759+
*/
1760+
// Message: @property path declaration ("Foo.Bar") root node name ("Foo") does not match previous real property name ("foo").
1761+
1762+
/**
1763+
* @typedef (SomeType) SomeTypedef
1764+
* @property foo
1765+
* @property foo
1766+
*/
1767+
// Message: Duplicate @property "foo"
1768+
1769+
/**
1770+
* @typedef (SomeType) SomeTypedef
1771+
* @prop foo
1772+
* @prop foo
1773+
*/
1774+
// Settings: {"jsdoc":{"tagNamePreference":{"property":"prop"}}}
1775+
// Message: Duplicate @prop "foo"
1776+
1777+
/**
1778+
* @typedef (SomeType) SomeTypedef
1779+
* @property foo
1780+
*/
1781+
// Settings: {"jsdoc":{"tagNamePreference":{"property":false}}}
1782+
// Message: Unexpected tag `@property`
1783+
````
1784+
1785+
The following patterns are not considered problems:
1786+
1787+
````js
1788+
/**
1789+
*
1790+
*/
1791+
1792+
/**
1793+
* @typedef (SomeType) SomeTypedef
1794+
* @property foo
1795+
*/
1796+
1797+
/**
1798+
* @typedef (SomeType) SomeTypedef
1799+
* @prop foo
1800+
*/
1801+
1802+
/**
1803+
* @typedef (SomeType) SomeTypedef
1804+
* @property foo
1805+
* @property bar
1806+
*/
1807+
1808+
/**
1809+
* @typedef (SomeType) SomeTypedef
1810+
* @property foo
1811+
* @property foo.foo
1812+
* @property bar
1813+
*/
1814+
1815+
/**
1816+
* Assign the project to a list of employees.
1817+
* @typedef (SomeType) SomeTypedef
1818+
* @property {object[]} employees - The employees who are responsible for the project.
1819+
* @property {string} employees[].name - The name of an employee.
1820+
* @property {string} employees[].department - The employee's department.
1821+
*/
1822+
1823+
/**
1824+
* @typedef (SomeType) SomeTypedef
1825+
* @property {Error} error Exit code
1826+
* @property {number} [code = 1] Exit code
1827+
*/
1828+
1829+
/**
1830+
* @namespace (SomeType) SomeNamespace
1831+
* @property {Error} error Exit code
1832+
* @property {number} [code = 1] Exit code
1833+
*/
1834+
1835+
/**
1836+
* @class
1837+
* @property {Error} error Exit code
1838+
* @property {number} [code = 1] Exit code
1839+
*/
1840+
function quux (code = 1) {
1841+
this.error = new Error('oops');
1842+
this.code = code;
1843+
}
1844+
````
1845+
1846+
17311847
<a name="eslint-plugin-jsdoc-rules-check-syntax"></a>
17321848
### <code>check-syntax</code>
17331849

@@ -1926,10 +2042,10 @@ wizaction
19262042

19272043
Note that the tags indicated as replacements in `settings.jsdoc.tagNamePreference` will automatically be considered as valid.
19282044

1929-
<a name="eslint-plugin-jsdoc-rules-check-tag-names-options-4"></a>
2045+
<a name="eslint-plugin-jsdoc-rules-check-tag-names-options-5"></a>
19302046
#### Options
19312047

1932-
<a name="eslint-plugin-jsdoc-rules-check-tag-names-options-4-definedtags"></a>
2048+
<a name="eslint-plugin-jsdoc-rules-check-tag-names-options-5-definedtags"></a>
19332049
##### <code>definedTags</code>
19342050

19352051
Use an array of `definedTags` strings to configure additional, allowed tags.
@@ -2529,7 +2645,7 @@ Date
25292645
RegExp
25302646
```
25312647

2532-
<a name="eslint-plugin-jsdoc-rules-check-types-options-5"></a>
2648+
<a name="eslint-plugin-jsdoc-rules-check-types-options-6"></a>
25332649
#### Options
25342650

25352651
`check-types` allows one option:
@@ -3416,22 +3532,22 @@ This rule checks the values for a handful of tags:
34163532
`allowedAuthors` is present, ensure that the author value is one
34173533
of these array items.
34183534

3419-
<a name="eslint-plugin-jsdoc-rules-check-values-options-6"></a>
3535+
<a name="eslint-plugin-jsdoc-rules-check-values-options-7"></a>
34203536
#### Options
34213537

3422-
<a name="eslint-plugin-jsdoc-rules-check-values-options-6-allowedauthors"></a>
3538+
<a name="eslint-plugin-jsdoc-rules-check-values-options-7-allowedauthors"></a>
34233539
##### <code>allowedAuthors</code>
34243540

34253541
An array of allowable author values. If absent, only non-whitespace will
34263542
be checked for.
34273543

3428-
<a name="eslint-plugin-jsdoc-rules-check-values-options-6-allowedlicenses"></a>
3544+
<a name="eslint-plugin-jsdoc-rules-check-values-options-7-allowedlicenses"></a>
34293545
##### <code>allowedLicenses</code>
34303546

34313547
An array of allowable license values or `true` to allow any license text.
34323548
If present as an array, will be used in place of SPDX identifiers.
34333549

3434-
<a name="eslint-plugin-jsdoc-rules-check-values-options-6-licensepattern"></a>
3550+
<a name="eslint-plugin-jsdoc-rules-check-values-options-7-licensepattern"></a>
34353551
##### <code>licensePattern</code>
34363552

34373553
A string to be converted into a `RegExp` (with `u` flag) and whose first
@@ -3664,10 +3780,10 @@ Note that `@private` will still be checked for content by this rule even with
36643780
`settings.jsdoc.ignorePrivate` set to `true` (a setting which normally
36653781
causes rules not to take effect).
36663782
3667-
<a name="eslint-plugin-jsdoc-rules-empty-tags-options-7"></a>
3783+
<a name="eslint-plugin-jsdoc-rules-empty-tags-options-8"></a>
36683784
#### Options
36693785
3670-
<a name="eslint-plugin-jsdoc-rules-empty-tags-options-7-tags"></a>
3786+
<a name="eslint-plugin-jsdoc-rules-empty-tags-options-8-tags"></a>
36713787
##### <code>tags</code>
36723788
36733789
If you want additional tags to be checked for their descriptions, you may
@@ -3895,10 +4011,10 @@ by our supported Node versions):
38954011
Applies to the jsdoc block description and `@description` (or `@desc`)
38964012
by default but the `tags` option (see below) may be used to match other tags.
38974013
3898-
<a name="eslint-plugin-jsdoc-rules-match-description-options-8"></a>
4014+
<a name="eslint-plugin-jsdoc-rules-match-description-options-9"></a>
38994015
#### Options
39004016
3901-
<a name="eslint-plugin-jsdoc-rules-match-description-options-8-matchdescription"></a>
4017+
<a name="eslint-plugin-jsdoc-rules-match-description-options-9-matchdescription"></a>
39024018
##### <code>matchDescription</code>
39034019
39044020
You can supply your own expression to override the default, passing a
@@ -3913,7 +4029,7 @@ You can supply your own expression to override the default, passing a
39134029
As with the default, the supplied regular expression will be applied with the
39144030
Unicode (`"u"`) flag and is *not* case-insensitive.
39154031
3916-
<a name="eslint-plugin-jsdoc-rules-match-description-options-8-tags-1"></a>
4032+
<a name="eslint-plugin-jsdoc-rules-match-description-options-9-tags-1"></a>
39174033
##### <code>tags</code>
39184034
39194035
If you want different regular expressions to apply to tags, you may use
@@ -3950,7 +4066,7 @@ its "description" (e.g., for `@returns {someType} some description`, the
39504066
description is `some description` while for `@some-tag xyz`, the description
39514067
is `xyz`).
39524068
3953-
<a name="eslint-plugin-jsdoc-rules-match-description-options-8-maindescription"></a>
4069+
<a name="eslint-plugin-jsdoc-rules-match-description-options-9-maindescription"></a>
39544070
##### <code>mainDescription</code>
39554071
39564072
If you wish to override the main function description without changing the
@@ -3972,7 +4088,7 @@ There is no need to add `mainDescription: true`, as by default, the main
39724088
function (and only the main function) is linted, though you may disable checking
39734089
it by setting it to `false`.
39744090
3975-
<a name="eslint-plugin-jsdoc-rules-match-description-options-8-contexts"></a>
4091+
<a name="eslint-plugin-jsdoc-rules-match-description-options-9-contexts"></a>
39764092
##### <code>contexts</code>
39774093
39784094
Set this to an array of strings representing the AST context
@@ -4616,7 +4732,7 @@ function quux () {
46164732
46174733
Enforces a consistent padding of the block description.
46184734
4619-
<a name="eslint-plugin-jsdoc-rules-newline-after-description-options-9"></a>
4735+
<a name="eslint-plugin-jsdoc-rules-newline-after-description-options-10"></a>
46204736
#### Options
46214737
46224738
This rule allows one optional string argument. If it is `"always"` then a problem is raised when there is no newline after the description. If it is `"never"` then a problem is raised when there is a newline after the description. The default value is `"always"`.
@@ -4887,7 +5003,7 @@ The following types are always considered defined.
48875003
Note that preferred types indicated within `settings.jsdoc.preferredTypes` will
48885004
also be assumed to be defined.
48895005
4890-
<a name="eslint-plugin-jsdoc-rules-no-undefined-types-options-10"></a>
5006+
<a name="eslint-plugin-jsdoc-rules-no-undefined-types-options-11"></a>
48915007
#### Options
48925008
48935009
An option object may have the following key:
@@ -5316,10 +5432,10 @@ tag descriptions are written in complete sentences, i.e.,
53165432
* Periods after items within the `abbreviations` option array are not treated
53175433
as sentence endings.
53185434
5319-
<a name="eslint-plugin-jsdoc-rules-require-description-complete-sentence-options-11"></a>
5435+
<a name="eslint-plugin-jsdoc-rules-require-description-complete-sentence-options-12"></a>
53205436
#### Options
53215437
5322-
<a name="eslint-plugin-jsdoc-rules-require-description-complete-sentence-options-11-tags-2"></a>
5438+
<a name="eslint-plugin-jsdoc-rules-require-description-complete-sentence-options-12-tags-2"></a>
53235439
##### <code>tags</code>
53245440
53255441
If you want additional tags to be checked for their descriptions, you may
@@ -5341,7 +5457,7 @@ its "description" (e.g., for `@returns {someType} some description`, the
53415457
description is `some description` while for `@some-tag xyz`, the description
53425458
is `xyz`).
53435459
5344-
<a name="eslint-plugin-jsdoc-rules-require-description-complete-sentence-options-11-abbreviations"></a>
5460+
<a name="eslint-plugin-jsdoc-rules-require-description-complete-sentence-options-12-abbreviations"></a>
53455461
##### <code>abbreviations</code>
53465462
53475463
You can provide an `abbreviations` options array to avoid such strings of text
@@ -5973,7 +6089,7 @@ Requires that all functions have a description.
59736089
`"tag"`) must have a non-empty description that explains the purpose of the
59746090
method.
59756091
5976-
<a name="eslint-plugin-jsdoc-rules-require-description-options-12"></a>
6092+
<a name="eslint-plugin-jsdoc-rules-require-description-options-13"></a>
59776093
#### Options
59786094
59796095
An options object may have any of the following properties:
@@ -6269,25 +6385,25 @@ Requires that all functions have examples.
62696385
* All functions must have one or more `@example` tags.
62706386
* Every example tag must have a non-empty description that explains the method's usage.
62716387
6272-
<a name="eslint-plugin-jsdoc-rules-require-example-options-13"></a>
6388+
<a name="eslint-plugin-jsdoc-rules-require-example-options-14"></a>
62736389
#### Options
62746390
62756391
This rule has an object option.
62766392
6277-
<a name="eslint-plugin-jsdoc-rules-require-example-options-13-exemptedby"></a>
6393+
<a name="eslint-plugin-jsdoc-rules-require-example-options-14-exemptedby"></a>
62786394
##### <code>exemptedBy</code>
62796395
62806396
Array of tags (e.g., `['type']`) whose presence on the document
62816397
block avoids the need for an `@example`. Defaults to an empty array.
62826398
6283-
<a name="eslint-plugin-jsdoc-rules-require-example-options-13-avoidexampleonconstructors"></a>
6399+
<a name="eslint-plugin-jsdoc-rules-require-example-options-14-avoidexampleonconstructors"></a>
62846400
##### <code>avoidExampleOnConstructors</code>
62856401
62866402
Set to `true` to avoid the need for an example on a constructor (whether
62876403
indicated as such by a jsdoc tag or by being within an ES6 `class`).
62886404
Defaults to `false`.
62896405
6290-
<a name="eslint-plugin-jsdoc-rules-require-example-options-13-contexts-1"></a>
6406+
<a name="eslint-plugin-jsdoc-rules-require-example-options-14-contexts-1"></a>
62916407
##### <code>contexts</code>
62926408
62936409
Set this to an array of strings representing the AST context
@@ -6612,7 +6728,7 @@ function quux () {
66126728
66136729
Requires a hyphen before the `@param` description.
66146730
6615-
<a name="eslint-plugin-jsdoc-rules-require-hyphen-before-param-description-options-14"></a>
6731+
<a name="eslint-plugin-jsdoc-rules-require-hyphen-before-param-description-options-15"></a>
66166732
#### Options
66176733
66186734
This rule takes one optional string argument. If it is `"always"` then a problem is raised when there is no hyphen before the description. If it is `"never"` then a problem is raised when there is a hyphen before the description. The default value is `"always"`.
@@ -6718,7 +6834,7 @@ function quux () {
67186834
Checks for presence of jsdoc comments, on class declarations as well as
67196835
functions.
67206836
6721-
<a name="eslint-plugin-jsdoc-rules-require-jsdoc-options-15"></a>
6837+
<a name="eslint-plugin-jsdoc-rules-require-jsdoc-options-16"></a>
67226838
#### Options
67236839
67246840
Accepts one optional options object with the following optional keys.
@@ -7919,7 +8035,7 @@ function quux (foo) {
79198035

79208036
Requires that all function parameters are documented.
79218037

7922-
<a name="eslint-plugin-jsdoc-rules-require-param-options-16"></a>
8038+
<a name="eslint-plugin-jsdoc-rules-require-param-options-17"></a>
79238039
#### Options
79248040

79258041
An options object accepts one optional property:
@@ -9308,7 +9424,7 @@ Requires returns are documented.
93089424

93099425
Will also report if multiple `@returns` tags are present.
93109426

9311-
<a name="eslint-plugin-jsdoc-rules-require-returns-options-17"></a>
9427+
<a name="eslint-plugin-jsdoc-rules-require-returns-options-18"></a>
93129428
#### Options
93139429

93149430
- `exemptedBy` - Array of tags (e.g., `['type']`) whose presence on the document
@@ -9810,7 +9926,7 @@ Also impacts behaviors on namepath (or event)-defining and pointing tags:
98109926
allow `#`, `.`, or `~` at the end (which is not allowed at the end of
98119927
normal paths).
98129928
9813-
<a name="eslint-plugin-jsdoc-rules-valid-types-options-18"></a>
9929+
<a name="eslint-plugin-jsdoc-rules-valid-types-options-19"></a>
98149930
#### Options
98159931
98169932
- `allowEmptyNamepaths` (default: true) - Set to `false` to disallow

0 commit comments

Comments
 (0)