Skip to content

Commit 058018b

Browse files
committedAug 2, 2024
feat(check-template-names): check callback/function tag blocks
1 parent 12fca71 commit 058018b

File tree

4 files changed

+178
-26
lines changed

4 files changed

+178
-26
lines changed
 

‎.README/rules/check-template-names.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# `check-template-names`
22

33
Checks that any `@template` names are actually used in the connected
4-
`@typedef` or type alias.
4+
`@typedef`, `@callback`, `@function` or type structure.
55

66
Currently checks `ClassDeclaration`, `FunctionDeclaration`,
77
`TSInterfaceDeclaration` or `TSTypeAliasDeclaration` such as:

‎docs/rules/check-template-names.md

+46-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
# <code>check-template-names</code>
44

55
Checks that any `@template` names are actually used in the connected
6-
`@typedef` or type alias.
6+
`@typedef`, `@callback`, `@function` or type structure.
77

88
Currently checks `ClassDeclaration`, `FunctionDeclaration`,
99
`TSInterfaceDeclaration` or `TSTypeAliasDeclaration` such as:
@@ -190,6 +190,30 @@ export default class <NumType> {
190190
add: (x: NumType, y: NumType) => NumType;
191191
}
192192
// Message: @template D not in use
193+
194+
/**
195+
* @template D
196+
* @template V
197+
* @callback
198+
* @returns {[X, Y | undefined]}
199+
*/
200+
// Message: @template D not in use
201+
202+
/**
203+
* @template D
204+
* @template V
205+
* @function
206+
* @returns {[X, Y | undefined]}
207+
*/
208+
// Message: @template D not in use
209+
210+
/**
211+
* @template D
212+
* @template V
213+
* @function
214+
* @param {[X, Y | undefined]} someParam
215+
*/
216+
// Message: @template D not in use
193217
````
194218

195219

@@ -327,5 +351,26 @@ export default class <NumType> {
327351
*/
328352
export function mapGroupBy(array, callbackFn) {
329353
}
354+
355+
/**
356+
* @template D
357+
* @template V
358+
* @callback
359+
* @returns {[D, V | undefined]}
360+
*/
361+
362+
/**
363+
* @template D
364+
* @template V
365+
* @function
366+
* @returns {[D, V | undefined]}
367+
*/
368+
369+
/**
370+
* @template D
371+
* @template V
372+
* @function
373+
* @param {[D, V | undefined]} someParam
374+
*/
330375
````
331376

‎src/rules/checkTemplateNames.js

+41-24
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,36 @@ export default iterateJsdoc(({
4343
});
4444
};
4545

46+
const checkParamsAndReturnsTags = () => {
47+
const paramName = /** @type {string} */ (utils.getPreferredTagName({
48+
tagName: 'param',
49+
}));
50+
const paramTags = utils.getTags(paramName);
51+
for (const paramTag of paramTags) {
52+
checkForUsedTypes(paramTag.type);
53+
}
54+
55+
const returnsName = /** @type {string} */ (utils.getPreferredTagName({
56+
tagName: 'returns',
57+
}));
58+
const returnsTags = utils.getTags(returnsName);
59+
for (const returnsTag of returnsTags) {
60+
checkForUsedTypes(returnsTag.type);
61+
}
62+
};
63+
64+
const checkTemplateTags = () => {
65+
for (const tag of templateTags) {
66+
const {name} = tag;
67+
const names = name.split(/,\s*/);
68+
for (const name of names) {
69+
if (!usedNames.has(name)) {
70+
report(`@template ${name} not in use`, null, tag);
71+
}
72+
}
73+
}
74+
};
75+
4676
/**
4777
* @param {import('@typescript-eslint/types').TSESTree.FunctionDeclaration|
4878
* import('@typescript-eslint/types').TSESTree.ClassDeclaration|
@@ -57,31 +87,10 @@ export default iterateJsdoc(({
5787
usedNames.add(name);
5888
}
5989
if (checkParamsAndReturns) {
60-
const paramName = /** @type {string} */ (utils.getPreferredTagName({
61-
tagName: 'param',
62-
}));
63-
const paramTags = utils.getTags(paramName);
64-
for (const paramTag of paramTags) {
65-
checkForUsedTypes(paramTag.type);
66-
}
67-
68-
const returnsName = /** @type {string} */ (utils.getPreferredTagName({
69-
tagName: 'returns',
70-
}));
71-
const returnsTags = utils.getTags(returnsName);
72-
for (const returnsTag of returnsTags) {
73-
checkForUsedTypes(returnsTag.type);
74-
}
75-
}
76-
for (const tag of templateTags) {
77-
const {name} = tag;
78-
const names = name.split(/,\s*/);
79-
for (const name of names) {
80-
if (!usedNames.has(name)) {
81-
report(`@template ${name} not in use`, null, tag);
82-
}
83-
}
90+
checkParamsAndReturnsTags();
8491
}
92+
93+
checkTemplateTags();
8594
};
8695

