Skip to content

Commit

Permalink
feat(check-types, no-undefined-types, valid-types): with `setti…
Browse files Browse the repository at this point in the history
…ngs.jsdoc.mode`, only expect types on certain tags if in `"closure"` mode
  • Loading branch information
brettz9 committed Oct 29, 2019
1 parent fd36278 commit 42e8de2
Show file tree
Hide file tree
Showing 11 changed files with 86 additions and 27 deletions.
4 changes: 3 additions & 1 deletion .README/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,9 @@ You can then selectively add to or override the recommended rules.

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

### Alias Preference

Expand Down
2 changes: 1 addition & 1 deletion .README/rules/check-types.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,6 @@ String | **string** | **string** | `("test") instanceof String` -> **`false`**
|Aliases|`constructor`, `const`, `extends`, `var`, `arg`, `argument`, `prop`, `return`, `exception`, `yield`|
|Closure-only|`package`, `private`, `protected`, `public`, `static`|
|Options|`noDefaults`, `unifyParentAndChildTypeChecks`|
|Settings|`preferredTypes`|
|Settings|`preferredTypes`, `mode`|

<!-- assertions checkTypes -->
6 changes: 5 additions & 1 deletion .README/rules/no-undefined-types.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ the tag types in the table below:

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

The following tags will also be checked but only when the mode is `closure`:

`@package`, `@private`, `@protected`, `@public`, `@static`

The following types are always considered defined.

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

<!-- assertions noUndefinedTypes -->
1 change: 1 addition & 0 deletions .README/rules/valid-types.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,5 +54,6 @@ Also impacts behaviors on namepath (or event)-defining and pointing tags:
|Aliases|`extends`, `constructor`, `const`, `host`, `emits`, `func`, `method`, `var`, `arg`, `argument`, `prop`, `return`, `exception`, `yield`|
|Closure-only|For type only: `package`, `private`, `protected`, `public`, `static`|
|Options|`allowEmptyNamepaths`, `checkSeesForNamepaths`|
|Settings|`mode`|

<!-- assertions validTypes -->
25 changes: 22 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,9 @@ You can then selectively add to or override the recommended rules.

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

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

The following patterns are considered problems:

Expand Down Expand Up @@ -3896,6 +3898,10 @@ the tag types in the table below:

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

The following tags will also be checked but only when the mode is `closure`:

`@package`, `@private`, `@protected`, `@public`, `@static`

The following types are always considered defined.

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

The following patterns are considered problems:

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

The following patterns are considered problems:

