Skip to content

Commit 7beadb6

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 9389932 commit 7beadb6

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
@@ -2173,7 +2175,7 @@ String | **string** | **string** | `("test") instanceof String` -> **`false`**
21732175
|Aliases|`constructor`, `const`, `extends`, `var`, `arg`, `argument`, `prop`, `return`, `exception`, `yield`|
21742176
|Closure-only|`package`, `private`, `protected`, `public`, `static`|
21752177
|Options|`noDefaults`, `unifyParentAndChildTypeChecks`|
2176-
|Settings|`preferredTypes`|
2178+
|Settings|`preferredTypes`, `mode`|
21772179

21782180
The following patterns are considered problems:
21792181

@@ -3872,6 +3874,10 @@ the tag types in the table below:
38723874

38733875
`@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`.
38743876

3877+
The following tags will also be checked but only when the mode is `closure`:
3878+
3879+
`@package`, `@private`, `@protected`, `@public`, `@static`
3880+
38753881
The following types are always considered defined.
38763882

38773883
- `null`, `undefined`, `void`, `string`, `boolean`, `object`, `function`
@@ -3898,7 +3904,7 @@ An option object may have the following key:
38983904
|Aliases|`constructor`, `const`, `extends`, `var`, `arg`, `argument`, `prop`, `return`, `exception`, `yield`|
38993905
|Closure-only|`package`, `private`, `protected`, `public`, `static`|
39003906
|Options|`definedTypes`|
3901-
|Settings|`preferredTypes`|
3907+
|Settings|`preferredTypes`, `mode`|
39023908

39033909
The following patterns are considered problems:
39043910

@@ -8015,6 +8021,7 @@ Also impacts behaviors on namepath (or event)-defining and pointing tags:
80158021
|Aliases|`extends`, `constructor`, `const`, `host`, `emits`, `func`, `method`, `var`, `arg`, `argument`, `prop`, `return`, `exception`, `yield`|
80168022
|Closure-only|For type only: `package`, `private`, `protected`, `public`, `static`|
80178023
|Options|`allowEmptyNamepaths`, `checkSeesForNamepaths`|
8024+
|Settings|`mode`|
80188025

80198026
The following patterns are considered problems:
80208027

@@ -8147,6 +8154,13 @@ function quux() {
81478154
*/
81488155
function quux (foo, bar, baz) {}
81498156
// Message: Syntax error in type: bar|foo<
8157+
8158+
/**
8159+
* @private {BadTypeChecked<}
8160+
*/
8161+
function quux () {}
8162+
// Settings: {"jsdoc":{"mode":"closure"}}
8163+
// Message: Syntax error in type: BadTypeChecked<
81508164
````
81518165

81528166
The following patterns are not considered problems:
@@ -8293,6 +8307,11 @@ let UserDefinedGCCType;
82938307
* @modifies {foo|bar}
82948308
*/
82958309
function quux (foo, bar, baz) {}
8310+
8311+
/**
8312+
* @private {BadTypeNotCheckedInJsdoc<}
8313+
*/
8314+
function quux () {}
82968315
````
82978316

82988317

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)