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,136 +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
|
-
/**
|
|
8
|
-
* @param {string} description
|
|
9
|
-
* @returns {import('../iterateJsdoc.js').Integer}
|
|
10
|
-
*/
|
|
11
|
-
const checkDescription = (description) => {
|
|
12
|
-
return description
|
|
13
|
-
.trim()
|
|
14
|
-
.split('\n')
|
|
15
|
-
.filter(Boolean)
|
|
16
|
-
.length;
|
|
17
|
-
};
|
|
18
|
-
exports.default = (0, iterateJsdoc_js_1.default)(({ context, jsdoc, report, utils, }) => {
|
|
19
|
-
if (utils.avoidDocs()) {
|
|
20
|
-
return;
|
|
21
|
-
}
|
|
22
|
-
const { descriptionStyle = 'body', } = context.options[0] || {};
|
|
23
|
-
let targetTagName = utils.getPreferredTagName({
|
|
24
|
-
// We skip reporting except when `@description` is essential to the rule,
|
|
25
|
-
// so user can block the tag and still meaningfully use this rule
|
|
26
|
-
// even if the tag is present (and `check-tag-names` is the one to
|
|
27
|
-
// normally report the fact that it is blocked but present)
|
|
28
|
-
skipReportingBlockedTag: descriptionStyle !== 'tag',
|
|
29
|
-
tagName: 'description',
|
|
30
|
-
});
|
|
31
|
-
if (!targetTagName) {
|
|
32
|
-
return;
|
|
33
|
-
}
|
|
34
|
-
const isBlocked = typeof targetTagName === 'object' && 'blocked' in targetTagName && targetTagName.blocked;
|
|
35
|
-
if (isBlocked) {
|
|
36
|
-
targetTagName = /** @type {{blocked: true; tagName: string;}} */ (targetTagName).tagName;
|
|
37
|
-
}
|
|
38
|
-
if (descriptionStyle !== 'tag') {
|
|
39
|
-
const { description, } = utils.getDescription();
|
|
40
|
-
if (checkDescription(description || '')) {
|
|
41
|
-
return;
|
|
42
|
-
}
|
|
43
|
-
if (descriptionStyle === 'body') {
|
|
44
|
-
const descTags = utils.getPresentTags([
|
|
45
|
-
'desc', 'description',
|
|
46
|
-
]);
|
|
47
|
-
if (descTags.length) {
|
|
48
|
-
const [{ tag: tagName, },] = descTags;
|
|
49
|
-
report(`Remove the @${tagName} tag to leave a plain block description or add additional description text above the @${tagName} line.`);
|
|
50
|
-
}
|
|
51
|
-
else {
|
|
52
|
-
report('Missing JSDoc block description.');
|
|
53
|
-
}
|
|
54
|
-
return;
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
const functionExamples = isBlocked ?
|
|
58
|
-
[] :
|
|
59
|
-
jsdoc.tags.filter(({ tag, }) => {
|
|
60
|
-
return tag === targetTagName;
|
|
61
|
-
});
|
|
62
|
-
if (!functionExamples.length) {
|
|
63
|
-
report(descriptionStyle === 'any' ?
|
|
64
|
-
`Missing JSDoc block description or @${targetTagName} declaration.` :
|
|
65
|
-
`Missing JSDoc @${targetTagName} declaration.`);
|
|
66
|
-
return;
|
|
67
|
-
}
|
|
68
|
-
for (const example of functionExamples) {
|
|
69
|
-
if (!checkDescription(`${example.name} ${utils.getTagDescription(example)}`)) {
|
|
70
|
-
report(`Missing JSDoc @${targetTagName} description.`, null, example);
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
}, {
|
|
74
|
-
contextDefaults: true,
|
|
75
|
-
meta: {
|
|
76
|
-
docs: {
|
|
77
|
-
description: 'Requires that all functions have a description.',
|
|
78
|
-
url: 'https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/require-description.md#repos-sticky-header',
|
|
79
|
-
},
|
|
80
|
-
schema: [
|
|
81
|
-
{
|
|
82
|
-
additionalProperties: false,
|
|
83
|
-
properties: {
|
|
84
|
-
checkConstructors: {
|
|
85
|
-
default: true,
|
|
86
|
-
type: 'boolean',
|
|
87
|
-
},
|
|
88
|
-
checkGetters: {
|
|
89
|
-
default: true,
|
|
90
|
-
type: 'boolean',
|
|
91
|
-
},
|
|
92
|
-
checkSetters: {
|
|
93
|
-
default: true,
|
|
94
|
-
type: 'boolean',
|
|
95
|
-
},
|
|
96
|
-
contexts: {
|
|
97
|
-
items: {
|
|
98
|
-
anyOf: [
|
|
99
|
-
{
|
|
100
|
-
type: 'string',
|
|
101
|
-
},
|
|
102
|
-
{
|
|
103
|
-
additionalProperties: false,
|
|
104
|
-
properties: {
|
|
105
|
-
comment: {
|
|
106
|
-
type: 'string',
|
|
107
|
-
},
|
|
108
|
-
context: {
|
|
109
|
-
type: 'string',
|
|
110
|
-
},
|
|
111
|
-
},
|
|
112
|
-
type: 'object',
|
|
113
|
-
},
|
|
114
|
-
],
|
|
115
|
-
},
|
|
116
|
-
type: 'array',
|
|
117
|
-
},
|
|
118
|
-
descriptionStyle: {
|
|
119
|
-
enum: [
|
|
120
|
-
'body', 'tag', 'any',
|
|
121
|
-
],
|
|
122
|
-
type: 'string',
|
|
123
|
-
},
|
|
124
|
-
exemptedBy: {
|
|
125
|
-
items: {
|
|
126
|
-
type: 'string',
|
|
127
|
-
},
|
|
128
|
-
type: 'array',
|
|
129
|
-
},
|
|
130
|
-
},
|
|
131
|
-
type: 'object',
|
|
132
|
-
},
|
|
133
|
-
],
|
|
134
|
-
type: 'suggestion',
|
|
135
|
-
},
|
|
136
|
-
});
|
|
@@ -1,258 +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
|
-
const escape_string_regexp_1 = __importDefault(require("escape-string-regexp"));
|
|
8
|
-
const otherDescriptiveTags = new Set([
|
|
9
|
-
'classdesc', 'deprecated', 'exception', 'file', 'fileoverview', 'overview',
|
|
10
|
-
// 'copyright' and 'see' might be good addition, but as the former may be
|
|
11
|
-
// sensitive text, and the latter may have just a link, they are not
|
|
12
|
-
// included by default
|
|
13
|
-
'summary', 'throws', 'todo', 'yield', 'yields',
|
|
14
|
-
]);
|
|
15
|
-
/**
|
|
16
|
-
* @param {string} text
|
|
17
|
-
* @returns {string[]}
|
|
18
|
-
*/
|
|
19
|
-
const extractParagraphs = (text) => {
|
|
20
|
-
return text.split(/(?<![;:])\n\n+/v);
|
|
21
|
-
};
|
|
22
|
-
/**
|
|
23
|
-
* @param {string} text
|
|
24
|
-
* @param {string|RegExp} abbreviationsRegex
|
|
25
|
-
* @returns {string[]}
|
|
26
|
-
*/
|
|
27
|
-
const extractSentences = (text, abbreviationsRegex) => {
|
|
28
|
-
const txt = text
|
|
29
|
-
// Remove all {} tags.
|
|
30
|
-
.replaceAll(/(?<!^)\{[\s\S]*?\}\s*/gv, '')
|
|
31
|
-
// Remove custom abbreviations
|
|
32
|
-
.replace(abbreviationsRegex, '');
|
|
33
|
-
const sentenceEndGrouping = /([.?!])(?:\s+|$)/gv;
|
|
34
|
-
const puncts = [
|
|
35
|
-
...txt.matchAll(sentenceEndGrouping),
|
|
36
|
-
].map((sentEnd) => {
|
|
37
|
-
return sentEnd[0];
|
|
38
|
-
});
|
|
39
|
-
return txt
|
|
40
|
-
.split(/[.?!](?:\s+|$)/v)
|
|
41
|
-
// Re-add the dot.
|
|
42
|
-
.map((sentence, idx) => {
|
|
43
|
-
return !puncts[idx] && /^\s*$/v.test(sentence) ? sentence : `${sentence}${puncts[idx] || ''}`;
|
|
44
|
-
});
|
|
45
|
-
};
|
|
46
|
-
/**
|
|
47
|
-
* @param {string} text
|
|
48
|
-
* @returns {boolean}
|
|
49
|
-
*/
|
|
50
|
-
const isNewLinePrecededByAPeriod = (text) => {
|
|
51
|
-
/** @type {boolean} */
|
|
52
|
-
let lastLineEndsSentence;
|
|
53
|
-
const lines = text.split('\n');
|
|
54
|
-
return !lines.some((line) => {
|
|
55
|
-
if (lastLineEndsSentence === false && /^[A-Z][a-z]/v.test(line)) {
|
|
56
|
-
return true;
|
|
57
|
-
}
|
|
58
|
-
lastLineEndsSentence = /[.:?!\|]$/v.test(line);
|
|
59
|
-
return false;
|
|
60
|
-
});
|
|
61
|
-
};
|
|
62
|
-
/**
|
|
63
|
-
* @param {string} str
|
|
64
|
-
* @returns {boolean}
|
|
65
|
-
*/
|
|
66
|
-
const isCapitalized = (str) => {
|
|
67
|
-
return str[0] === str[0].toUpperCase();
|
|
68
|
-
};
|
|
69
|
-
/**
|
|
70
|
-
* @param {string} str
|
|
71
|
-
* @returns {boolean}
|
|
72
|
-
*/
|
|
73
|
-
const isTable = (str) => {
|
|
74
|
-
return str.charAt(0) === '|';
|
|
75
|
-
};
|
|
76
|
-
/**
|
|
77
|
-
* @param {string} str
|
|
78
|
-
* @returns {string}
|
|
79
|
-
*/
|
|
80
|
-
const capitalize = (str) => {
|
|
81
|
-
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
82
|
-
};
|
|
83
|
-
/**
|
|
84
|
-
* @param {string} description
|
|
85
|
-
* @param {import('../iterateJsdoc.js').Report} reportOrig
|
|
86
|
-
* @param {import('eslint').Rule.Node} jsdocNode
|
|
87
|
-
* @param {string|RegExp} abbreviationsRegex
|
|
88
|
-
* @param {import('eslint').SourceCode} sourceCode
|
|
89
|
-
* @param {import('comment-parser').Spec|{
|
|
90
|
-
* line: import('../iterateJsdoc.js').Integer
|
|
91
|
-
* }} tag
|
|
92
|
-
* @param {boolean} newlineBeforeCapsAssumesBadSentenceEnd
|
|
93
|
-
* @returns {boolean}
|
|
94
|
-
*/
|
|
95
|
-
const validateDescription = (description, reportOrig, jsdocNode, abbreviationsRegex, sourceCode, tag, newlineBeforeCapsAssumesBadSentenceEnd) => {
|
|
96
|
-
if (!description || (/^\n+$/v).test(description)) {
|
|
97
|
-
return false;
|
|
98
|
-
}
|
|
99
|
-
const descriptionNoHeadings = description.replaceAll(/^\s*#[^\n]*(\n|$)/gmv, '');
|
|
100
|
-
const paragraphs = extractParagraphs(descriptionNoHeadings).filter(Boolean);
|
|
101
|
-
return paragraphs.some((paragraph, parIdx) => {
|
|
102
|
-
const sentences = extractSentences(paragraph, abbreviationsRegex);
|
|
103
|
-
const fix = /** @type {import('eslint').Rule.ReportFixer} */ (fixer) => {
|
|
104
|
-
let text = sourceCode.getText(jsdocNode);
|
|
105
|
-
if (!/[.:?!]$/v.test(paragraph)) {
|
|
106
|
-
const line = paragraph.split('\n').findLast(Boolean);
|
|
107
|
-
text = text.replace(new RegExp(`${(0, escape_string_regexp_1.default)(
|
|
108
|
-
/** @type {string} */
|
|
109
|
-
(line))}$`, 'mv'), `${line}.`);
|
|
110
|
-
}
|
|
111
|
-
for (const sentence of sentences.filter((sentence_) => {
|
|
112
|
-
return !(/^\s*$/v).test(sentence_) && !isCapitalized(sentence_) &&
|
|
113
|
-
!isTable(sentence_);
|
|
114
|
-
})) {
|
|
115
|
-
const beginning = sentence.split('\n')[0];
|
|
116
|
-
if ('tag' in tag && tag.tag) {
|
|
117
|
-
const reg = new RegExp(`(@${(0, escape_string_regexp_1.default)(tag.tag)}.*)${(0, escape_string_regexp_1.default)(beginning)}`, 'v');
|
|
118
|
-
text = text.replace(reg, (_$0, $1) => {
|
|
119
|
-
return $1 + capitalize(beginning);
|
|
120
|
-
});
|
|
121
|
-
}
|
|
122
|
-
else {
|
|
123
|
-
text = text.replace(new RegExp('((?:[.?!]|\\*|\\})\\s*)' + (0, escape_string_regexp_1.default)(beginning), 'v'), '$1' + capitalize(beginning));
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
return fixer.replaceText(jsdocNode, text);
|
|
127
|
-
};
|
|
128
|
-
/**
|
|
129
|
-
* @param {string} msg
|
|
130
|
-
* @param {import('eslint').Rule.ReportFixer | null | undefined} fixer
|
|
131
|
-
* @param {{
|
|
132
|
-
* line?: number | undefined;
|
|
133
|
-
* column?: number | undefined;
|
|
134
|
-
* } | (import('comment-parser').Spec & {
|
|
135
|
-
* line?: number | undefined;
|
|
136
|
-
* column?: number | undefined;
|
|
137
|
-
* })} tagObj
|
|
138
|
-
* @returns {void}
|
|
139
|
-
*/
|
|
140
|
-
const report = (msg, fixer, tagObj) => {
|
|
141
|
-
if ('line' in tagObj) {
|
|
142
|
-
/**
|
|
143
|
-
* @type {{
|
|
144
|
-
* line: number;
|
|
145
|
-
* }}
|
|
146
|
-
*/ (tagObj).line += parIdx * 2;
|
|
147
|
-
}
|
|
148
|
-
else {
|
|
149
|
-
/** @type {import('comment-parser').Spec} */ (tagObj).source[0].number += parIdx * 2;
|
|
150
|
-
}
|
|
151
|
-
// Avoid errors if old column doesn't exist here
|
|
152
|
-
tagObj.column = 0;
|
|
153
|
-
reportOrig(msg, fixer, tagObj);
|
|
154
|
-
};
|
|
155
|
-
if (sentences.some((sentence) => {
|
|
156
|
-
return (/^[.?!]$/v).test(sentence);
|
|
157
|
-
})) {
|
|
158
|
-
report('Sentences must be more than punctuation.', null, tag);
|
|
159
|
-
}
|
|
160
|
-
if (sentences.some((sentence) => {
|
|
161
|
-
return !(/^\s*$/v).test(sentence) && !isCapitalized(sentence) && !isTable(sentence);
|
|
162
|
-
})) {
|
|
163
|
-
report('Sentences should start with an uppercase character.', fix, tag);
|
|
164
|
-
}
|
|
165
|
-
const paragraphNoAbbreviations = paragraph.replace(abbreviationsRegex, '');
|
|
166
|
-
if (!/(?:[.?!\|]|```)\s*$/v.test(paragraphNoAbbreviations)) {
|
|
167
|
-
report('Sentences must end with a period.', fix, tag);
|
|
168
|
-
return true;
|
|
169
|
-
}
|
|
170
|
-
if (newlineBeforeCapsAssumesBadSentenceEnd && !isNewLinePrecededByAPeriod(paragraphNoAbbreviations)) {
|
|
171
|
-
report('A line of text is started with an uppercase character, but the preceding line does not end the sentence.', null, tag);
|
|
172
|
-
return true;
|
|
173
|
-
}
|
|
174
|
-
return false;
|
|
175
|
-
});
|
|
176
|
-
};
|
|
177
|
-
exports.default = (0, iterateJsdoc_js_1.default)(({ context, jsdoc, jsdocNode, report, sourceCode, utils, }) => {
|
|
178
|
-
const /** @type {{abbreviations: string[], newlineBeforeCapsAssumesBadSentenceEnd: boolean}} */ { abbreviations = [], newlineBeforeCapsAssumesBadSentenceEnd = false, } = context.options[0] || {};
|
|
179
|
-
const abbreviationsRegex = abbreviations.length ?
|
|
180
|
-
new RegExp('\\b' + abbreviations.map((abbreviation) => {
|
|
181
|
-
return (0, escape_string_regexp_1.default)(abbreviation.replaceAll(/\.$/gv, '') + '.');
|
|
182
|
-
}).join('|') + '(?:$|\\s)', 'gv') :
|
|
183
|
-
'';
|
|
184
|
-
let { description, } = utils.getDescription();
|
|
185
|
-
const indices = [
|
|
186
|
-
...description.matchAll(/```[\s\S]*```/gv),
|
|
187
|
-
].map((match) => {
|
|
188
|
-
const { index, } = match;
|
|
189
|
-
const [{ length, },] = match;
|
|
190
|
-
return {
|
|
191
|
-
index,
|
|
192
|
-
length,
|
|
193
|
-
};
|
|
194
|
-
}).toReversed();
|
|
195
|
-
for (const { index, length, } of indices) {
|
|
196
|
-
description = description.slice(0, index) +
|
|
197
|
-
description.slice(/** @type {import('../iterateJsdoc.js').Integer} */ (index) + length);
|
|
198
|
-
}
|
|
199
|
-
if (validateDescription(description, report, jsdocNode, abbreviationsRegex, sourceCode, {
|
|
200
|
-
line: jsdoc.source[0].number + 1,
|
|
201
|
-
}, newlineBeforeCapsAssumesBadSentenceEnd)) {
|
|
202
|
-
return;
|
|
203
|
-
}
|
|
204
|
-
utils.forEachPreferredTag('description', (matchingJsdocTag) => {
|
|
205
|
-
const desc = `${matchingJsdocTag.name} ${utils.getTagDescription(matchingJsdocTag)}`.trim();
|
|
206
|
-
validateDescription(desc, report, jsdocNode, abbreviationsRegex, sourceCode, matchingJsdocTag, newlineBeforeCapsAssumesBadSentenceEnd);
|
|
207
|
-
}, true);
|
|
208
|
-
const { tagsWithNames, } = utils.getTagsByType(jsdoc.tags);
|
|
209
|
-
const tagsWithoutNames = utils.filterTags(({ tag: tagName, }) => {
|
|
210
|
-
return otherDescriptiveTags.has(tagName) ||
|
|
211
|
-
utils.hasOptionTag(tagName) && !tagsWithNames.some(({ tag, }) => {
|
|
212
|
-
// If user accidentally adds tags with names (or like `returns`
|
|
213
|
-
// get parsed as having names), do not add to this list
|
|
214
|
-
return tag === tagName;
|
|
215
|
-
});
|
|
216
|
-
});
|
|
217
|
-
tagsWithNames.some((tag) => {
|
|
218
|
-
const desc = /** @type {string} */ (utils.getTagDescription(tag)).replace(/^- /v, '').trimEnd();
|
|
219
|
-
return validateDescription(desc, report, jsdocNode, abbreviationsRegex, sourceCode, tag, newlineBeforeCapsAssumesBadSentenceEnd);
|
|
220
|
-
});
|
|
221
|
-
tagsWithoutNames.some((tag) => {
|
|
222
|
-
const desc = `${tag.name} ${utils.getTagDescription(tag)}`.trim();
|
|
223
|
-
return validateDescription(desc, report, jsdocNode, abbreviationsRegex, sourceCode, tag, newlineBeforeCapsAssumesBadSentenceEnd);
|
|
224
|
-
});
|
|
225
|
-
}, {
|
|
226
|
-
iterateAllJsdocs: true,
|
|
227
|
-
meta: {
|
|
228
|
-
docs: {
|
|
229
|
-
description: 'Requires that block description, explicit `@description`, and `@param`/`@returns` tag descriptions are written in complete sentences.',
|
|
230
|
-
url: 'https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/require-description-complete-sentence.md#repos-sticky-header',
|
|
231
|
-
},
|
|
232
|
-
fixable: 'code',
|
|
233
|
-
schema: [
|
|
234
|
-
{
|
|
235
|
-
additionalProperties: false,
|
|
236
|
-
properties: {
|
|
237
|
-
abbreviations: {
|
|
238
|
-
items: {
|
|
239
|
-
type: 'string',
|
|
240
|
-
},
|
|
241
|
-
type: 'array',
|
|
242
|
-
},
|
|
243
|
-
newlineBeforeCapsAssumesBadSentenceEnd: {
|
|
244
|
-
type: 'boolean',
|
|
245
|
-
},
|
|
246
|
-
tags: {
|
|
247
|
-
items: {
|
|
248
|
-
type: 'string',
|
|
249
|
-
},
|
|
250
|
-
type: 'array',
|
|
251
|
-
},
|
|
252
|
-
},
|
|
253
|
-
type: 'object',
|
|
254
|
-
},
|
|
255
|
-
],
|
|
256
|
-
type: 'suggestion',
|
|
257
|
-
},
|
|
258
|
-
});
|
|
@@ -1,103 +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, jsdoc, report, utils, }) => {
|
|
8
|
-
if (utils.avoidDocs()) {
|
|
9
|
-
return;
|
|
10
|
-
}
|
|
11
|
-
const { enableFixer = true, exemptNoArguments = false, } = context.options[0] || {};
|
|
12
|
-
const targetTagName = 'example';
|
|
13
|
-
const functionExamples = jsdoc.tags.filter(({ tag, }) => {
|
|
14
|
-
return tag === targetTagName;
|
|
15
|
-
});
|
|
16
|
-
if (!functionExamples.length) {
|
|
17
|
-
if (exemptNoArguments && utils.isIteratingFunctionOrVariable() &&
|
|
18
|
-
!utils.hasParams()) {
|
|
19
|
-
return;
|
|
20
|
-
}
|
|
21
|
-
utils.reportJSDoc(`Missing JSDoc @${targetTagName} declaration.`, null, () => {
|
|
22
|
-
if (enableFixer) {
|
|
23
|
-
utils.addTag(targetTagName);
|
|
24
|
-
}
|
|
25
|
-
});
|
|
26
|
-
return;
|
|
27
|
-
}
|
|
28
|
-
for (const example of functionExamples) {
|
|
29
|
-
const exampleContent = `${example.name} ${utils.getTagDescription(example)}`
|
|
30
|
-
.trim()
|
|
31
|
-
.split('\n')
|
|
32
|
-
.filter(Boolean);
|
|
33
|
-
if (!exampleContent.length) {
|
|
34
|
-
report(`Missing JSDoc @${targetTagName} description.`, null, example);
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
}, {
|
|
38
|
-
contextDefaults: true,
|
|
39
|
-
meta: {
|
|
40
|
-
docs: {
|
|
41
|
-
description: 'Requires that all functions have examples.',
|
|
42
|
-
url: 'https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/require-example.md#repos-sticky-header',
|
|
43
|
-
},
|
|
44
|
-
fixable: 'code',
|
|
45
|
-
schema: [
|
|
46
|
-
{
|
|
47
|
-
additionalProperties: false,
|
|
48
|
-
properties: {
|
|
49
|
-
checkConstructors: {
|
|
50
|
-
default: true,
|
|
51
|
-
type: 'boolean',
|
|
52
|
-
},
|
|
53
|
-
checkGetters: {
|
|
54
|
-
default: false,
|
|
55
|
-
type: 'boolean',
|
|
56
|
-
},
|
|
57
|
-
checkSetters: {
|
|
58
|
-
default: false,
|
|
59
|
-
type: 'boolean',
|
|
60
|
-
},
|
|
61
|
-
contexts: {
|
|
62
|
-
items: {
|
|
63
|
-
anyOf: [
|
|
64
|
-
{
|
|
65
|
-
type: 'string',
|
|
66
|
-
},
|
|
67
|
-
{
|
|
68
|
-
additionalProperties: false,
|
|
69
|
-
properties: {
|
|
70
|
-
comment: {
|
|
71
|
-
type: 'string',
|
|
72
|
-
},
|
|
73
|
-
context: {
|
|
74
|
-
type: 'string',
|
|
75
|
-
},
|
|
76
|
-
},
|
|
77
|
-
type: 'object',
|
|
78
|
-
},
|
|
79
|
-
],
|
|
80
|
-
},
|
|
81
|
-
type: 'array',
|
|
82
|
-
},
|
|
83
|
-
enableFixer: {
|
|
84
|
-
default: true,
|
|
85
|
-
type: 'boolean',
|
|
86
|
-
},
|
|
87
|
-
exemptedBy: {
|
|
88
|
-
items: {
|
|
89
|
-
type: 'string',
|
|
90
|
-
},
|
|
91
|
-
type: 'array',
|
|
92
|
-
},
|
|
93
|
-
exemptNoArguments: {
|
|
94
|
-
default: false,
|
|
95
|
-
type: 'boolean',
|
|
96
|
-
},
|
|
97
|
-
},
|
|
98
|
-
type: 'object',
|
|
99
|
-
},
|
|
100
|
-
],
|
|
101
|
-
type: 'suggestion',
|
|
102
|
-
},
|
|
103
|
-
});
|
|
@@ -1,117 +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
|
-
const defaultTags = {
|
|
8
|
-
file: {
|
|
9
|
-
initialCommentsOnly: true,
|
|
10
|
-
mustExist: true,
|
|
11
|
-
preventDuplicates: true,
|
|
12
|
-
},
|
|
13
|
-
};
|
|
14
|
-
/**
|
|
15
|
-
* @param {import('../iterateJsdoc.js').StateObject} state
|
|
16
|
-
* @returns {void}
|
|
17
|
-
*/
|
|
18
|
-
const setDefaults = (state) => {
|
|
19
|
-
// First iteration
|
|
20
|
-
if (!state.globalTags) {
|
|
21
|
-
state.globalTags = {};
|
|
22
|
-
state.hasDuplicates = {};
|
|
23
|
-
state.hasTag = {};
|
|
24
|
-
state.hasNonCommentBeforeTag = {};
|
|
25
|
-
}
|
|
26
|
-
};
|
|
27
|
-
exports.default = (0, iterateJsdoc_js_1.default)(({ context, jsdocNode, state, utils, }) => {
|
|
28
|
-
const { tags = defaultTags, } = context.options[0] || {};
|
|
29
|
-
setDefaults(state);
|
|
30
|
-
for (const tagName of Object.keys(tags)) {
|
|
31
|
-
const targetTagName = /** @type {string} */ (utils.getPreferredTagName({
|
|
32
|
-
tagName,
|
|
33
|
-
}));
|
|
34
|
-
const hasTag = Boolean(targetTagName && utils.hasTag(targetTagName));
|
|
35
|
-
state.hasTag[tagName] = hasTag || state.hasTag[tagName];
|
|
36
|
-
const hasDuplicate = state.hasDuplicates[tagName];
|
|
37
|
-
if (hasDuplicate === false) {
|
|
38
|
-
// Was marked before, so if a tag now, is a dupe
|
|
39
|
-
state.hasDuplicates[tagName] = hasTag;
|
|
40
|
-
}
|
|
41
|
-
else if (!hasDuplicate && hasTag) {
|
|
42
|
-
// No dupes set before, but has first tag, so change state
|
|
43
|
-
// from `undefined` to `false` so can detect next time
|
|
44
|
-
state.hasDuplicates[tagName] = false;
|
|
45
|
-
state.hasNonCommentBeforeTag[tagName] = state.hasNonComment &&
|
|
46
|
-
state.hasNonComment < jsdocNode.range[0];
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
}, {
|
|
50
|
-
exit({ context, state, utils, }) {
|
|
51
|
-
setDefaults(state);
|
|
52
|
-
const { tags = defaultTags, } = context.options[0] || {};
|
|
53
|
-
for (const [tagName, { initialCommentsOnly = false, mustExist = false, preventDuplicates = false, },] of Object.entries(tags)) {
|
|
54
|
-
const obj = utils.getPreferredTagNameObject({
|
|
55
|
-
tagName,
|
|
56
|
-
});
|
|
57
|
-
if (obj && typeof obj === 'object' && 'blocked' in obj) {
|
|
58
|
-
utils.reportSettings(`\`settings.jsdoc.tagNamePreference\` cannot block @${obj.tagName} ` +
|
|
59
|
-
'for the `require-file-overview` rule');
|
|
60
|
-
}
|
|
61
|
-
else {
|
|
62
|
-
const targetTagName = (obj && typeof obj === 'object' && obj.replacement) || obj;
|
|
63
|
-
if (mustExist && !state.hasTag[tagName]) {
|
|
64
|
-
utils.reportSettings(`Missing @${targetTagName}`);
|
|
65
|
-
}
|
|
66
|
-
if (preventDuplicates && state.hasDuplicates[tagName]) {
|
|
67
|
-
utils.reportSettings(`Duplicate @${targetTagName}`);
|
|
68
|
-
}
|
|
69
|
-
if (initialCommentsOnly &&
|
|
70
|
-
state.hasNonCommentBeforeTag[tagName]) {
|
|
71
|
-
utils.reportSettings(`@${targetTagName} should be at the beginning of the file`);
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
},
|
|
76
|
-
iterateAllJsdocs: true,
|
|
77
|
-
meta: {
|
|
78
|
-
docs: {
|
|
79
|
-
description: 'Checks that all files have one `@file`, `@fileoverview`, or `@overview` tag at the beginning of the file.',
|
|
80
|
-
url: 'https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/require-file-overview.md#repos-sticky-header',
|
|
81
|
-
},
|
|
82
|
-
schema: [
|
|
83
|
-
{
|
|
84
|
-
additionalProperties: false,
|
|
85
|
-
properties: {
|
|
86
|
-
tags: {
|
|
87
|
-
patternProperties: {
|
|
88
|
-
'.*': {
|
|
89
|
-
additionalProperties: false,
|
|
90
|
-
properties: {
|
|
91
|
-
initialCommentsOnly: {
|
|
92
|
-
type: 'boolean',
|
|
93
|
-
},
|
|
94
|
-
mustExist: {
|
|
95
|
-
type: 'boolean',
|
|
96
|
-
},
|
|
97
|
-
preventDuplicates: {
|
|
98
|
-
type: 'boolean',
|
|
99
|
-
},
|
|
100
|
-
},
|
|
101
|
-
type: 'object',
|
|
102
|
-
},
|
|
103
|
-
},
|
|
104
|
-
type: 'object',
|
|
105
|
-
},
|
|
106
|
-
},
|
|
107
|
-
type: 'object',
|
|
108
|
-
},
|
|
109
|
-
],
|
|
110
|
-
type: 'suggestion',
|
|
111
|
-
},
|
|
112
|
-
nonComment({ node, state, }) {
|
|
113
|
-
if (!state.hasNonComment) {
|
|
114
|
-
state.hasNonComment = node.range[0];
|
|
115
|
-
}
|
|
116
|
-
},
|
|
117
|
-
});
|