@@ -59,8 +59,12 @@ export default iterateJsdoc(({
5959 report,
6060 settings,
6161 sourceCode,
62+ state,
6263 utils,
6364} ) => {
65+ /** @type {string[] } */
66+ const foundTypedefValues = [ ] ;
67+
6468 const {
6569 scopeManager,
6670 } = sourceCode ;
@@ -73,11 +77,13 @@ export default iterateJsdoc(({
7377 const
7478 /**
7579 * @type {{
80+ * checkUsedTypedefs: boolean
7681 * definedTypes: string[],
7782 * disableReporting: boolean,
78- * markVariablesAsUsed: boolean
83+ * markVariablesAsUsed: boolean,
7984 * }}
8085 */ {
86+ checkUsedTypedefs = false ,
8187 definedTypes = [ ] ,
8288 disableReporting = false ,
8389 markVariablesAsUsed = true ,
@@ -128,14 +134,16 @@ export default iterateJsdoc(({
128134 return commentNode . value . replace ( / ^ \s * g l o b a l s / v, '' ) . trim ( ) . split ( / , \s * / v) ;
129135 } ) . concat ( Object . keys ( context . languageOptions . globals ?? [ ] ) ) ;
130136
131- const typedefDeclarations = comments
137+ const typedefs = comments
132138 . flatMap ( ( doc ) => {
133139 return doc . tags . filter ( ( {
134140 tag,
135141 } ) => {
136142 return utils . isNamepathDefiningTag ( tag ) ;
137143 } ) ;
138- } )
144+ } ) ;
145+
146+ const typedefDeclarations = typedefs
139147 . map ( ( tag ) => {
140148 return tag . name ;
141149 } ) ;
@@ -204,9 +212,9 @@ export default iterateJsdoc(({
204212 return [ ] ;
205213 }
206214
207- const jsdoc = parseComment ( commentNode , '' ) ;
215+ const jsdc = parseComment ( commentNode , '' ) ;
208216
209- return jsdoc . tags . filter ( ( tag ) => {
217+ return jsdc . tags . filter ( ( tag ) => {
210218 return tag . tag === 'template' ;
211219 } ) ;
212220 } ;
@@ -510,10 +518,74 @@ export default iterateJsdoc(({
510518 context . markVariableAsUsed ( val ) ;
511519 }
512520 }
521+
522+ if ( checkUsedTypedefs && typedefDeclarations . includes ( val ) ) {
523+ foundTypedefValues . push ( val ) ;
524+ }
513525 }
514526 } ) ;
515527 }
528+
529+ state . foundTypedefValues = foundTypedefValues ;
516530} , {
531+ // We use this method rather than checking at end of handler above because
532+ // in that case, it is invoked too many times and would thus report errors
533+ // too many times.
534+ exit ( {
535+ context,
536+ state,
537+ utils,
538+ } ) {
539+ const {
540+ checkUsedTypedefs = false ,
541+ } = context . options [ 0 ] || { } ;
542+
543+ if ( ! checkUsedTypedefs ) {
544+ return ;
545+ }
546+
547+ const allComments = context . sourceCode . getAllComments ( ) ;
548+ const comments = allComments
549+ . filter ( ( comment ) => {
550+ return ( / ^ \* (? ! \* ) / v) . test ( comment . value ) ;
551+ } )
552+ . map ( ( commentNode ) => {
553+ return {
554+ doc : parseComment ( commentNode , '' ) ,
555+ loc : commentNode . loc ,
556+ } ;
557+ } ) ;
558+ const typedefs = comments
559+ . flatMap ( ( {
560+ doc,
561+ loc,
562+ } ) => {
563+ const tags = doc . tags . filter ( ( {
564+ tag,
565+ } ) => {
566+ return utils . isNamepathDefiningTag ( tag ) ;
567+ } ) ;
568+ if ( ! tags . length ) {
569+ return [ ] ;
570+ }
571+
572+ return {
573+ loc,
574+ tags,
575+ } ;
576+ } ) ;
577+
578+ for ( const typedef of typedefs ) {
579+ if (
580+ ! state . foundTypedefValues . includes ( typedef . tags [ 0 ] . name )
581+ ) {
582+ context . report ( {
583+ loc : /** @type {import('@eslint/core').SourceLocation } */ ( typedef . loc ) ,
584+ message : 'This typedef was not used within the file' ,
585+ } ) ;
586+ }
587+ }
588+ } ,
517589 iterateAllJsdocs : true ,
518590 meta : {
519591 docs : {
@@ -524,6 +596,10 @@ export default iterateJsdoc(({
524596 {
525597 additionalProperties : false ,
526598 properties : {
599+ checkUsedTypedefs : {
600+ description : 'Whether to check typedefs for use within the file' ,
601+ type : 'boolean' ,
602+ } ,
527603 definedTypes : {
528604 description : `This array can be populated to indicate other types which
529605are automatically considered as defined (in addition to globals, etc.).
@@ -536,7 +612,7 @@ Defaults to an empty array.`,
536612 disableReporting : {
537613 description : `Whether to disable reporting of errors. Defaults to
538614\`false\`. This may be set to \`true\` in order to take advantage of only
539- marking defined variables as used.` ,
615+ marking defined variables as used or checking used typedefs .` ,
540616 type : 'boolean' ,
541617 } ,
542618 markVariablesAsUsed : {
0 commit comments