8796
const handleTypeAliases = () => {
@@ -116,6 +125,14 @@ export default iterateJsdoc(({
116125
}
117126
};
118127

128+
const callbackTags = utils.getTags('callback');
129+
const functionTags = utils.getTags('function');
130+
if (callbackTags.length || functionTags.length) {
131+
checkParamsAndReturnsTags();
132+
checkTemplateTags();
133+
return;
134+
}
135+
119136
const typedefTags = utils.getTags('typedef');
120137
if (!typedefTags.length || typedefTags.length >= 2) {
121138
handleTypeAliases();

‎test/rules/assertions/checkTemplateNames.js

+90
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,66 @@ export default {
402402
parser: typescriptEslintParser
403403
},
404404
},
405+
{
406+
code: `
407+
/**
408+
* @template D
409+
* @template V
410+
* @callback
411+
* @returns {[X, Y | undefined]}
412+
*/
413+
`,
414+
errors: [
415+
{
416+
line: 3,
417+
message: '@template D not in use',
418+
},
419+
{
420+
line: 4,
421+
message: '@template V not in use',
422+
},
423+
],
424+
},
425+
{
426+
code: `
427+
/**
428+
* @template D
429+
* @template V
430+
* @function
431+
* @returns {[X, Y | undefined]}
432+
*/
433+
`,
434+
errors: [
435+
{
436+
line: 3,
437+
message: '@template D not in use',
438+
},
439+
{
440+
line: 4,
441+
message: '@template V not in use',
442+
},
443+
],
444+
},
445+
{
446+
code: `
447+
/**
448+
* @template D
449+
* @template V
450+
* @function
451+
* @param {[X, Y | undefined]} someParam
452+
*/
453+
`,
454+
errors: [
455+
{
456+
line: 3,
457+
message: '@template D not in use',
458+
},
459+
{
460+
line: 4,
461+
message: '@template V not in use',
462+
},
463+
],
464+
},
405465
],
406466
valid: [
407467
{
@@ -624,5 +684,35 @@ export default {
624684
parser: typescriptEslintParser
625685
},
626686
},
687+
{
688+
code: `
689+
/**
690+
* @template D
691+
* @template V
692+
* @callback
693+
* @returns {[D, V | undefined]}
694+
*/
695+
`,
696+
},
697+
{
698+
code: `
699+
/**
700+
* @template D
701+
* @template V
702+
* @function
703+
* @returns {[D, V | undefined]}
704+
*/
705+
`,
706+
},
707+
{
708+
code: `
709+
/**
710+
* @template D
711+
* @template V
712+
* @function
713+
* @param {[D, V | undefined]} someParam
714+
*/
715+
`,
716+
},
627717
],
628718
};

0 commit comments

Comments
 (0)
Please sign in to comment.