Skip to content

Commit 5b0ba6c

Browse files
committed
feat(check-types, no-undefined-types, valid-types): With settings.jsdoc.mode, only expect types on certain tags if in "closure" mode
1 parent 71c189d commit 5b0ba6c

File tree

11 files changed

+86
-27
lines changed

11 files changed

+86
-27
lines changed

.README/README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,9 @@ You can then selectively add to or override the recommended rules.
9292

9393
- `settings.jsdoc.mode` - Set to `jsdoc` (the default), `typescript`, or `closure`.
9494
Currently is used for checking preferred tag names and in the `check-tag-names`
95-
rule.
95+
rule. For type-checking rules, the setting also determines which tags will be
96+
checked for types (Closure allows types on some tags which the others do not,
97+
so these tags will additionally be checked in "closure" mode).
9698

9799
### Alias Preference
98100

.README/rules/check-types.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,6 @@ String | **string** | **string** | `("test") instanceof String` -> **`false`**
8989
|Aliases|`constructor`, `const`, `extends`, `var`, `arg`, `argument`, `prop`, `return`, `exception`, `yield`|
9090
|Closure-only|`package`, `private`, `protected`, `public`, `static`|
9191
|Options|`noDefaults`, `unifyParentAndChildTypeChecks`|
92-
|Settings|`preferredTypes`|
92+
|Settings|`preferredTypes`, `mode`|
9393

9494
<!-- assertions checkTypes -->

.README/rules/no-undefined-types.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ the tag types in the table below:
1313

1414
`@callback`, `@class` (or `@constructor`), `@constant` (or `@const`), `@event`, `@external` (or `@host`), `@function` (or `@func` or `@method`), `@interface`, `@member` (or `@var`), `@mixin`, `@name`, `@namespace`, `@template` (for Closure/TypeScript), `@typedef`.
1515

16+
The following tags will also be checked but only when the mode is `closure`:
17+
18+
`@package`, `@private`, `@protected`, `@public`, `@static`
19+
1620
The following types are always considered defined.
1721

1822
- `null`, `undefined`, `void`, `string`, `boolean`, `object`, `function`
@@ -38,6 +42,6 @@ An option object may have the following key:
3842
|Aliases|`constructor`, `const`, `extends`, `var`, `arg`, `argument`, `prop`, `return`, `exception`, `yield`|
3943
|Closure-only|`package`, `private`, `protected`, `public`, `static`|
4044
|Options|`definedTypes`|
41-
|Settings|`preferredTypes`|
45+
|Settings|`preferredTypes`, `mode`|
4246

4347
<!-- assertions noUndefinedTypes -->

.README/rules/valid-types.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,5 +54,6 @@ Also impacts behaviors on namepath (or event)-defining and pointing tags:
5454
|Aliases|`extends`, `constructor`, `const`, `host`, `emits`, `func`, `method`, `var`, `arg`, `argument`, `prop`, `return`, `exception`, `yield`|
5555
|Closure-only|For type only: `package`, `private`, `protected`, `public`, `static`|
5656
|Options|`allowEmptyNamepaths`, `checkSeesForNamepaths`|
57+
|Settings|`mode`|
5758

5859
<!-- assertions validTypes -->

README.md

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,9 @@ You can then selectively add to or override the recommended rules.
134134

135135
- `settings.jsdoc.mode` - Set to `jsdoc` (the default), `typescript`, or `closure`.
136136
Currently is used for checking preferred tag names and in the `check-tag-names`
137-
rule.
137+
rule. For type-checking rules, the setting also determines which tags will be
138+
checked for types (Closure allows types on some tags which the others do not,
139+
so these tags will additionally be checked in "closure" mode).
138140

139141
<a name="eslint-plugin-jsdoc-settings-alias-preference"></a>
140142
### Alias Preference
@@ -2197,7 +2199,7 @@ String | **string** | **string** | `("test") instanceof String` -> **`false`**
21972199
|Aliases|`constructor`, `const`, `extends`, `var`, `arg`, `argument`, `prop`, `return`, `exception`, `yield`|
21982200
|Closure-only|`package`, `private`, `protected`, `public`, `static`|
21992201
|Options|`noDefaults`, `unifyParentAndChildTypeChecks`|
2200-
|Settings|`preferredTypes`|
2202+
|Settings|`preferredTypes`, `mode`|
22012203

22022204
The following patterns are considered problems:
22032205

@@ -3896,6 +3898,10 @@ the tag types in the table below:
38963898

38973899
`@callback`, `@class` (or `@constructor`), `@constant` (or `@const`), `@event`, `@external` (or `@host`), `@function` (or `@func` or `@method`), `@interface`, `@member` (or `@var`), `@mixin`, `@name`, `@namespace`, `@template` (for Closure/TypeScript), `@typedef`.
38983900

