eslint-plugin-jsdoc 56.0.0 → 56.0.2
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/dist/cjs/getJsdocProcessorPlugin.d.cts +5 -1
- package/dist/cjs/iterateJsdoc.d.cts +6 -2
- package/dist/getJsdocProcessorPlugin.cts +3 -1
- package/dist/iterateJsdoc.cts +9 -4
- package/package.json +4 -4
- package/src/getJsdocProcessorPlugin.cts +3 -1
- package/src/iterateJsdoc.cts +9 -4
- package/dist/cjs/WarnSettings.js +0 -30
- package/dist/cjs/alignTransform.js +0 -285
- package/dist/cjs/defaultTagOrder.js +0 -152
- package/dist/cjs/exportParser.js +0 -754
- package/dist/cjs/getDefaultTagStructureForMode.js +0 -840
- package/dist/cjs/getJsdocProcessorPlugin.cjs +0 -4
- package/dist/cjs/getJsdocProcessorPlugin.js +0 -553
- package/dist/cjs/index-cjs.js +0 -492
- package/dist/cjs/index.cjs.cjs +0 -6
- package/dist/cjs/iterateJsdoc.cjs +0 -38
- package/dist/cjs/iterateJsdoc.js +0 -1981
- package/dist/cjs/jsdocUtils.js +0 -1470
- package/dist/cjs/rules/checkAccess.js +0 -35
- package/dist/cjs/rules/checkAlignment.js +0 -63
- package/dist/cjs/rules/checkExamples.js +0 -486
- package/dist/cjs/rules/checkIndentation.js +0 -66
- package/dist/cjs/rules/checkLineAlignment.js +0 -297
- package/dist/cjs/rules/checkParamNames.js +0 -320
- package/dist/cjs/rules/checkPropertyNames.js +0 -105
- package/dist/cjs/rules/checkSyntax.js +0 -27
- package/dist/cjs/rules/checkTagNames.js +0 -252
- package/dist/cjs/rules/checkTemplateNames.js +0 -189
- package/dist/cjs/rules/checkTypes.js +0 -421
- package/dist/cjs/rules/checkValues.js +0 -163
- package/dist/cjs/rules/convertToJsdocComments.js +0 -313
- package/dist/cjs/rules/emptyTags.js +0 -79
- package/dist/cjs/rules/implementsOnClasses.js +0 -63
- package/dist/cjs/rules/importsAsDependencies.js +0 -105
- package/dist/cjs/rules/informativeDocs.js +0 -153
- package/dist/cjs/rules/linesBeforeBlock.js +0 -106
- package/dist/cjs/rules/matchDescription.js +0 -240
- package/dist/cjs/rules/matchName.js +0 -122
- package/dist/cjs/rules/multilineBlocks.js +0 -339
- package/dist/cjs/rules/noBadBlocks.js +0 -88
- package/dist/cjs/rules/noBlankBlockDescriptions.js +0 -56
- package/dist/cjs/rules/noBlankBlocks.js +0 -41
- package/dist/cjs/rules/noDefaults.js +0 -84
- package/dist/cjs/rules/noMissingSyntax.js +0 -164
- package/dist/cjs/rules/noMultiAsterisks.js +0 -83
- package/dist/cjs/rules/noRestrictedSyntax.js +0 -75
- package/dist/cjs/rules/noTypes.js +0 -88
- package/dist/cjs/rules/noUndefinedTypes.js +0 -451
- package/dist/cjs/rules/requireAsteriskPrefix.js +0 -144
- package/dist/cjs/rules/requireDescription.js +0 -136
- package/dist/cjs/rules/requireDescriptionCompleteSentence.js +0 -258
- package/dist/cjs/rules/requireExample.js +0 -103
- package/dist/cjs/rules/requireFileOverview.js +0 -117
- package/dist/cjs/rules/requireHyphenBeforeParamDescription.js +0 -144
- package/dist/cjs/rules/requireJsdoc.js +0 -629
- package/dist/cjs/rules/requireParam.js +0 -480
- package/dist/cjs/rules/requireParamDescription.js +0 -77
- package/dist/cjs/rules/requireParamName.js +0 -52
- package/dist/cjs/rules/requireParamType.js +0 -77
- package/dist/cjs/rules/requireProperty.js +0 -44
- package/dist/cjs/rules/requirePropertyDescription.js +0 -22
- package/dist/cjs/rules/requirePropertyName.js +0 -22
- package/dist/cjs/rules/requirePropertyType.js +0 -22
- package/dist/cjs/rules/requireReturns.js +0 -197
- package/dist/cjs/rules/requireReturnsCheck.js +0 -108
- package/dist/cjs/rules/requireReturnsDescription.js +0 -58
- package/dist/cjs/rules/requireReturnsType.js +0 -52
- package/dist/cjs/rules/requireTemplate.js +0 -173
- package/dist/cjs/rules/requireThrows.js +0 -101
- package/dist/cjs/rules/requireYields.js +0 -172
- package/dist/cjs/rules/requireYieldsCheck.js +0 -164
- package/dist/cjs/rules/sortTags.js +0 -392
- package/dist/cjs/rules/tagLines.js +0 -259
- package/dist/cjs/rules/textEscaping.js +0 -125
- package/dist/cjs/rules/typeFormatting.js +0 -328
- package/dist/cjs/rules/validTypes.js +0 -333
- package/dist/cjs/tagNames.js +0 -209
- package/dist/cjs/utils/hasReturnValue.js +0 -469
|
@@ -1,451 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
const iterateJsdoc_js_1 = __importStar(require("../iterateJsdoc.js"));
|
|
37
|
-
const jsdoccomment_1 = require("@es-joy/jsdoccomment");
|
|
38
|
-
const parse_imports_exports_1 = require("parse-imports-exports");
|
|
39
|
-
const extraTypes = [
|
|
40
|
-
'null', 'undefined', 'void', 'string', 'boolean', 'object',
|
|
41
|
-
'function', 'symbol',
|
|
42
|
-
'number', 'bigint', 'NaN', 'Infinity',
|
|
43
|
-
'any', '*', 'never', 'unknown', 'const',
|
|
44
|
-
'this', 'true', 'false',
|
|
45
|
-
'Array', 'Object', 'RegExp', 'Date', 'Function', 'Intl',
|
|
46
|
-
];
|
|
47
|
-
const typescriptGlobals = [
|
|
48
|
-
// https://www.typescriptlang.org/docs/handbook/utility-types.html
|
|
49
|
-
'Awaited',
|
|
50
|
-
'Partial',
|
|
51
|
-
'Required',
|
|
52
|
-
'Readonly',
|
|
53
|
-
'Record',
|
|
54
|
-
'Pick',
|
|
55
|
-
'Omit',
|
|
56
|
-
'Exclude',
|
|
57
|
-
'Extract',
|
|
58
|
-
'NonNullable',
|
|
59
|
-
'Parameters',
|
|
60
|
-
'ConstructorParameters',
|
|
61
|
-
'ReturnType',
|
|
62
|
-
'InstanceType',
|
|
63
|
-
'ThisParameterType',
|
|
64
|
-
'OmitThisParameter',
|
|
65
|
-
'ThisType',
|
|
66
|
-
'Uppercase',
|
|
67
|
-
'Lowercase',
|
|
68
|
-
'Capitalize',
|
|
69
|
-
'Uncapitalize',
|
|
70
|
-
];
|
|
71
|
-
/**
|
|
72
|
-
* @param {string|false|undefined} [str]
|
|
73
|
-
* @returns {undefined|string|false}
|
|
74
|
-
*/
|
|
75
|
-
const stripPseudoTypes = (str) => {
|
|
76
|
-
return str && str.replace(/(?:\.|<>|\.<>|\[\])$/v, '');
|
|
77
|
-
};
|
|
78
|
-
exports.default = (0, iterateJsdoc_js_1.default)(({ context, node, report, settings, sourceCode, utils, }) => {
|
|
79
|
-
const { scopeManager, } = sourceCode;
|
|
80
|
-
// When is this ever `null`?
|
|
81
|
-
const globalScope = /** @type {import('eslint').Scope.Scope} */ (scopeManager.globalScope);
|
|
82
|
-
const
|
|
83
|
-
/**
|
|
84
|
-
* @type {{
|
|
85
|
-
* definedTypes: string[],
|
|
86
|
-
* disableReporting: boolean,
|
|
87
|
-
* markVariablesAsUsed: boolean
|
|
88
|
-
* }}
|
|
89
|
-
*/ { definedTypes = [], disableReporting = false, markVariablesAsUsed = true, } = context.options[0] || {};
|
|
90
|
-
/** @type {(string|undefined)[]} */
|
|
91
|
-
let definedPreferredTypes = [];
|
|
92
|
-
const { mode, preferredTypes, structuredTags, } = settings;
|
|
93
|
-
if (Object.keys(preferredTypes).length) {
|
|
94
|
-
definedPreferredTypes = /** @type {string[]} */ (Object.values(preferredTypes).map((preferredType) => {
|
|
95
|
-
if (typeof preferredType === 'string') {
|
|
96
|
-
// May become an empty string but will be filtered out below
|
|
97
|
-
return stripPseudoTypes(preferredType);
|
|
98
|
-
}
|
|
99
|
-
if (!preferredType) {
|
|
100
|
-
return undefined;
|
|
101
|
-
}
|
|
102
|
-
if (typeof preferredType !== 'object') {
|
|
103
|
-
utils.reportSettings('Invalid `settings.jsdoc.preferredTypes`. Values must be falsy, a string, or an object.');
|
|
104
|
-
}
|
|
105
|
-
return stripPseudoTypes(preferredType.replacement);
|
|
106
|
-
})
|
|
107
|
-
.filter(Boolean));
|
|
108
|
-
}
|
|
109
|
-
const allComments = sourceCode.getAllComments();
|
|
110
|
-
const comments = allComments
|
|
111
|
-
.filter((comment) => {
|
|
112
|
-
return (/^\*\s/v).test(comment.value);
|
|
113
|
-
})
|
|
114
|
-
.map((commentNode) => {
|
|
115
|
-
return (0, iterateJsdoc_js_1.parseComment)(commentNode, '');
|
|
116
|
-
});
|
|
117
|
-
const globals = allComments
|
|
118
|
-
.filter((comment) => {
|
|
119
|
-
return (/^\s*globals/v).test(comment.value);
|
|
120
|
-
}).flatMap((commentNode) => {
|
|
121
|
-
return commentNode.value.replace(/^\s*globals/v, '').trim().split(/,\s*/v);
|
|
122
|
-
}).concat(Object.keys(context.languageOptions.globals ?? []));
|
|
123
|
-
const typedefDeclarations = comments
|
|
124
|
-
.flatMap((doc) => {
|
|
125
|
-
return doc.tags.filter(({ tag, }) => {
|
|
126
|
-
return utils.isNamepathDefiningTag(tag);
|
|
127
|
-
});
|
|
128
|
-
})
|
|
129
|
-
.map((tag) => {
|
|
130
|
-
return tag.name;
|
|
131
|
-
});
|
|
132
|
-
const importTags = settings.mode === 'typescript' ? /** @type {string[]} */ (comments.flatMap((doc) => {
|
|
133
|
-
return doc.tags.filter(({ tag, }) => {
|
|
134
|
-
return tag === 'import';
|
|
135
|
-
});
|
|
136
|
-
}).flatMap((tag) => {
|
|
137
|
-
const { description, name, type, } = tag;
|
|
138
|
-
const typePart = type ? `{${type}} ` : '';
|
|
139
|
-
const imprt = 'import ' + (description ?
|
|
140
|
-
`${typePart}${name} ${description}` :
|
|
141
|
-
`${typePart}${name}`);
|
|
142
|
-
const importsExports = (0, parse_imports_exports_1.parseImportsExports)(imprt.trim());
|
|
143
|
-
const types = [];
|
|
144
|
-
const namedImports = Object.values(importsExports.namedImports || {})[0]?.[0];
|
|
145
|
-
if (namedImports) {
|
|
146
|
-
if (namedImports.default) {
|
|
147
|
-
types.push(namedImports.default);
|
|
148
|
-
}
|
|
149
|
-
if (namedImports.names) {
|
|
150
|
-
types.push(...Object.keys(namedImports.names));
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
const namespaceImports = Object.values(importsExports.namespaceImports || {})[0]?.[0];
|
|
154
|
-
if (namespaceImports) {
|
|
155
|
-
if (namespaceImports.namespace) {
|
|
156
|
-
types.push(namespaceImports.namespace);
|
|
157
|
-
}
|
|
158
|
-
if (namespaceImports.default) {
|
|
159
|
-
types.push(namespaceImports.default);
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
return types;
|
|
163
|
-
}).filter(Boolean)) : [];
|
|
164
|
-
const ancestorNodes = [];
|
|
165
|
-
let currentNode = node;
|
|
166
|
-
// No need for Program node?
|
|
167
|
-
while (currentNode?.parent) {
|
|
168
|
-
ancestorNodes.push(currentNode);
|
|
169
|
-
currentNode = currentNode.parent;
|
|
170
|
-
}
|
|
171
|
-
/**
|
|
172
|
-
* @param {import('eslint').Rule.Node} ancestorNode
|
|
173
|
-
* @returns {import('comment-parser').Spec[]}
|
|
174
|
-
*/
|
|
175
|
-
const getTemplateTags = function (ancestorNode) {
|
|
176
|
-
const commentNode = (0, jsdoccomment_1.getJSDocComment)(sourceCode, ancestorNode, settings);
|
|
177
|
-
if (!commentNode) {
|
|
178
|
-
return [];
|
|
179
|
-
}
|
|
180
|
-
const jsdoc = (0, iterateJsdoc_js_1.parseComment)(commentNode, '');
|
|
181
|
-
return jsdoc.tags.filter((tag) => {
|
|
182
|
-
return tag.tag === 'template';
|
|
183
|
-
});
|
|
184
|
-
};
|
|
185
|
-
// `currentScope` may be `null` or `Program`, so in such a case,
|
|
186
|
-
// we look to present tags instead
|
|
187
|
-
const templateTags = ancestorNodes.length ?
|
|
188
|
-
ancestorNodes.flatMap((ancestorNode) => {
|
|
189
|
-
return getTemplateTags(ancestorNode);
|
|
190
|
-
}) :
|
|
191
|
-
utils.getPresentTags([
|
|
192
|
-
'template',
|
|
193
|
-
]);
|
|
194
|
-
const closureGenericTypes = templateTags.flatMap((tag) => {
|
|
195
|
-
return utils.parseClosureTemplateTag(tag);
|
|
196
|
-
});
|
|
197
|
-
// In modules, including Node, there is a global scope at top with the
|
|
198
|
-
// Program scope inside
|
|
199
|
-
const cjsOrESMScope = globalScope.childScopes[0]?.block?.type === 'Program';
|
|
200
|
-
/**
|
|
201
|
-
* @param {import("eslint").Scope.Scope | null} scope
|
|
202
|
-
* @returns {Set<string>}
|
|
203
|
-
*/
|
|
204
|
-
const getValidRuntimeIdentifiers = (scope) => {
|
|
205
|
-
const result = new Set();
|
|
206
|
-
let scp = scope;
|
|
207
|
-
while (scp) {
|
|
208
|
-
for (const { name, } of scp.variables) {
|
|
209
|
-
result.add(name);
|
|
210
|
-
}
|
|
211
|
-
scp = scp.upper;
|
|
212
|
-
}
|
|
213
|
-
return result;
|
|
214
|
-
};
|
|
215
|
-
/**
|
|
216
|
-
* We treat imports differently as we can't introspect their children.
|
|
217
|
-
* @type {string[]}
|
|
218
|
-
*/
|
|
219
|
-
const imports = [];
|
|
220
|
-
const allDefinedTypes = new Set(globalScope.variables.map(({ name, }) => {
|
|
221
|
-
return name;
|
|
222
|
-
})
|
|
223
|
-
// If the file is a module, concat the variables from the module scope.
|
|
224
|
-
.concat(cjsOrESMScope ?
|
|
225
|
-
globalScope.childScopes.flatMap(({ variables, }) => {
|
|
226
|
-
return variables;
|
|
227
|
-
}).flatMap(({ identifiers, name, }) => {
|
|
228
|
-
const globalItem = /** @type {import('estree').Identifier & {parent: import('@typescript-eslint/types').TSESTree.Node}} */ (identifiers?.[0])?.parent;
|
|
229
|
-
switch (globalItem?.type) {
|
|
230
|
-
case 'ClassDeclaration':
|
|
231
|
-
return [
|
|
232
|
-
name,
|
|
233
|
-
...globalItem.body.body.map((item) => {
|
|
234
|
-
const property = /** @type {import('@typescript-eslint/types').TSESTree.Identifier} */ (
|
|
235
|
-
/** @type {import('@typescript-eslint/types').TSESTree.PropertyDefinition} */ (item)?.key)?.name;
|
|
236
|
-
/* c8 ignore next 3 -- Guard */
|
|
237
|
-
if (!property) {
|
|
238
|
-
return '';
|
|
239
|
-
}
|
|
240
|
-
return `${name}.${property}`;
|
|
241
|
-
}).filter(Boolean),
|
|
242
|
-
];
|
|
243
|
-
case 'ImportDefaultSpecifier':
|
|
244
|
-
case 'ImportNamespaceSpecifier':
|
|
245
|
-
case 'ImportSpecifier':
|
|
246
|
-
imports.push(name);
|
|
247
|
-
break;
|
|
248
|
-
case 'TSInterfaceDeclaration':
|
|
249
|
-
return [
|
|
250
|
-
name,
|
|
251
|
-
...globalItem.body.body.map((item) => {
|
|
252
|
-
const property = /** @type {import('@typescript-eslint/types').TSESTree.Identifier} */ (
|
|
253
|
-
/** @type {import('@typescript-eslint/types').TSESTree.TSPropertySignature} */ (item)?.key)?.name;
|
|
254
|
-
/* c8 ignore next 3 -- Guard */
|
|
255
|
-
if (!property) {
|
|
256
|
-
return '';
|
|
257
|
-
}
|
|
258
|
-
return `${name}.${property}`;
|
|
259
|
-
}).filter(Boolean),
|
|
260
|
-
];
|
|
261
|
-
case 'VariableDeclarator':
|
|
262
|
-
if ( /** @type {import('@typescript-eslint/types').TSESTree.Identifier} */(
|
|
263
|
-
/** @type {import('@typescript-eslint/types').TSESTree.CallExpression} */ (globalItem?.init)?.callee)?.name === 'require') {
|
|
264
|
-
imports.push(/** @type {import('@typescript-eslint/types').TSESTree.Identifier} */ (globalItem.id).name);
|
|
265
|
-
break;
|
|
266
|
-
}
|
|
267
|
-
return [];
|
|
268
|
-
}
|
|
269
|
-
return [
|
|
270
|
-
name,
|
|
271
|
-
];
|
|
272
|
-
/* c8 ignore next */
|
|
273
|
-
}) : [])
|
|
274
|
-
.concat(extraTypes)
|
|
275
|
-
.concat(typedefDeclarations)
|
|
276
|
-
.concat(importTags)
|
|
277
|
-
.concat(definedTypes)
|
|
278
|
-
.concat(/** @type {string[]} */ (definedPreferredTypes))
|
|
279
|
-
.concat((() => {
|
|
280
|
-
// Other methods are not in scope, but we need them, and we grab them here
|
|
281
|
-
if (node?.type === 'MethodDefinition') {
|
|
282
|
-
return /** @type {import('estree').ClassBody} */ (node.parent).body.flatMap((methodOrProp) => {
|
|
283
|
-
if (methodOrProp.type === 'MethodDefinition') {
|
|
284
|
-
// eslint-disable-next-line unicorn/no-lonely-if -- Pattern
|
|
285
|
-
if (methodOrProp.key.type === 'Identifier') {
|
|
286
|
-
return [
|
|
287
|
-
methodOrProp.key.name,
|
|
288
|
-
`${ /** @type {import('estree').ClassDeclaration} */(node.parent?.parent)?.id?.name}.${methodOrProp.key.name}`,
|
|
289
|
-
];
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
if (methodOrProp.type === 'PropertyDefinition') {
|
|
293
|
-
// eslint-disable-next-line unicorn/no-lonely-if -- Pattern
|
|
294
|
-
if (methodOrProp.key.type === 'Identifier') {
|
|
295
|
-
return [
|
|
296
|
-
methodOrProp.key.name,
|
|
297
|
-
`${ /** @type {import('estree').ClassDeclaration} */(node.parent?.parent)?.id?.name}.${methodOrProp.key.name}`,
|
|
298
|
-
];
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
/* c8 ignore next 2 -- Not yet built */
|
|
302
|
-
return '';
|
|
303
|
-
}).filter(Boolean);
|
|
304
|
-
}
|
|
305
|
-
return [];
|
|
306
|
-
})())
|
|
307
|
-
.concat(...getValidRuntimeIdentifiers(node && ((sourceCode.getScope &&
|
|
308
|
-
/* c8 ignore next 3 */
|
|
309
|
-
sourceCode.getScope(node)) ||
|
|
310
|
-
// @ts-expect-error ESLint 8
|
|
311
|
-
context.getScope())))
|
|
312
|
-
.concat(settings.mode === 'jsdoc' ?
|
|
313
|
-
[] :
|
|
314
|
-
[
|
|
315
|
-
...settings.mode === 'typescript' ? typescriptGlobals : [],
|
|
316
|
-
...closureGenericTypes,
|
|
317
|
-
]));
|
|
318
|
-
/**
|
|
319
|
-
* @typedef {{
|
|
320
|
-
* parsedType: import('jsdoc-type-pratt-parser').RootResult;
|
|
321
|
-
* tag: import('comment-parser').Spec|import('@es-joy/jsdoccomment').JsdocInlineTagNoType & {
|
|
322
|
-
* line?: import('../iterateJsdoc.js').Integer
|
|
323
|
-
* }
|
|
324
|
-
* }} TypeAndTagInfo
|
|
325
|
-
*/
|
|
326
|
-
/**
|
|
327
|
-
* @param {string} propertyName
|
|
328
|
-
* @returns {(tag: (import('@es-joy/jsdoccomment').JsdocInlineTagNoType & {
|
|
329
|
-
* name?: string,
|
|
330
|
-
* type?: string,
|
|
331
|
-
* line?: import('../iterateJsdoc.js').Integer
|
|
332
|
-
* })|import('comment-parser').Spec & {
|
|
333
|
-
* namepathOrURL?: string
|
|
334
|
-
* }
|
|
335
|
-
* ) => undefined|TypeAndTagInfo}
|
|
336
|
-
*/
|
|
337
|
-
const tagToParsedType = (propertyName) => {
|
|
338
|
-
return (tag) => {
|
|
339
|
-
try {
|
|
340
|
-
const potentialType = tag[
|
|
341
|
-
/** @type {"type"|"name"|"namepathOrURL"} */ (propertyName)];
|
|
342
|
-
return {
|
|
343
|
-
parsedType: mode === 'permissive' ?
|
|
344
|
-
(0, jsdoccomment_1.tryParse)(/** @type {string} */ (potentialType)) :
|
|
345
|
-
(0, jsdoccomment_1.parse)(/** @type {string} */ (potentialType), mode),
|
|
346
|
-
tag,
|
|
347
|
-
};
|
|
348
|
-
}
|
|
349
|
-
catch {
|
|
350
|
-
return undefined;
|
|
351
|
-
}
|
|
352
|
-
};
|
|
353
|
-
};
|
|
354
|
-
const typeTags = utils.filterTags(({ tag, }) => {
|
|
355
|
-
return tag !== 'import' && utils.tagMightHaveTypePosition(tag) && (tag !== 'suppress' || settings.mode !== 'closure');
|
|
356
|
-
}).map(tagToParsedType('type'));
|
|
357
|
-
const namepathReferencingTags = utils.filterTags(({ tag, }) => {
|
|
358
|
-
return utils.isNamepathReferencingTag(tag);
|
|
359
|
-
}).map(tagToParsedType('name'));
|
|
360
|
-
const namepathOrUrlReferencingTags = utils.filterAllTags(({ tag, }) => {
|
|
361
|
-
return utils.isNamepathOrUrlReferencingTag(tag);
|
|
362
|
-
}).map(tagToParsedType('namepathOrURL'));
|
|
363
|
-
const tagsWithTypes = /** @type {TypeAndTagInfo[]} */ ([
|
|
364
|
-
...typeTags,
|
|
365
|
-
...namepathReferencingTags,
|
|
366
|
-
...namepathOrUrlReferencingTags,
|
|
367
|
-
// Remove types which failed to parse
|
|
368
|
-
].filter(Boolean));
|
|
369
|
-
for (const { parsedType, tag, } of tagsWithTypes) {
|
|
370
|
-
(0, jsdoccomment_1.traverse)(parsedType, (nde, parentNode) => {
|
|
371
|
-
/**
|
|
372
|
-
* @type {import('jsdoc-type-pratt-parser').NameResult & {
|
|
373
|
-
* _parent?: import('jsdoc-type-pratt-parser').NonRootResult
|
|
374
|
-
* }}
|
|
375
|
-
*/
|
|
376
|
-
// eslint-disable-next-line canonical/id-match -- Avoid clashes
|
|
377
|
-
(nde)._parent = parentNode;
|
|
378
|
-
const { type, value, } = /** @type {import('jsdoc-type-pratt-parser').NameResult} */ (nde);
|
|
379
|
-
let val = value;
|
|
380
|
-
/** @type {import('jsdoc-type-pratt-parser').NonRootResult|undefined} */
|
|
381
|
-
let currNode = nde;
|
|
382
|
-
do {
|
|
383
|
-
currNode =
|
|
384
|
-
/**
|
|
385
|
-
* @type {import('jsdoc-type-pratt-parser').NameResult & {
|
|
386
|
-
* _parent?: import('jsdoc-type-pratt-parser').NonRootResult
|
|
387
|
-
* }}
|
|
388
|
-
*/ (currNode)._parent;
|
|
389
|
-
if (
|
|
390
|
-
// Avoid appending for imports and globals since we don't want to
|
|
391
|
-
// check their properties which may or may not exist
|
|
392
|
-
!imports.includes(val) && !globals.includes(val) &&
|
|
393
|
-
!importTags.includes(val) &&
|
|
394
|
-
!extraTypes.includes(val) &&
|
|
395
|
-
!typedefDeclarations.includes(val) &&
|
|
396
|
-
currNode && 'right' in currNode &&
|
|
397
|
-
currNode.right?.type === 'JsdocTypeProperty') {
|
|
398
|
-
val = val + '.' + currNode.right.value;
|
|
399
|
-
}
|
|
400
|
-
} while (currNode?.type === 'JsdocTypeNamePath');
|
|
401
|
-
if (type === 'JsdocTypeName') {
|
|
402
|
-
const structuredTypes = structuredTags[tag.tag]?.type;
|
|
403
|
-
if (!allDefinedTypes.has(val) &&
|
|
404
|
-
(!Array.isArray(structuredTypes) || !structuredTypes.includes(val))) {
|
|
405
|
-
if (!disableReporting) {
|
|
406
|
-
report(`The type '${val}' is undefined.`, null, tag);
|
|
407
|
-
}
|
|
408
|
-
}
|
|
409
|
-
else if (markVariablesAsUsed && !extraTypes.includes(val)) {
|
|
410
|
-
if (sourceCode.markVariableAsUsed) {
|
|
411
|
-
sourceCode.markVariableAsUsed(val);
|
|
412
|
-
/* c8 ignore next 4 */
|
|
413
|
-
}
|
|
414
|
-
else {
|
|
415
|
-
// @ts-expect-error ESLint 8
|
|
416
|
-
context.markVariableAsUsed(val);
|
|
417
|
-
}
|
|
418
|
-
}
|
|
419
|
-
}
|
|
420
|
-
});
|
|
421
|
-
}
|
|
422
|
-
}, {
|
|
423
|
-
iterateAllJsdocs: true,
|
|
424
|
-
meta: {
|
|
425
|
-
docs: {
|
|
426
|
-
description: 'Checks that types in jsdoc comments are defined.',
|
|
427
|
-
url: 'https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/no-undefined-types.md#repos-sticky-header',
|
|
428
|
-
},
|
|
429
|
-
schema: [
|
|
430
|
-
{
|
|
431
|
-
additionalProperties: false,
|
|
432
|
-
properties: {
|
|
433
|
-
definedTypes: {
|
|
434
|
-
items: {
|
|
435
|
-
type: 'string',
|
|
436
|
-
},
|
|
437
|
-
type: 'array',
|
|
438
|
-
},
|
|
439
|
-
disableReporting: {
|
|
440
|
-
type: 'boolean',
|
|
441
|
-
},
|
|
442
|
-
markVariablesAsUsed: {
|
|
443
|
-
type: 'boolean',
|
|
444
|
-
},
|
|
445
|
-
},
|
|
446
|
-
type: 'object',
|
|
447
|
-
},
|
|
448
|
-
],
|
|
449
|
-
type: 'suggestion',
|
|
450
|
-
},
|
|
451
|
-
});
|
|
@@ -1,144 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
const iterateJsdoc_js_1 = __importDefault(require("../iterateJsdoc.js"));
|
|
7
|
-
exports.default = (0, iterateJsdoc_js_1.default)(({ context, indent, jsdoc, utils, }) => {
|
|
8
|
-
const [defaultRequireValue = 'always', { tags: tagMap = {}, } = {},] = context.options;
|
|
9
|
-
const { source, } = jsdoc;
|
|
10
|
-
const always = defaultRequireValue === 'always';
|
|
11
|
-
const never = defaultRequireValue === 'never';
|
|
12
|
-
/** @type {string} */
|
|
13
|
-
let currentTag;
|
|
14
|
-
source.some(({ number, tokens, }) => {
|
|
15
|
-
const { delimiter, description, end, tag, } = tokens;
|
|
16
|
-
/**
|
|
17
|
-
* @returns {void}
|
|
18
|
-
*/
|
|
19
|
-
const neverFix = () => {
|
|
20
|
-
tokens.delimiter = '';
|
|
21
|
-
tokens.postDelimiter = '';
|
|
22
|
-
};
|
|
23
|
-
/**
|
|
24
|
-
* @param {string} checkValue
|
|
25
|
-
* @returns {boolean}
|
|
26
|
-
*/
|
|
27
|
-
const checkNever = (checkValue) => {
|
|
28
|
-
if (delimiter && delimiter !== '/**' && (never && !tagMap.always?.includes(checkValue) ||
|
|
29
|
-
tagMap.never?.includes(checkValue))) {
|
|
30
|
-
utils.reportJSDoc('Expected JSDoc line to have no prefix.', {
|
|
31
|
-
column: 0,
|
|
32
|
-
line: number,
|
|
33
|
-
}, neverFix);
|
|
34
|
-
return true;
|
|
35
|
-
}
|
|
36
|
-
return false;
|
|
37
|
-
};
|
|
38
|
-
/**
|
|
39
|
-
* @returns {void}
|
|
40
|
-
*/
|
|
41
|
-
const alwaysFix = () => {
|
|
42
|
-
if (!tokens.start) {
|
|
43
|
-
tokens.start = indent + ' ';
|
|
44
|
-
}
|
|
45
|
-
tokens.delimiter = '*';
|
|
46
|
-
tokens.postDelimiter = tag || description ? ' ' : '';
|
|
47
|
-
};
|
|
48
|
-
/**
|
|
49
|
-
* @param {string} checkValue
|
|
50
|
-
* @returns {boolean}
|
|
51
|
-
*/
|
|
52
|
-
const checkAlways = (checkValue) => {
|
|
53
|
-
if (!delimiter && (always && !tagMap.never?.includes(checkValue) ||
|
|
54
|
-
tagMap.always?.includes(checkValue))) {
|
|
55
|
-
utils.reportJSDoc('Expected JSDoc line to have the prefix.', {
|
|
56
|
-
column: 0,
|
|
57
|
-
line: number,
|
|
58
|
-
}, alwaysFix);
|
|
59
|
-
return true;
|
|
60
|
-
}
|
|
61
|
-
return false;
|
|
62
|
-
};
|
|
63
|
-
if (tag) {
|
|
64
|
-
// Remove at sign
|
|
65
|
-
currentTag = tag.slice(1);
|
|
66
|
-
}
|
|
67
|
-
if (
|
|
68
|
-
// If this is the end but has a tag, the delimiter will also be
|
|
69
|
-
// populated and will be safely ignored later
|
|
70
|
-
end && !tag) {
|
|
71
|
-
return false;
|
|
72
|
-
}
|
|
73
|
-
if (!currentTag) {
|
|
74
|
-
if (tagMap.any?.includes('*description')) {
|
|
75
|
-
return false;
|
|
76
|
-
}
|
|
77
|
-
if (checkNever('*description')) {
|
|
78
|
-
return true;
|
|
79
|
-
}
|
|
80
|
-
if (checkAlways('*description')) {
|
|
81
|
-
return true;
|
|
82
|
-
}
|
|
83
|
-
return false;
|
|
84
|
-
}
|
|
85
|
-
if (tagMap.any?.includes(currentTag)) {
|
|
86
|
-
return false;
|
|
87
|
-
}
|
|
88
|
-
if (checkNever(currentTag)) {
|
|
89
|
-
return true;
|
|
90
|
-
}
|
|
91
|
-
if (checkAlways(currentTag)) {
|
|
92
|
-
return true;
|
|
93
|
-
}
|
|
94
|
-
return false;
|
|
95
|
-
});
|
|
96
|
-
}, {
|
|
97
|
-
iterateAllJsdocs: true,
|
|
98
|
-
meta: {
|
|
99
|
-
docs: {
|
|
100
|
-
description: 'Requires that each JSDoc line starts with an `*`.',
|
|
101
|
-
url: 'https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/require-asterisk-prefix.md#repos-sticky-header',
|
|
102
|
-
},
|
|
103
|
-
fixable: 'code',
|
|
104
|
-
schema: [
|
|
105
|
-
{
|
|
106
|
-
enum: [
|
|
107
|
-
'always', 'never', 'any',
|
|
108
|
-
],
|
|
109
|
-
type: 'string',
|
|
110
|
-
},
|
|
111
|
-
{
|
|
112
|
-
additionalProperties: false,
|
|
113
|
-
properties: {
|
|
114
|
-
tags: {
|
|
115
|
-
additionalProperties: false,
|
|
116
|
-
properties: {
|
|
117
|
-
always: {
|
|
118
|
-
items: {
|
|
119
|
-
type: 'string',
|
|
120
|
-
},
|
|
121
|
-
type: 'array',
|
|
122
|
-
},
|
|
123
|
-
any: {
|
|
124
|
-
items: {
|
|
125
|
-
type: 'string',
|
|
126
|
-
},
|
|
127
|
-
type: 'array',
|
|
128
|
-
},
|
|
129
|
-
never: {
|
|
130
|
-
items: {
|
|
131
|
-
type: 'string',
|
|
132
|
-
},
|
|
133
|
-
type: 'array',
|
|
134
|
-
},
|
|
135
|
-
},
|
|
136
|
-
type: 'object',
|
|
137
|
-
},
|
|
138
|
-
},
|
|
139
|
-
type: 'object',
|
|
140
|
-
},
|
|
141
|
-
],
|
|
142
|
-
type: 'layout',
|
|
143
|
-
},
|
|
144
|
-
});
|