Skip to content

Commit 7022f65

Browse files
committed
fix(check-types, no-undefined-types, valid-types): look within curly brackets of this and define tags (and if present within export) when in Closure mode; fixes #430
1 parent 471302a commit 7022f65

File tree

5 files changed

+277
-3
lines changed

5 files changed

+277
-3
lines changed

README.md

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3009,6 +3009,20 @@ function quux (foo) {
30093009

30103010
/** @typedef {String} foo */
30113011
// Message: Invalid JSDoc @typedef "foo" type "String"; prefer: "string".
3012+
3013+
/**
3014+
* @this {array}
3015+
*/
3016+
function quux () {}
3017+
// Settings: {"jsdoc":{"mode":"closure"}}
3018+
// Message: Invalid JSDoc @this type "array"; prefer: "Array".
3019+
3020+
/**
3021+
* @export {array}
3022+
*/
3023+
function quux () {}
3024+
// Settings: {"jsdoc":{"mode":"closure"}}
3025+
// Message: Invalid JSDoc @export type "array"; prefer: "Array".
30123026
````
30133027

30143028
The following patterns are not considered problems:
@@ -3217,6 +3231,18 @@ function quux (foo) {
32173231

32183232
/** @param {function(...)} callback The function to invoke. */
32193233
var subscribe = function(callback) {};
3234+
3235+
/**
3236+
* @this {Array}
3237+
*/
3238+
function quux () {}
3239+
// Settings: {"jsdoc":{"mode":"closure"}}
3240+
3241+
/**
3242+
* @export {Array}
3243+
*/
3244+
function quux () {}
3245+
// Settings: {"jsdoc":{"mode":"closure"}}
32203246
````
32213247

32223248

@@ -4811,6 +4837,20 @@ class Foo {
48114837
function quux (varargs) {
48124838
}
48134839
// Message: The type 'VAR_TYPE' is undefined.
4840+
4841+
/**
4842+
* @this {Navigator}
4843+
*/
4844+
function quux () {}
4845+
// Settings: {"jsdoc":{"mode":"closure"}}
4846+
// Message: The type 'Navigator' is undefined.
4847+
4848+
/**
4849+
* @export {SomeType}
4850+
*/
4851+
function quux () {}
4852+
// Settings: {"jsdoc":{"mode":"closure"}}
4853+
// Message: The type 'SomeType' is undefined.
48144854
````
48154855
48164856
The following patterns are not considered problems:
@@ -5029,6 +5069,20 @@ function quux (varargs) {
50295069
*/
50305070
function quux (varargs) {
50315071
}
5072+
5073+
class Navigator {}
5074+
/**
5075+
* @this {Navigator}
5076+
*/
5077+
function quux () {}
5078+
// Settings: {"jsdoc":{"mode":"closure"}}
5079+
5080+
class SomeType {}
5081+
/**
5082+
* @export {SomeType}
5083+
*/
5084+
function quux () {}
5085+
// Settings: {"jsdoc":{"mode":"closure"}}
50325086
````
50335087
50345088
@@ -8997,6 +9051,13 @@ function quux (foo, bar, baz) {}
89979051
function quux () {}
89989052
// Settings: {"jsdoc":{"mode":"closure"}}
89999053
// Message: Syntax error in type: BadTypeChecked<
9054+
9055+
/**
9056+
* @this {BadTypeChecked<}
9057+
*/
9058+
function quux () {}
9059+
// Settings: {"jsdoc":{"mode":"closure"}}
9060+
// Message: Syntax error in type: BadTypeChecked<
90009061
````
90019062
90029063
The following patterns are not considered problems:
@@ -9148,6 +9209,24 @@ function quux (foo, bar, baz) {}
91489209
* @private {BadTypeNotCheckedInJsdoc<}
91499210
*/
91509211
function quux () {}
9212+
9213+
/**
9214+
* @this {Navigator}
9215+
*/
9216+
function quux () {}
9217+
// Settings: {"jsdoc":{"mode":"closure"}}
9218+
9219+
/**
9220+
* @export {SomeType}
9221+
*/
9222+
function quux () {}
9223+
// Settings: {"jsdoc":{"mode":"closure"}}
9224+
9225+
/**
9226+
* @define {boolean}
9227+
*/
9228+
function quux () {}
9229+
// Settings: {"jsdoc":{"mode":"closure"}}
91519230
````
91529231
91539232

src/jsdocUtils.js

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,12 @@ const tagsWithMandatoryTypePosition = [
183183
'type',
184184
];
185185

186+
const tagsWithMandatoryTypePositionClosure = [
187+
...tagsWithMandatoryTypePosition,
188+
'this',
189+
'define',
190+
];
191+
186192
// All of these have a signature with "type" except for
187193
// `augments`/`extends` ("namepath")
188194
// `param`/`arg`/`argument` (no signature)
@@ -224,6 +230,8 @@ const tagsWithOptionalTypePosition = [
224230
const tagsWithOptionalTypePositionClosure = [
225231
...tagsWithOptionalTypePosition,
226232

233+
'export',
234+
227235
// Shows the signature with curly brackets but not in the example
228236
// "typeExpression"
229237
'package',
@@ -328,9 +336,13 @@ const isNamepathDefiningTag = (tagName) => {
328336
};
329337

330338
const tagMightHaveTypePosition = (mode, tag) => {
331-
return tagsWithMandatoryTypePosition.includes(tag) || (mode === 'closure' ?
332-
tagsWithOptionalTypePositionClosure.includes(tag) :
333-
tagsWithOptionalTypePosition.includes(tag));
339+
if (mode === 'closure') {
340+
return tagsWithMandatoryTypePositionClosure.includes(tag) ||
341+
tagsWithOptionalTypePositionClosure.includes(tag);
342+
}
343+
344+
return tagsWithMandatoryTypePosition.includes(tag) ||
345+
tagsWithOptionalTypePosition.includes(tag);
334346
};
335347

336348
const tagMustHaveTypePosition = (tag) => {

test/rules/assertions/checkTypes.js

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1703,6 +1703,40 @@ export default {
17031703
],
17041704
output: '/** @typedef {string} foo */',
17051705
},
1706+
{
1707+
code: `
1708+
/**
1709+
* @this {array}
1710+
*/
1711+
function quux () {}
1712+
`,
1713+
errors: [{
1714+
line: 3,
1715+
message: 'Invalid JSDoc @this type "array"; prefer: "Array".',
1716+
}],
1717+
settings: {
1718+
jsdoc: {
1719+
mode: 'closure',
1720+
},
1721+
},
1722+
},
1723+
{
1724+
code: `
1725+
/**
1726+
* @export {array}
1727+
*/
1728+
function quux () {}
1729+
`,
1730+
errors: [{
1731+
line: 3,
1732+
message: 'Invalid JSDoc @export type "array"; prefer: "Array".',
1733+
}],
1734+
settings: {
1735+
jsdoc: {
1736+
mode: 'closure',
1737+
},
1738+
},
1739+
},
17061740
],
17071741
valid: [
17081742
{
@@ -2089,5 +2123,31 @@ export default {
20892123
var subscribe = function(callback) {};
20902124
`,
20912125
},
2126+
{
2127+
code: `
2128+
/**
2129+
* @this {Array}
2130+
*/
2131+
function quux () {}
2132+
`,
2133+
settings: {
2134+
jsdoc: {
2135+
mode: 'closure',
2136+
},
2137+
},
2138+
},
2139+
{
2140+
code: `
2141+
/**
2142+
* @export {Array}
2143+
*/
2144+
function quux () {}
2145+
`,
2146+
settings: {
2147+
jsdoc: {
2148+
mode: 'closure',
2149+
},
2150+
},
2151+
},
20922152
],
20932153
};

test/rules/assertions/noUndefinedTypes.js

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,44 @@ export default {
276276
},
277277
],
278278
},
279+
{
280+
code: `
281+
/**
282+
* @this {Navigator}
283+
*/
284+
function quux () {}
285+
`,
286+
errors: [
287+
{
288+
line: 3,
289+
message: 'The type \'Navigator\' is undefined.',
290+
},
291+
],
292+
settings: {
293+
jsdoc: {
294+
mode: 'closure',
295+
},
296+
},
297+
},
298+
{
299+
code: `
300+
/**
301+
* @export {SomeType}
302+
*/
303+
function quux () {}
304+
`,
305+
errors: [
306+
{
307+
line: 3,
308+
message: 'The type \'SomeType\' is undefined.',
309+
},
310+
],
311+
settings: {
312+
jsdoc: {
313+
mode: 'closure',
314+
},
315+
},
316+
},
279317
],
280318
valid: [
281319
{
@@ -616,5 +654,33 @@ export default {
616654
}
617655
`,
618656
},
657+
{
658+
code: `
659+
class Navigator {}
660+
/**
661+
* @this {Navigator}
662+
*/
663+
function quux () {}
664+
`,
665+
settings: {
666+
jsdoc: {
667+
mode: 'closure',
668+
},
669+
},
670+
},
671+
{
672+
code: `
673+
class SomeType {}
674+
/**
675+
* @export {SomeType}
676+
*/
677+
function quux () {}
678+
`,
679+
settings: {
680+
jsdoc: {
681+
mode: 'closure',
682+
},
683+
},
684+
},
619685
],
620686
};

test/rules/assertions/validTypes.js

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,24 @@ export default {
286286
},
287287
},
288288
},
289+
{
290+
code: `
291+
/**
292+
* @this {BadTypeChecked<}
293+
*/
294+
function quux () {}
295+
`,
296+
errors: [
297+
{
298+
message: 'Syntax error in type: BadTypeChecked<',
299+
},
300+
],
301+
settings: {
302+
jsdoc: {
303+
mode: 'closure',
304+
},
305+
},
306+
},
289307
],
290308
valid: [
291309
{
@@ -509,5 +527,44 @@ export default {
509527
510528
`,
511529
},
530+
{
531+
code: `
532+
/**
533+
* @this {Navigator}
534+
*/
535+
function quux () {}
536+
`,
537+
settings: {
538+
jsdoc: {
539+
mode: 'closure',
540+
},
541+
},
542+
},
543+
{
544+
code: `
545+
/**
546+
* @export {SomeType}
547+
*/
548+
function quux () {}
549+
`,
550+
settings: {
551+
jsdoc: {
552+
mode: 'closure',
553+
},
554+
},
555+
},
556+
{
557+
code: `
558+
/**
559+
* @define {boolean}
560+
*/
561+
function quux () {}
562+
`,
563+
settings: {
564+
jsdoc: {
565+
mode: 'closure',
566+
},
567+
},
568+
},
512569
],
513570
};

0 commit comments

Comments
 (0)