eslint-plugin-jsdoc 60.1.1 → 60.2.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 +1 -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 +7 -5
- package/dist/iterateJsdoc.cjs.map +1 -1
- package/dist/iterateJsdoc.d.ts +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 +20 -0
- package/package.json +1 -1
- package/src/index-cjs.js +3 -0
- package/src/index.js +3 -0
- package/src/iterateJsdoc.js +31 -13
- package/src/rules/preferImportTag.js +452 -0
- package/src/rules.d.ts +20 -0
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
var _iterateJsdoc = _interopRequireWildcard(require("../iterateJsdoc.cjs"));
|
|
8
|
+
var _jsdoccomment = require("@es-joy/jsdoccomment");
|
|
9
|
+
var _parseImportsExports = require("parse-imports-exports");
|
|
10
|
+
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
|
|
11
|
+
var _default = exports.default = (0, _iterateJsdoc.default)(({
|
|
12
|
+
context,
|
|
13
|
+
jsdoc,
|
|
14
|
+
settings,
|
|
15
|
+
sourceCode,
|
|
16
|
+
utils
|
|
17
|
+
}) => {
|
|
18
|
+
const {
|
|
19
|
+
mode
|
|
20
|
+
} = settings;
|
|
21
|
+
const {
|
|
22
|
+
enableFixer = true,
|
|
23
|
+
exemptTypedefs = true,
|
|
24
|
+
outputType = 'namespaced-import'
|
|
25
|
+
} = context.options[0] || {};
|
|
26
|
+
const allComments = sourceCode.getAllComments();
|
|
27
|
+
const comments = allComments.filter(comment => {
|
|
28
|
+
return /^\*(?!\*)/v.test(comment.value);
|
|
29
|
+
}).map(commentNode => {
|
|
30
|
+
return (0, _jsdoccomment.commentParserToESTree)((0, _iterateJsdoc.parseComment)(commentNode, ''), mode === 'permissive' ? 'typescript' : mode);
|
|
31
|
+
});
|
|
32
|
+
const typedefs = comments.flatMap(doc => {
|
|
33
|
+
return doc.tags.filter(({
|
|
34
|
+
tag
|
|
35
|
+
}) => {
|
|
36
|
+
return utils.isNamepathDefiningTag(tag);
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
const imports = comments.flatMap(doc => {
|
|
40
|
+
return doc.tags.filter(({
|
|
41
|
+
tag
|
|
42
|
+
}) => {
|
|
43
|
+
return tag === 'import';
|
|
44
|
+
});
|
|
45
|
+
}).map(tag => {
|
|
46
|
+
// Causes problems with stringification otherwise
|
|
47
|
+
tag.delimiter = '';
|
|
48
|
+
return tag;
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* @param {import('@es-joy/jsdoccomment').JsdocTagWithInline} tag
|
|
53
|
+
*/
|
|
54
|
+
const iterateInlineImports = tag => {
|
|
55
|
+
const potentialType = tag.type;
|
|
56
|
+
let parsedType;
|
|
57
|
+
try {
|
|
58
|
+
parsedType = mode === 'permissive' ? (0, _jsdoccomment.tryParse)(/** @type {string} */potentialType) : (0, _jsdoccomment.parse)(/** @type {string} */potentialType, mode);
|
|
59
|
+
} catch {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
(0, _jsdoccomment.traverse)(parsedType, (nde, parentNode) => {
|
|
63
|
+
// @ts-expect-error Adding our own property for use below
|
|
64
|
+
nde.parentNode = parentNode;
|
|
65
|
+
});
|
|
66
|
+
(0, _jsdoccomment.traverse)(parsedType, nde => {
|
|
67
|
+
const {
|
|
68
|
+
element,
|
|
69
|
+
type
|
|
70
|
+
} = /** @type {import('jsdoc-type-pratt-parser').ImportResult} */nde;
|
|
71
|
+
if (type !== 'JsdocTypeImport') {
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
let currentNode = nde;
|
|
75
|
+
|
|
76
|
+
/** @type {string[]} */
|
|
77
|
+
const pathSegments = [];
|
|
78
|
+
|
|
79
|
+
/** @type {import('jsdoc-type-pratt-parser').NamePathResult[]} */
|
|
80
|
+
const nodes = [];
|
|
81
|
+
|
|
82
|
+
/** @type {string[]} */
|
|
83
|
+
const extraPathSegments = [];
|
|
84
|
+
|
|
85
|
+
/** @type {(import('jsdoc-type-pratt-parser').QuoteStyle|undefined)[]} */
|
|
86
|
+
const quotes = [];
|
|
87
|
+
const propertyOrBrackets = /** @type {import('jsdoc-type-pratt-parser').NamePathResult['pathType'][]} */[];
|
|
88
|
+
|
|
89
|
+
// @ts-expect-error Referencing our own property added above
|
|
90
|
+
while (currentNode && currentNode.parentNode) {
|
|
91
|
+
// @ts-expect-error Referencing our own property added above
|
|
92
|
+
currentNode = currentNode.parentNode;
|
|
93
|
+
/* c8 ignore next 3 -- Guard */
|
|
94
|
+
if (currentNode.type !== 'JsdocTypeNamePath') {
|
|
95
|
+
break;
|
|
96
|
+
}
|
|
97
|
+
pathSegments.unshift(currentNode.right.value);
|
|
98
|
+
nodes.unshift(currentNode);
|
|
99
|
+
propertyOrBrackets.unshift(currentNode.pathType);
|
|
100
|
+
quotes.unshift(currentNode.right.meta.quote);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* @param {string} matchingName
|
|
105
|
+
* @param {string[]} extrPathSegments
|
|
106
|
+
*/
|
|
107
|
+
const getFixer = (matchingName, extrPathSegments) => {
|
|
108
|
+
return () => {
|
|
109
|
+
/** @type {import('jsdoc-type-pratt-parser').NamePathResult|undefined} */
|
|
110
|
+
let node = nodes.at(0);
|
|
111
|
+
if (!node) {
|
|
112
|
+
// Not really a NamePathResult, but will be converted later anyways
|
|
113
|
+
node = /** @type {import('jsdoc-type-pratt-parser').NamePathResult} */
|
|
114
|
+
/** @type {unknown} */
|
|
115
|
+
nde;
|
|
116
|
+
}
|
|
117
|
+
const keys = /** @type {(keyof import('jsdoc-type-pratt-parser').NamePathResult)[]} */
|
|
118
|
+
Object.keys(node);
|
|
119
|
+
for (const key of keys) {
|
|
120
|
+
delete node[key];
|
|
121
|
+
}
|
|
122
|
+
if (extrPathSegments.length) {
|
|
123
|
+
let newNode = /** @type {import('jsdoc-type-pratt-parser').NamePathResult} */
|
|
124
|
+
/** @type {unknown} */
|
|
125
|
+
node;
|
|
126
|
+
while (extrPathSegments.length && newNode) {
|
|
127
|
+
newNode.type = 'JsdocTypeNamePath';
|
|
128
|
+
newNode.right = {
|
|
129
|
+
meta: {
|
|
130
|
+
quote: quotes.shift()
|
|
131
|
+
},
|
|
132
|
+
type: 'JsdocTypeProperty',
|
|
133
|
+
value: (/** @type {string} */extrPathSegments.shift())
|
|
134
|
+
};
|
|
135
|
+
newNode.pathType = /** @type {import('jsdoc-type-pratt-parser').NamePathResult['pathType']} */
|
|
136
|
+
propertyOrBrackets.shift();
|
|
137
|
+
// @ts-expect-error Temporary
|
|
138
|
+
newNode.left = {};
|
|
139
|
+
newNode = /** @type {import('jsdoc-type-pratt-parser').NamePathResult} */
|
|
140
|
+
newNode.left;
|
|
141
|
+
}
|
|
142
|
+
const nameNode = /** @type {import('jsdoc-type-pratt-parser').NameResult} */
|
|
143
|
+
/** @type {unknown} */
|
|
144
|
+
newNode;
|
|
145
|
+
nameNode.type = 'JsdocTypeName';
|
|
146
|
+
nameNode.value = matchingName;
|
|
147
|
+
} else {
|
|
148
|
+
const newNode = /** @type {import('jsdoc-type-pratt-parser').NameResult} */
|
|
149
|
+
/** @type {unknown} */
|
|
150
|
+
node;
|
|
151
|
+
newNode.type = 'JsdocTypeName';
|
|
152
|
+
newNode.value = matchingName;
|
|
153
|
+
}
|
|
154
|
+
for (const src of tag.source) {
|
|
155
|
+
if (src.tokens.type) {
|
|
156
|
+
src.tokens.type = `{${(0, _jsdoccomment.stringify)(parsedType)}}`;
|
|
157
|
+
break;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
/** @type {string[]} */
|
|
164
|
+
let unusedPathSegments = [];
|
|
165
|
+
const findMatchingTypedef = () => {
|
|
166
|
+
// Don't want typedefs to find themselves
|
|
167
|
+
if (!exemptTypedefs) {
|
|
168
|
+
return undefined;
|
|
169
|
+
}
|
|
170
|
+
const pthSegments = [...pathSegments];
|
|
171
|
+
return typedefs.find(typedef => {
|
|
172
|
+
let typedefNode = typedef.parsedType;
|
|
173
|
+
let namepathMatch;
|
|
174
|
+
while (typedefNode && typedefNode.type === 'JsdocTypeNamePath') {
|
|
175
|
+
const pathSegment = pthSegments.shift();
|
|
176
|
+
if (!pathSegment) {
|
|
177
|
+
namepathMatch = false;
|
|
178
|
+
break;
|
|
179
|
+
}
|
|
180
|
+
if (typedefNode.right.value !== pathSegment) {
|
|
181
|
+
if (namepathMatch === true) {
|
|
182
|
+
// It stopped matching, so stop
|
|
183
|
+
break;
|
|
184
|
+
}
|
|
185
|
+
extraPathSegments.push(pathSegment);
|
|
186
|
+
namepathMatch = false;
|
|
187
|
+
continue;
|
|
188
|
+
}
|
|
189
|
+
namepathMatch = true;
|
|
190
|
+
unusedPathSegments = pthSegments;
|
|
191
|
+
typedefNode = typedefNode.left;
|
|
192
|
+
}
|
|
193
|
+
return namepathMatch &&
|
|
194
|
+
// `import('eslint')` matches
|
|
195
|
+
typedefNode && typedefNode.type === 'JsdocTypeImport' && typedefNode.element.value === element.value;
|
|
196
|
+
});
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
// Check @typedef's first as should be longest match, allowing
|
|
200
|
+
// for shorter abbreviations
|
|
201
|
+
const matchingTypedef = findMatchingTypedef();
|
|
202
|
+
if (matchingTypedef) {
|
|
203
|
+
utils.reportJSDoc('Inline `import()` found; using `@typedef`', tag, enableFixer ? getFixer(matchingTypedef.name, [...extraPathSegments, ...unusedPathSegments.slice(-1), ...unusedPathSegments.slice(0, -1)]) : null);
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
const findMatchingImport = () => {
|
|
207
|
+
for (const imprt of imports) {
|
|
208
|
+
const parsedImport = (0, _parseImportsExports.parseImportsExports)((0, _jsdoccomment.estreeToString)(imprt).replace(/^\s*@/v, '').trim());
|
|
209
|
+
const namedImportsModuleSpecifier = Object.keys(parsedImport.namedImports || {})[0];
|
|
210
|
+
const namedImports = Object.values(parsedImport.namedImports || {})[0]?.[0];
|
|
211
|
+
const namedImportNames = (namedImports && namedImports.names && Object.keys(namedImports.names)) ?? [];
|
|
212
|
+
const namespaceImports = Object.values(parsedImport.namespaceImports || {})[0]?.[0];
|
|
213
|
+
const namespaceImportsDefault = namespaceImports && namespaceImports.default;
|
|
214
|
+
const namespaceImportsNamespace = namespaceImports && namespaceImports.namespace;
|
|
215
|
+
const namespaceImportsModuleSpecifier = Object.keys(parsedImport.namespaceImports || {})[0];
|
|
216
|
+
const lastPathSegment = pathSegments.at(-1);
|
|
217
|
+
if (namespaceImportsDefault && namespaceImportsModuleSpecifier === element.value || element.value === namedImportsModuleSpecifier && (lastPathSegment && namedImportNames.includes(lastPathSegment) || lastPathSegment === 'default') || namespaceImportsNamespace && namespaceImportsModuleSpecifier === element.value) {
|
|
218
|
+
return {
|
|
219
|
+
namedImportNames,
|
|
220
|
+
namedImports,
|
|
221
|
+
namedImportsModuleSpecifier,
|
|
222
|
+
namespaceImports,
|
|
223
|
+
namespaceImportsDefault,
|
|
224
|
+
namespaceImportsModuleSpecifier,
|
|
225
|
+
namespaceImportsNamespace
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
return undefined;
|
|
230
|
+
};
|
|
231
|
+
const matchingImport = findMatchingImport();
|
|
232
|
+
if (matchingImport) {
|
|
233
|
+
const {
|
|
234
|
+
namedImportNames,
|
|
235
|
+
namedImports,
|
|
236
|
+
namedImportsModuleSpecifier,
|
|
237
|
+
namespaceImportsNamespace
|
|
238
|
+
} = matchingImport;
|
|
239
|
+
if (!namedImportNames.length && namedImportsModuleSpecifier && namedImports.default) {
|
|
240
|
+
utils.reportJSDoc('Inline `import()` found; prefer `@import`', tag, enableFixer ? getFixer(namedImports.default, []) : null);
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
const lastPthSegment = pathSegments.at(-1);
|
|
244
|
+
if (lastPthSegment && namedImportNames.includes(lastPthSegment)) {
|
|
245
|
+
utils.reportJSDoc('Inline `import()` found; prefer `@import`', tag, enableFixer ? getFixer(lastPthSegment, pathSegments.slice(0, -1)) : null);
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
if (namespaceImportsNamespace) {
|
|
249
|
+
utils.reportJSDoc('Inline `import()` found; prefer `@import`', tag, enableFixer ? getFixer(namespaceImportsNamespace, [...pathSegments]) : null);
|
|
250
|
+
return;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
if (!pathSegments.length) {
|
|
254
|
+
utils.reportJSDoc('Inline `import()` found; prefer `@import`', tag, enableFixer ? fixer => {
|
|
255
|
+
getFixer(element.value, [])();
|
|
256
|
+
const programNode = sourceCode.getNodeByRangeIndex(0);
|
|
257
|
+
return fixer.insertTextBefore(/** @type {import('estree').Program} */programNode, `/** @import * as ${element.value} from '${element.value}'; */`);
|
|
258
|
+
} : null);
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
const lstPathSegment = pathSegments.at(-1);
|
|
262
|
+
if (lstPathSegment && lstPathSegment === 'default') {
|
|
263
|
+
utils.reportJSDoc('Inline `import()` found; prefer `@import`', tag, enableFixer ? fixer => {
|
|
264
|
+
getFixer(element.value, [])();
|
|
265
|
+
const programNode = sourceCode.getNodeByRangeIndex(0);
|
|
266
|
+
return fixer.insertTextBefore(/** @type {import('estree').Program} */programNode, `/** @import ${element.value} from '${element.value}'; */`);
|
|
267
|
+
} : null);
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
270
|
+
utils.reportJSDoc('Inline `import()` found; prefer `@import`', tag, enableFixer ? fixer => {
|
|
271
|
+
if (outputType === 'namespaced-import') {
|
|
272
|
+
getFixer(element.value, [...pathSegments])();
|
|
273
|
+
} else {
|
|
274
|
+
getFixer(/** @type {string} */pathSegments.at(-1), pathSegments.slice(0, -1))();
|
|
275
|
+
}
|
|
276
|
+
const programNode = sourceCode.getNodeByRangeIndex(0);
|
|
277
|
+
return fixer.insertTextBefore(/** @type {import('estree').Program} */programNode, outputType === 'namespaced-import' ? `/** @import * as ${element.value} from '${element.value}'; */` : `/** @import { ${pathSegments.at(-1)} } from '${element.value}'; */`);
|
|
278
|
+
} : null);
|
|
279
|
+
});
|
|
280
|
+
};
|
|
281
|
+
for (const tag of jsdoc.tags) {
|
|
282
|
+
const mightHaveTypePosition = utils.tagMightHaveTypePosition(tag.tag);
|
|
283
|
+
const hasTypePosition = mightHaveTypePosition === true && Boolean(tag.type);
|
|
284
|
+
if (hasTypePosition && (!exemptTypedefs || !utils.isNamepathDefiningTag(tag.tag))) {
|
|
285
|
+
iterateInlineImports(tag);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
}, {
|
|
289
|
+
iterateAllJsdocs: true,
|
|
290
|
+
meta: {
|
|
291
|
+
docs: {
|
|
292
|
+
description: 'Prefer `@import` tags to inline `import()` statements.',
|
|
293
|
+
url: 'https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/prefer-import-tag.md#repos-sticky-header'
|
|
294
|
+
},
|
|
295
|
+
fixable: 'code',
|
|
296
|
+
schema: [{
|
|
297
|
+
additionalProperties: false,
|
|
298
|
+
properties: {
|
|
299
|
+
enableFixer: {
|
|
300
|
+
description: 'Whether or not to enable the fixer to add `@import` tags.',
|
|
301
|
+
type: 'boolean'
|
|
302
|
+
},
|
|
303
|
+
exemptTypedefs: {
|
|
304
|
+
description: 'Whether to allow `import()` statements within `@typedef`',
|
|
305
|
+
type: 'boolean'
|
|
306
|
+
},
|
|
307
|
+
// We might add `typedef` and `typedef-local-only`, but also raises
|
|
308
|
+
// question of how deep the generated typedef should be
|
|
309
|
+
outputType: {
|
|
310
|
+
description: 'What kind of `@import` to generate when no matching `@typedef` or `@import` is found',
|
|
311
|
+
enum: ['named-import', 'namespaced-import'],
|
|
312
|
+
type: 'string'
|
|
313
|
+
}
|
|
314
|
+
},
|
|
315
|
+
type: 'object'
|
|
316
|
+
}],
|
|
317
|
+
type: 'suggestion'
|
|
318
|
+
}
|
|
319
|
+
});
|
|
320
|
+
module.exports = exports.default;
|
|
321
|
+
//# sourceMappingURL=preferImportTag.cjs.map
|
|
@@ -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
|
@@ -1272,6 +1272,26 @@ export interface Rules {
|
|
|
1272
1272
|
}
|
|
1273
1273
|
];
|
|
1274
1274
|
|
|
1275
|
+
/** Prefer `@import` tags to inline `import()` statements. */
|
|
1276
|
+
"jsdoc/prefer-import-tag":
|
|
1277
|
+
| []
|
|
1278
|
+
| [
|
|
1279
|
+
{
|
|
1280
|
+
/**
|
|
1281
|
+
* Whether or not to enable the fixer to add `@import` tags.
|
|
1282
|
+
*/
|
|
1283
|
+
enableFixer?: boolean;
|
|
1284
|
+
/**
|
|
1285
|
+
* Whether to allow `import()` statements within `@typedef`
|
|
1286
|
+
*/
|
|
1287
|
+
exemptTypedefs?: boolean;
|
|
1288
|
+
/**
|
|
1289
|
+
* What kind of `@import` to generate when no matching `@typedef` or `@import` is found
|
|
1290
|
+
*/
|
|
1291
|
+
outputType?: "named-import" | "namespaced-import";
|
|
1292
|
+
}
|
|
1293
|
+
];
|
|
1294
|
+
|
|
1275
1295
|
/** Reports use of `any` or `*` type */
|
|
1276
1296
|
"jsdoc/reject-any-type": [];
|
|
1277
1297
|
|
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
|
@@ -116,7 +116,7 @@ import esquery from 'esquery';
|
|
|
116
116
|
* @callback ReportJSDoc
|
|
117
117
|
* @param {string} msg
|
|
118
118
|
* @param {null|import('comment-parser').Spec|{line: Integer, column?: Integer}} [tag]
|
|
119
|
-
* @param {(() => void)|null} [handler]
|
|
119
|
+
* @param {((fixer: import('eslint').Rule.RuleFixer) => import('eslint').Rule.Fix|void)|null} [handler]
|
|
120
120
|
* @param {boolean} [specRewire]
|
|
121
121
|
* @param {undefined|{
|
|
122
122
|
* [key: string]: string
|
|
@@ -771,7 +771,8 @@ const getUtils = (
|
|
|
771
771
|
report(msg, handler ? /** @type {import('eslint').Rule.ReportFixer} */ (
|
|
772
772
|
fixer,
|
|
773
773
|
) => {
|
|
774
|
-
handler();
|
|
774
|
+
const extraFix = handler(fixer);
|
|
775
|
+
|
|
775
776
|
const replacement = utils.stringify(jsdoc, specRewire);
|
|
776
777
|
|
|
777
778
|
if (!replacement) {
|
|
@@ -780,21 +781,38 @@ const getUtils = (
|
|
|
780
781
|
0, jsdocNode.range[0],
|
|
781
782
|
).search(/\n[ \t]*$/v);
|
|
782
783
|
if (lastLineBreakPos > -1) {
|
|
783
|
-
return
|
|
784
|
-
|
|
785
|
-
|
|
784
|
+
return [
|
|
785
|
+
fixer.removeRange([
|
|
786
|
+
lastLineBreakPos, jsdocNode.range[1],
|
|
787
|
+
]),
|
|
788
|
+
/* c8 ignore next 2 -- Guard */
|
|
789
|
+
...(extraFix ? [
|
|
790
|
+
extraFix,
|
|
791
|
+
] : []),
|
|
792
|
+
];
|
|
786
793
|
}
|
|
787
794
|
|
|
788
|
-
return
|
|
789
|
-
|
|
790
|
-
[
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
+
return [
|
|
796
|
+
fixer.removeRange(
|
|
797
|
+
(/\s/v).test(text.charAt(jsdocNode.range[1])) ?
|
|
798
|
+
[
|
|
799
|
+
jsdocNode.range[0], jsdocNode.range[1] + 1,
|
|
800
|
+
] :
|
|
801
|
+
jsdocNode.range,
|
|
802
|
+
),
|
|
803
|
+
/* c8 ignore next 2 -- Guard */
|
|
804
|
+
...(extraFix ? [
|
|
805
|
+
extraFix,
|
|
806
|
+
] : []),
|
|
807
|
+
];
|
|
795
808
|
}
|
|
796
809
|
|
|
797
|
-
return
|
|
810
|
+
return [
|
|
811
|
+
fixer.replaceText(jsdocNode, replacement),
|
|
812
|
+
...(extraFix ? [
|
|
813
|
+
extraFix,
|
|
814
|
+
] : []),
|
|
815
|
+
];
|
|
798
816
|
} : null, tag, data);
|
|
799
817
|
};
|
|
800
818
|
|