Skip to content

Commit

Permalink
fix(valid-types): add undocumented modifies so its types will be …
Browse files Browse the repository at this point in the history
…checked

Also list differences in code in whether required/optional, name/namepath/type, curly brackets for type or not;
we ought to ask jsdoc/typescript about some apparent discrepancies or lack of clarity;
adding `modifies` to list for now (though see #401 )
  • Loading branch information
brettz9 committed Oct 15, 2019
1 parent 8861f4d commit 474ecb0
Show file tree
Hide file tree
Showing 4 changed files with 117 additions and 24 deletions.
12 changes: 6 additions & 6 deletions .README/rules/valid-types.md
Expand Up @@ -13,7 +13,7 @@ Also impacts behaviors on namepath (or event)-defining and pointing tags:
1. Name(path)-pointing tags requiring namepath: `@alias`, `@augments`, `@extends`, `@lends`, `@memberof`, `@memberof!`, `@mixes`, `@this`
1. Name(path)-pointing tags (which may have value without namepath or their
namepath can be expressed elsewhere on the block): `@listens`, `@fires`,
`@emits`
`@emits`, and `@modifies`
1. Name(path)-pointing tags (multiple names in one): `@borrows`

...with the following applying to the above sets:
Expand All @@ -38,10 +38,10 @@ Also impacts behaviors on namepath (or event)-defining and pointing tags:
empty name paths with `@callback`, `@event`, `@class`, `@constructor`,
`@constant`, `@const`, `@function`, `@func`, `@method`, `@interface`,
`@member`, `@var`, `@mixin`, `@namespace`, `@listens`, `@fires`,
or `@emits` (these might often be expected to have an accompanying
name path, though they have some indicative value without one; these
may also allow names to be defined in another manner elsewhere in
the block)
`@modifies`, or `@emits` (these might often be expected to have an
accompanying name path, though they have some indicative value without
one; these may also allow names to be defined in another manner elsewhere
in the block)
- `checkSeesForNamepaths` (default: false) - Set this to `true` to insist
that `@see` only use name paths (the tag is normally permitted to
allow other text)
Expand All @@ -50,7 +50,7 @@ Also impacts behaviors on namepath (or event)-defining and pointing tags:
|||
|---|---|
|Context|everywhere|
|Tags|For name only unless otherwise stated: `alias`, `augments`, `borrows`, `callback`, `class` (for name and type), `constant` (for name and type), `enum` (for type), `event`, `external`, `fires`, `function`, `implements` (for type), `interface`, `lends`, `listens`, `member` (for name and type), `memberof`, `memberof!`, `mixes`, `mixin`, `module` (for name and type), `name`, `namespace` (for name and type), `param` (for name and type), `property` (for name and type), `returns` (for type), `this`, `throws` (for type), `type` (for type), `typedef` (for name and type), `yields` (for type)|
|Tags|For name only unless otherwise stated: `alias`, `augments`, `borrows`, `callback`, `class` (for name and type), `constant` (for name and type), `enum` (for type), `event`, `external`, `fires`, `function`, `implements` (for type), `interface`, `lends`, `listens`, `member` (for name and type), `memberof`, `memberof!`, `mixes`, `mixin`, `modifies`, `module` (for name and type), `name`, `namespace` (for name and type), `param` (for name and type), `property` (for name and type), `returns` (for type), `this`, `throws` (for type), `type` (for type), `typedef` (for name and type), `yields` (for type)|
|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`|
Expand Down
23 changes: 17 additions & 6 deletions README.md
Expand Up @@ -7669,7 +7669,7 @@ Also impacts behaviors on namepath (or event)-defining and pointing tags:
1. Name(path)-pointing tags requiring namepath: `@alias`, `@augments`, `@extends`, `@lends`, `@memberof`, `@memberof!`, `@mixes`, `@this`
1. Name(path)-pointing tags (which may have value without namepath or their
namepath can be expressed elsewhere on the block): `@listens`, `@fires`,
`@emits`
`@emits`, and `@modifies`
1. Name(path)-pointing tags (multiple names in one): `@borrows`

...with the following applying to the above sets:
Expand All @@ -7695,10 +7695,10 @@ Also impacts behaviors on namepath (or event)-defining and pointing tags:
empty name paths with `@callback`, `@event`, `@class`, `@constructor`,
`@constant`, `@const`, `@function`, `@func`, `@method`, `@interface`,
`@member`, `@var`, `@mixin`, `@namespace`, `@listens`, `@fires`,
or `@emits` (these might often be expected to have an accompanying
name path, though they have some indicative value without one; these
may also allow names to be defined in another manner elsewhere in
the block)
`@modifies`, or `@emits` (these might often be expected to have an
accompanying name path, though they have some indicative value without
one; these may also allow names to be defined in another manner elsewhere
in the block)
- `checkSeesForNamepaths` (default: false) - Set this to `true` to insist
that `@see` only use name paths (the tag is normally permitted to
allow other text)
Expand All @@ -7707,7 +7707,7 @@ Also impacts behaviors on namepath (or event)-defining and pointing tags:
|||
|---|---|
|Context|everywhere|
|Tags|For name only unless otherwise stated: `alias`, `augments`, `borrows`, `callback`, `class` (for name and type), `constant` (for name and type), `enum` (for type), `event`, `external`, `fires`, `function`, `implements` (for type), `interface`, `lends`, `listens`, `member` (for name and type), `memberof`, `memberof!`, `mixes`, `mixin`, `module` (for name and type), `name`, `namespace` (for name and type), `param` (for name and type), `property` (for name and type), `returns` (for type), `this`, `throws` (for type), `type` (for type), `typedef` (for name and type), `yields` (for type)|
|Tags|For name only unless otherwise stated: `alias`, `augments`, `borrows`, `callback`, `class` (for name and type), `constant` (for name and type), `enum` (for type), `event`, `external`, `fires`, `function`, `implements` (for type), `interface`, `lends`, `listens`, `member` (for name and type), `memberof`, `memberof!`, `mixes`, `mixin`, `modifies`, `module` (for name and type), `name`, `namespace` (for name and type), `param` (for name and type), `property` (for name and type), `returns` (for type), `this`, `throws` (for type), `type` (for type), `typedef` (for name and type), `yields` (for type)|
|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`|
Expand Down Expand Up @@ -7837,6 +7837,12 @@ function quux() {
*/
let foo;
// Message: Tag @type must have a type

/**
* @modifies {bar|foo<}
*/
function quux (foo, bar, baz) {}
// Message: Syntax error in type: bar|foo<
````

The following patterns are not considered problems:
Expand Down Expand Up @@ -7978,6 +7984,11 @@ function quux() {
* @typedef {number|string}
*/
let UserDefinedGCCType;

/**
* @modifies {foo|bar}
*/
function quux (foo, bar, baz) {}
````


85 changes: 73 additions & 12 deletions src/jsdocUtils.js
Expand Up @@ -132,83 +132,144 @@ const hasDefinedTypeReturnTag = (tag) => {
return true;
};

// Todo: These type and namepath tag listings currently look
// at tags with `{...}` as being a type, but jsdoc may
// allow some namepaths only within brackets as well

const tagsWithMandatoryType = [
// These both show curly brackets in the doc signature and examples
'implements',
'type',
];

const tagsWithOptionalType = [
// These have the example showing curly brackets but not in their doc signature, e.g.: https://jsdoc.app/tags-enum.html
'enum',
'member', 'var',
'module',

'typedef',

// These do not show curly brackets in either the signature or examples
'augments', 'extends',
'class', 'constructor',
'constant', 'const',

// These show the signature with curly brackets but not in the example
'module',
'namespace',

// These have no formal signature in the docs but show curly brackets
// in the examples
'param', 'arg', 'argument',
'property', 'prop',

// These show curly brackets in the signature and in the examples
'returns', 'return',
'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
// Shows the signature with curly brackets but not in the example
'package',
'private',
'protected',

// 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,
// except for `member`/`var` (which show in their example)
const namepathDefiningTags = [
// These appears to require a "name" in their signature, albeit these
// are somewhat different from other "names" (including as described
// at https://jsdoc.app/about-namepaths.html )
'external', 'host',
'name',
'typedef',
'event',

// These allow for "names" in their signature, but indicate as optional
'class', 'constructor',
'constant', 'const',
'callback',
'function', 'func', 'method',
'interface',
'member', 'var',
'mixin',
'namespace',

// Todo: Should add `module` here (with optional "name" and no curly brackets);
// this block impacts `no-undefined-types` and `valid-types` (search for "isNamepathDefiningTag|tagMightHaveNamepath|tagMightHaveEitherTypeOrNamepath")

// These seem to all require a "namepath" in their signatures (with no counter-examples)
'name',
'typedef',
'callback',
];

// The following do not seem to allow curly brackets in their doc
// signature or examples (besides `modifies`)
const tagsWithOptionalNamepath = [
...namepathDefiningTags,
'alias',
'augments', 'extends',

// `borrows` has a different format, however, so needs special parsing
// `borrows` has a different format, however, so needs special parsing;
// seems to require both, and as "namepaths"
'borrows',

// Signature seems to require a "name" (of an event) and no counter-examples
'emits', 'fires',
'lends',
'listens',

// Signature seems to require a "namepath" (and no counter-examples)
'alias',
'augments', 'extends',
'lends',
'this',

// Signature seems to require a "namepath" (and no counter-examples),
// though it allows an incomplete namepath ending with connecting symbol
'memberof', 'memberof!',

// Signature seems to require a "OtherObjectPath" with no counter-examples
'mixes',

// Signature allows for namepath or text
'see',
'this',
];

// Todo: `@link` seems to require a namepath OR URL and might be checked as such.

// The doc signature of `event` seems to require a "name"
const tagsWithMandatoryNamepath = [
'callback',
// "name" (and a special syntax for the `external` name)
'external', 'host',

// "namepath"
'callback',
'name',
'typedef',
];

const tagsWithMandatoryTypeOrNamepath = [
// "namepath"
'alias',
'augments', 'extends',
'borrows',
'external', 'host',
'lends',
'memberof', 'memberof!',
'mixes',
'name',
'this',
'typedef',

// "name"
'external', 'host',

// "OtherObjectPath"
'mixes',
];

const isNamepathDefiningTag = (tagName) => {
Expand Down
21 changes: 21 additions & 0 deletions test/rules/assertions/validTypes.js
Expand Up @@ -254,6 +254,19 @@ export default {
},
],
},
{
code: `
/**
* @modifies {bar|foo<}
*/
function quux (foo, bar, baz) {}
`,
errors: [
{
message: 'Syntax error in type: bar|foo<',
},
],
},
],
valid: [
{
Expand Down Expand Up @@ -460,5 +473,13 @@ export default {
let UserDefinedGCCType;
`,
},
{
code: `
/**
* @modifies {foo|bar}
*/
function quux (foo, bar, baz) {}
`,
},
],
};

0 comments on commit 474ecb0

Please sign in to comment.