3901+
The following tags will also be checked but only when the mode is `closure`:
3902+
3903+
`@package`, `@private`, `@protected`, `@public`, `@static`
3904+
38993905
The following types are always considered defined.
39003906

39013907
- `null`, `undefined`, `void`, `string`, `boolean`, `object`, `function`
@@ -3922,7 +3928,7 @@ An option object may have the following key:
39223928
|Aliases|`constructor`, `const`, `extends`, `var`, `arg`, `argument`, `prop`, `return`, `exception`, `yield`|
39233929
|Closure-only|`package`, `private`, `protected`, `public`, `static`|
39243930
|Options|`definedTypes`|
3925-
|Settings|`preferredTypes`|
3931+
|Settings|`preferredTypes`, `mode`|
39263932

39273933
The following patterns are considered problems:
39283934

@@ -8039,6 +8045,7 @@ Also impacts behaviors on namepath (or event)-defining and pointing tags:
80398045
|Aliases|`extends`, `constructor`, `const`, `host`, `emits`, `func`, `method`, `var`, `arg`, `argument`, `prop`, `return`, `exception`, `yield`|
80408046
|Closure-only|For type only: `package`, `private`, `protected`, `public`, `static`|
80418047
|Options|`allowEmptyNamepaths`, `checkSeesForNamepaths`|
8048+
|Settings|`mode`|
80428049

80438050
The following patterns are considered problems:
80448051

