eslint-plugin-jsdoc 55.3.0 → 56.0.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/dist/cjs/WarnSettings.d.ts +16 -0
- package/dist/cjs/WarnSettings.js +30 -0
- package/dist/cjs/alignTransform.d.ts +33 -0
- package/dist/cjs/alignTransform.js +285 -0
- package/dist/cjs/defaultTagOrder.d.ts +4 -0
- package/dist/cjs/defaultTagOrder.js +152 -0
- package/dist/cjs/exportParser.d.ts +40 -0
- package/dist/cjs/exportParser.js +754 -0
- package/dist/cjs/getDefaultTagStructureForMode.d.ts +10 -0
- package/dist/cjs/getDefaultTagStructureForMode.js +840 -0
- package/dist/cjs/getJsdocProcessorPlugin.cjs +4 -0
- package/dist/cjs/getJsdocProcessorPlugin.d.cts +1 -0
- package/dist/cjs/getJsdocProcessorPlugin.d.ts +66 -0
- package/dist/cjs/getJsdocProcessorPlugin.js +553 -0
- package/dist/cjs/index-cjs.d.ts +16 -0
- package/dist/cjs/index-cjs.js +492 -0
- package/dist/cjs/index.cjs.cjs +6 -0
- package/dist/cjs/index.cjs.d.cts +2 -0
- package/dist/cjs/iterateJsdoc.cjs +38 -0
- package/dist/cjs/iterateJsdoc.d.cts +2 -0
- package/dist/cjs/iterateJsdoc.d.ts +462 -0
- package/dist/cjs/iterateJsdoc.js +1981 -0
- package/dist/cjs/jsdocUtils.d.ts +454 -0
- package/dist/cjs/jsdocUtils.js +1470 -0
- package/dist/cjs/rules/checkAccess.d.ts +2 -0
- package/dist/cjs/rules/checkAccess.js +35 -0
- package/dist/cjs/rules/checkAlignment.d.ts +2 -0
- package/dist/cjs/rules/checkAlignment.js +63 -0
- package/dist/cjs/rules/checkExamples.d.ts +3 -0
- package/dist/cjs/rules/checkExamples.js +486 -0
- package/dist/cjs/rules/checkIndentation.d.ts +2 -0
- package/dist/cjs/rules/checkIndentation.js +66 -0
- package/dist/cjs/rules/checkLineAlignment.d.ts +9 -0
- package/dist/cjs/rules/checkLineAlignment.js +297 -0
- package/dist/cjs/rules/checkParamNames.d.ts +2 -0
- package/dist/cjs/rules/checkParamNames.js +320 -0
- package/dist/cjs/rules/checkPropertyNames.d.ts +2 -0
- package/dist/cjs/rules/checkPropertyNames.js +105 -0
- package/dist/cjs/rules/checkSyntax.d.ts +2 -0
- package/dist/cjs/rules/checkSyntax.js +27 -0
- package/dist/cjs/rules/checkTagNames.d.ts +2 -0
- package/dist/cjs/rules/checkTagNames.js +252 -0
- package/dist/cjs/rules/checkTemplateNames.d.ts +2 -0
- package/dist/cjs/rules/checkTemplateNames.js +189 -0
- package/dist/cjs/rules/checkTypes.d.ts +2 -0
- package/dist/cjs/rules/checkTypes.js +421 -0
- package/dist/cjs/rules/checkValues.d.ts +2 -0
- package/dist/cjs/rules/checkValues.js +163 -0
- package/dist/cjs/rules/convertToJsdocComments.d.ts +251 -0
- package/dist/cjs/rules/convertToJsdocComments.js +313 -0
- package/dist/cjs/rules/emptyTags.d.ts +2 -0
- package/dist/cjs/rules/emptyTags.js +79 -0
- package/dist/cjs/rules/implementsOnClasses.d.ts +2 -0
- package/dist/cjs/rules/implementsOnClasses.js +63 -0
- package/dist/cjs/rules/importsAsDependencies.d.ts +2 -0
- package/dist/cjs/rules/importsAsDependencies.js +105 -0
- package/dist/cjs/rules/informativeDocs.d.ts +2 -0
- package/dist/cjs/rules/informativeDocs.js +153 -0
- package/dist/cjs/rules/linesBeforeBlock.d.ts +2 -0
- package/dist/cjs/rules/linesBeforeBlock.js +106 -0
- package/dist/cjs/rules/matchDescription.d.ts +2 -0
- package/dist/cjs/rules/matchDescription.js +240 -0
- package/dist/cjs/rules/matchName.d.ts +2 -0
- package/dist/cjs/rules/matchName.js +122 -0
- package/dist/cjs/rules/multilineBlocks.d.ts +2 -0
- package/dist/cjs/rules/multilineBlocks.js +339 -0
- package/dist/cjs/rules/noBadBlocks.d.ts +2 -0
- package/dist/cjs/rules/noBadBlocks.js +88 -0
- package/dist/cjs/rules/noBlankBlockDescriptions.d.ts +2 -0
- package/dist/cjs/rules/noBlankBlockDescriptions.js +56 -0
- package/dist/cjs/rules/noBlankBlocks.d.ts +2 -0
- package/dist/cjs/rules/noBlankBlocks.js +41 -0
- package/dist/cjs/rules/noDefaults.d.ts +2 -0
- package/dist/cjs/rules/noDefaults.js +84 -0
- package/dist/cjs/rules/noMissingSyntax.d.ts +9 -0
- package/dist/cjs/rules/noMissingSyntax.js +164 -0
- package/dist/cjs/rules/noMultiAsterisks.d.ts +2 -0
- package/dist/cjs/rules/noMultiAsterisks.js +83 -0
- package/dist/cjs/rules/noRestrictedSyntax.d.ts +2 -0
- package/dist/cjs/rules/noRestrictedSyntax.js +75 -0
- package/dist/cjs/rules/noTypes.d.ts +2 -0
- package/dist/cjs/rules/noTypes.js +88 -0
- package/dist/cjs/rules/noUndefinedTypes.d.ts +2 -0
- package/dist/cjs/rules/noUndefinedTypes.js +451 -0
- package/dist/cjs/rules/requireAsteriskPrefix.d.ts +2 -0
- package/dist/cjs/rules/requireAsteriskPrefix.js +144 -0
- package/dist/cjs/rules/requireDescription.d.ts +2 -0
- package/dist/cjs/rules/requireDescription.js +136 -0
- package/dist/cjs/rules/requireDescriptionCompleteSentence.d.ts +2 -0
- package/dist/cjs/rules/requireDescriptionCompleteSentence.js +258 -0
- package/dist/cjs/rules/requireExample.d.ts +2 -0
- package/dist/cjs/rules/requireExample.js +103 -0
- package/dist/cjs/rules/requireFileOverview.d.ts +2 -0
- package/dist/cjs/rules/requireFileOverview.js +117 -0
- package/dist/cjs/rules/requireHyphenBeforeParamDescription.d.ts +2 -0
- package/dist/cjs/rules/requireHyphenBeforeParamDescription.js +144 -0
- package/dist/cjs/rules/requireJsdoc.d.ts +25 -0
- package/dist/cjs/rules/requireJsdoc.js +629 -0
- package/dist/cjs/rules/requireParam.d.ts +3 -0
- package/dist/cjs/rules/requireParam.js +480 -0
- package/dist/cjs/rules/requireParamDescription.d.ts +2 -0
- package/dist/cjs/rules/requireParamDescription.js +77 -0
- package/dist/cjs/rules/requireParamName.d.ts +2 -0
- package/dist/cjs/rules/requireParamName.js +52 -0
- package/dist/cjs/rules/requireParamType.d.ts +2 -0
- package/dist/cjs/rules/requireParamType.js +77 -0
- package/dist/cjs/rules/requireProperty.d.ts +2 -0
- package/dist/cjs/rules/requireProperty.js +44 -0
- package/dist/cjs/rules/requirePropertyDescription.d.ts +2 -0
- package/dist/cjs/rules/requirePropertyDescription.js +22 -0
- package/dist/cjs/rules/requirePropertyName.d.ts +2 -0
- package/dist/cjs/rules/requirePropertyName.js +22 -0
- package/dist/cjs/rules/requirePropertyType.d.ts +2 -0
- package/dist/cjs/rules/requirePropertyType.js +22 -0
- package/dist/cjs/rules/requireReturns.d.ts +2 -0
- package/dist/cjs/rules/requireReturns.js +197 -0
- package/dist/cjs/rules/requireReturnsCheck.d.ts +2 -0
- package/dist/cjs/rules/requireReturnsCheck.js +108 -0
- package/dist/cjs/rules/requireReturnsDescription.d.ts +2 -0
- package/dist/cjs/rules/requireReturnsDescription.js +58 -0
- package/dist/cjs/rules/requireReturnsType.d.ts +2 -0
- package/dist/cjs/rules/requireReturnsType.js +52 -0
- package/dist/cjs/rules/requireTemplate.d.ts +2 -0
- package/dist/cjs/rules/requireTemplate.js +173 -0
- package/dist/cjs/rules/requireThrows.d.ts +2 -0
- package/dist/cjs/rules/requireThrows.js +101 -0
- package/dist/cjs/rules/requireYields.d.ts +2 -0
- package/dist/cjs/rules/requireYields.js +172 -0
- package/dist/cjs/rules/requireYieldsCheck.d.ts +2 -0
- package/dist/cjs/rules/requireYieldsCheck.js +164 -0
- package/dist/cjs/rules/sortTags.d.ts +2 -0
- package/dist/cjs/rules/sortTags.js +392 -0
- package/dist/cjs/rules/tagLines.d.ts +2 -0
- package/dist/cjs/rules/tagLines.js +259 -0
- package/dist/cjs/rules/textEscaping.d.ts +2 -0
- package/dist/cjs/rules/textEscaping.js +125 -0
- package/dist/cjs/rules/typeFormatting.d.ts +2 -0
- package/dist/cjs/rules/typeFormatting.js +328 -0
- package/dist/cjs/rules/validTypes.d.ts +2 -0
- package/dist/cjs/rules/validTypes.js +333 -0
- package/dist/cjs/tagNames.d.ts +15 -0
- package/dist/cjs/tagNames.js +209 -0
- package/dist/cjs/utils/hasReturnValue.d.ts +19 -0
- package/dist/cjs/utils/hasReturnValue.js +469 -0
- package/dist/getJsdocProcessorPlugin.cts +3 -0
- package/dist/index.cjs.cts +3 -0
- package/dist/iterateJsdoc.cts +6 -0
- package/dist/rules/typeFormatting.cjs +82 -38
- package/dist/rules/typeFormatting.cjs.map +1 -1
- package/dist/rules.d.ts +4 -7
- package/package.json +24 -13
- package/src/getJsdocProcessorPlugin.cts +3 -0
- package/src/index.cjs.cts +3 -0
- package/src/iterateJsdoc.cts +6 -0
- package/src/rules/typeFormatting.js +104 -40
- package/src/rules.d.ts +4 -7
|
@@ -0,0 +1,1470 @@
|
|
|
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
|
+
exports.hasValueOrExecutorHasNonEmptyResolveValue = exports.hasReturnValue = exports.tagMustHaveTypePosition = exports.tagMustHaveNamePosition = exports.tagMissingRequiredTypeOrNamepath = exports.tagMightHaveTypePosition = exports.tagMightHaveNamePosition = exports.tagMightHaveNamepath = exports.tagMightHaveEitherTypeOrNamePosition = exports.setTagStructure = exports.pathDoesNotBeginWith = exports.parseClosureTemplateTag = exports.overrideTagStructure = exports.mayBeUndefinedTypeTag = exports.isValidTag = exports.isSetter = exports.isNamepathReferencingTag = exports.isNamepathOrUrlReferencingTag = exports.isNamepathDefiningTag = exports.isGetter = exports.isConstructor = exports.hasYieldValue = exports.hasThrowValue = exports.hasTag = exports.hasParams = exports.hasATag = exports.getTagStructureForMode = exports.getTagsByType = exports.getTags = exports.getTagDescription = exports.getRegexFromString = exports.getPreferredTagNameSimple = exports.getPreferredTagName = exports.getJsdocTagsDeep = exports.getIndent = exports.getFunctionParameterNames = exports.getContextObject = exports.getAllTags = exports.forEachPreferredTag = exports.flattenRoots = exports.filterTags = exports.exemptSpeciaMethods = exports.enforcedContexts = exports.dropPathSegmentQuotes = exports.comparePaths = void 0;
|
|
7
|
+
const getDefaultTagStructureForMode_js_1 = __importDefault(require("./getDefaultTagStructureForMode.js"));
|
|
8
|
+
const tagNames_js_1 = require("./tagNames.js");
|
|
9
|
+
const WarnSettings_js_1 = __importDefault(require("./WarnSettings.js"));
|
|
10
|
+
const jsdoccomment_1 = require("@es-joy/jsdoccomment");
|
|
11
|
+
/**
|
|
12
|
+
* @typedef {number} Integer
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* @typedef {import('./utils/hasReturnValue.js').ESTreeOrTypeScriptNode} ESTreeOrTypeScriptNode
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* @typedef {"jsdoc"|"typescript"|"closure"|"permissive"} ParserMode
|
|
19
|
+
*/
|
|
20
|
+
/**
|
|
21
|
+
* @type {import('./getDefaultTagStructureForMode.js').TagStructure}
|
|
22
|
+
*/
|
|
23
|
+
let tagStructure;
|
|
24
|
+
/**
|
|
25
|
+
* @param {ParserMode} mode
|
|
26
|
+
* @returns {void}
|
|
27
|
+
*/
|
|
28
|
+
const setTagStructure = (mode) => {
|
|
29
|
+
tagStructure = (0, getDefaultTagStructureForMode_js_1.default)(mode);
|
|
30
|
+
};
|
|
31
|
+
exports.setTagStructure = setTagStructure;
|
|
32
|
+
/**
|
|
33
|
+
* @typedef {undefined|string|{
|
|
34
|
+
* name: Integer,
|
|
35
|
+
* restElement: boolean
|
|
36
|
+
* }|{
|
|
37
|
+
* isRestProperty: boolean|undefined,
|
|
38
|
+
* name: string,
|
|
39
|
+
* restElement: boolean
|
|
40
|
+
* }|{
|
|
41
|
+
* name: string,
|
|
42
|
+
* restElement: boolean
|
|
43
|
+
* }} ParamCommon
|
|
44
|
+
*/
|
|
45
|
+
/**
|
|
46
|
+
* @typedef {ParamCommon|[string|undefined, (FlattendRootInfo & {
|
|
47
|
+
* annotationParamName?: string,
|
|
48
|
+
* })]|NestedParamInfo} ParamNameInfo
|
|
49
|
+
*/
|
|
50
|
+
/**
|
|
51
|
+
* @typedef {{
|
|
52
|
+
* hasPropertyRest: boolean,
|
|
53
|
+
* hasRestElement: boolean,
|
|
54
|
+
* names: string[],
|
|
55
|
+
* rests: boolean[],
|
|
56
|
+
* }} FlattendRootInfo
|
|
57
|
+
*/
|
|
58
|
+
/**
|
|
59
|
+
* @typedef {[string, (string[]|ParamInfo[])]} NestedParamInfo
|
|
60
|
+
*/
|
|
61
|
+
/**
|
|
62
|
+
* @typedef {ParamCommon|
|
|
63
|
+
* [string|undefined, (FlattendRootInfo & {
|
|
64
|
+
* annotationParamName?: string
|
|
65
|
+
* })]|
|
|
66
|
+
* NestedParamInfo} ParamInfo
|
|
67
|
+
*/
|
|
68
|
+
/**
|
|
69
|
+
* Given a nested array of property names, reduce them to a single array,
|
|
70
|
+
* appending the name of the root element along the way if present.
|
|
71
|
+
* @callback FlattenRoots
|
|
72
|
+
* @param {ParamInfo[]} params
|
|
73
|
+
* @param {string} [root]
|
|
74
|
+
* @returns {FlattendRootInfo}
|
|
75
|
+
*/
|
|
76
|
+
/** @type {FlattenRoots} */
|
|
77
|
+
const flattenRoots = (params, root = '') => {
|
|
78
|
+
let hasRestElement = false;
|
|
79
|
+
let hasPropertyRest = false;
|
|
80
|
+
/**
|
|
81
|
+
* @type {boolean[]}
|
|
82
|
+
*/
|
|
83
|
+
const rests = [];
|
|
84
|
+
const names = params.reduce(
|
|
85
|
+
/**
|
|
86
|
+
* @param {string[]} acc
|
|
87
|
+
* @param {ParamInfo} cur
|
|
88
|
+
* @returns {string[]}
|
|
89
|
+
*/
|
|
90
|
+
(acc, cur) => {
|
|
91
|
+
if (Array.isArray(cur)) {
|
|
92
|
+
let nms;
|
|
93
|
+
if (Array.isArray(cur[1])) {
|
|
94
|
+
nms = cur[1];
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
if (cur[1].hasRestElement) {
|
|
98
|
+
hasRestElement = true;
|
|
99
|
+
}
|
|
100
|
+
if (cur[1].hasPropertyRest) {
|
|
101
|
+
hasPropertyRest = true;
|
|
102
|
+
}
|
|
103
|
+
nms = cur[1].names;
|
|
104
|
+
}
|
|
105
|
+
const flattened = flattenRoots(nms, root ? `${root}.${cur[0]}` : cur[0]);
|
|
106
|
+
if (flattened.hasRestElement) {
|
|
107
|
+
hasRestElement = true;
|
|
108
|
+
}
|
|
109
|
+
if (flattened.hasPropertyRest) {
|
|
110
|
+
hasPropertyRest = true;
|
|
111
|
+
}
|
|
112
|
+
const inner = /** @type {string[]} */ ([
|
|
113
|
+
root ? `${root}.${cur[0]}` : cur[0],
|
|
114
|
+
...flattened.names,
|
|
115
|
+
].filter(Boolean));
|
|
116
|
+
rests.push(false, ...flattened.rests);
|
|
117
|
+
return acc.concat(inner);
|
|
118
|
+
}
|
|
119
|
+
if (typeof cur === 'object') {
|
|
120
|
+
if ('isRestProperty' in cur && cur.isRestProperty) {
|
|
121
|
+
hasPropertyRest = true;
|
|
122
|
+
rests.push(true);
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
rests.push(false);
|
|
126
|
+
}
|
|
127
|
+
if ('restElement' in cur && cur.restElement) {
|
|
128
|
+
hasRestElement = true;
|
|
129
|
+
}
|
|
130
|
+
acc.push(root ? `${root}.${String(cur.name)}` : String(cur.name));
|
|
131
|
+
}
|
|
132
|
+
else if (typeof cur !== 'undefined') {
|
|
133
|
+
rests.push(false);
|
|
134
|
+
acc.push(root ? `${root}.${cur}` : cur);
|
|
135
|
+
}
|
|
136
|
+
return acc;
|
|
137
|
+
}, []);
|
|
138
|
+
return {
|
|
139
|
+
hasPropertyRest,
|
|
140
|
+
hasRestElement,
|
|
141
|
+
names,
|
|
142
|
+
rests,
|
|
143
|
+
};
|
|
144
|
+
};
|
|
145
|
+
exports.flattenRoots = flattenRoots;
|
|
146
|
+
/**
|
|
147
|
+
* @param {import('@typescript-eslint/types').TSESTree.TSIndexSignature|
|
|
148
|
+
* import('@typescript-eslint/types').TSESTree.TSConstructSignatureDeclaration|
|
|
149
|
+
* import('@typescript-eslint/types').TSESTree.TSCallSignatureDeclaration|
|
|
150
|
+
* import('@typescript-eslint/types').TSESTree.TSPropertySignature} propSignature
|
|
151
|
+
* @returns {undefined|string|[string, string[]]}
|
|
152
|
+
*/
|
|
153
|
+
const getPropertiesFromPropertySignature = (propSignature) => {
|
|
154
|
+
if (propSignature.type === 'TSIndexSignature' ||
|
|
155
|
+
propSignature.type === 'TSConstructSignatureDeclaration' ||
|
|
156
|
+
propSignature.type === 'TSCallSignatureDeclaration') {
|
|
157
|
+
return undefined;
|
|
158
|
+
}
|
|
159
|
+
if (propSignature.typeAnnotation && propSignature.typeAnnotation.typeAnnotation.type === 'TSTypeLiteral') {
|
|
160
|
+
return [
|
|
161
|
+
/** @type {import('@typescript-eslint/types').TSESTree.Identifier} */ (propSignature.key).name,
|
|
162
|
+
propSignature.typeAnnotation.typeAnnotation.members.map((member) => {
|
|
163
|
+
return /** @type {string} */ (getPropertiesFromPropertySignature(
|
|
164
|
+
/** @type {import('@typescript-eslint/types').TSESTree.TSPropertySignature} */ (member)));
|
|
165
|
+
}),
|
|
166
|
+
];
|
|
167
|
+
}
|
|
168
|
+
return /** @type {import('@typescript-eslint/types').TSESTree.Identifier} */ (propSignature.key).name;
|
|
169
|
+
};
|
|
170
|
+
/**
|
|
171
|
+
* @param {ESTreeOrTypeScriptNode|null} functionNode
|
|
172
|
+
* @param {boolean} [checkDefaultObjects]
|
|
173
|
+
* @throws {Error}
|
|
174
|
+
* @returns {ParamNameInfo[]}
|
|
175
|
+
*/
|
|
176
|
+
const getFunctionParameterNames = (functionNode, checkDefaultObjects) => {
|
|
177
|
+
/* eslint-disable complexity -- Temporary */
|
|
178
|
+
/**
|
|
179
|
+
* @param {import('estree').Identifier|import('estree').AssignmentPattern|
|
|
180
|
+
* import('estree').ObjectPattern|import('estree').Property|
|
|
181
|
+
* import('estree').RestElement|import('estree').ArrayPattern|
|
|
182
|
+
* import('@typescript-eslint/types').TSESTree.TSParameterProperty|
|
|
183
|
+
* import('@typescript-eslint/types').TSESTree.Property|
|
|
184
|
+
* import('@typescript-eslint/types').TSESTree.RestElement|
|
|
185
|
+
* import('@typescript-eslint/types').TSESTree.Identifier|
|
|
186
|
+
* import('@typescript-eslint/types').TSESTree.ObjectPattern|
|
|
187
|
+
* import('@typescript-eslint/types').TSESTree.BindingName|
|
|
188
|
+
* import('@typescript-eslint/types').TSESTree.Parameter
|
|
189
|
+
* } param
|
|
190
|
+
* @param {boolean} [isProperty]
|
|
191
|
+
* @returns {ParamNameInfo|[string, ParamNameInfo[]]}
|
|
192
|
+
*/
|
|
193
|
+
const getParamName = (param, isProperty) => {
|
|
194
|
+
/* eslint-enable complexity -- Temporary */
|
|
195
|
+
const hasLeftTypeAnnotation = 'left' in param && 'typeAnnotation' in param.left;
|
|
196
|
+
if ('typeAnnotation' in param || hasLeftTypeAnnotation) {
|
|
197
|
+
const typeAnnotation = hasLeftTypeAnnotation ?
|
|
198
|
+
/** @type {import('@typescript-eslint/types').TSESTree.Identifier} */ (param.left).typeAnnotation :
|
|
199
|
+
/** @type {import('@typescript-eslint/types').TSESTree.Identifier|import('@typescript-eslint/types').TSESTree.ObjectPattern} */
|
|
200
|
+
(param).typeAnnotation;
|
|
201
|
+
if (typeAnnotation?.typeAnnotation?.type === 'TSTypeLiteral') {
|
|
202
|
+
const propertyNames = typeAnnotation.typeAnnotation.members.map((member) => {
|
|
203
|
+
return getPropertiesFromPropertySignature(
|
|
204
|
+
/** @type {import('@typescript-eslint/types').TSESTree.TSPropertySignature} */
|
|
205
|
+
(member));
|
|
206
|
+
});
|
|
207
|
+
const flattened = {
|
|
208
|
+
...flattenRoots(propertyNames),
|
|
209
|
+
annotationParamName: 'name' in param ? param.name : undefined,
|
|
210
|
+
};
|
|
211
|
+
const hasLeftName = 'left' in param && 'name' in param.left;
|
|
212
|
+
if ('name' in param || hasLeftName) {
|
|
213
|
+
return [
|
|
214
|
+
hasLeftName ?
|
|
215
|
+
/** @type {import('@typescript-eslint/types').TSESTree.Identifier} */ (param.left).name :
|
|
216
|
+
/** @type {import('@typescript-eslint/types').TSESTree.Identifier} */ (param).name,
|
|
217
|
+
flattened,
|
|
218
|
+
];
|
|
219
|
+
}
|
|
220
|
+
return [
|
|
221
|
+
undefined, flattened,
|
|
222
|
+
];
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
if ('name' in param) {
|
|
226
|
+
return param.name;
|
|
227
|
+
}
|
|
228
|
+
if ('left' in param && 'name' in param.left) {
|
|
229
|
+
return param.left.name;
|
|
230
|
+
}
|
|
231
|
+
if (param.type === 'ObjectPattern' ||
|
|
232
|
+
('left' in param &&
|
|
233
|
+
(param).left.type === 'ObjectPattern')) {
|
|
234
|
+
const properties = /** @type {import('@typescript-eslint/types').TSESTree.ObjectPattern} */ (param).properties ||
|
|
235
|
+
/** @type {import('estree').ObjectPattern} */
|
|
236
|
+
(
|
|
237
|
+
/** @type {import('@typescript-eslint/types').TSESTree.AssignmentPattern} */ (param).left)?.properties;
|
|
238
|
+
const roots = properties.map((prop) => {
|
|
239
|
+
return getParamName(prop, true);
|
|
240
|
+
});
|
|
241
|
+
return [
|
|
242
|
+
undefined, flattenRoots(roots),
|
|
243
|
+
];
|
|
244
|
+
}
|
|
245
|
+
if (param.type === 'Property') {
|
|
246
|
+
switch (param.value.type) {
|
|
247
|
+
case 'ArrayPattern': {
|
|
248
|
+
return [
|
|
249
|
+
/** @type {import('estree').Identifier} */
|
|
250
|
+
(param.key).name,
|
|
251
|
+
/** @type {import('estree').ArrayPattern} */ (param.value).elements.map((prop, idx) => {
|
|
252
|
+
return {
|
|
253
|
+
name: idx,
|
|
254
|
+
restElement: prop?.type === 'RestElement',
|
|
255
|
+
};
|
|
256
|
+
}),
|
|
257
|
+
];
|
|
258
|
+
}
|
|
259
|
+
case 'ObjectPattern': {
|
|
260
|
+
return [
|
|
261
|
+
/** @type {import('estree').Identifier} */ (param.key).name,
|
|
262
|
+
/** @type {import('estree').ObjectPattern} */ (param.value).properties.map((prop) => {
|
|
263
|
+
return /** @type {string|[string, string[]]} */ (getParamName(prop, isProperty));
|
|
264
|
+
}),
|
|
265
|
+
];
|
|
266
|
+
}
|
|
267
|
+
case 'AssignmentPattern': {
|
|
268
|
+
switch (param.value.left.type) {
|
|
269
|
+
case 'ArrayPattern':
|
|
270
|
+
return [
|
|
271
|
+
/** @type {import('estree').Identifier} */
|
|
272
|
+
(param.key).name,
|
|
273
|
+
/** @type {import('estree').ArrayPattern} */ (param.value.left).elements.map((prop, idx) => {
|
|
274
|
+
return {
|
|
275
|
+
name: idx,
|
|
276
|
+
restElement: prop?.type === 'RestElement',
|
|
277
|
+
};
|
|
278
|
+
}),
|
|
279
|
+
];
|
|
280
|
+
case 'Identifier':
|
|
281
|
+
// Default parameter
|
|
282
|
+
if (checkDefaultObjects && param.value.right.type === 'ObjectExpression') {
|
|
283
|
+
return [
|
|
284
|
+
/** @type {import('estree').Identifier} */ (param.key).name,
|
|
285
|
+
/** @type {import('estree').AssignmentPattern} */ (param.value).right.properties.map((prop) => {
|
|
286
|
+
return /** @type {string} */ (getParamName(
|
|
287
|
+
/** @type {import('estree').Property} */
|
|
288
|
+
(prop), isProperty));
|
|
289
|
+
}),
|
|
290
|
+
];
|
|
291
|
+
}
|
|
292
|
+
break;
|
|
293
|
+
case 'ObjectPattern':
|
|
294
|
+
return [
|
|
295
|
+
/** @type {import('estree').Identifier} */
|
|
296
|
+
(param.key).name,
|
|
297
|
+
/** @type {import('estree').ObjectPattern} */ (param.value.left).properties.map((prop) => {
|
|
298
|
+
return getParamName(prop, isProperty);
|
|
299
|
+
}),
|
|
300
|
+
];
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
switch (param.key.type) {
|
|
305
|
+
case 'Identifier':
|
|
306
|
+
return param.key.name;
|
|
307
|
+
// The key of an object could also be a string or number
|
|
308
|
+
case 'Literal':
|
|
309
|
+
/* c8 ignore next 2 -- `raw` may not be present in all parsers */
|
|
310
|
+
return /** @type {string} */ (param.key.raw ||
|
|
311
|
+
param.key.value);
|
|
312
|
+
// case 'MemberExpression':
|
|
313
|
+
default:
|
|
314
|
+
// Todo: We should really create a structure (and a corresponding
|
|
315
|
+
// option analogous to `checkRestProperty`) which allows for
|
|
316
|
+
// (and optionally requires) dynamic properties to have a single
|
|
317
|
+
// line of documentation
|
|
318
|
+
return undefined;
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
if (param.type === 'ArrayPattern' ||
|
|
322
|
+
/** @type {import('estree').AssignmentPattern} */ (param).left?.type === 'ArrayPattern') {
|
|
323
|
+
const elements = /** @type {import('estree').ArrayPattern} */ (param).elements || /** @type {import('estree').ArrayPattern} */ (
|
|
324
|
+
/** @type {import('estree').AssignmentPattern} */ (param).left)?.elements;
|
|
325
|
+
const roots = elements.map((prop, idx) => {
|
|
326
|
+
return {
|
|
327
|
+
name: `"${idx}"`,
|
|
328
|
+
restElement: prop?.type === 'RestElement',
|
|
329
|
+
};
|
|
330
|
+
});
|
|
331
|
+
return [
|
|
332
|
+
undefined, flattenRoots(roots),
|
|
333
|
+
];
|
|
334
|
+
}
|
|
335
|
+
if ([
|
|
336
|
+
'ExperimentalRestProperty', 'RestElement',
|
|
337
|
+
].includes(param.type)) {
|
|
338
|
+
return {
|
|
339
|
+
isRestProperty: isProperty,
|
|
340
|
+
name: /** @type {import('@typescript-eslint/types').TSESTree.Identifier} */ (
|
|
341
|
+
/** @type {import('@typescript-eslint/types').TSESTree.RestElement} */ (param
|
|
342
|
+
// @ts-expect-error Ok
|
|
343
|
+
).argument).name ?? param?.argument?.elements?.map(({
|
|
344
|
+
// @ts-expect-error Ok
|
|
345
|
+
name, }) => {
|
|
346
|
+
return name;
|
|
347
|
+
}),
|
|
348
|
+
restElement: true,
|
|
349
|
+
};
|
|
350
|
+
}
|
|
351
|
+
if (param.type === 'TSParameterProperty') {
|
|
352
|
+
return getParamName(
|
|
353
|
+
/** @type {import('@typescript-eslint/types').TSESTree.Identifier} */ (
|
|
354
|
+
/** @type {import('@typescript-eslint/types').TSESTree.TSParameterProperty} */ (param).parameter), true);
|
|
355
|
+
}
|
|
356
|
+
throw new Error(`Unsupported function signature format: \`${param.type}\`.`);
|
|
357
|
+
};
|
|
358
|
+
if (!functionNode) {
|
|
359
|
+
return [];
|
|
360
|
+
}
|
|
361
|
+
return ( /** @type {import('@typescript-eslint/types').TSESTree.FunctionDeclaration} */(functionNode).params || /** @type {import('@typescript-eslint/types').TSESTree.MethodDefinition} */ (functionNode).value?.params || []).map((param) => {
|
|
362
|
+
return getParamName(param);
|
|
363
|
+
});
|
|
364
|
+
};
|
|
365
|
+
exports.getFunctionParameterNames = getFunctionParameterNames;
|
|
366
|
+
/**
|
|
367
|
+
* @param {ESTreeOrTypeScriptNode} functionNode
|
|
368
|
+
* @returns {Integer}
|
|
369
|
+
*/
|
|
370
|
+
const hasParams = (functionNode) => {
|
|
371
|
+
// Should also check `functionNode.value.params` if supporting `MethodDefinition`
|
|
372
|
+
return /** @type {import('@typescript-eslint/types').TSESTree.FunctionDeclaration} */ (functionNode).params.length;
|
|
373
|
+
};
|
|
374
|
+
exports.hasParams = hasParams;
|
|
375
|
+
/**
|
|
376
|
+
* Gets all names of the target type, including those that refer to a path, e.g.
|
|
377
|
+
* `foo` or `foo.bar`.
|
|
378
|
+
* @param {import('comment-parser').Block} jsdoc
|
|
379
|
+
* @param {string} targetTagName
|
|
380
|
+
* @returns {{
|
|
381
|
+
* idx: Integer,
|
|
382
|
+
* name: string,
|
|
383
|
+
* type: string
|
|
384
|
+
* }[]}
|
|
385
|
+
*/
|
|
386
|
+
const getJsdocTagsDeep = (jsdoc, targetTagName) => {
|
|
387
|
+
const ret = [];
|
|
388
|
+
for (const [idx, { name, tag, type, },] of jsdoc.tags.entries()) {
|
|
389
|
+
if (tag !== targetTagName) {
|
|
390
|
+
continue;
|
|
391
|
+
}
|
|
392
|
+
ret.push({
|
|
393
|
+
idx,
|
|
394
|
+
name,
|
|
395
|
+
type,
|
|
396
|
+
});
|
|
397
|
+
}
|
|
398
|
+
return ret;
|
|
399
|
+
};
|
|
400
|
+
exports.getJsdocTagsDeep = getJsdocTagsDeep;
|
|
401
|
+
const modeWarnSettings = (0, WarnSettings_js_1.default)();
|
|
402
|
+
/**
|
|
403
|
+
* @param {ParserMode|undefined} mode
|
|
404
|
+
* @param {Reporter} context
|
|
405
|
+
* @returns {import('./tagNames.js').AliasedTags}
|
|
406
|
+
*/
|
|
407
|
+
const getTagNamesForMode = (mode, context) => {
|
|
408
|
+
switch (mode) {
|
|
409
|
+
case 'closure':
|
|
410
|
+
case 'permissive':
|
|
411
|
+
return tagNames_js_1.closureTags;
|
|
412
|
+
case 'jsdoc':
|
|
413
|
+
return tagNames_js_1.jsdocTags;
|
|
414
|
+
case 'typescript':
|
|
415
|
+
return tagNames_js_1.typeScriptTags;
|
|
416
|
+
default:
|
|
417
|
+
if (!modeWarnSettings.hasBeenWarned(context, 'mode')) {
|
|
418
|
+
context.report({
|
|
419
|
+
loc: {
|
|
420
|
+
end: {
|
|
421
|
+
column: 1,
|
|
422
|
+
line: 1,
|
|
423
|
+
},
|
|
424
|
+
start: {
|
|
425
|
+
column: 1,
|
|
426
|
+
line: 1,
|
|
427
|
+
},
|
|
428
|
+
},
|
|
429
|
+
message: `Unrecognized value \`${mode}\` for \`settings.jsdoc.mode\`.`,
|
|
430
|
+
});
|
|
431
|
+
modeWarnSettings.markSettingAsWarned(context, 'mode');
|
|
432
|
+
}
|
|
433
|
+
// We'll avoid breaking too many other rules
|
|
434
|
+
return tagNames_js_1.jsdocTags;
|
|
435
|
+
}
|
|
436
|
+
};
|
|
437
|
+
/**
|
|
438
|
+
* @param {import('comment-parser').Spec} tg
|
|
439
|
+
* @param {boolean} [returnArray]
|
|
440
|
+
* @returns {string[]|string}
|
|
441
|
+
*/
|
|
442
|
+
const getTagDescription = (tg, returnArray) => {
|
|
443
|
+
/**
|
|
444
|
+
* @type {string[]}
|
|
445
|
+
*/
|
|
446
|
+
const descriptions = [];
|
|
447
|
+
tg.source.some(({ tokens: { description, end, lineEnd, name, postDelimiter, postTag, tag, type, }, }) => {
|
|
448
|
+
const desc = (tag && postTag ||
|
|
449
|
+
!tag && !name && !type && postDelimiter || ''
|
|
450
|
+
// Remove space
|
|
451
|
+
).slice(1) +
|
|
452
|
+
(description || '') + (lineEnd || '');
|
|
453
|
+
if (end) {
|
|
454
|
+
if (desc) {
|
|
455
|
+
descriptions.push(desc);
|
|
456
|
+
}
|
|
457
|
+
return true;
|
|
458
|
+
}
|
|
459
|
+
descriptions.push(desc);
|
|
460
|
+
return false;
|
|
461
|
+
});
|
|
462
|
+
return returnArray ? descriptions : descriptions.join('\n');
|
|
463
|
+
};
|
|
464
|
+
exports.getTagDescription = getTagDescription;
|
|
465
|
+
/**
|
|
466
|
+
* @typedef {{
|
|
467
|
+
* report: (descriptor: import('eslint').Rule.ReportDescriptor) => void
|
|
468
|
+
* }} Reporter
|
|
469
|
+
*/
|
|
470
|
+
/**
|
|
471
|
+
* @param {string} name
|
|
472
|
+
* @param {ParserMode|undefined} mode
|
|
473
|
+
* @param {TagNamePreference} tagPreference
|
|
474
|
+
* @param {Reporter} context
|
|
475
|
+
* @returns {string|false|{
|
|
476
|
+
* message: string;
|
|
477
|
+
* replacement?: string|undefined;
|
|
478
|
+
* }}
|
|
479
|
+
*/
|
|
480
|
+
const getPreferredTagNameSimple = (name, mode, tagPreference = {},
|
|
481
|
+
// eslint-disable-next-line unicorn/no-object-as-default-parameter -- Ok
|
|
482
|
+
context = {
|
|
483
|
+
report() {
|
|
484
|
+
// No-op
|
|
485
|
+
},
|
|
486
|
+
}) => {
|
|
487
|
+
const prefValues = Object.values(tagPreference);
|
|
488
|
+
if (prefValues.includes(name) || prefValues.some((prefVal) => {
|
|
489
|
+
return prefVal && typeof prefVal === 'object' && prefVal.replacement === name;
|
|
490
|
+
})) {
|
|
491
|
+
return name;
|
|
492
|
+
}
|
|
493
|
+
// Allow keys to have a 'tag ' prefix to avoid upstream bug in ESLint
|
|
494
|
+
// that disallows keys that conflict with Object.prototype,
|
|
495
|
+
// e.g. 'tag constructor' for 'constructor':
|
|
496
|
+
// https://github.com/eslint/eslint/issues/13289
|
|
497
|
+
// https://github.com/gajus/eslint-plugin-jsdoc/issues/537
|
|
498
|
+
const tagPreferenceFixed = Object.fromEntries(Object
|
|
499
|
+
.entries(tagPreference)
|
|
500
|
+
.map(([key, value,]) => {
|
|
501
|
+
return [
|
|
502
|
+
key.replace(/^tag /v, ''), value,
|
|
503
|
+
];
|
|
504
|
+
}));
|
|
505
|
+
if (Object.hasOwn(tagPreferenceFixed, name)) {
|
|
506
|
+
return tagPreferenceFixed[name];
|
|
507
|
+
}
|
|
508
|
+
const tagNames = getTagNamesForMode(mode, context);
|
|
509
|
+
const preferredTagName = Object.entries(tagNames).find(([, aliases,]) => {
|
|
510
|
+
return aliases.includes(name);
|
|
511
|
+
})?.[0];
|
|
512
|
+
if (preferredTagName) {
|
|
513
|
+
return preferredTagName;
|
|
514
|
+
}
|
|
515
|
+
return name;
|
|
516
|
+
};
|
|
517
|
+
exports.getPreferredTagNameSimple = getPreferredTagNameSimple;
|
|
518
|
+
/**
|
|
519
|
+
* @param {import('eslint').Rule.RuleContext} context
|
|
520
|
+
* @param {ParserMode|undefined} mode
|
|
521
|
+
* @param {string} name
|
|
522
|
+
* @param {string[]} definedTags
|
|
523
|
+
* @returns {boolean}
|
|
524
|
+
*/
|
|
525
|
+
const isValidTag = (context, mode, name, definedTags) => {
|
|
526
|
+
const tagNames = getTagNamesForMode(mode, context);
|
|
527
|
+
const validTagNames = Object.keys(tagNames).concat(Object.values(tagNames).flat());
|
|
528
|
+
const additionalTags = definedTags;
|
|
529
|
+
const allTags = validTagNames.concat(additionalTags);
|
|
530
|
+
return allTags.includes(name);
|
|
531
|
+
};
|
|
532
|
+
exports.isValidTag = isValidTag;
|
|
533
|
+
/**
|
|
534
|
+
* @param {import('./iterateJsdoc.js').JsdocBlockWithInline} jsdoc
|
|
535
|
+
* @param {string} targetTagName
|
|
536
|
+
* @returns {boolean}
|
|
537
|
+
*/
|
|
538
|
+
const hasTag = (jsdoc, targetTagName) => {
|
|
539
|
+
const targetTagLower = targetTagName.toLowerCase();
|
|
540
|
+
return jsdoc.tags.some((doc) => {
|
|
541
|
+
return doc.tag.toLowerCase() === targetTagLower;
|
|
542
|
+
});
|
|
543
|
+
};
|
|
544
|
+
exports.hasTag = hasTag;
|
|
545
|
+
/**
|
|
546
|
+
* @param {import('./iterateJsdoc.js').JsdocBlockWithInline} jsdoc
|
|
547
|
+
* @param {(tag: import('@es-joy/jsdoccomment').JsdocTagWithInline) => boolean} filter
|
|
548
|
+
* @returns {import('@es-joy/jsdoccomment').JsdocTagWithInline[]}
|
|
549
|
+
*/
|
|
550
|
+
const filterTags = (jsdoc, filter) => {
|
|
551
|
+
return jsdoc.tags.filter((tag) => {
|
|
552
|
+
return filter(tag);
|
|
553
|
+
});
|
|
554
|
+
};
|
|
555
|
+
exports.filterTags = filterTags;
|
|
556
|
+
/**
|
|
557
|
+
* @param {import('./iterateJsdoc.js').JsdocBlockWithInline} jsdoc
|
|
558
|
+
* @param {string} tagName
|
|
559
|
+
* @returns {import('comment-parser').Spec[]}
|
|
560
|
+
*/
|
|
561
|
+
const getTags = (jsdoc, tagName) => {
|
|
562
|
+
return filterTags(jsdoc, (item) => {
|
|
563
|
+
return item.tag === tagName;
|
|
564
|
+
});
|
|
565
|
+
};
|
|
566
|
+
exports.getTags = getTags;
|
|
567
|
+
/**
|
|
568
|
+
* @param {import('./iterateJsdoc.js').JsdocBlockWithInline} jsdoc
|
|
569
|
+
* @param {{
|
|
570
|
+
* tagName: string,
|
|
571
|
+
* context?: import('eslint').Rule.RuleContext,
|
|
572
|
+
* mode?: ParserMode,
|
|
573
|
+
* report?: import('./iterateJsdoc.js').Report
|
|
574
|
+
* tagNamePreference?: TagNamePreference
|
|
575
|
+
* skipReportingBlockedTag?: boolean,
|
|
576
|
+
* allowObjectReturn?: boolean,
|
|
577
|
+
* defaultMessage?: string,
|
|
578
|
+
* }} cfg
|
|
579
|
+
* @returns {string|undefined|false|{
|
|
580
|
+
* message: string;
|
|
581
|
+
* replacement?: string|undefined;
|
|
582
|
+
* }|{
|
|
583
|
+
* blocked: true,
|
|
584
|
+
* tagName: string
|
|
585
|
+
* }}
|
|
586
|
+
*/
|
|
587
|
+
const getPreferredTagName = (jsdoc, { allowObjectReturn = false, context, tagName, defaultMessage = `Unexpected tag \`@${tagName}\``, mode, report = () => { }, skipReportingBlockedTag = false, tagNamePreference, }) => {
|
|
588
|
+
const ret = getPreferredTagNameSimple(tagName, mode, tagNamePreference, context);
|
|
589
|
+
const isObject = ret && typeof ret === 'object';
|
|
590
|
+
if (hasTag(jsdoc, tagName) && (ret === false || isObject && !ret.replacement)) {
|
|
591
|
+
if (skipReportingBlockedTag) {
|
|
592
|
+
return {
|
|
593
|
+
blocked: true,
|
|
594
|
+
tagName,
|
|
595
|
+
};
|
|
596
|
+
}
|
|
597
|
+
const message = isObject && ret.message || defaultMessage;
|
|
598
|
+
report(message, null, getTags(jsdoc, tagName)[0]);
|
|
599
|
+
return false;
|
|
600
|
+
}
|
|
601
|
+
return isObject && !allowObjectReturn ? ret.replacement : ret;
|
|
602
|
+
};
|
|
603
|
+
exports.getPreferredTagName = getPreferredTagName;
|
|
604
|
+
/**
|
|
605
|
+
* @param {import('./iterateJsdoc.js').JsdocBlockWithInline} jsdoc
|
|
606
|
+
* @param {string} tagName
|
|
607
|
+
* @param {(
|
|
608
|
+
* matchingJsdocTag: import('@es-joy/jsdoccomment').JsdocTagWithInline,
|
|
609
|
+
* targetTagName: string
|
|
610
|
+
* ) => void} arrayHandler
|
|
611
|
+
* @param {object} cfg
|
|
612
|
+
* @param {import('eslint').Rule.RuleContext} [cfg.context]
|
|
613
|
+
* @param {ParserMode} [cfg.mode]
|
|
614
|
+
* @param {import('./iterateJsdoc.js').Report} [cfg.report]
|
|
615
|
+
* @param {TagNamePreference} [cfg.tagNamePreference]
|
|
616
|
+
* @param {boolean} [cfg.skipReportingBlockedTag]
|
|
617
|
+
* @returns {void}
|
|
618
|
+
*/
|
|
619
|
+
const forEachPreferredTag = (jsdoc, tagName, arrayHandler, { context, mode, report, skipReportingBlockedTag = false, tagNamePreference, } = {}) => {
|
|
620
|
+
const targetTagName = /** @type {string|false} */ (getPreferredTagName(jsdoc, {
|
|
621
|
+
context,
|
|
622
|
+
mode,
|
|
623
|
+
report,
|
|
624
|
+
skipReportingBlockedTag,
|
|
625
|
+
tagName,
|
|
626
|
+
tagNamePreference,
|
|
627
|
+
}));
|
|
628
|
+
if (!targetTagName ||
|
|
629
|
+
skipReportingBlockedTag && targetTagName && typeof targetTagName === 'object') {
|
|
630
|
+
return;
|
|
631
|
+
}
|
|
632
|
+
const matchingJsdocTags = jsdoc.tags.filter(({ tag, }) => {
|
|
633
|
+
return tag === targetTagName;
|
|
634
|
+
});
|
|
635
|
+
for (const matchingJsdocTag of matchingJsdocTags) {
|
|
636
|
+
arrayHandler(
|
|
637
|
+
/**
|
|
638
|
+
* @type {import('@es-joy/jsdoccomment').JsdocTagWithInline}
|
|
639
|
+
*/ (matchingJsdocTag), targetTagName);
|
|
640
|
+
}
|
|
641
|
+
};
|
|
642
|
+
exports.forEachPreferredTag = forEachPreferredTag;
|
|
643
|
+
/**
|
|
644
|
+
* Get all tags, inline tags and inline tags in tags
|
|
645
|
+
* @param {import('./iterateJsdoc.js').JsdocBlockWithInline} jsdoc
|
|
646
|
+
* @returns {(import('comment-parser').Spec|
|
|
647
|
+
* import('@es-joy/jsdoccomment').JsdocInlineTagNoType)[]}
|
|
648
|
+
*/
|
|
649
|
+
const getAllTags = (jsdoc) => {
|
|
650
|
+
return [
|
|
651
|
+
...jsdoc.tags,
|
|
652
|
+
...jsdoc.inlineTags.map((inlineTag) => {
|
|
653
|
+
// Tags don't have source or line numbers, so add before returning
|
|
654
|
+
let line = -1;
|
|
655
|
+
for (const { tokens: { description, }, } of jsdoc.source) {
|
|
656
|
+
line++;
|
|
657
|
+
if (description && description.includes(`{@${inlineTag.tag}`)) {
|
|
658
|
+
break;
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
inlineTag.line = line;
|
|
662
|
+
return inlineTag;
|
|
663
|
+
}),
|
|
664
|
+
...jsdoc.tags.flatMap((tag) => {
|
|
665
|
+
let tagBegins = -1;
|
|
666
|
+
for (const { tokens: { tag: tg, }, } of jsdoc.source) {
|
|
667
|
+
tagBegins++;
|
|
668
|
+
if (tg) {
|
|
669
|
+
break;
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
for (const inlineTag of tag.inlineTags) {
|
|
673
|
+
/** @type {import('./iterateJsdoc.js').Integer} */
|
|
674
|
+
let line = 0;
|
|
675
|
+
for (const { number, tokens: { description, }, } of tag.source) {
|
|
676
|
+
if (description && description.includes(`{@${inlineTag.tag}`)) {
|
|
677
|
+
line = number;
|
|
678
|
+
break;
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
inlineTag.line = tagBegins + line - 1;
|
|
682
|
+
}
|
|
683
|
+
return (
|
|
684
|
+
/**
|
|
685
|
+
* @type {import('comment-parser').Spec & {
|
|
686
|
+
* inlineTags: import('@es-joy/jsdoccomment').JsdocInlineTagNoType[]
|
|
687
|
+
* }}
|
|
688
|
+
*/ (tag).inlineTags);
|
|
689
|
+
}),
|
|
690
|
+
];
|
|
691
|
+
};
|
|
692
|
+
exports.getAllTags = getAllTags;
|
|
693
|
+
/**
|
|
694
|
+
* @param {import('./iterateJsdoc.js').JsdocBlockWithInline} jsdoc
|
|
695
|
+
* @param {string[]} targetTagNames
|
|
696
|
+
* @returns {boolean}
|
|
697
|
+
*/
|
|
698
|
+
const hasATag = (jsdoc, targetTagNames) => {
|
|
699
|
+
return targetTagNames.some((targetTagName) => {
|
|
700
|
+
return hasTag(jsdoc, targetTagName);
|
|
701
|
+
});
|
|
702
|
+
};
|
|
703
|
+
exports.hasATag = hasATag;
|
|
704
|
+
/**
|
|
705
|
+
* Checks if the JSDoc comment has an undefined type.
|
|
706
|
+
* @param {import('comment-parser').Spec|null|undefined} tag
|
|
707
|
+
* the tag which should be checked.
|
|
708
|
+
* @param {ParserMode} mode
|
|
709
|
+
* @returns {boolean}
|
|
710
|
+
* true in case a defined type is undeclared; otherwise false.
|
|
711
|
+
*/
|
|
712
|
+
const mayBeUndefinedTypeTag = (tag, mode) => {
|
|
713
|
+
// The function should not continue in the event the type is not defined...
|
|
714
|
+
if (typeof tag === 'undefined' || tag === null) {
|
|
715
|
+
return true;
|
|
716
|
+
}
|
|
717
|
+
// .. same applies if it declares an `{undefined}` or `{void}` type
|
|
718
|
+
const tagType = tag.type.trim();
|
|
719
|
+
// Exit early if matching
|
|
720
|
+
if (tagType === 'undefined' || tagType === 'void' ||
|
|
721
|
+
tagType === '*' || tagType === 'any') {
|
|
722
|
+
return true;
|
|
723
|
+
}
|
|
724
|
+
let parsedTypes;
|
|
725
|
+
try {
|
|
726
|
+
parsedTypes = (0, jsdoccomment_1.tryParse)(tagType, mode === 'permissive' ? undefined : [
|
|
727
|
+
mode,
|
|
728
|
+
]);
|
|
729
|
+
}
|
|
730
|
+
catch {
|
|
731
|
+
// Ignore
|
|
732
|
+
}
|
|
733
|
+
if (
|
|
734
|
+
// We do not traverse deeply as it could be, e.g., `Promise<void>`
|
|
735
|
+
parsedTypes &&
|
|
736
|
+
parsedTypes.type === 'JsdocTypeUnion' &&
|
|
737
|
+
parsedTypes.elements.find((elem) => {
|
|
738
|
+
return elem.type === 'JsdocTypeUndefined' ||
|
|
739
|
+
elem.type === 'JsdocTypeName' && elem.value === 'void';
|
|
740
|
+
})) {
|
|
741
|
+
return true;
|
|
742
|
+
}
|
|
743
|
+
// In any other case, a type is present
|
|
744
|
+
return false;
|
|
745
|
+
};
|
|
746
|
+
exports.mayBeUndefinedTypeTag = mayBeUndefinedTypeTag;
|
|
747
|
+
/**
|
|
748
|
+
* @param {import('./getDefaultTagStructureForMode.js').TagStructure} map
|
|
749
|
+
* @param {string} tag
|
|
750
|
+
* @returns {Map<string, string|string[]|boolean|undefined>}
|
|
751
|
+
*/
|
|
752
|
+
const ensureMap = (map, tag) => {
|
|
753
|
+
if (!map.has(tag)) {
|
|
754
|
+
map.set(tag, new Map());
|
|
755
|
+
}
|
|
756
|
+
return /** @type {Map<string, string | boolean>} */ (map.get(tag));
|
|
757
|
+
};
|
|
758
|
+
/**
|
|
759
|
+
* @param {import('./iterateJsdoc.js').StructuredTags} structuredTags
|
|
760
|
+
* @param {import('./getDefaultTagStructureForMode.js').TagStructure} tagMap
|
|
761
|
+
* @returns {void}
|
|
762
|
+
*/
|
|
763
|
+
const overrideTagStructure = (structuredTags, tagMap = tagStructure) => {
|
|
764
|
+
for (const [tag, { name, required = [], type, },] of Object.entries(structuredTags)) {
|
|
765
|
+
const tagStruct = ensureMap(tagMap, tag);
|
|
766
|
+
tagStruct.set('namepathRole', name);
|
|
767
|
+
tagStruct.set('typeAllowed', type);
|
|
768
|
+
const requiredName = required.includes('name');
|
|
769
|
+
if (requiredName && name === false) {
|
|
770
|
+
throw new Error('Cannot add "name" to `require` with the tag\'s `name` set to `false`');
|
|
771
|
+
}
|
|
772
|
+
tagStruct.set('nameRequired', requiredName);
|
|
773
|
+
const requiredType = required.includes('type');
|
|
774
|
+
if (requiredType && type === false) {
|
|
775
|
+
throw new Error('Cannot add "type" to `require` with the tag\'s `type` set to `false`');
|
|
776
|
+
}
|
|
777
|
+
tagStruct.set('typeRequired', requiredType);
|
|
778
|
+
const typeOrNameRequired = required.includes('typeOrNameRequired');
|
|
779
|
+
if (typeOrNameRequired && name === false) {
|
|
780
|
+
throw new Error('Cannot add "typeOrNameRequired" to `require` with the tag\'s `name` set to `false`');
|
|
781
|
+
}
|
|
782
|
+
if (typeOrNameRequired && type === false) {
|
|
783
|
+
throw new Error('Cannot add "typeOrNameRequired" to `require` with the tag\'s `type` set to `false`');
|
|
784
|
+
}
|
|
785
|
+
tagStruct.set('typeOrNameRequired', typeOrNameRequired);
|
|
786
|
+
}
|
|
787
|
+
};
|
|
788
|
+
exports.overrideTagStructure = overrideTagStructure;
|
|
789
|
+
/**
|
|
790
|
+
* @param {ParserMode} mode
|
|
791
|
+
* @param {import('./iterateJsdoc.js').StructuredTags} structuredTags
|
|
792
|
+
* @returns {import('./getDefaultTagStructureForMode.js').TagStructure}
|
|
793
|
+
*/
|
|
794
|
+
const getTagStructureForMode = (mode, structuredTags) => {
|
|
795
|
+
const tagStruct = (0, getDefaultTagStructureForMode_js_1.default)(mode);
|
|
796
|
+
try {
|
|
797
|
+
overrideTagStructure(structuredTags, tagStruct);
|
|
798
|
+
/* c8 ignore next 3 */
|
|
799
|
+
}
|
|
800
|
+
catch {
|
|
801
|
+
//
|
|
802
|
+
}
|
|
803
|
+
return tagStruct;
|
|
804
|
+
};
|
|
805
|
+
exports.getTagStructureForMode = getTagStructureForMode;
|
|
806
|
+
/**
|
|
807
|
+
* @param {string} tag
|
|
808
|
+
* @param {import('./getDefaultTagStructureForMode.js').TagStructure} tagMap
|
|
809
|
+
* @returns {boolean}
|
|
810
|
+
*/
|
|
811
|
+
const isNamepathDefiningTag = (tag, tagMap = tagStructure) => {
|
|
812
|
+
const tagStruct = ensureMap(tagMap, tag);
|
|
813
|
+
return tagStruct.get('namepathRole') === 'namepath-defining';
|
|
814
|
+
};
|
|
815
|
+
exports.isNamepathDefiningTag = isNamepathDefiningTag;
|
|
816
|
+
/**
|
|
817
|
+
* @param {string} tag
|
|
818
|
+
* @param {import('./getDefaultTagStructureForMode.js').TagStructure} tagMap
|
|
819
|
+
* @returns {boolean}
|
|
820
|
+
*/
|
|
821
|
+
const isNamepathReferencingTag = (tag, tagMap = tagStructure) => {
|
|
822
|
+
const tagStruct = ensureMap(tagMap, tag);
|
|
823
|
+
return tagStruct.get('namepathRole') === 'namepath-referencing';
|
|
824
|
+
};
|
|
825
|
+
exports.isNamepathReferencingTag = isNamepathReferencingTag;
|
|
826
|
+
/**
|
|
827
|
+
* @param {string} tag
|
|
828
|
+
* @param {import('./getDefaultTagStructureForMode.js').TagStructure} tagMap
|
|
829
|
+
* @returns {boolean}
|
|
830
|
+
*/
|
|
831
|
+
const isNamepathOrUrlReferencingTag = (tag, tagMap = tagStructure) => {
|
|
832
|
+
const tagStruct = ensureMap(tagMap, tag);
|
|
833
|
+
return tagStruct.get('namepathRole') === 'namepath-or-url-referencing';
|
|
834
|
+
};
|
|
835
|
+
exports.isNamepathOrUrlReferencingTag = isNamepathOrUrlReferencingTag;
|
|
836
|
+
/**
|
|
837
|
+
* @param {string} tag
|
|
838
|
+
* @param {import('./getDefaultTagStructureForMode.js').TagStructure} tagMap
|
|
839
|
+
* @returns {boolean|undefined}
|
|
840
|
+
*/
|
|
841
|
+
const tagMustHaveTypePosition = (tag, tagMap = tagStructure) => {
|
|
842
|
+
const tagStruct = ensureMap(tagMap, tag);
|
|
843
|
+
return /** @type {boolean|undefined} */ (tagStruct.get('typeRequired'));
|
|
844
|
+
};
|
|
845
|
+
exports.tagMustHaveTypePosition = tagMustHaveTypePosition;
|
|
846
|
+
/**
|
|
847
|
+
* @param {string} tag
|
|
848
|
+
* @param {import('./getDefaultTagStructureForMode.js').TagStructure} tagMap
|
|
849
|
+
* @returns {boolean|string}
|
|
850
|
+
*/
|
|
851
|
+
const tagMightHaveTypePosition = (tag, tagMap = tagStructure) => {
|
|
852
|
+
if (tagMustHaveTypePosition(tag, tagMap)) {
|
|
853
|
+
return true;
|
|
854
|
+
}
|
|
855
|
+
const tagStruct = ensureMap(tagMap, tag);
|
|
856
|
+
const ret = /** @type {boolean|undefined} */ (tagStruct.get('typeAllowed'));
|
|
857
|
+
return ret === undefined ? true : ret;
|
|
858
|
+
};
|
|
859
|
+
exports.tagMightHaveTypePosition = tagMightHaveTypePosition;
|
|
860
|
+
const namepathTypes = new Set([
|
|
861
|
+
'namepath-defining', 'namepath-referencing',
|
|
862
|
+
]);
|
|
863
|
+
/**
|
|
864
|
+
* @param {string} tag
|
|
865
|
+
* @param {import('./getDefaultTagStructureForMode.js').TagStructure} tagMap
|
|
866
|
+
* @returns {boolean}
|
|
867
|
+
*/
|
|
868
|
+
const tagMightHaveNamePosition = (tag, tagMap = tagStructure) => {
|
|
869
|
+
const tagStruct = ensureMap(tagMap, tag);
|
|
870
|
+
const ret = tagStruct.get('namepathRole');
|
|
871
|
+
return ret === undefined ? true : Boolean(ret);
|
|
872
|
+
};
|
|
873
|
+
exports.tagMightHaveNamePosition = tagMightHaveNamePosition;
|
|
874
|
+
/**
|
|
875
|
+
* @param {string} tag
|
|
876
|
+
* @param {import('./getDefaultTagStructureForMode.js').TagStructure} tagMap
|
|
877
|
+
* @returns {boolean}
|
|
878
|
+
*/
|
|
879
|
+
const tagMightHaveNamepath = (tag, tagMap = tagStructure) => {
|
|
880
|
+
const tagStruct = ensureMap(tagMap, tag);
|
|
881
|
+
const nampathRole = tagStruct.get('namepathRole');
|
|
882
|
+
return nampathRole !== false &&
|
|
883
|
+
namepathTypes.has(/** @type {string} */ (nampathRole));
|
|
884
|
+
};
|
|
885
|
+
exports.tagMightHaveNamepath = tagMightHaveNamepath;
|
|
886
|
+
/**
|
|
887
|
+
* @param {string} tag
|
|
888
|
+
* @param {import('./getDefaultTagStructureForMode.js').TagStructure} tagMap
|
|
889
|
+
* @returns {boolean|undefined}
|
|
890
|
+
*/
|
|
891
|
+
const tagMustHaveNamePosition = (tag, tagMap = tagStructure) => {
|
|
892
|
+
const tagStruct = ensureMap(tagMap, tag);
|
|
893
|
+
return /** @type {boolean|undefined} */ (tagStruct.get('nameRequired'));
|
|
894
|
+
};
|
|
895
|
+
exports.tagMustHaveNamePosition = tagMustHaveNamePosition;
|
|
896
|
+
/**
|
|
897
|
+
* @param {string} tag
|
|
898
|
+
* @param {import('./getDefaultTagStructureForMode.js').TagStructure} tagMap
|
|
899
|
+
* @returns {boolean}
|
|
900
|
+
*/
|
|
901
|
+
const tagMightHaveEitherTypeOrNamePosition = (tag, tagMap) => {
|
|
902
|
+
return Boolean(tagMightHaveTypePosition(tag, tagMap)) || tagMightHaveNamepath(tag, tagMap);
|
|
903
|
+
};
|
|
904
|
+
exports.tagMightHaveEitherTypeOrNamePosition = tagMightHaveEitherTypeOrNamePosition;
|
|
905
|
+
/**
|
|
906
|
+
* @param {string} tag
|
|
907
|
+
* @param {import('./getDefaultTagStructureForMode.js').TagStructure} tagMap
|
|
908
|
+
* @returns {boolean|undefined}
|
|
909
|
+
*/
|
|
910
|
+
const tagMustHaveEitherTypeOrNamePosition = (tag, tagMap) => {
|
|
911
|
+
const tagStruct = ensureMap(tagMap, tag);
|
|
912
|
+
return /** @type {boolean} */ (tagStruct.get('typeOrNameRequired'));
|
|
913
|
+
};
|
|
914
|
+
/**
|
|
915
|
+
* @param {import('comment-parser').Spec} tag
|
|
916
|
+
* @param {import('./getDefaultTagStructureForMode.js').TagStructure} tagMap
|
|
917
|
+
* @returns {boolean|undefined}
|
|
918
|
+
*/
|
|
919
|
+
const tagMissingRequiredTypeOrNamepath = (tag, tagMap = tagStructure) => {
|
|
920
|
+
const mustHaveTypePosition = tagMustHaveTypePosition(tag.tag, tagMap);
|
|
921
|
+
const mightHaveTypePosition = tagMightHaveTypePosition(tag.tag, tagMap);
|
|
922
|
+
const hasTypePosition = mightHaveTypePosition && Boolean(tag.type);
|
|
923
|
+
const hasNameOrNamepathPosition = (tagMustHaveNamePosition(tag.tag, tagMap) ||
|
|
924
|
+
tagMightHaveNamepath(tag.tag, tagMap)) && Boolean(tag.name);
|
|
925
|
+
const mustHaveEither = tagMustHaveEitherTypeOrNamePosition(tag.tag, tagMap);
|
|
926
|
+
const hasEither = tagMightHaveEitherTypeOrNamePosition(tag.tag, tagMap) &&
|
|
927
|
+
(hasTypePosition || hasNameOrNamepathPosition);
|
|
928
|
+
return mustHaveEither && !hasEither && !mustHaveTypePosition;
|
|
929
|
+
};
|
|
930
|
+
exports.tagMissingRequiredTypeOrNamepath = tagMissingRequiredTypeOrNamepath;
|
|
931
|
+
/* eslint-disable complexity -- Temporary */
|
|
932
|
+
/**
|
|
933
|
+
* @param {ESTreeOrTypeScriptNode|null|undefined} node
|
|
934
|
+
* @param {boolean} [checkYieldReturnValue]
|
|
935
|
+
* @returns {boolean}
|
|
936
|
+
*/
|
|
937
|
+
const hasNonFunctionYield = (node, checkYieldReturnValue) => {
|
|
938
|
+
/* eslint-enable complexity -- Temporary */
|
|
939
|
+
if (!node) {
|
|
940
|
+
return false;
|
|
941
|
+
}
|
|
942
|
+
switch (node.type) {
|
|
943
|
+
case 'ArrayExpression':
|
|
944
|
+
case 'ArrayPattern':
|
|
945
|
+
return node.elements.some((element) => {
|
|
946
|
+
return hasNonFunctionYield(element, checkYieldReturnValue);
|
|
947
|
+
});
|
|
948
|
+
case 'AssignmentExpression':
|
|
949
|
+
case 'BinaryExpression':
|
|
950
|
+
case 'LogicalExpression': {
|
|
951
|
+
return hasNonFunctionYield(node.left, checkYieldReturnValue) ||
|
|
952
|
+
hasNonFunctionYield(node.right, checkYieldReturnValue);
|
|
953
|
+
}
|
|
954
|
+
case 'AssignmentPattern':
|
|
955
|
+
return hasNonFunctionYield(node.right, checkYieldReturnValue);
|
|
956
|
+
case 'BlockStatement': {
|
|
957
|
+
return node.body.some((bodyNode) => {
|
|
958
|
+
return ![
|
|
959
|
+
'ArrowFunctionExpression',
|
|
960
|
+
'FunctionDeclaration',
|
|
961
|
+
'FunctionExpression',
|
|
962
|
+
].includes(bodyNode.type) && hasNonFunctionYield(bodyNode, checkYieldReturnValue);
|
|
963
|
+
});
|
|
964
|
+
}
|
|
965
|
+
/* c8 ignore next 2 -- In Babel? */
|
|
966
|
+
case 'CallExpression':
|
|
967
|
+
// @ts-expect-error In Babel?
|
|
968
|
+
case 'OptionalCallExpression':
|
|
969
|
+
return node.arguments.some((element) => {
|
|
970
|
+
return hasNonFunctionYield(element, checkYieldReturnValue);
|
|
971
|
+
});
|
|
972
|
+
case 'ChainExpression':
|
|
973
|
+
case 'ExpressionStatement': {
|
|
974
|
+
return hasNonFunctionYield(node.expression, checkYieldReturnValue);
|
|
975
|
+
}
|
|
976
|
+
/* c8 ignore next 2 -- In Babel? */
|
|
977
|
+
// @ts-expect-error In Babel?
|
|
978
|
+
case 'ClassProperty':
|
|
979
|
+
/* c8 ignore next 2 -- In Babel? */
|
|
980
|
+
// @ts-expect-error In Babel?
|
|
981
|
+
case 'ObjectProperty':
|
|
982
|
+
/* c8 ignore next 2 -- In Babel? */
|
|
983
|
+
case 'Property':
|
|
984
|
+
case 'PropertyDefinition':
|
|
985
|
+
return node.computed && hasNonFunctionYield(node.key, checkYieldReturnValue) ||
|
|
986
|
+
hasNonFunctionYield(node.value, checkYieldReturnValue);
|
|
987
|
+
case 'ConditionalExpression':
|
|
988
|
+
case 'IfStatement': {
|
|
989
|
+
return hasNonFunctionYield(node.test, checkYieldReturnValue) ||
|
|
990
|
+
hasNonFunctionYield(node.consequent, checkYieldReturnValue) ||
|
|
991
|
+
hasNonFunctionYield(node.alternate, checkYieldReturnValue);
|
|
992
|
+
}
|
|
993
|
+
case 'DoWhileStatement':
|
|
994
|
+
case 'ForInStatement':
|
|
995
|
+
case 'ForOfStatement':
|
|
996
|
+
case 'ForStatement':
|
|
997
|
+
case 'LabeledStatement':
|
|
998
|
+
case 'WhileStatement':
|
|
999
|
+
case 'WithStatement': {
|
|
1000
|
+
return hasNonFunctionYield(node.body, checkYieldReturnValue);
|
|
1001
|
+
}
|
|
1002
|
+
/* c8 ignore next 2 -- In Babel? */
|
|
1003
|
+
// @ts-expect-error In Babel?
|
|
1004
|
+
case 'Import':
|
|
1005
|
+
case 'ImportExpression':
|
|
1006
|
+
return hasNonFunctionYield(node.source, checkYieldReturnValue);
|
|
1007
|
+
// ?.
|
|
1008
|
+
/* c8 ignore next 2 -- In Babel? */
|
|
1009
|
+
case 'MemberExpression':
|
|
1010
|
+
// @ts-expect-error In Babel?
|
|
1011
|
+
case 'OptionalMemberExpression':
|
|
1012
|
+
return hasNonFunctionYield(node.object, checkYieldReturnValue) ||
|
|
1013
|
+
hasNonFunctionYield(node.property, checkYieldReturnValue);
|
|
1014
|
+
case 'ObjectExpression':
|
|
1015
|
+
/* eslint-disable no-fallthrough */
|
|
1016
|
+
case 'ObjectPattern':
|
|
1017
|
+
/* eslint-enable no-fallthrough */
|
|
1018
|
+
return node.properties.some((property) => {
|
|
1019
|
+
return hasNonFunctionYield(property, checkYieldReturnValue);
|
|
1020
|
+
});
|
|
1021
|
+
/* c8 ignore next 2 -- In Babel? */
|
|
1022
|
+
// @ts-expect-error In Babel?
|
|
1023
|
+
case 'ObjectMethod':
|
|
1024
|
+
/* c8 ignore next 6 -- In Babel? */
|
|
1025
|
+
// @ts-expect-error In Babel?
|
|
1026
|
+
return node.computed && hasNonFunctionYield(node.key, checkYieldReturnValue) ||
|
|
1027
|
+
// @ts-expect-error In Babel?
|
|
1028
|
+
node.arguments.some((nde) => {
|
|
1029
|
+
return hasNonFunctionYield(nde, checkYieldReturnValue);
|
|
1030
|
+
});
|
|
1031
|
+
case 'ReturnStatement': {
|
|
1032
|
+
if (node.argument === null) {
|
|
1033
|
+
return false;
|
|
1034
|
+
}
|
|
1035
|
+
return hasNonFunctionYield(node.argument, checkYieldReturnValue);
|
|
1036
|
+
}
|
|
1037
|
+
// Comma
|
|
1038
|
+
case 'SequenceExpression':
|
|
1039
|
+
case 'TemplateLiteral':
|
|
1040
|
+
return node.expressions.some((subExpression) => {
|
|
1041
|
+
return hasNonFunctionYield(subExpression, checkYieldReturnValue);
|
|
1042
|
+
});
|
|
1043
|
+
case 'SpreadElement':
|
|
1044
|
+
case 'UnaryExpression':
|
|
1045
|
+
return hasNonFunctionYield(node.argument, checkYieldReturnValue);
|
|
1046
|
+
case 'SwitchStatement': {
|
|
1047
|
+
return node.cases.some((someCase) => {
|
|
1048
|
+
return someCase.consequent.some((nde) => {
|
|
1049
|
+
return hasNonFunctionYield(nde, checkYieldReturnValue);
|
|
1050
|
+
});
|
|
1051
|
+
});
|
|
1052
|
+
}
|
|
1053
|
+
case 'TaggedTemplateExpression':
|
|
1054
|
+
return hasNonFunctionYield(node.quasi, checkYieldReturnValue);
|
|
1055
|
+
case 'TryStatement': {
|
|
1056
|
+
return hasNonFunctionYield(node.block, checkYieldReturnValue) ||
|
|
1057
|
+
hasNonFunctionYield(node.handler && node.handler.body, checkYieldReturnValue) ||
|
|
1058
|
+
hasNonFunctionYield(
|
|
1059
|
+
/** @type {import('@typescript-eslint/types').TSESTree.BlockStatement} */
|
|
1060
|
+
(node.finalizer), checkYieldReturnValue);
|
|
1061
|
+
}
|
|
1062
|
+
case 'VariableDeclaration': {
|
|
1063
|
+
return node.declarations.some((nde) => {
|
|
1064
|
+
return hasNonFunctionYield(nde, checkYieldReturnValue);
|
|
1065
|
+
});
|
|
1066
|
+
}
|
|
1067
|
+
case 'VariableDeclarator': {
|
|
1068
|
+
return hasNonFunctionYield(node.id, checkYieldReturnValue) ||
|
|
1069
|
+
hasNonFunctionYield(node.init, checkYieldReturnValue);
|
|
1070
|
+
}
|
|
1071
|
+
case 'YieldExpression': {
|
|
1072
|
+
if (checkYieldReturnValue) {
|
|
1073
|
+
if (
|
|
1074
|
+
/** @type {import('eslint').Rule.Node} */ (node).parent.type === 'VariableDeclarator') {
|
|
1075
|
+
return true;
|
|
1076
|
+
}
|
|
1077
|
+
return false;
|
|
1078
|
+
}
|
|
1079
|
+
// void return does not count.
|
|
1080
|
+
if (node.argument === null) {
|
|
1081
|
+
return false;
|
|
1082
|
+
}
|
|
1083
|
+
return true;
|
|
1084
|
+
}
|
|
1085
|
+
default: {
|
|
1086
|
+
return false;
|
|
1087
|
+
}
|
|
1088
|
+
}
|
|
1089
|
+
};
|
|
1090
|
+
/**
|
|
1091
|
+
* Checks if a node has a return statement. Void return does not count.
|
|
1092
|
+
* @param {ESTreeOrTypeScriptNode} node
|
|
1093
|
+
* @param {boolean} [checkYieldReturnValue]
|
|
1094
|
+
* @returns {boolean}
|
|
1095
|
+
*/
|
|
1096
|
+
const hasYieldValue = (node, checkYieldReturnValue) => {
|
|
1097
|
+
return /** @type {import('@typescript-eslint/types').TSESTree.FunctionDeclaration} */ (node).generator && (
|
|
1098
|
+
/** @type {import('@typescript-eslint/types').TSESTree.FunctionDeclaration} */ (node).expression || hasNonFunctionYield(
|
|
1099
|
+
/** @type {import('@typescript-eslint/types').TSESTree.FunctionDeclaration} */
|
|
1100
|
+
(node).body, checkYieldReturnValue));
|
|
1101
|
+
};
|
|
1102
|
+
exports.hasYieldValue = hasYieldValue;
|
|
1103
|
+
/**
|
|
1104
|
+
* Checks if a node has a throws statement.
|
|
1105
|
+
* @param {ESTreeOrTypeScriptNode|null|undefined} node
|
|
1106
|
+
* @param {boolean} [innerFunction]
|
|
1107
|
+
* @returns {boolean}
|
|
1108
|
+
*/
|
|
1109
|
+
// eslint-disable-next-line complexity
|
|
1110
|
+
const hasThrowValue = (node, innerFunction) => {
|
|
1111
|
+
if (!node) {
|
|
1112
|
+
return false;
|
|
1113
|
+
}
|
|
1114
|
+
// There are cases where a function may execute its inner function which
|
|
1115
|
+
// throws, but we're treating functions atomically rather than trying to
|
|
1116
|
+
// follow them
|
|
1117
|
+
switch (node.type) {
|
|
1118
|
+
case 'ArrowFunctionExpression':
|
|
1119
|
+
case 'FunctionDeclaration':
|
|
1120
|
+
case 'FunctionExpression': {
|
|
1121
|
+
return !innerFunction && !node.async && hasThrowValue(node.body, true);
|
|
1122
|
+
}
|
|
1123
|
+
case 'BlockStatement': {
|
|
1124
|
+
return node.body.some((bodyNode) => {
|
|
1125
|
+
return bodyNode.type !== 'FunctionDeclaration' && hasThrowValue(bodyNode);
|
|
1126
|
+
});
|
|
1127
|
+
}
|
|
1128
|
+
case 'DoWhileStatement':
|
|
1129
|
+
case 'ForInStatement':
|
|
1130
|
+
case 'ForOfStatement':
|
|
1131
|
+
case 'ForStatement':
|
|
1132
|
+
case 'LabeledStatement':
|
|
1133
|
+
case 'WhileStatement':
|
|
1134
|
+
case 'WithStatement': {
|
|
1135
|
+
return hasThrowValue(node.body);
|
|
1136
|
+
}
|
|
1137
|
+
case 'IfStatement': {
|
|
1138
|
+
return hasThrowValue(node.consequent) || hasThrowValue(node.alternate);
|
|
1139
|
+
}
|
|
1140
|
+
case 'SwitchStatement': {
|
|
1141
|
+
return node.cases.some((someCase) => {
|
|
1142
|
+
return someCase.consequent.some((nde) => {
|
|
1143
|
+
return hasThrowValue(nde);
|
|
1144
|
+
});
|
|
1145
|
+
});
|
|
1146
|
+
}
|
|
1147
|
+
case 'ThrowStatement': {
|
|
1148
|
+
return true;
|
|
1149
|
+
}
|
|
1150
|
+
// We only consider it to throw an error if the catch or finally blocks throw an error.
|
|
1151
|
+
case 'TryStatement': {
|
|
1152
|
+
return hasThrowValue(node.handler && node.handler.body) ||
|
|
1153
|
+
hasThrowValue(node.finalizer);
|
|
1154
|
+
}
|
|
1155
|
+
default: {
|
|
1156
|
+
return false;
|
|
1157
|
+
}
|
|
1158
|
+
}
|
|
1159
|
+
};
|
|
1160
|
+
exports.hasThrowValue = hasThrowValue;
|
|
1161
|
+
/**
|
|
1162
|
+
* @param {string} tag
|
|
1163
|
+
*/
|
|
1164
|
+
/*
|
|
1165
|
+
const isInlineTag = (tag) => {
|
|
1166
|
+
return /^(@link|@linkcode|@linkplain|@tutorial) /v.test(tag);
|
|
1167
|
+
};
|
|
1168
|
+
*/
|
|
1169
|
+
/**
|
|
1170
|
+
* Parses GCC Generic/Template types
|
|
1171
|
+
* @see {@link https://github.com/google/closure-compiler/wiki/Generic-Types}
|
|
1172
|
+
* @see {@link https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html#template}
|
|
1173
|
+
* @param {import('comment-parser').Spec} tag
|
|
1174
|
+
* @returns {string[]}
|
|
1175
|
+
*/
|
|
1176
|
+
const parseClosureTemplateTag = (tag) => {
|
|
1177
|
+
return tag.name
|
|
1178
|
+
.split(',')
|
|
1179
|
+
.map((type) => {
|
|
1180
|
+
return type.trim().replace(/^\[?(?<name>.*?)=.*$/v, '$<name>');
|
|
1181
|
+
});
|
|
1182
|
+
};
|
|
1183
|
+
exports.parseClosureTemplateTag = parseClosureTemplateTag;
|
|
1184
|
+
/**
|
|
1185
|
+
* @typedef {true|string[]} DefaultContexts
|
|
1186
|
+
*/
|
|
1187
|
+
/**
|
|
1188
|
+
* Checks user option for `contexts` array, defaulting to
|
|
1189
|
+
* contexts designated by the rule. Returns an array of
|
|
1190
|
+
* ESTree AST types, indicating allowable contexts.
|
|
1191
|
+
* @param {import('eslint').Rule.RuleContext} context
|
|
1192
|
+
* @param {DefaultContexts|undefined} defaultContexts
|
|
1193
|
+
* @param {{
|
|
1194
|
+
* contexts?: import('./iterateJsdoc.js').Context[]
|
|
1195
|
+
* }} settings
|
|
1196
|
+
* @returns {(string|import('./iterateJsdoc.js').ContextObject)[]}
|
|
1197
|
+
*/
|
|
1198
|
+
const enforcedContexts = (context, defaultContexts, settings) => {
|
|
1199
|
+
const contexts = context.options[0]?.contexts || settings.contexts || (defaultContexts === true ? [
|
|
1200
|
+
'ArrowFunctionExpression',
|
|
1201
|
+
'FunctionDeclaration',
|
|
1202
|
+
'FunctionExpression',
|
|
1203
|
+
'TSDeclareFunction',
|
|
1204
|
+
] : defaultContexts);
|
|
1205
|
+
return contexts;
|
|
1206
|
+
};
|
|
1207
|
+
exports.enforcedContexts = enforcedContexts;
|
|
1208
|
+
/**
|
|
1209
|
+
* @param {import('./iterateJsdoc.js').Context[]} contexts
|
|
1210
|
+
* @param {import('./iterateJsdoc.js').CheckJsdoc} checkJsdoc
|
|
1211
|
+
* @param {import('@es-joy/jsdoccomment').CommentHandler} [handler]
|
|
1212
|
+
* @returns {import('eslint').Rule.RuleListener}
|
|
1213
|
+
*/
|
|
1214
|
+
const getContextObject = (contexts, checkJsdoc, handler) => {
|
|
1215
|
+
/** @type {import('eslint').Rule.RuleListener} */
|
|
1216
|
+
const properties = {};
|
|
1217
|
+
for (const [idx, prop,] of contexts.entries()) {
|
|
1218
|
+
/** @type {string} */
|
|
1219
|
+
let property;
|
|
1220
|
+
/** @type {(node: import('eslint').Rule.Node) => void} */
|
|
1221
|
+
let value;
|
|
1222
|
+
if (typeof prop === 'object') {
|
|
1223
|
+
const selInfo = {
|
|
1224
|
+
lastIndex: idx,
|
|
1225
|
+
selector: prop.context,
|
|
1226
|
+
};
|
|
1227
|
+
if (prop.comment) {
|
|
1228
|
+
property = /** @type {string} */ (prop.context);
|
|
1229
|
+
value = checkJsdoc.bind(null, {
|
|
1230
|
+
...selInfo,
|
|
1231
|
+
comment: prop.comment,
|
|
1232
|
+
},
|
|
1233
|
+
/**
|
|
1234
|
+
* @type {(jsdoc: import('@es-joy/jsdoccomment').JsdocBlockWithInline) => boolean}
|
|
1235
|
+
*/
|
|
1236
|
+
( /** @type {import('@es-joy/jsdoccomment').CommentHandler} */(handler).bind(null, prop.comment)));
|
|
1237
|
+
}
|
|
1238
|
+
else {
|
|
1239
|
+
property = /** @type {string} */ (prop.context);
|
|
1240
|
+
value = checkJsdoc.bind(null, selInfo, null);
|
|
1241
|
+
}
|
|
1242
|
+
}
|
|
1243
|
+
else {
|
|
1244
|
+
const selInfo = {
|
|
1245
|
+
lastIndex: idx,
|
|
1246
|
+
selector: prop,
|
|
1247
|
+
};
|
|
1248
|
+
property = prop;
|
|
1249
|
+
value = checkJsdoc.bind(null, selInfo, null);
|
|
1250
|
+
}
|
|
1251
|
+
const old = /**
|
|
1252
|
+
* @type {((node: import('eslint').Rule.Node) => void)}
|
|
1253
|
+
*/ (properties[property]);
|
|
1254
|
+
properties[property] = old ?
|
|
1255
|
+
/**
|
|
1256
|
+
* @type {((node: import('eslint').Rule.Node) => void)}
|
|
1257
|
+
*/
|
|
1258
|
+
function (node) {
|
|
1259
|
+
old(node);
|
|
1260
|
+
value(node);
|
|
1261
|
+
} :
|
|
1262
|
+
value;
|
|
1263
|
+
}
|
|
1264
|
+
return properties;
|
|
1265
|
+
};
|
|
1266
|
+
exports.getContextObject = getContextObject;
|
|
1267
|
+
const tagsWithNamesAndDescriptions = new Set([
|
|
1268
|
+
'arg', 'argument', 'param', 'prop', 'property',
|
|
1269
|
+
'return',
|
|
1270
|
+
// These two are parsed by our custom parser as though having a `name`
|
|
1271
|
+
'returns', 'template',
|
|
1272
|
+
]);
|
|
1273
|
+
/**
|
|
1274
|
+
* @typedef {{
|
|
1275
|
+
* [key: string]: false|string|
|
|
1276
|
+
* {message: string, replacement?: string}
|
|
1277
|
+
* }} TagNamePreference
|
|
1278
|
+
*/
|
|
1279
|
+
/**
|
|
1280
|
+
* @param {import('eslint').Rule.RuleContext} context
|
|
1281
|
+
* @param {ParserMode|undefined} mode
|
|
1282
|
+
* @param {import('comment-parser').Spec[]} tags
|
|
1283
|
+
* @returns {{
|
|
1284
|
+
* tagsWithNames: import('comment-parser').Spec[],
|
|
1285
|
+
* tagsWithoutNames: import('comment-parser').Spec[]
|
|
1286
|
+
* }}
|
|
1287
|
+
*/
|
|
1288
|
+
const getTagsByType = (context, mode, tags) => {
|
|
1289
|
+
/**
|
|
1290
|
+
* @type {import('comment-parser').Spec[]}
|
|
1291
|
+
*/
|
|
1292
|
+
const tagsWithoutNames = [];
|
|
1293
|
+
const tagsWithNames = tags.filter((tag) => {
|
|
1294
|
+
const { tag: tagName, } = tag;
|
|
1295
|
+
const tagWithName = tagsWithNamesAndDescriptions.has(tagName);
|
|
1296
|
+
if (!tagWithName) {
|
|
1297
|
+
tagsWithoutNames.push(tag);
|
|
1298
|
+
}
|
|
1299
|
+
return tagWithName;
|
|
1300
|
+
});
|
|
1301
|
+
return {
|
|
1302
|
+
tagsWithNames,
|
|
1303
|
+
tagsWithoutNames,
|
|
1304
|
+
};
|
|
1305
|
+
};
|
|
1306
|
+
exports.getTagsByType = getTagsByType;
|
|
1307
|
+
/**
|
|
1308
|
+
* @param {import('eslint').SourceCode|{
|
|
1309
|
+
* text: string
|
|
1310
|
+
* }} sourceCode
|
|
1311
|
+
* @returns {string}
|
|
1312
|
+
*/
|
|
1313
|
+
const getIndent = (sourceCode) => {
|
|
1314
|
+
return (sourceCode.text.match(/^\n*([ \t]+)/v)?.[1] ?? '') + ' ';
|
|
1315
|
+
};
|
|
1316
|
+
exports.getIndent = getIndent;
|
|
1317
|
+
/**
|
|
1318
|
+
* @param {import('eslint').Rule.Node|null} node
|
|
1319
|
+
* @returns {boolean}
|
|
1320
|
+
*/
|
|
1321
|
+
const isConstructor = (node) => {
|
|
1322
|
+
return node?.type === 'MethodDefinition' && node.kind === 'constructor' ||
|
|
1323
|
+
/** @type {import('@typescript-eslint/types').TSESTree.MethodDefinition} */ (node?.parent)?.kind === 'constructor';
|
|
1324
|
+
};
|
|
1325
|
+
exports.isConstructor = isConstructor;
|
|
1326
|
+
/**
|
|
1327
|
+
* @param {import('eslint').Rule.Node|null} node
|
|
1328
|
+
* @returns {boolean}
|
|
1329
|
+
*/
|
|
1330
|
+
const isGetter = (node) => {
|
|
1331
|
+
return node !== null &&
|
|
1332
|
+
/**
|
|
1333
|
+
* @type {import('@typescript-eslint/types').TSESTree.MethodDefinition|
|
|
1334
|
+
* import('@typescript-eslint/types').TSESTree.Property}
|
|
1335
|
+
*/ (node.parent)?.kind === 'get';
|
|
1336
|
+
};
|
|
1337
|
+
exports.isGetter = isGetter;
|
|
1338
|
+
/**
|
|
1339
|
+
* @param {import('eslint').Rule.Node|null} node
|
|
1340
|
+
* @returns {boolean}
|
|
1341
|
+
*/
|
|
1342
|
+
const isSetter = (node) => {
|
|
1343
|
+
return node !== null &&
|
|
1344
|
+
/**
|
|
1345
|
+
* @type {import('@typescript-eslint/types').TSESTree.MethodDefinition|
|
|
1346
|
+
* import('@typescript-eslint/types').TSESTree.Property}
|
|
1347
|
+
*/ (node.parent)?.kind === 'set';
|
|
1348
|
+
};
|
|
1349
|
+
exports.isSetter = isSetter;
|
|
1350
|
+
/**
|
|
1351
|
+
* @param {import('eslint').Rule.Node} node
|
|
1352
|
+
* @returns {boolean}
|
|
1353
|
+
*/
|
|
1354
|
+
const hasAccessorPair = (node) => {
|
|
1355
|
+
const { key, kind: sourceKind, type, } =
|
|
1356
|
+
/**
|
|
1357
|
+
* @type {import('@typescript-eslint/types').TSESTree.MethodDefinition|
|
|
1358
|
+
* import('@typescript-eslint/types').TSESTree.Property}
|
|
1359
|
+
*/ (node);
|
|
1360
|
+
const sourceName =
|
|
1361
|
+
/** @type {import('@typescript-eslint/types').TSESTree.Identifier} */ (key).name;
|
|
1362
|
+
const oppositeKind = sourceKind === 'get' ? 'set' : 'get';
|
|
1363
|
+
const sibling = type === 'MethodDefinition' ?
|
|
1364
|
+
/** @type {import('@typescript-eslint/types').TSESTree.ClassBody} */ (node.parent).body :
|
|
1365
|
+
/** @type {import('@typescript-eslint/types').TSESTree.ObjectExpression} */ (node.parent).properties;
|
|
1366
|
+
return (sibling.some((child) => {
|
|
1367
|
+
const { key: ky, kind, } = /**
|
|
1368
|
+
* @type {import('@typescript-eslint/types').TSESTree.MethodDefinition|
|
|
1369
|
+
* import('@typescript-eslint/types').TSESTree.Property}
|
|
1370
|
+
*/ (child);
|
|
1371
|
+
const name =
|
|
1372
|
+
/** @type {import('@typescript-eslint/types').TSESTree.Identifier} */ (ky).name;
|
|
1373
|
+
return kind === oppositeKind && name === sourceName;
|
|
1374
|
+
}));
|
|
1375
|
+
};
|
|
1376
|
+
/**
|
|
1377
|
+
* @param {import('./iterateJsdoc.js').JsdocBlockWithInline} jsdoc
|
|
1378
|
+
* @param {import('eslint').Rule.Node|null} node
|
|
1379
|
+
* @param {import('eslint').Rule.RuleContext} context
|
|
1380
|
+
* @param {import('json-schema').JSONSchema4} schema
|
|
1381
|
+
* @returns {boolean}
|
|
1382
|
+
*/
|
|
1383
|
+
const exemptSpeciaMethods = (jsdoc, node, context, schema) => {
|
|
1384
|
+
/**
|
|
1385
|
+
* @param {"checkGetters"|"checkSetters"|"checkConstructors"} prop
|
|
1386
|
+
* @returns {boolean|"no-setter"|"no-getter"}
|
|
1387
|
+
*/
|
|
1388
|
+
const hasSchemaOption = (prop) => {
|
|
1389
|
+
const schemaProperties = schema[0].properties;
|
|
1390
|
+
return context.options[0]?.[prop] ??
|
|
1391
|
+
(schemaProperties[prop] && schemaProperties[prop].default);
|
|
1392
|
+
};
|
|
1393
|
+
const checkGetters = hasSchemaOption('checkGetters');
|
|
1394
|
+
const checkSetters = hasSchemaOption('checkSetters');
|
|
1395
|
+
return !hasSchemaOption('checkConstructors') &&
|
|
1396
|
+
(isConstructor(node) ||
|
|
1397
|
+
hasATag(jsdoc, [
|
|
1398
|
+
'class',
|
|
1399
|
+
'constructor',
|
|
1400
|
+
])) ||
|
|
1401
|
+
isGetter(node) && (!checkGetters ||
|
|
1402
|
+
checkGetters === 'no-setter' && hasAccessorPair(/** @type {import('./iterateJsdoc.js').Node} */ (node).parent)) ||
|
|
1403
|
+
isSetter(node) && (!checkSetters ||
|
|
1404
|
+
checkSetters === 'no-getter' && hasAccessorPair(/** @type {import('./iterateJsdoc.js').Node} */ (node).parent));
|
|
1405
|
+
};
|
|
1406
|
+
exports.exemptSpeciaMethods = exemptSpeciaMethods;
|
|
1407
|
+
/**
|
|
1408
|
+
* Since path segments may be unquoted (if matching a reserved word,
|
|
1409
|
+
* identifier or numeric literal) or single or double quoted, in either
|
|
1410
|
+
* the `@param` or in source, we need to strip the quotes to give a fair
|
|
1411
|
+
* comparison.
|
|
1412
|
+
* @param {string} str
|
|
1413
|
+
* @returns {string}
|
|
1414
|
+
*/
|
|
1415
|
+
const dropPathSegmentQuotes = (str) => {
|
|
1416
|
+
return str.replaceAll(/\.(['"])(.*)\1/gv, '.$2');
|
|
1417
|
+
};
|
|
1418
|
+
exports.dropPathSegmentQuotes = dropPathSegmentQuotes;
|
|
1419
|
+
/**
|
|
1420
|
+
* @param {string} name
|
|
1421
|
+
* @returns {(otherPathName: string) => boolean}
|
|
1422
|
+
*/
|
|
1423
|
+
const comparePaths = (name) => {
|
|
1424
|
+
return (otherPathName) => {
|
|
1425
|
+
return otherPathName === name ||
|
|
1426
|
+
dropPathSegmentQuotes(otherPathName) === dropPathSegmentQuotes(name);
|
|
1427
|
+
};
|
|
1428
|
+
};
|
|
1429
|
+
exports.comparePaths = comparePaths;
|
|
1430
|
+
/**
|
|
1431
|
+
* @callback PathDoesNotBeginWith
|
|
1432
|
+
* @param {string} name
|
|
1433
|
+
* @param {string} otherPathName
|
|
1434
|
+
* @returns {boolean}
|
|
1435
|
+
*/
|
|
1436
|
+
/** @type {PathDoesNotBeginWith} */
|
|
1437
|
+
const pathDoesNotBeginWith = (name, otherPathName) => {
|
|
1438
|
+
return !name.startsWith(otherPathName) &&
|
|
1439
|
+
!dropPathSegmentQuotes(name).startsWith(dropPathSegmentQuotes(otherPathName));
|
|
1440
|
+
};
|
|
1441
|
+
exports.pathDoesNotBeginWith = pathDoesNotBeginWith;
|
|
1442
|
+
/**
|
|
1443
|
+
* @param {string} regexString
|
|
1444
|
+
* @param {string} [requiredFlags]
|
|
1445
|
+
* @returns {RegExp}
|
|
1446
|
+
*/
|
|
1447
|
+
const getRegexFromString = (regexString, requiredFlags) => {
|
|
1448
|
+
const match = regexString.match(/^\/(.*)\/([gimyvus]*)$/vs);
|
|
1449
|
+
let flags = 'v';
|
|
1450
|
+
let regex = regexString;
|
|
1451
|
+
if (match) {
|
|
1452
|
+
[
|
|
1453
|
+
,
|
|
1454
|
+
regex,
|
|
1455
|
+
flags,
|
|
1456
|
+
] = match;
|
|
1457
|
+
if (!flags) {
|
|
1458
|
+
flags = 'v';
|
|
1459
|
+
}
|
|
1460
|
+
}
|
|
1461
|
+
const uniqueFlags = [
|
|
1462
|
+
...new Set(flags + (requiredFlags || '')),
|
|
1463
|
+
];
|
|
1464
|
+
flags = uniqueFlags.join('');
|
|
1465
|
+
return new RegExp(regex, flags);
|
|
1466
|
+
};
|
|
1467
|
+
exports.getRegexFromString = getRegexFromString;
|
|
1468
|
+
var hasReturnValue_js_1 = require("./utils/hasReturnValue.js");
|
|
1469
|
+
Object.defineProperty(exports, "hasReturnValue", { enumerable: true, get: function () { return hasReturnValue_js_1.hasReturnValue; } });
|
|
1470
|
+
Object.defineProperty(exports, "hasValueOrExecutorHasNonEmptyResolveValue", { enumerable: true, get: function () { return hasReturnValue_js_1.hasValueOrExecutorHasNonEmptyResolveValue; } });
|