Expand Down Expand Up @@ -8171,6 +8178,13 @@ function quux() {
*/
function quux (foo, bar, baz) {}
// Message: Syntax error in type: bar|foo<

/**
* @private {BadTypeChecked<}
*/
function quux () {}
// Settings: {"jsdoc":{"mode":"closure"}}
// Message: Syntax error in type: BadTypeChecked<
````

The following patterns are not considered problems:
Expand Down Expand Up @@ -8317,6 +8331,11 @@ let UserDefinedGCCType;
* @modifies {foo|bar}
*/
function quux (foo, bar, baz) {}

/**
* @private {BadTypeNotCheckedInJsdoc<}
*/
function quux () {}
````


6 changes: 3 additions & 3 deletions src/iterateJsdoc.js
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ const getUtils = (
};

utils.tagMightHaveEitherTypeOrNamepath = (tagName) => {
return jsdocUtils.tagMightHaveEitherTypeOrNamepath(tagName);
return jsdocUtils.tagMightHaveEitherTypeOrNamepath(mode, tagName);
};

utils.tagMustHaveNamepath = (tagName) => {
Expand All @@ -215,8 +215,8 @@ const getUtils = (
return jsdocUtils.tagMustHaveType(tagName);
};

utils.tagMightHaveType = (tagName) => {
return jsdocUtils.tagMightHaveType(tagName);
utils.tagMightHaveAType = (tagName) => {
return jsdocUtils.tagMightHaveAType(mode, tagName);
};

utils.isNamepathDefiningTag = (tagName) => {
Expand Down
27 changes: 16 additions & 11 deletions src/jsdocUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,15 @@ const tagsWithOptionalType = [
'throws', 'exception',
'yields', 'yield',

// Todo: Omit these GCC specific items when in non-GCC mode after landing https://github.com/gajus/eslint-plugin-jsdoc/issues/356
// Has no documentation, but test example has curly brackets, and
// "name" would be suggested rather than "namepath" based on example; not
// sure if name is required
'modifies',
];

const tagsWithOptionalTypeClosure = [
...tagsWithOptionalType,

// Shows the signature with curly brackets but not in the example
// "typeExpression"
'package',
Expand All @@ -229,11 +237,6 @@ const tagsWithOptionalType = [
// These do not show a signature nor show curly brackets in the example
'public',
'static',

// Has no documentation, but test example has curly brackets, and
// "name" would be suggested rather than "namepath" based on example; not
// sure if name is required
'modifies',
];

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

const tagMightHaveType = (tag) => {
return tagsWithMandatoryType.includes(tag) || tagsWithOptionalType.includes(tag);
const tagMightHaveAType = (mode, tag) => {
return tagsWithMandatoryType.includes(tag) || (mode === 'closure' ?
tagsWithOptionalTypeClosure.includes(tag) :
tagsWithOptionalType.includes(tag));
};

const tagMustHaveType = (tag) => {
Expand All @@ -343,8 +348,8 @@ const tagMustHaveNamepath = (tag) => {
return tagsWithMandatoryNamepath.includes(tag);
};

const tagMightHaveEitherTypeOrNamepath = (tag) => {
return tagMightHaveType(tag) || tagMightHaveNamepath(tag);
const tagMightHaveEitherTypeOrNamepath = (mode, tag) => {
return tagMightHaveAType(mode, tag) || tagMightHaveNamepath(tag);
};

const tagMustHaveEitherTypeOrNamepath = (tag) => {
Expand Down Expand Up @@ -535,9 +540,9 @@ export default {
isNamepathDefiningTag,
isValidTag,
parseClosureTemplateTag,
tagMightHaveAType,
tagMightHaveEitherTypeOrNamepath,
tagMightHaveNamepath,
tagMightHaveType,
tagMustHaveEitherTypeOrNamepath,
tagMustHaveNamepath,
tagMustHaveType,
Expand Down
6 changes: 3 additions & 3 deletions src/rules/checkTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,16 @@ export default iterateJsdoc(({
settings,
context,
}) => {
const jsdocTags = utils.filterTags((tag) => {
return utils.tagMightHaveType(tag.tag);
const jsdocTagsWithPossibleType = utils.filterTags((tag) => {
return utils.tagMightHaveAType(tag.tag);
});

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

jsdocTags.forEach((jsdocTag) => {
jsdocTagsWithPossibleType.forEach((jsdocTag) => {
const invalidTypes = [];
let typeAst;

Expand Down
6 changes: 3 additions & 3 deletions src/rules/noUndefinedTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,11 +105,11 @@ export default iterateJsdoc(({
.concat(definedPreferredTypes)
.concat(closureGenericTypes);

const jsdocTags = utils.filterTags((tag) => {
return utils.tagMightHaveType(tag.tag);
const jsdocTagsWithPossibleType = utils.filterTags((tag) => {
return utils.tagMightHaveAType(tag.tag);
});

jsdocTags.forEach((tag) => {
jsdocTagsWithPossibleType.forEach((tag) => {
let parsedType;

try {
Expand Down
2 changes: 1 addition & 1 deletion src/rules/validTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ export default iterateJsdoc(({
return true;
};

const hasType = utils.tagMightHaveType(tag.tag) && Boolean(tag.type);
const hasType = utils.tagMightHaveAType(tag.tag) && Boolean(tag.type);
const mustHaveType = utils.tagMustHaveType(tag.tag);

const hasNamePath = utils.tagMightHaveNamepath(tag.tag) && Boolean(tag.name) && !(tag.tag === 'see' && !checkSeesForNamepaths);
Expand Down
28 changes: 28 additions & 0 deletions test/rules/assertions/validTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,25 @@ export default {
},
],
},
{
code: `
/**
* @private {BadTypeChecked<}
*/
function quux () {}
`,
errors: [
{
message: 'Syntax error in type: BadTypeChecked<',
},
],
settings: {
jsdoc: {
mode: 'closure',
},
},
},
],
valid: [
{
Expand Down Expand Up @@ -481,5 +500,14 @@ export default {
function quux (foo, bar, baz) {}
`,
},
{
code: `
/**
* @private {BadTypeNotCheckedInJsdoc<}
*/
function quux () {}
`,
},
],
};

0 comments on commit 42e8de2

Please sign in to comment.