@@ -8171,6 +8178,13 @@ function quux() {
81718178
*/
81728179
function quux (foo, bar, baz) {}
81738180
// Message: Syntax error in type: bar|foo<
8181+
8182+
/**
8183+
* @private {BadTypeChecked<}
8184+
*/
8185+
function quux () {}
8186+
// Settings: {"jsdoc":{"mode":"closure"}}
8187+
// Message: Syntax error in type: BadTypeChecked<
81748188
````
81758189

81768190
The following patterns are not considered problems:
@@ -8317,6 +8331,11 @@ let UserDefinedGCCType;
83178331
* @modifies {foo|bar}
83188332
*/
83198333
function quux (foo, bar, baz) {}
8334+
8335+
/**
8336+
* @private {BadTypeNotCheckedInJsdoc<}
8337+
*/
8338+
function quux () {}
83208339
````
83218340

83228341

src/iterateJsdoc.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ const getUtils = (
200200
};
201201

202202
utils.tagMightHaveEitherTypeOrNamepath = (tagName) => {
203-
return jsdocUtils.tagMightHaveEitherTypeOrNamepath(tagName);
203+
return jsdocUtils.tagMightHaveEitherTypeOrNamepath(mode, tagName);
204204
};
205205

206206
utils.tagMustHaveNamepath = (tagName) => {
@@ -215,8 +215,8 @@ const getUtils = (
215215
return jsdocUtils.tagMustHaveType(tagName);
216216
};
217217

218-
utils.tagMightHaveType = (tagName) => {
219-
return jsdocUtils.tagMightHaveType(tagName);
218+
utils.tagMightHaveAType = (tagName) => {
219+
return jsdocUtils.tagMightHaveAType(mode, tagName);
220220
};
221221

222222
utils.isNamepathDefiningTag = (tagName) => {

src/jsdocUtils.js

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,15 @@ const tagsWithOptionalType = [
219219
'throws', 'exception',
220220
'yields', 'yield',
221221

222-
// Todo: Omit these GCC specific items when in non-GCC mode after landing https://github.com/gajus/eslint-plugin-jsdoc/issues/356
222+
// Has no documentation, but test example has curly brackets, and
223+
// "name" would be suggested rather than "namepath" based on example; not
224+
// sure if name is required
225+
'modifies',
226+
];
227+
228+
const tagsWithOptionalTypeClosure = [
229+
...tagsWithOptionalType,
230+
223231
// Shows the signature with curly brackets but not in the example
224232
// "typeExpression"
225233
'package',
@@ -229,11 +237,6 @@ const tagsWithOptionalType = [
229237
// These do not show a signature nor show curly brackets in the example
230238
'public',
231239
'static',
232-
233-
// Has no documentation, but test example has curly brackets, and
234-
// "name" would be suggested rather than "namepath" based on example; not
235-
// sure if name is required
236-
'modifies',
237240
];
238241

239242
// None of these show as having curly brackets for their name/namepath
@@ -327,8 +330,10 @@ const isNamepathDefiningTag = (tagName) => {
327330
return namepathDefiningTags.includes(tagName);
328331
};
329332

330-
const tagMightHaveType = (tag) => {
331-
return tagsWithMandatoryType.includes(tag) || tagsWithOptionalType.includes(tag);
333+
const tagMightHaveAType = (mode, tag) => {
334+
return tagsWithMandatoryType.includes(tag) || (mode === 'closure' ?
335+
tagsWithOptionalTypeClosure.includes(tag) :
336+
tagsWithOptionalType.includes(tag));
332337
};
333338

334339
const tagMustHaveType = (tag) => {
@@ -343,8 +348,8 @@ const tagMustHaveNamepath = (tag) => {
343348
return tagsWithMandatoryNamepath.includes(tag);
344349
};
345350

346-
const tagMightHaveEitherTypeOrNamepath = (tag) => {
347-
return tagMightHaveType(tag) || tagMightHaveNamepath(tag);
351+
const tagMightHaveEitherTypeOrNamepath = (mode, tag) => {
352+
return tagMightHaveAType(mode, tag) || tagMightHaveNamepath(tag);
348353
};
349354

350355
const tagMustHaveEitherTypeOrNamepath = (tag) => {
@@ -535,9 +540,9 @@ export default {
535540
isNamepathDefiningTag,
536541
isValidTag,
537542
parseClosureTemplateTag,
543+
tagMightHaveAType,
538544
tagMightHaveEitherTypeOrNamepath,
539545
tagMightHaveNamepath,
540-
tagMightHaveType,
541546
tagMustHaveEitherTypeOrNamepath,
542547
tagMustHaveNamepath,
543548
tagMustHaveType,

src/rules/checkTypes.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,16 +25,16 @@ export default iterateJsdoc(({
2525
settings,
2626
context,
2727
}) => {
28-
const jsdocTags = utils.filterTags((tag) => {
29-
return utils.tagMightHaveType(tag.tag);
28+
const jsdocTagsWithPossibleType = utils.filterTags((tag) => {
29+
return utils.tagMightHaveAType(tag.tag);
3030
});
3131

3232
const {preferredTypes} = settings;
3333
const optionObj = context.options[0];
3434
const noDefaults = _.get(optionObj, 'noDefaults');
3535
const unifyParentAndChildTypeChecks = _.get(optionObj, 'unifyParentAndChildTypeChecks');
3636

37-
jsdocTags.forEach((jsdocTag) => {
37+
jsdocTagsWithPossibleType.forEach((jsdocTag) => {
3838
const invalidTypes = [];
3939
let typeAst;
4040

src/rules/noUndefinedTypes.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -105,11 +105,11 @@ export default iterateJsdoc(({
105105
.concat(definedPreferredTypes)
106106
.concat(closureGenericTypes);
107107

108-
const jsdocTags = utils.filterTags((tag) => {
109-
return utils.tagMightHaveType(tag.tag);
108+
const jsdocTagsWithPossibleType = utils.filterTags((tag) => {
109+
return utils.tagMightHaveAType(tag.tag);
110110
});
111111

112-
jsdocTags.forEach((tag) => {
112+
jsdocTagsWithPossibleType.forEach((tag) => {
113113
let parsedType;
114114

115115
try {

src/rules/validTypes.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ export default iterateJsdoc(({
7373
return true;
7474
};
7575

76-
const hasType = utils.tagMightHaveType(tag.tag) && Boolean(tag.type);
76+
const hasType = utils.tagMightHaveAType(tag.tag) && Boolean(tag.type);
7777
const mustHaveType = utils.tagMustHaveType(tag.tag);
7878

7979
const hasNamePath = utils.tagMightHaveNamepath(tag.tag) && Boolean(tag.name) && !(tag.tag === 'see' && !checkSeesForNamepaths);

test/rules/assertions/validTypes.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,25 @@ export default {
267267
},
268268
],
269269
},
270+
{
271+
code: `
272+
/**
273+
* @private {BadTypeChecked<}
274+
*/
275+
function quux () {}
276+
277+
`,
278+
errors: [
279+
{
280+
message: 'Syntax error in type: BadTypeChecked<',
281+
},
282+
],
283+
settings: {
284+
jsdoc: {
285+
mode: 'closure',
286+
},
287+
},
288+
},
270289
],
271290
valid: [
272291
{
@@ -481,5 +500,14 @@ export default {
481500
function quux (foo, bar, baz) {}
482501
`,
483502
},
503+
{
504+
code: `
505+
/**
506+
* @private {BadTypeNotCheckedInJsdoc<}
507+
*/
508+
function quux () {}
509+
510+
`,
511+
},
484512
],
485513
};

0 commit comments

Comments
 (0)