Skip to content

Commit 474ecb0

Browse files
committed
fix(valid-types): add undocumented modifies so its types will be 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 )
1 parent 8861f4d commit 474ecb0

File tree

4 files changed

+117
-24
lines changed

4 files changed

+117
-24
lines changed

.README/rules/valid-types.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ Also impacts behaviors on namepath (or event)-defining and pointing tags:
1313
1. Name(path)-pointing tags requiring namepath: `@alias`, `@augments`, `@extends`, `@lends`, `@memberof`, `@memberof!`, `@mixes`, `@this`
1414
1. Name(path)-pointing tags (which may have value without namepath or their
1515
namepath can be expressed elsewhere on the block): `@listens`, `@fires`,
16-
`@emits`
16+
`@emits`, and `@modifies`
1717
1. Name(path)-pointing tags (multiple names in one): `@borrows`
1818

1919
...with the following applying to the above sets:
@@ -38,10 +38,10 @@ Also impacts behaviors on namepath (or event)-defining and pointing tags:
3838
empty name paths with `@callback`, `@event`, `@class`, `@constructor`,
3939
`@constant`, `@const`, `@function`, `@func`, `@method`, `@interface`,
4040
`@member`, `@var`, `@mixin`, `@namespace`, `@listens`, `@fires`,
41-
or `@emits` (these might often be expected to have an accompanying
42-
name path, though they have some indicative value without one; these
43-
may also allow names to be defined in another manner elsewhere in
44-
the block)
41+
`@modifies`, or `@emits` (these might often be expected to have an
42+
accompanying name path, though they have some indicative value without
43+
one; these may also allow names to be defined in another manner elsewhere
44+
in the block)
4545
- `checkSeesForNamepaths` (default: false) - Set this to `true` to insist
4646
that `@see` only use name paths (the tag is normally permitted to
4747
allow other text)
@@ -50,7 +50,7 @@ Also impacts behaviors on namepath (or event)-defining and pointing tags:
5050
|||
5151
|---|---|
5252
|Context|everywhere|
53-
|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)|
53+
|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)|
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`|

README.md

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7669,7 +7669,7 @@ Also impacts behaviors on namepath (or event)-defining and pointing tags:
76697669
1. Name(path)-pointing tags requiring namepath: `@alias`, `@augments`, `@extends`, `@lends`, `@memberof`, `@memberof!`, `@mixes`, `@this`
76707670
1. Name(path)-pointing tags (which may have value without namepath or their
76717671
namepath can be expressed elsewhere on the block): `@listens`, `@fires`,
7672-
`@emits`
7672+
`@emits`, and `@modifies`
76737673
1. Name(path)-pointing tags (multiple names in one): `@borrows`
76747674

76757675
...with the following applying to the above sets:
@@ -7695,10 +7695,10 @@ Also impacts behaviors on namepath (or event)-defining and pointing tags:
76957695
empty name paths with `@callback`, `@event`, `@class`, `@constructor`,
76967696
`@constant`, `@const`, `@function`, `@func`, `@method`, `@interface`,
76977697
`@member`, `@var`, `@mixin`, `@namespace`, `@listens`, `@fires`,
7698-
or `@emits` (these might often be expected to have an accompanying
7699-
name path, though they have some indicative value without one; these
7700-
may also allow names to be defined in another manner elsewhere in
7701-
the block)
7698+
`@modifies`, or `@emits` (these might often be expected to have an
7699+
accompanying name path, though they have some indicative value without
7700+
one; these may also allow names to be defined in another manner elsewhere
7701+
in the block)
77027702
- `checkSeesForNamepaths` (default: false) - Set this to `true` to insist
77037703
that `@see` only use name paths (the tag is normally permitted to
77047704
allow other text)
@@ -7707,7 +7707,7 @@ Also impacts behaviors on namepath (or event)-defining and pointing tags:
77077707
|||
77087708
|---|---|
77097709
|Context|everywhere|
7710-
|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)|
7710+
|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)|
77117711
|Aliases|`extends`, `constructor`, `const`, `host`, `emits`, `func`, `method`, `var`, `arg`, `argument`, `prop`, `return`, `exception`, `yield`|
77127712
|Closure-only|For type only: `package`, `private`, `protected`, `public`, `static`|
77137713
|Options|`allowEmptyNamepaths`, `checkSeesForNamepaths`|
@@ -7837,6 +7837,12 @@ function quux() {
78377837
*/
78387838
let foo;
78397839
// Message: Tag @type must have a type
7840+
7841+
/**
7842+
* @modifies {bar|foo<}
7843+
*/
7844+
function quux (foo, bar, baz) {}
7845+
// Message: Syntax error in type: bar|foo<
78407846
````
78417847

78427848
The following patterns are not considered problems:
@@ -7978,6 +7984,11 @@ function quux() {
79787984
* @typedef {number|string}
79797985
*/
79807986
let UserDefinedGCCType;
7987+
7988+
/**
7989+
* @modifies {foo|bar}
7990+
*/
7991+
function quux (foo, bar, baz) {}
79817992
````
79827993

79837994

src/jsdocUtils.js

Lines changed: 73 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -132,83 +132,144 @@ const hasDefinedTypeReturnTag = (tag) => {
132132
return true;
133133
};
134134

135+
// Todo: These type and namepath tag listings currently look
136+
// at tags with `{...}` as being a type, but jsdoc may
137+
// allow some namepaths only within brackets as well
138+
135139
const tagsWithMandatoryType = [
140+
// These both show curly brackets in the doc signature and examples
136141
'implements',
137142
'type',
138143
];
139144

140145
const tagsWithOptionalType = [
146+
// These have the example showing curly brackets but not in their doc signature, e.g.: https://jsdoc.app/tags-enum.html
141147
'enum',
142148
'member', 'var',
143-
'module',
149+
144150
'typedef',
151+
152+
// These do not show curly brackets in either the signature or examples
145153
'augments', 'extends',
146154
'class', 'constructor',
147155
'constant', 'const',
156+
157+
// These show the signature with curly brackets but not in the example
158+
'module',
148159
'namespace',
160+
161+
// These have no formal signature in the docs but show curly brackets
162+
// in the examples
149163
'param', 'arg', 'argument',
150164
'property', 'prop',
165+
166+
// These show curly brackets in the signature and in the examples
151167
'returns', 'return',
152168
'throws', 'exception',
153169
'yields', 'yield',
154170

155171
// Todo: Omit these GCC specific items when in non-GCC mode after landing https://github.com/gajus/eslint-plugin-jsdoc/issues/356
172+
// Shows the signature with curly brackets but not in the example
156173
'package',
157174
'private',
158175
'protected',
176+
177+
// These do not show a signature nor show curly brackets in the example
159178
'public',
160179
'static',
180+
181+
// Has no documentation, but test example has curly brackets, and
182+
// "name" would be suggested rather than "namepath" based on example; not
183+
// sure if name is required
184+
'modifies',
161185
];
162186

187+
// None of these show as having curly brackets for their name/namepath,
188+
// except for `member`/`var` (which show in their example)
163189
const namepathDefiningTags = [
190+
// These appears to require a "name" in their signature, albeit these
191+
// are somewhat different from other "names" (including as described
192+
// at https://jsdoc.app/about-namepaths.html )
164193
'external', 'host',
165-
'name',
166-
'typedef',
167194
'event',
195+
196+
// These allow for "names" in their signature, but indicate as optional
168197
'class', 'constructor',
169198
'constant', 'const',
170-
'callback',
171199
'function', 'func', 'method',
172200
'interface',
173201
'member', 'var',
174202
'mixin',
175203
'namespace',
204+
205+
// Todo: Should add `module` here (with optional "name" and no curly brackets);
206+
// this block impacts `no-undefined-types` and `valid-types` (search for "isNamepathDefiningTag|tagMightHaveNamepath|tagMightHaveEitherTypeOrNamepath")
207+
208+
// These seem to all require a "namepath" in their signatures (with no counter-examples)
209+
'name',
210+
'typedef',
211+
'callback',
176212
];
177213

214+
// The following do not seem to allow curly brackets in their doc
215+
// signature or examples (besides `modifies`)
178216
const tagsWithOptionalNamepath = [
179217
...namepathDefiningTags,
180-
'alias',
181-
'augments', 'extends',
182218

183-
// `borrows` has a different format, however, so needs special parsing
219+
// `borrows` has a different format, however, so needs special parsing;
220+
// seems to require both, and as "namepaths"
184221
'borrows',
222+
223+
// Signature seems to require a "name" (of an event) and no counter-examples
185224
'emits', 'fires',
186-
'lends',
187225
'listens',
226+
227+
// Signature seems to require a "namepath" (and no counter-examples)
228+
'alias',
229+
'augments', 'extends',
230+
'lends',
231+
'this',
232+
233+
// Signature seems to require a "namepath" (and no counter-examples),
234+
// though it allows an incomplete namepath ending with connecting symbol
188235
'memberof', 'memberof!',
236+
237+
// Signature seems to require a "OtherObjectPath" with no counter-examples
189238
'mixes',
239+
240+
// Signature allows for namepath or text
190241
'see',
191-
'this',
192242
];
193243

244+
// Todo: `@link` seems to require a namepath OR URL and might be checked as such.
245+
246+
// The doc signature of `event` seems to require a "name"
194247
const tagsWithMandatoryNamepath = [
195-
'callback',
248+
// "name" (and a special syntax for the `external` name)
196249
'external', 'host',
250+
251+
// "namepath"
252+
'callback',
197253
'name',
198254
'typedef',
199255
];
200256

201257
const tagsWithMandatoryTypeOrNamepath = [
258+
// "namepath"
202259
'alias',
203260
'augments', 'extends',
204261
'borrows',
205-
'external', 'host',
206262
'lends',
207263
'memberof', 'memberof!',
208-
'mixes',
209264
'name',
210265
'this',
211266
'typedef',
267+
268+
// "name"
269+
'external', 'host',
270+
271+
// "OtherObjectPath"
272+
'mixes',
212273
];
213274

214275
const isNamepathDefiningTag = (tagName) => {

test/rules/assertions/validTypes.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,19 @@ export default {
254254
},
255255
],
256256
},
257+
{
258+
code: `
259+
/**
260+
* @modifies {bar|foo<}
261+
*/
262+
function quux (foo, bar, baz) {}
263+
`,
264+
errors: [
265+
{
266+
message: 'Syntax error in type: bar|foo<',
267+
},
268+
],
269+
},
257270
],
258271
valid: [
259272
{
@@ -460,5 +473,13 @@ export default {
460473
let UserDefinedGCCType;
461474
`,
462475
},
476+
{
477+
code: `
478+
/**
479+
* @modifies {foo|bar}
480+
*/
481+
function quux (foo, bar, baz) {}
482+
`,
483+
},
463484
],
464485
};

0 commit comments

Comments
 (0)