eslint-plugin-jsdoc 60.1.1 → 60.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/cjs/iterateJsdoc.d.ts +6 -1
- package/dist/cjs/rules/preferImportTag.d.ts +2 -0
- package/dist/index-cjs.cjs +3 -0
- package/dist/index-cjs.cjs.map +1 -1
- package/dist/index.cjs +3 -0
- package/dist/index.cjs.map +1 -1
- package/dist/iterateJsdoc.cjs +21 -14
- package/dist/iterateJsdoc.cjs.map +1 -1
- package/dist/iterateJsdoc.d.ts +6 -1
- package/dist/rules/noUndefinedTypes.cjs +69 -6
- package/dist/rules/noUndefinedTypes.cjs.map +1 -1
- package/dist/rules/preferImportTag.cjs +321 -0
- package/dist/rules/preferImportTag.cjs.map +1 -0
- package/dist/rules/preferImportTag.d.ts +3 -0
- package/dist/rules.d.ts +25 -1
- package/package.json +1 -1
- package/src/index-cjs.js +3 -0
- package/src/index.js +3 -0
- package/src/iterateJsdoc.js +55 -32
- package/src/rules/noUndefinedTypes.js +82 -6
- package/src/rules/preferImportTag.js +452 -0
- package/src/rules.d.ts +25 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preferImportTag.cjs","names":["_iterateJsdoc","_interopRequireWildcard","require","_jsdoccomment","_parseImportsExports","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","default","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","_default","exports","iterateJsdoc","context","jsdoc","settings","sourceCode","utils","mode","enableFixer","exemptTypedefs","outputType","options","allComments","getAllComments","comments","filter","comment","test","value","map","commentNode","commentParserToESTree","parseComment","typedefs","flatMap","doc","tags","tag","isNamepathDefiningTag","imports","delimiter","iterateInlineImports","potentialType","type","parsedType","tryParseType","parseType","traverse","nde","parentNode","element","currentNode","pathSegments","nodes","extraPathSegments","quotes","propertyOrBrackets","unshift","right","pathType","meta","quote","getFixer","matchingName","extrPathSegments","node","at","keys","key","length","newNode","shift","left","nameNode","src","source","tokens","stringify","unusedPathSegments","findMatchingTypedef","undefined","pthSegments","find","typedef","typedefNode","namepathMatch","pathSegment","push","matchingTypedef","reportJSDoc","name","slice","findMatchingImport","imprt","parsedImport","parseImportsExports","estreeToString","replace","trim","namedImportsModuleSpecifier","namedImports","values","namedImportNames","names","namespaceImports","namespaceImportsDefault","namespaceImportsNamespace","namespace","namespaceImportsModuleSpecifier","lastPathSegment","includes","matchingImport","lastPthSegment","fixer","programNode","getNodeByRangeIndex","insertTextBefore","lstPathSegment","mightHaveTypePosition","tagMightHaveTypePosition","hasTypePosition","Boolean","iterateAllJsdocs","docs","description","url","fixable","schema","additionalProperties","properties","enum","module"],"sources":["../../src/rules/preferImportTag.js"],"sourcesContent":["import iterateJsdoc, {\n parseComment,\n} from '../iterateJsdoc.js';\nimport {\n commentParserToESTree,\n estreeToString,\n // getJSDocComment,\n parse as parseType,\n stringify,\n traverse,\n tryParse as tryParseType,\n} from '@es-joy/jsdoccomment';\nimport {\n parseImportsExports,\n} from 'parse-imports-exports';\n\nexport default iterateJsdoc(({\n context,\n jsdoc,\n settings,\n sourceCode,\n utils,\n}) => {\n const {\n mode,\n } = settings;\n\n const {\n enableFixer = true,\n exemptTypedefs = true,\n outputType = 'namespaced-import',\n } = context.options[0] || {};\n\n const allComments = sourceCode.getAllComments();\n const comments = allComments\n .filter((comment) => {\n return (/^\\*(?!\\*)/v).test(comment.value);\n })\n .map((commentNode) => {\n return commentParserToESTree(\n parseComment(commentNode, ''), mode === 'permissive' ? 'typescript' : mode,\n );\n });\n\n const typedefs = comments\n .flatMap((doc) => {\n return doc.tags.filter(({\n tag,\n }) => {\n return utils.isNamepathDefiningTag(tag);\n });\n });\n\n const imports = comments\n .flatMap((doc) => {\n return doc.tags.filter(({\n tag,\n }) => {\n return tag === 'import';\n });\n }).map((tag) => {\n // Causes problems with stringification otherwise\n tag.delimiter = '';\n return tag;\n });\n\n /**\n * @param {import('@es-joy/jsdoccomment').JsdocTagWithInline} tag\n */\n const iterateInlineImports = (tag) => {\n const potentialType = tag.type;\n let parsedType;\n try {\n parsedType = mode === 'permissive' ?\n tryParseType(/** @type {string} */ (potentialType)) :\n parseType(/** @type {string} */ (potentialType), mode);\n } catch {\n return;\n }\n\n traverse(parsedType, (nde, parentNode) => {\n // @ts-expect-error Adding our own property for use below\n nde.parentNode = parentNode;\n });\n\n traverse(parsedType, (nde) => {\n const {\n element,\n type,\n } = /** @type {import('jsdoc-type-pratt-parser').ImportResult} */ (nde);\n if (type !== 'JsdocTypeImport') {\n return;\n }\n\n let currentNode = nde;\n\n /** @type {string[]} */\n const pathSegments = [];\n\n /** @type {import('jsdoc-type-pratt-parser').NamePathResult[]} */\n const nodes = [];\n\n /** @type {string[]} */\n const extraPathSegments = [];\n\n /** @type {(import('jsdoc-type-pratt-parser').QuoteStyle|undefined)[]} */\n const quotes = [];\n\n const propertyOrBrackets = /** @type {import('jsdoc-type-pratt-parser').NamePathResult['pathType'][]} */ ([]);\n\n // @ts-expect-error Referencing our own property added above\n while (currentNode && currentNode.parentNode) {\n // @ts-expect-error Referencing our own property added above\n currentNode = currentNode.parentNode;\n /* c8 ignore next 3 -- Guard */\n if (currentNode.type !== 'JsdocTypeNamePath') {\n break;\n }\n\n pathSegments.unshift(currentNode.right.value);\n nodes.unshift(currentNode);\n propertyOrBrackets.unshift(currentNode.pathType);\n quotes.unshift(currentNode.right.meta.quote);\n }\n\n /**\n * @param {string} matchingName\n * @param {string[]} extrPathSegments\n */\n const getFixer = (matchingName, extrPathSegments) => {\n return () => {\n /** @type {import('jsdoc-type-pratt-parser').NamePathResult|undefined} */\n let node = nodes.at(0);\n if (!node) {\n // Not really a NamePathResult, but will be converted later anyways\n node = /** @type {import('jsdoc-type-pratt-parser').NamePathResult} */ (\n /** @type {unknown} */\n (nde)\n );\n }\n\n const keys = /** @type {(keyof import('jsdoc-type-pratt-parser').NamePathResult)[]} */ (\n Object.keys(node)\n );\n\n for (const key of keys) {\n delete node[key];\n }\n\n if (extrPathSegments.length) {\n let newNode = /** @type {import('jsdoc-type-pratt-parser').NamePathResult} */ (\n /** @type {unknown} */\n (node)\n );\n while (extrPathSegments.length && newNode) {\n newNode.type = 'JsdocTypeNamePath';\n newNode.right = {\n meta: {\n quote: quotes.shift(),\n },\n type: 'JsdocTypeProperty',\n value: /** @type {string} */ (extrPathSegments.shift()),\n };\n\n newNode.pathType = /** @type {import('jsdoc-type-pratt-parser').NamePathResult['pathType']} */ (\n propertyOrBrackets.shift()\n );\n // @ts-expect-error Temporary\n newNode.left = {};\n newNode = /** @type {import('jsdoc-type-pratt-parser').NamePathResult} */ (\n newNode.left\n );\n }\n\n const nameNode = /** @type {import('jsdoc-type-pratt-parser').NameResult} */ (\n /** @type {unknown} */\n (newNode)\n );\n nameNode.type = 'JsdocTypeName';\n nameNode.value = matchingName;\n } else {\n const newNode = /** @type {import('jsdoc-type-pratt-parser').NameResult} */ (\n /** @type {unknown} */\n (node)\n );\n newNode.type = 'JsdocTypeName';\n newNode.value = matchingName;\n }\n\n for (const src of tag.source) {\n if (src.tokens.type) {\n src.tokens.type = `{${stringify(parsedType)}}`;\n break;\n }\n }\n };\n };\n\n /** @type {string[]} */\n let unusedPathSegments = [];\n\n const findMatchingTypedef = () => {\n // Don't want typedefs to find themselves\n if (!exemptTypedefs) {\n return undefined;\n }\n\n const pthSegments = [\n ...pathSegments,\n ];\n return typedefs.find((typedef) => {\n let typedefNode = typedef.parsedType;\n let namepathMatch;\n while (typedefNode && typedefNode.type === 'JsdocTypeNamePath') {\n const pathSegment = pthSegments.shift();\n if (!pathSegment) {\n namepathMatch = false;\n break;\n }\n\n if (typedefNode.right.value !== pathSegment) {\n if (namepathMatch === true) {\n // It stopped matching, so stop\n break;\n }\n\n extraPathSegments.push(pathSegment);\n namepathMatch = false;\n continue;\n }\n\n namepathMatch = true;\n\n unusedPathSegments = pthSegments;\n\n typedefNode = typedefNode.left;\n }\n\n return namepathMatch &&\n // `import('eslint')` matches\n typedefNode &&\n typedefNode.type === 'JsdocTypeImport' &&\n typedefNode.element.value === element.value;\n });\n };\n\n // Check @typedef's first as should be longest match, allowing\n // for shorter abbreviations\n const matchingTypedef = findMatchingTypedef();\n if (matchingTypedef) {\n utils.reportJSDoc(\n 'Inline `import()` found; using `@typedef`',\n tag,\n enableFixer ? getFixer(matchingTypedef.name, [\n ...extraPathSegments,\n ...unusedPathSegments.slice(-1),\n ...unusedPathSegments.slice(0, -1),\n ]) : null,\n );\n return;\n }\n\n const findMatchingImport = () => {\n for (const imprt of imports) {\n const parsedImport = parseImportsExports(\n estreeToString(imprt).replace(/^\\s*@/v, '').trim(),\n );\n\n const namedImportsModuleSpecifier = Object.keys(parsedImport.namedImports || {})[0];\n\n const namedImports = Object.values(parsedImport.namedImports || {})[0]?.[0];\n const namedImportNames = (namedImports && namedImports.names && Object.keys(namedImports.names)) ?? [];\n\n const namespaceImports = Object.values(parsedImport.namespaceImports || {})[0]?.[0];\n\n const namespaceImportsDefault = namespaceImports && namespaceImports.default;\n const namespaceImportsNamespace = namespaceImports && namespaceImports.namespace;\n const namespaceImportsModuleSpecifier = Object.keys(parsedImport.namespaceImports || {})[0];\n\n const lastPathSegment = pathSegments.at(-1);\n\n if (\n (namespaceImportsDefault &&\n namespaceImportsModuleSpecifier === element.value) ||\n (element.value === namedImportsModuleSpecifier && (\n (lastPathSegment && namedImportNames.includes(lastPathSegment)) ||\n lastPathSegment === 'default'\n )) ||\n (namespaceImportsNamespace &&\n namespaceImportsModuleSpecifier === element.value)\n ) {\n return {\n namedImportNames,\n namedImports,\n namedImportsModuleSpecifier,\n namespaceImports,\n namespaceImportsDefault,\n namespaceImportsModuleSpecifier,\n namespaceImportsNamespace,\n };\n }\n }\n\n return undefined;\n };\n\n const matchingImport = findMatchingImport();\n if (matchingImport) {\n const {\n namedImportNames,\n namedImports,\n namedImportsModuleSpecifier,\n namespaceImportsNamespace,\n } = matchingImport;\n if (!namedImportNames.length && namedImportsModuleSpecifier && namedImports.default) {\n utils.reportJSDoc(\n 'Inline `import()` found; prefer `@import`',\n tag,\n enableFixer ? getFixer(namedImports.default, []) : null,\n );\n return;\n }\n\n const lastPthSegment = pathSegments.at(-1);\n if (lastPthSegment && namedImportNames.includes(lastPthSegment)) {\n utils.reportJSDoc(\n 'Inline `import()` found; prefer `@import`',\n tag,\n enableFixer ? getFixer(lastPthSegment, pathSegments.slice(0, -1)) : null,\n );\n return;\n }\n\n if (namespaceImportsNamespace) {\n utils.reportJSDoc(\n 'Inline `import()` found; prefer `@import`',\n tag,\n enableFixer ? getFixer(namespaceImportsNamespace, [\n ...pathSegments,\n ]) : null,\n );\n return;\n }\n }\n\n if (!pathSegments.length) {\n utils.reportJSDoc(\n 'Inline `import()` found; prefer `@import`',\n tag,\n enableFixer ? (fixer) => {\n getFixer(element.value, [])();\n\n const programNode = sourceCode.getNodeByRangeIndex(0);\n return fixer.insertTextBefore(\n /** @type {import('estree').Program} */ (programNode),\n `/** @import * as ${element.value} from '${element.value}'; */`,\n );\n } : null,\n );\n return;\n }\n\n const lstPathSegment = pathSegments.at(-1);\n if (lstPathSegment && lstPathSegment === 'default') {\n utils.reportJSDoc(\n 'Inline `import()` found; prefer `@import`',\n tag,\n enableFixer ? (fixer) => {\n getFixer(element.value, [])();\n\n const programNode = sourceCode.getNodeByRangeIndex(0);\n return fixer.insertTextBefore(\n /** @type {import('estree').Program} */ (programNode),\n `/** @import ${element.value} from '${element.value}'; */`,\n );\n } : null,\n );\n return;\n }\n\n utils.reportJSDoc(\n 'Inline `import()` found; prefer `@import`',\n tag,\n enableFixer ? (fixer) => {\n if (outputType === 'namespaced-import') {\n getFixer(element.value, [\n ...pathSegments,\n ])();\n } else {\n getFixer(\n /** @type {string} */ (pathSegments.at(-1)),\n pathSegments.slice(0, -1),\n )();\n }\n\n const programNode = sourceCode.getNodeByRangeIndex(0);\n return fixer.insertTextBefore(\n /** @type {import('estree').Program} */ (programNode),\n outputType === 'namespaced-import' ?\n `/** @import * as ${element.value} from '${element.value}'; */` :\n `/** @import { ${pathSegments.at(-1)} } from '${element.value}'; */`,\n );\n } : null,\n );\n });\n };\n\n for (const tag of jsdoc.tags) {\n const mightHaveTypePosition = utils.tagMightHaveTypePosition(tag.tag);\n const hasTypePosition = mightHaveTypePosition === true && Boolean(tag.type);\n if (hasTypePosition && (!exemptTypedefs || !utils.isNamepathDefiningTag(tag.tag))) {\n iterateInlineImports(tag);\n }\n }\n}, {\n iterateAllJsdocs: true,\n meta: {\n docs: {\n description: 'Prefer `@import` tags to inline `import()` statements.',\n url: 'https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/prefer-import-tag.md#repos-sticky-header',\n },\n fixable: 'code',\n schema: [\n {\n additionalProperties: false,\n properties: {\n enableFixer: {\n description: 'Whether or not to enable the fixer to add `@import` tags.',\n type: 'boolean',\n },\n exemptTypedefs: {\n description: 'Whether to allow `import()` statements within `@typedef`',\n type: 'boolean',\n },\n\n // We might add `typedef` and `typedef-local-only`, but also raises\n // question of how deep the generated typedef should be\n outputType: {\n description: 'What kind of `@import` to generate when no matching `@typedef` or `@import` is found',\n enum: [\n 'named-import',\n 'namespaced-import',\n ],\n type: 'string',\n },\n },\n type: 'object',\n },\n ],\n type: 'suggestion',\n },\n});\n"],"mappings":"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","ignoreList":[]}
|
package/dist/rules.d.ts
CHANGED
|
@@ -1250,6 +1250,10 @@ export interface Rules {
|
|
|
1250
1250
|
| []
|
|
1251
1251
|
| [
|
|
1252
1252
|
{
|
|
1253
|
+
/**
|
|
1254
|
+
* Whether to check typedefs for use within the file
|
|
1255
|
+
*/
|
|
1256
|
+
checkUsedTypedefs?: boolean;
|
|
1253
1257
|
/**
|
|
1254
1258
|
* This array can be populated to indicate other types which
|
|
1255
1259
|
* are automatically considered as defined (in addition to globals, etc.).
|
|
@@ -1259,7 +1263,7 @@ export interface Rules {
|
|
|
1259
1263
|
/**
|
|
1260
1264
|
* Whether to disable reporting of errors. Defaults to
|
|
1261
1265
|
* `false`. This may be set to `true` in order to take advantage of only
|
|
1262
|
-
* marking defined variables as used.
|
|
1266
|
+
* marking defined variables as used or checking used typedefs.
|
|
1263
1267
|
*/
|
|
1264
1268
|
disableReporting?: boolean;
|
|
1265
1269
|
/**
|
|
@@ -1272,6 +1276,26 @@ export interface Rules {
|
|
|
1272
1276
|
}
|
|
1273
1277
|
];
|
|
1274
1278
|
|
|
1279
|
+
/** Prefer `@import` tags to inline `import()` statements. */
|
|
1280
|
+
"jsdoc/prefer-import-tag":
|
|
1281
|
+
| []
|
|
1282
|
+
| [
|
|
1283
|
+
{
|
|
1284
|
+
/**
|
|
1285
|
+
* Whether or not to enable the fixer to add `@import` tags.
|
|
1286
|
+
*/
|
|
1287
|
+
enableFixer?: boolean;
|
|
1288
|
+
/**
|
|
1289
|
+
* Whether to allow `import()` statements within `@typedef`
|
|
1290
|
+
*/
|
|
1291
|
+
exemptTypedefs?: boolean;
|
|
1292
|
+
/**
|
|
1293
|
+
* What kind of `@import` to generate when no matching `@typedef` or `@import` is found
|
|
1294
|
+
*/
|
|
1295
|
+
outputType?: "named-import" | "namespaced-import";
|
|
1296
|
+
}
|
|
1297
|
+
];
|
|
1298
|
+
|
|
1275
1299
|
/** Reports use of `any` or `*` type */
|
|
1276
1300
|
"jsdoc/reject-any-type": [];
|
|
1277
1301
|
|
package/package.json
CHANGED
package/src/index-cjs.js
CHANGED
|
@@ -37,6 +37,7 @@ import noMultiAsterisks from './rules/noMultiAsterisks.js';
|
|
|
37
37
|
import noRestrictedSyntax from './rules/noRestrictedSyntax.js';
|
|
38
38
|
import noTypes from './rules/noTypes.js';
|
|
39
39
|
import noUndefinedTypes from './rules/noUndefinedTypes.js';
|
|
40
|
+
import preferImportTag from './rules/preferImportTag.js';
|
|
40
41
|
import requireAsteriskPrefix from './rules/requireAsteriskPrefix.js';
|
|
41
42
|
import requireDescription from './rules/requireDescription.js';
|
|
42
43
|
import requireDescriptionCompleteSentence from './rules/requireDescriptionCompleteSentence.js';
|
|
@@ -111,6 +112,7 @@ index.rules = {
|
|
|
111
112
|
'no-restricted-syntax': noRestrictedSyntax,
|
|
112
113
|
'no-types': noTypes,
|
|
113
114
|
'no-undefined-types': noUndefinedTypes,
|
|
115
|
+
'prefer-import-tag': preferImportTag,
|
|
114
116
|
'reject-any-type': buildRejectOrPreferRuleDefinition({
|
|
115
117
|
description: 'Reports use of `any` or `*` type',
|
|
116
118
|
overrideSettings: {
|
|
@@ -283,6 +285,7 @@ const createRecommendedRuleset = (warnOrError, flatName) => {
|
|
|
283
285
|
'jsdoc/no-restricted-syntax': 'off',
|
|
284
286
|
'jsdoc/no-types': 'off',
|
|
285
287
|
'jsdoc/no-undefined-types': warnOrError,
|
|
288
|
+
'jsdoc/prefer-import-tag': 'off',
|
|
286
289
|
'jsdoc/reject-any-type': warnOrError,
|
|
287
290
|
'jsdoc/reject-function-type': warnOrError,
|
|
288
291
|
'jsdoc/require-asterisk-prefix': 'off',
|
package/src/index.js
CHANGED
|
@@ -43,6 +43,7 @@ import noMultiAsterisks from './rules/noMultiAsterisks.js';
|
|
|
43
43
|
import noRestrictedSyntax from './rules/noRestrictedSyntax.js';
|
|
44
44
|
import noTypes from './rules/noTypes.js';
|
|
45
45
|
import noUndefinedTypes from './rules/noUndefinedTypes.js';
|
|
46
|
+
import preferImportTag from './rules/preferImportTag.js';
|
|
46
47
|
import requireAsteriskPrefix from './rules/requireAsteriskPrefix.js';
|
|
47
48
|
import requireDescription from './rules/requireDescription.js';
|
|
48
49
|
import requireDescriptionCompleteSentence from './rules/requireDescriptionCompleteSentence.js';
|
|
@@ -117,6 +118,7 @@ index.rules = {
|
|
|
117
118
|
'no-restricted-syntax': noRestrictedSyntax,
|
|
118
119
|
'no-types': noTypes,
|
|
119
120
|
'no-undefined-types': noUndefinedTypes,
|
|
121
|
+
'prefer-import-tag': preferImportTag,
|
|
120
122
|
'reject-any-type': buildRejectOrPreferRuleDefinition({
|
|
121
123
|
description: 'Reports use of `any` or `*` type',
|
|
122
124
|
overrideSettings: {
|
|
@@ -289,6 +291,7 @@ const createRecommendedRuleset = (warnOrError, flatName) => {
|
|
|
289
291
|
'jsdoc/no-restricted-syntax': 'off',
|
|
290
292
|
'jsdoc/no-types': 'off',
|
|
291
293
|
'jsdoc/no-undefined-types': warnOrError,
|
|
294
|
+
'jsdoc/prefer-import-tag': 'off',
|
|
292
295
|
'jsdoc/reject-any-type': warnOrError,
|
|
293
296
|
'jsdoc/reject-function-type': warnOrError,
|
|
294
297
|
'jsdoc/require-asterisk-prefix': 'off',
|
package/src/iterateJsdoc.js
CHANGED
|
@@ -92,6 +92,10 @@ import esquery from 'esquery';
|
|
|
92
92
|
* parseClosureTemplateTag: ParseClosureTemplateTag,
|
|
93
93
|
* getPreferredTagNameObject: GetPreferredTagNameObject,
|
|
94
94
|
* pathDoesNotBeginWith: import('./jsdocUtils.js').PathDoesNotBeginWith
|
|
95
|
+
* isNamepathDefiningTag: IsNamepathX,
|
|
96
|
+
* isNamepathReferencingTag: IsNamepathX,
|
|
97
|
+
* isNamepathOrUrlReferencingTag: IsNamepathX,
|
|
98
|
+
* tagMightHaveNamepath: IsNamepathX,
|
|
95
99
|
* }} BasicUtils
|
|
96
100
|
*/
|
|
97
101
|
|
|
@@ -116,7 +120,7 @@ import esquery from 'esquery';
|
|
|
116
120
|
* @callback ReportJSDoc
|
|
117
121
|
* @param {string} msg
|
|
118
122
|
* @param {null|import('comment-parser').Spec|{line: Integer, column?: Integer}} [tag]
|
|
119
|
-
* @param {(() => void)|null} [handler]
|
|
123
|
+
* @param {((fixer: import('eslint').Rule.RuleFixer) => import('eslint').Rule.Fix|void)|null} [handler]
|
|
120
124
|
* @param {boolean} [specRewire]
|
|
121
125
|
* @param {undefined|{
|
|
122
126
|
* [key: string]: string
|
|
@@ -566,7 +570,8 @@ const {
|
|
|
566
570
|
* hasNonComment: number,
|
|
567
571
|
* hasNonCommentBeforeTag: {
|
|
568
572
|
* [key: string]: boolean|number
|
|
569
|
-
* }
|
|
573
|
+
* },
|
|
574
|
+
* foundTypedefValues: string[]
|
|
570
575
|
* }} StateObject
|
|
571
576
|
*/
|
|
572
577
|
|
|
@@ -599,6 +604,24 @@ const getBasicUtils = (context, {
|
|
|
599
604
|
/** @type {BasicUtils} */
|
|
600
605
|
const utils = {};
|
|
601
606
|
|
|
607
|
+
for (const method of [
|
|
608
|
+
'isNamepathDefiningTag',
|
|
609
|
+
'isNamepathReferencingTag',
|
|
610
|
+
'isNamepathOrUrlReferencingTag',
|
|
611
|
+
'tagMightHaveNamepath',
|
|
612
|
+
]) {
|
|
613
|
+
/** @type {IsNamepathX} */
|
|
614
|
+
utils[
|
|
615
|
+
/** @type {"isNamepathDefiningTag"|"isNamepathReferencingTag"|"isNamepathOrUrlReferencingTag"|"tagMightHaveNamepath"} */ (
|
|
616
|
+
method
|
|
617
|
+
)] = (tagName) => {
|
|
618
|
+
return jsdocUtils[
|
|
619
|
+
/** @type {"isNamepathDefiningTag"|"isNamepathReferencingTag"|"isNamepathOrUrlReferencingTag"|"tagMightHaveNamepath"} */
|
|
620
|
+
(method)
|
|
621
|
+
](tagName);
|
|
622
|
+
};
|
|
623
|
+
}
|
|
624
|
+
|
|
602
625
|
/** @type {ReportSettings} */
|
|
603
626
|
utils.reportSettings = (message) => {
|
|
604
627
|
context.report({
|
|
@@ -771,7 +794,8 @@ const getUtils = (
|
|
|
771
794
|
report(msg, handler ? /** @type {import('eslint').Rule.ReportFixer} */ (
|
|
772
795
|
fixer,
|
|
773
796
|
) => {
|
|
774
|
-
handler();
|
|
797
|
+
const extraFix = handler(fixer);
|
|
798
|
+
|
|
775
799
|
const replacement = utils.stringify(jsdoc, specRewire);
|
|
776
800
|
|
|
777
801
|
if (!replacement) {
|
|
@@ -780,21 +804,38 @@ const getUtils = (
|
|
|
780
804
|
0, jsdocNode.range[0],
|
|
781
805
|
).search(/\n[ \t]*$/v);
|
|
782
806
|
if (lastLineBreakPos > -1) {
|
|
783
|
-
return
|
|
784
|
-
|
|
785
|
-
|
|
807
|
+
return [
|
|
808
|
+
fixer.removeRange([
|
|
809
|
+
lastLineBreakPos, jsdocNode.range[1],
|
|
810
|
+
]),
|
|
811
|
+
/* c8 ignore next 2 -- Guard */
|
|
812
|
+
...(extraFix ? [
|
|
813
|
+
extraFix,
|
|
814
|
+
] : []),
|
|
815
|
+
];
|
|
786
816
|
}
|
|
787
817
|
|
|
788
|
-
return
|
|
789
|
-
|
|
790
|
-
[
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
818
|
+
return [
|
|
819
|
+
fixer.removeRange(
|
|
820
|
+
(/\s/v).test(text.charAt(jsdocNode.range[1])) ?
|
|
821
|
+
[
|
|
822
|
+
jsdocNode.range[0], jsdocNode.range[1] + 1,
|
|
823
|
+
] :
|
|
824
|
+
jsdocNode.range,
|
|
825
|
+
),
|
|
826
|
+
/* c8 ignore next 2 -- Guard */
|
|
827
|
+
...(extraFix ? [
|
|
828
|
+
extraFix,
|
|
829
|
+
] : []),
|
|
830
|
+
];
|
|
795
831
|
}
|
|
796
832
|
|
|
797
|
-
return
|
|
833
|
+
return [
|
|
834
|
+
fixer.replaceText(jsdocNode, replacement),
|
|
835
|
+
...(extraFix ? [
|
|
836
|
+
extraFix,
|
|
837
|
+
] : []),
|
|
838
|
+
];
|
|
798
839
|
} : null, tag, data);
|
|
799
840
|
};
|
|
800
841
|
|
|
@@ -1525,24 +1566,6 @@ const getUtils = (
|
|
|
1525
1566
|
};
|
|
1526
1567
|
}
|
|
1527
1568
|
|
|
1528
|
-
for (const method of [
|
|
1529
|
-
'isNamepathDefiningTag',
|
|
1530
|
-
'isNamepathReferencingTag',
|
|
1531
|
-
'isNamepathOrUrlReferencingTag',
|
|
1532
|
-
'tagMightHaveNamepath',
|
|
1533
|
-
]) {
|
|
1534
|
-
/** @type {IsNamepathX} */
|
|
1535
|
-
utils[
|
|
1536
|
-
/** @type {"isNamepathDefiningTag"|"isNamepathReferencingTag"|"isNamepathOrUrlReferencingTag"|"tagMightHaveNamepath"} */ (
|
|
1537
|
-
method
|
|
1538
|
-
)] = (tagName) => {
|
|
1539
|
-
return jsdocUtils[
|
|
1540
|
-
/** @type {"isNamepathDefiningTag"|"isNamepathReferencingTag"|"isNamepathOrUrlReferencingTag"|"tagMightHaveNamepath"} */
|
|
1541
|
-
(method)
|
|
1542
|
-
](tagName);
|
|
1543
|
-
};
|
|
1544
|
-
}
|
|
1545
|
-
|
|
1546
1569
|
/** @type {GetTagStructureForMode} */
|
|
1547
1570
|
utils.getTagStructureForMode = (mde) => {
|
|
1548
1571
|
return jsdocUtils.getTagStructureForMode(mde, settings.structuredTags);
|
|
@@ -59,8 +59,12 @@ export default iterateJsdoc(({
|
|
|
59
59
|
report,
|
|
60
60
|
settings,
|
|
61
61
|
sourceCode,
|
|
62
|
+
state,
|
|
62
63
|
utils,
|
|
63
64
|
}) => {
|
|
65
|
+
/** @type {string[]} */
|
|
66
|
+
const foundTypedefValues = [];
|
|
67
|
+
|
|
64
68
|
const {
|
|
65
69
|
scopeManager,
|
|
66
70
|
} = sourceCode;
|
|
@@ -73,11 +77,13 @@ export default iterateJsdoc(({
|
|
|
73
77
|
const
|
|
74
78
|
/**
|
|
75
79
|
* @type {{
|
|
80
|
+
* checkUsedTypedefs: boolean
|
|
76
81
|
* definedTypes: string[],
|
|
77
82
|
* disableReporting: boolean,
|
|
78
|
-
* markVariablesAsUsed: boolean
|
|
83
|
+
* markVariablesAsUsed: boolean,
|
|
79
84
|
* }}
|
|
80
85
|
*/ {
|
|
86
|
+
checkUsedTypedefs = false,
|
|
81
87
|
definedTypes = [],
|
|
82
88
|
disableReporting = false,
|
|
83
89
|
markVariablesAsUsed = true,
|
|
@@ -128,14 +134,16 @@ export default iterateJsdoc(({
|
|
|
128
134
|
return commentNode.value.replace(/^\s*globals/v, '').trim().split(/,\s*/v);
|
|
129
135
|
}).concat(Object.keys(context.languageOptions.globals ?? []));
|
|
130
136
|
|
|
131
|
-
const
|
|
137
|
+
const typedefs = comments
|
|
132
138
|
.flatMap((doc) => {
|
|
133
139
|
return doc.tags.filter(({
|
|
134
140
|
tag,
|
|
135
141
|
}) => {
|
|
136
142
|
return utils.isNamepathDefiningTag(tag);
|
|
137
143
|
});
|
|
138
|
-
})
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
const typedefDeclarations = typedefs
|
|
139
147
|
.map((tag) => {
|
|
140
148
|
return tag.name;
|
|
141
149
|
});
|
|
@@ -204,9 +212,9 @@ export default iterateJsdoc(({
|
|
|
204
212
|
return [];
|
|
205
213
|
}
|
|
206
214
|
|
|
207
|
-
const
|
|
215
|
+
const jsdc = parseComment(commentNode, '');
|
|
208
216
|
|
|
209
|
-
return
|
|
217
|
+
return jsdc.tags.filter((tag) => {
|
|
210
218
|
return tag.tag === 'template';
|
|
211
219
|
});
|
|
212
220
|
};
|
|
@@ -510,10 +518,74 @@ export default iterateJsdoc(({
|
|
|
510
518
|
context.markVariableAsUsed(val);
|
|
511
519
|
}
|
|
512
520
|
}
|
|
521
|
+
|
|
522
|
+
if (checkUsedTypedefs && typedefDeclarations.includes(val)) {
|
|
523
|
+
foundTypedefValues.push(val);
|
|
524
|
+
}
|
|
513
525
|
}
|
|
514
526
|
});
|
|
515
527
|
}
|
|
528
|
+
|
|
529
|
+
state.foundTypedefValues = foundTypedefValues;
|
|
516
530
|
}, {
|
|
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
|
+
},
|
|
517
589
|
iterateAllJsdocs: true,
|
|
518
590
|
meta: {
|
|
519
591
|
docs: {
|
|
@@ -524,6 +596,10 @@ export default iterateJsdoc(({
|
|
|
524
596
|
{
|
|
525
597
|
additionalProperties: false,
|
|
526
598
|
properties: {
|
|
599
|
+
checkUsedTypedefs: {
|
|
600
|
+
description: 'Whether to check typedefs for use within the file',
|
|
601
|
+
type: 'boolean',
|
|
602
|
+
},
|
|
527
603
|
definedTypes: {
|
|
528
604
|
description: `This array can be populated to indicate other types which
|
|
529
605
|
are automatically considered as defined (in addition to globals, etc.).
|
|
@@ -536,7 +612,7 @@ Defaults to an empty array.`,
|
|
|
536
612
|
disableReporting: {
|
|
537
613
|
description: `Whether to disable reporting of errors. Defaults to
|
|
538
614
|
\`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.`,
|
|
540
616
|
type: 'boolean',
|
|
541
617
|
},
|
|
542
618
|
markVariablesAsUsed: {
|