Skip to content

Commit 724cec4

Browse files
committed
Incorporated feedback
1 parent 86a1bb6 commit 724cec4

File tree

6 files changed

+82
-57
lines changed

6 files changed

+82
-57
lines changed

docs/rules/no-undefined-types.md

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -247,20 +247,12 @@ function quux () {}
247247
// Message: The type 'SomeType' is undefined.
248248

249249
/**
250-
* @namepathDefiner SomeType
251-
*/
252-
/**
253-
* @type {SomeType}
254-
*/
255-
// Settings: {"jsdoc":{"structuredTags":{"namepathDefiner":{"name":"namepath-referencing"}}}}
256-
// Message: The type 'SomeType' is undefined.
257-
258-
/**
259-
* @namepathDefiner SomeType
250+
* @namepathReferencing SomeType
260251
*/
261252
/**
262253
* @type {SomeType}
263254
*/
255+
// Settings: {"jsdoc":{"structuredTags":{"namepathReferencing":{"name":"namepath-referencing"}}}}
264256
// Message: The type 'SomeType' is undefined.
265257

266258
/**

src/getDefaultTagStructureForMode.js

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ const getDefaultTagStructureForMode = (mode) => {
1111
const isJsdocTypescriptOrPermissive = isJsdocOrTypescript || isPermissive;
1212

1313
// Properties:
14-
// `nameContents` - 'namepath-referencing'|'namepath-defining'|'text'|false
14+
// `nameContents` - 'namepath-referencing'|'namepath-defining'|'namepath-or-url-referencing'|'text'|false
1515
// `typeAllowed` - boolean
1616
// `nameRequired` - boolean
1717
// `typeRequired` - boolean
@@ -463,13 +463,9 @@ const getDefaultTagStructureForMode = (mode) => {
463463
'link', new Map([
464464
// Signature seems to require a namepath OR URL and might be checked as such.
465465
[
466-
'nameContents', 'namepath-referencing',
466+
'nameContents', 'namepath-or-url-referencing',
467467
],
468468

469-
// "namepath"
470-
[
471-
'typeOrNameRequired', true,
472-
],
473469
]),
474470
],
475471

@@ -478,12 +474,7 @@ const getDefaultTagStructureForMode = (mode) => {
478474
// Synonym for "link"
479475
// Signature seems to require a namepath OR URL and might be checked as such.
480476
[
481-
'nameContents', 'namepath-referencing',
482-
],
483-
484-
// "namepath"
485-
[
486-
'typeOrNameRequired', true,
477+
'nameContents', 'namepath-or-url-referencing',
487478
],
488479
]),
489480
],
@@ -493,12 +484,7 @@ const getDefaultTagStructureForMode = (mode) => {
493484
// Synonym for "link"
494485
// Signature seems to require a namepath OR URL and might be checked as such.
495486
[
496-
'nameContents', 'namepath-referencing',
497-
],
498-
499-
// "namepath"
500-
[
501-
'typeOrNameRequired', true,
487+
'nameContents', 'namepath-or-url-referencing',
502488
],
503489
]),
504490
],

src/iterateJsdoc.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -769,7 +769,6 @@ const getUtils = (
769769
for (const method of [
770770
'tagMightHaveNamePosition',
771771
'tagMightHaveTypePosition',
772-
'tagMightHaveEitherTypeOrNamePosition',
773772
]) {
774773
utils[method] = (tagName, otherModeMaps) => {
775774
const result = jsdocUtils[method](tagName);
@@ -816,6 +815,8 @@ const getUtils = (
816815

817816
for (const method of [
818817
'isNamepathDefiningTag',
818+
'isNamepathReferencingTag',
819+
'isNamepathOrUrlReferencingTag',
819820
'tagMightHaveNamepath',
820821
]) {
821822
utils[method] = (tagName) => {
@@ -869,8 +870,9 @@ const getUtils = (
869870
});
870871
};
871872

872-
utils.filterTags = (filter) => {
873-
return jsdocUtils.filterTags(jsdocUtils.getAllTags(jsdoc), filter);
873+
utils.filterTags = (filter, includeInlineTags = false) => {
874+
const tags = jsdocUtils.getAllTags(jsdoc, includeInlineTags);
875+
return jsdocUtils.filterTags(tags, filter);
874876
};
875877

876878
utils.getTagsByType = (tags) => {

src/jsdocUtils.js

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -458,14 +458,14 @@ const hasTag = (jsdoc, targetTagName) => {
458458
* @param {object} jsdoc
459459
* @returns {Array}
460460
*/
461-
const getAllTags = (jsdoc) => {
462-
return [
461+
const getAllTags = (jsdoc, includeInlineTags = false) => {
462+
return includeInlineTags ? [
463463
...jsdoc.tags,
464464
...jsdoc.inlineTags,
465465
...jsdoc.tags.flatMap((tag) => {
466466
return tag.inlineTags;
467467
}),
468-
];
468+
] : jsdoc.tags;
469469
};
470470

471471
/**
@@ -618,6 +618,26 @@ const isNamepathDefiningTag = (tag, tagMap = tagStructure) => {
618618
return tagStruct.get('nameContents') === 'namepath-defining';
619619
};
620620

621+
/**
622+
* @param tag
623+
* @param {Map} tagMap
624+
* @returns {boolean}
625+
*/
626+
const isNamepathReferencingTag = (tag, tagMap = tagStructure) => {
627+
const tagStruct = ensureMap(tagMap, tag);
628+
return tagStruct.get('nameContents') === 'namepath-referencing';
629+
};
630+
631+
/**
632+
* @param tag
633+
* @param {Map} tagMap
634+
* @returns {boolean}
635+
*/
636+
const isNamepathOrUrlReferencingTag = (tag, tagMap = tagStructure) => {
637+
const tagStruct = ensureMap(tagMap, tag);
638+
return tagStruct.get('nameContents') === 'namepath-or-url-referencing';
639+
};
640+
621641
/**
622642
* @param tag
623643
* @param {Map} tagMap
@@ -1267,6 +1287,8 @@ export default {
12671287
isConstructor,
12681288
isGetter,
12691289
isNamepathDefiningTag,
1290+
isNamepathOrUrlReferencingTag,
1291+
isNamepathReferencingTag,
12701292
isSetter,
12711293
isValidTag,
12721294
mayBeUndefinedTypeTag,

src/rules/noUndefinedTypes.js

Lines changed: 40 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -186,24 +186,48 @@ export default iterateJsdoc(({
186186
],
187187
));
188188

189-
const jsdocTagsWithPossibleType = utils.filterTags(({
190-
tag,
191-
}) => {
192-
return utils.tagMightHaveEitherTypeOrNamePosition(tag) && (tag !== 'suppress' || settings.mode !== 'closure');
193-
});
194-
195-
for (const tag of jsdocTagsWithPossibleType) {
196-
const possibleType = tag.type || tag.name || tag.namepathOrURL;
197-
198-
let parsedType;
189+
const tagToParsedType = (propertyName) => {
190+
return (tag) => {
191+
try {
192+
const potentialType = tag[propertyName];
193+
return {
194+
parsedType: mode === 'permissive' ? tryParseType(potentialType) : parseType(potentialType, mode),
195+
tag,
196+
};
197+
} catch {
198+
return undefined;
199+
}
200+
};
201+
};
199202

200-
try {
201-
parsedType = mode === 'permissive' ? tryParseType(possibleType) : parseType(possibleType, mode);
202-
} catch {
203-
// On syntax error, will be handled by valid-types.
204-
continue;
205-
}
203+
const tagsWithTypes = [
204+
// Tags with type
205+
...utils.filterTags(({
206+
tag,
207+
}) => {
208+
return utils.tagMightHaveTypePosition(tag) && (tag !== 'suppress' || settings.mode !== 'closure');
209+
}).map(tagToParsedType('type')),
210+
// Tags with namepaths
211+
...utils.filterTags(({
212+
tag,
213+
}) => {
214+
return utils.isNamepathReferencingTag(tag) && (tag !== 'suppress' || settings.mode !== 'closure');
215+
}).map(tagToParsedType('name')),
216+
// Inline tags
217+
...utils.filterTags(({
218+
tag,
219+
}) => {
220+
return utils.isNamepathOrUrlReferencingTag(tag) && (tag !== 'suppress' || settings.mode !== 'closure');
221+
}, true).map(tagToParsedType('namepathOrURL')),
222+
].filter((result) => {
223+
// Remove types which failed to parse
224+
return result;
225+
});
206226

227+
for (const {
228+
tag,
229+
parsedType,
230+
} of tagsWithTypes) {
207231
traverse(parsedType, ({
208232
type,
209233
value,

test/rules/assertions/noUndefinedTypes.js

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -380,7 +380,7 @@ export default {
380380
{
381381
code: `
382382
/**
383-
* @namepathDefiner SomeType
383+
* @namepathReferencing SomeType
384384
*/
385385
/**
386386
* @type {SomeType}
@@ -399,32 +399,31 @@ export default {
399399
settings: {
400400
jsdoc: {
401401
structuredTags: {
402-
namepathDefiner: {
402+
namepathReferencing: {
403403
name: 'namepath-referencing',
404404
},
405405
},
406406
},
407407
},
408408
},
409409
{
410+
// An unknown tag without an namepath contents declared via settings,
411+
// defaults to not having an impact on the type.
410412
code: `
411413
/**
412-
* @namepathDefiner SomeType
414+
* @namepathMentioning SomeType
413415
*/
414416
/**
415417
* @type {SomeType}
416418
*/
417419
`,
418420
errors: [
419-
{
420-
line: 3,
421-
message: 'The type \'SomeType\' is undefined.',
422-
},
423421
{
424422
line: 6,
425423
message: 'The type \'SomeType\' is undefined.',
426424
},
427425
],
426+
ignoreReadme: true,
428427
},
429428
{
430429
code: `

0 commit comments

Comments
 (0)