eslint-plugin-jsdoc 47.0.2 → 48.0.1

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.
Files changed (257) hide show
  1. package/dist/{WarnSettings.js → WarnSettings.cjs} +2 -2
  2. package/dist/WarnSettings.cjs.map +1 -0
  3. package/dist/{alignTransform.js → alignTransform.cjs} +2 -2
  4. package/dist/alignTransform.cjs.map +1 -0
  5. package/dist/{defaultTagOrder.js → defaultTagOrder.cjs} +1 -1
  6. package/dist/defaultTagOrder.cjs.map +1 -0
  7. package/dist/{exportParser.js → exportParser.cjs} +32 -36
  8. package/dist/exportParser.cjs.map +1 -0
  9. package/dist/{generateRule.js → generateRule.cjs} +7 -4
  10. package/dist/generateRule.cjs.map +1 -0
  11. package/dist/{getDefaultTagStructureForMode.js → getDefaultTagStructureForMode.cjs} +1 -1
  12. package/dist/getDefaultTagStructureForMode.cjs.map +1 -0
  13. package/dist/{index.js → index.cjs} +55 -55
  14. package/dist/index.cjs.map +1 -0
  15. package/dist/{iterateJsdoc.js → iterateJsdoc.cjs} +16 -21
  16. package/dist/iterateJsdoc.cjs.map +1 -0
  17. package/dist/{jsdocUtils.js → jsdocUtils.cjs} +17 -17
  18. package/dist/jsdocUtils.cjs.map +1 -0
  19. package/dist/rules/{checkAccess.js → checkAccess.cjs} +2 -2
  20. package/dist/rules/checkAccess.cjs.map +1 -0
  21. package/dist/rules/{checkAlignment.js → checkAlignment.cjs} +2 -2
  22. package/dist/rules/checkAlignment.cjs.map +1 -0
  23. package/dist/rules/{checkExamples.js → checkExamples.cjs} +2 -2
  24. package/dist/rules/checkExamples.cjs.map +1 -0
  25. package/dist/rules/{checkIndentation.js → checkIndentation.cjs} +2 -2
  26. package/dist/rules/checkIndentation.cjs.map +1 -0
  27. package/dist/rules/{checkLineAlignment.js → checkLineAlignment.cjs} +3 -3
  28. package/dist/rules/checkLineAlignment.cjs.map +1 -0
  29. package/dist/rules/{checkParamNames.js → checkParamNames.cjs} +2 -2
  30. package/dist/rules/checkParamNames.cjs.map +1 -0
  31. package/dist/rules/{checkPropertyNames.js → checkPropertyNames.cjs} +2 -2
  32. package/dist/rules/checkPropertyNames.cjs.map +1 -0
  33. package/dist/rules/{checkSyntax.js → checkSyntax.cjs} +2 -2
  34. package/dist/rules/checkSyntax.cjs.map +1 -0
  35. package/dist/rules/{checkTagNames.js → checkTagNames.cjs} +2 -2
  36. package/dist/rules/checkTagNames.cjs.map +1 -0
  37. package/dist/rules/{checkTypes.js → checkTypes.cjs} +2 -2
  38. package/dist/rules/checkTypes.cjs.map +1 -0
  39. package/dist/rules/{checkValues.js → checkValues.cjs} +2 -2
  40. package/dist/rules/checkValues.cjs.map +1 -0
  41. package/dist/rules/{emptyTags.js → emptyTags.cjs} +2 -2
  42. package/dist/rules/emptyTags.cjs.map +1 -0
  43. package/dist/rules/{implementsOnClasses.js → implementsOnClasses.cjs} +2 -2
  44. package/dist/rules/implementsOnClasses.cjs.map +1 -0
  45. package/dist/rules/{importsAsDependencies.js → importsAsDependencies.cjs} +10 -12
  46. package/dist/rules/importsAsDependencies.cjs.map +1 -0
  47. package/dist/rules/{informativeDocs.js → informativeDocs.cjs} +2 -2
  48. package/dist/rules/informativeDocs.cjs.map +1 -0
  49. package/dist/rules/{matchDescription.js → matchDescription.cjs} +2 -2
  50. package/dist/rules/matchDescription.cjs.map +1 -0
  51. package/dist/rules/{matchName.js → matchName.cjs} +2 -2
  52. package/dist/rules/matchName.cjs.map +1 -0
  53. package/dist/rules/{multilineBlocks.js → multilineBlocks.cjs} +2 -2
  54. package/dist/rules/multilineBlocks.cjs.map +1 -0
  55. package/dist/rules/{noBadBlocks.js → noBadBlocks.cjs} +2 -2
  56. package/dist/rules/noBadBlocks.cjs.map +1 -0
  57. package/dist/rules/{noBlankBlockDescriptions.js → noBlankBlockDescriptions.cjs} +2 -2
  58. package/dist/rules/noBlankBlockDescriptions.cjs.map +1 -0
  59. package/dist/rules/{noBlankBlocks.js → noBlankBlocks.cjs} +2 -2
  60. package/dist/rules/noBlankBlocks.cjs.map +1 -0
  61. package/dist/rules/{noDefaults.js → noDefaults.cjs} +2 -2
  62. package/dist/rules/noDefaults.cjs.map +1 -0
  63. package/dist/rules/{noMissingSyntax.js → noMissingSyntax.cjs} +2 -2
  64. package/dist/rules/noMissingSyntax.cjs.map +1 -0
  65. package/dist/rules/{noMultiAsterisks.js → noMultiAsterisks.cjs} +2 -2
  66. package/dist/rules/noMultiAsterisks.cjs.map +1 -0
  67. package/dist/rules/{noRestrictedSyntax.js → noRestrictedSyntax.cjs} +2 -2
  68. package/dist/rules/noRestrictedSyntax.cjs.map +1 -0
  69. package/dist/rules/{noTypes.js → noTypes.cjs} +2 -2
  70. package/dist/rules/noTypes.cjs.map +1 -0
  71. package/dist/rules/{noUndefinedTypes.js → noUndefinedTypes.cjs} +5 -5
  72. package/dist/rules/noUndefinedTypes.cjs.map +1 -0
  73. package/dist/rules/{requireAsteriskPrefix.js → requireAsteriskPrefix.cjs} +2 -2
  74. package/dist/rules/requireAsteriskPrefix.cjs.map +1 -0
  75. package/dist/rules/{requireDescription.js → requireDescription.cjs} +2 -2
  76. package/dist/rules/requireDescription.cjs.map +1 -0
  77. package/dist/rules/{requireDescriptionCompleteSentence.js → requireDescriptionCompleteSentence.cjs} +2 -2
  78. package/dist/rules/requireDescriptionCompleteSentence.cjs.map +1 -0
  79. package/dist/rules/{requireExample.js → requireExample.cjs} +2 -2
  80. package/dist/rules/requireExample.cjs.map +1 -0
  81. package/dist/rules/{requireFileOverview.js → requireFileOverview.cjs} +2 -2
  82. package/dist/rules/requireFileOverview.cjs.map +1 -0
  83. package/dist/rules/{requireHyphenBeforeParamDescription.js → requireHyphenBeforeParamDescription.cjs} +2 -2
  84. package/dist/rules/requireHyphenBeforeParamDescription.cjs.map +1 -0
  85. package/dist/rules/{requireJsdoc.js → requireJsdoc.cjs} +5 -5
  86. package/dist/rules/requireJsdoc.cjs.map +1 -0
  87. package/dist/rules/{requireParam.js → requireParam.cjs} +2 -2
  88. package/dist/rules/requireParam.cjs.map +1 -0
  89. package/dist/rules/{requireParamDescription.js → requireParamDescription.cjs} +2 -2
  90. package/dist/rules/requireParamDescription.cjs.map +1 -0
  91. package/dist/rules/{requireParamName.js → requireParamName.cjs} +2 -2
  92. package/dist/rules/requireParamName.cjs.map +1 -0
  93. package/dist/rules/{requireParamType.js → requireParamType.cjs} +2 -2
  94. package/dist/rules/requireParamType.cjs.map +1 -0
  95. package/dist/rules/{requireProperty.js → requireProperty.cjs} +2 -2
  96. package/dist/rules/requireProperty.cjs.map +1 -0
  97. package/dist/rules/{requirePropertyDescription.js → requirePropertyDescription.cjs} +2 -2
  98. package/dist/rules/requirePropertyDescription.cjs.map +1 -0
  99. package/dist/rules/{requirePropertyName.js → requirePropertyName.cjs} +2 -2
  100. package/dist/rules/requirePropertyName.cjs.map +1 -0
  101. package/dist/rules/{requirePropertyType.js → requirePropertyType.cjs} +2 -2
  102. package/dist/rules/requirePropertyType.cjs.map +1 -0
  103. package/dist/rules/{requireReturns.js → requireReturns.cjs} +4 -4
  104. package/dist/rules/requireReturns.cjs.map +1 -0
  105. package/dist/rules/{requireReturnsCheck.js → requireReturnsCheck.cjs} +2 -2
  106. package/dist/rules/requireReturnsCheck.cjs.map +1 -0
  107. package/dist/rules/{requireReturnsDescription.js → requireReturnsDescription.cjs} +2 -2
  108. package/dist/rules/requireReturnsDescription.cjs.map +1 -0
  109. package/dist/rules/{requireReturnsType.js → requireReturnsType.cjs} +2 -2
  110. package/dist/rules/requireReturnsType.cjs.map +1 -0
  111. package/dist/rules/{requireThrows.js → requireThrows.cjs} +2 -2
  112. package/dist/rules/requireThrows.cjs.map +1 -0
  113. package/dist/rules/{requireYields.js → requireYields.cjs} +2 -2
  114. package/dist/rules/requireYields.cjs.map +1 -0
  115. package/dist/rules/{requireYieldsCheck.js → requireYieldsCheck.cjs} +2 -2
  116. package/dist/rules/requireYieldsCheck.cjs.map +1 -0
  117. package/dist/rules/{sortTags.js → sortTags.cjs} +4 -4
  118. package/dist/rules/sortTags.cjs.map +1 -0
  119. package/dist/rules/{tagLines.js → tagLines.cjs} +2 -2
  120. package/dist/rules/tagLines.cjs.map +1 -0
  121. package/dist/rules/{textEscaping.js → textEscaping.cjs} +2 -2
  122. package/dist/rules/textEscaping.cjs.map +1 -0
  123. package/dist/rules/{validTypes.js → validTypes.cjs} +2 -2
  124. package/dist/rules/validTypes.cjs.map +1 -0
  125. package/dist/{tagNames.js → tagNames.cjs} +1 -1
  126. package/dist/tagNames.cjs.map +1 -0
  127. package/dist/utils/{hasReturnValue.js → hasReturnValue.cjs} +14 -17
  128. package/dist/utils/hasReturnValue.cjs.map +1 -0
  129. package/{eslint.config.mjs → eslint.config.js} +34 -28
  130. package/package.json +15 -15
  131. package/src/WarnSettings.js +34 -0
  132. package/src/alignTransform.js +356 -0
  133. package/src/defaultTagOrder.js +168 -0
  134. package/src/exportParser.js +957 -0
  135. package/src/getDefaultTagStructureForMode.js +969 -0
  136. package/src/index.js +266 -0
  137. package/src/iterateJsdoc.js +2555 -0
  138. package/src/jsdocUtils.js +1693 -0
  139. package/src/rules/checkAccess.js +45 -0
  140. package/src/rules/checkAlignment.js +63 -0
  141. package/src/rules/checkExamples.js +594 -0
  142. package/src/rules/checkIndentation.js +75 -0
  143. package/src/rules/checkLineAlignment.js +364 -0
  144. package/src/rules/checkParamNames.js +404 -0
  145. package/src/rules/checkPropertyNames.js +152 -0
  146. package/src/rules/checkSyntax.js +30 -0
  147. package/src/rules/checkTagNames.js +314 -0
  148. package/src/rules/checkTypes.js +535 -0
  149. package/src/rules/checkValues.js +220 -0
  150. package/src/rules/emptyTags.js +88 -0
  151. package/src/rules/implementsOnClasses.js +64 -0
  152. package/src/rules/importsAsDependencies.js +131 -0
  153. package/src/rules/informativeDocs.js +182 -0
  154. package/src/rules/matchDescription.js +286 -0
  155. package/src/rules/matchName.js +147 -0
  156. package/src/rules/multilineBlocks.js +333 -0
  157. package/src/rules/noBadBlocks.js +109 -0
  158. package/src/rules/noBlankBlockDescriptions.js +69 -0
  159. package/src/rules/noBlankBlocks.js +53 -0
  160. package/src/rules/noDefaults.js +85 -0
  161. package/src/rules/noMissingSyntax.js +195 -0
  162. package/src/rules/noMultiAsterisks.js +134 -0
  163. package/src/rules/noRestrictedSyntax.js +91 -0
  164. package/src/rules/noTypes.js +73 -0
  165. package/src/rules/noUndefinedTypes.js +328 -0
  166. package/src/rules/requireAsteriskPrefix.js +189 -0
  167. package/src/rules/requireDescription.js +161 -0
  168. package/src/rules/requireDescriptionCompleteSentence.js +333 -0
  169. package/src/rules/requireExample.js +118 -0
  170. package/src/rules/requireFileOverview.js +154 -0
  171. package/src/rules/requireHyphenBeforeParamDescription.js +178 -0
  172. package/src/rules/requireJsdoc.js +629 -0
  173. package/src/rules/requireParam.js +592 -0
  174. package/src/rules/requireParamDescription.js +89 -0
  175. package/src/rules/requireParamName.js +55 -0
  176. package/src/rules/requireParamType.js +89 -0
  177. package/src/rules/requireProperty.js +48 -0
  178. package/src/rules/requirePropertyDescription.js +25 -0
  179. package/src/rules/requirePropertyName.js +25 -0
  180. package/src/rules/requirePropertyType.js +25 -0
  181. package/src/rules/requireReturns.js +238 -0
  182. package/src/rules/requireReturnsCheck.js +141 -0
  183. package/src/rules/requireReturnsDescription.js +59 -0
  184. package/src/rules/requireReturnsType.js +51 -0
  185. package/src/rules/requireThrows.js +111 -0
  186. package/src/rules/requireYields.js +216 -0
  187. package/src/rules/requireYieldsCheck.js +208 -0
  188. package/src/rules/sortTags.js +557 -0
  189. package/src/rules/tagLines.js +359 -0
  190. package/src/rules/textEscaping.js +146 -0
  191. package/src/rules/validTypes.js +368 -0
  192. package/src/tagNames.js +234 -0
  193. package/src/utils/hasReturnValue.js +549 -0
  194. package/dist/WarnSettings.js.map +0 -1
  195. package/dist/alignTransform.js.map +0 -1
  196. package/dist/defaultTagOrder.js.map +0 -1
  197. package/dist/exportParser.js.map +0 -1
  198. package/dist/generateRule.js.map +0 -1
  199. package/dist/getDefaultTagStructureForMode.js.map +0 -1
  200. package/dist/index.js.map +0 -1
  201. package/dist/iterateJsdoc.js.map +0 -1
  202. package/dist/jsdocUtils.js.map +0 -1
  203. package/dist/rules/checkAccess.js.map +0 -1
  204. package/dist/rules/checkAlignment.js.map +0 -1
  205. package/dist/rules/checkExamples.js.map +0 -1
  206. package/dist/rules/checkIndentation.js.map +0 -1
  207. package/dist/rules/checkLineAlignment.js.map +0 -1
  208. package/dist/rules/checkParamNames.js.map +0 -1
  209. package/dist/rules/checkPropertyNames.js.map +0 -1
  210. package/dist/rules/checkSyntax.js.map +0 -1
  211. package/dist/rules/checkTagNames.js.map +0 -1
  212. package/dist/rules/checkTypes.js.map +0 -1
  213. package/dist/rules/checkValues.js.map +0 -1
  214. package/dist/rules/emptyTags.js.map +0 -1
  215. package/dist/rules/implementsOnClasses.js.map +0 -1
  216. package/dist/rules/importsAsDependencies.js.map +0 -1
  217. package/dist/rules/informativeDocs.js.map +0 -1
  218. package/dist/rules/matchDescription.js.map +0 -1
  219. package/dist/rules/matchName.js.map +0 -1
  220. package/dist/rules/multilineBlocks.js.map +0 -1
  221. package/dist/rules/noBadBlocks.js.map +0 -1
  222. package/dist/rules/noBlankBlockDescriptions.js.map +0 -1
  223. package/dist/rules/noBlankBlocks.js.map +0 -1
  224. package/dist/rules/noDefaults.js.map +0 -1
  225. package/dist/rules/noMissingSyntax.js.map +0 -1
  226. package/dist/rules/noMultiAsterisks.js.map +0 -1
  227. package/dist/rules/noRestrictedSyntax.js.map +0 -1
  228. package/dist/rules/noTypes.js.map +0 -1
  229. package/dist/rules/noUndefinedTypes.js.map +0 -1
  230. package/dist/rules/requireAsteriskPrefix.js.map +0 -1
  231. package/dist/rules/requireDescription.js.map +0 -1
  232. package/dist/rules/requireDescriptionCompleteSentence.js.map +0 -1
  233. package/dist/rules/requireExample.js.map +0 -1
  234. package/dist/rules/requireFileOverview.js.map +0 -1
  235. package/dist/rules/requireHyphenBeforeParamDescription.js.map +0 -1
  236. package/dist/rules/requireJsdoc.js.map +0 -1
  237. package/dist/rules/requireParam.js.map +0 -1
  238. package/dist/rules/requireParamDescription.js.map +0 -1
  239. package/dist/rules/requireParamName.js.map +0 -1
  240. package/dist/rules/requireParamType.js.map +0 -1
  241. package/dist/rules/requireProperty.js.map +0 -1
  242. package/dist/rules/requirePropertyDescription.js.map +0 -1
  243. package/dist/rules/requirePropertyName.js.map +0 -1
  244. package/dist/rules/requirePropertyType.js.map +0 -1
  245. package/dist/rules/requireReturns.js.map +0 -1
  246. package/dist/rules/requireReturnsCheck.js.map +0 -1
  247. package/dist/rules/requireReturnsDescription.js.map +0 -1
  248. package/dist/rules/requireReturnsType.js.map +0 -1
  249. package/dist/rules/requireThrows.js.map +0 -1
  250. package/dist/rules/requireYields.js.map +0 -1
  251. package/dist/rules/requireYieldsCheck.js.map +0 -1
  252. package/dist/rules/sortTags.js.map +0 -1
  253. package/dist/rules/tagLines.js.map +0 -1
  254. package/dist/rules/textEscaping.js.map +0 -1
  255. package/dist/rules/validTypes.js.map +0 -1
  256. package/dist/tagNames.js.map +0 -1
  257. package/dist/utils/hasReturnValue.js.map +0 -1
@@ -0,0 +1,328 @@
1
+ import iterateJsdoc, {
2
+ parseComment,
3
+ } from '../iterateJsdoc.js';
4
+ import {
5
+ getJSDocComment,
6
+ parse as parseType,
7
+ traverse,
8
+ tryParse as tryParseType,
9
+ } from '@es-joy/jsdoccomment';
10
+
11
+ const extraTypes = [
12
+ 'null', 'undefined', 'void', 'string', 'boolean', 'object',
13
+ 'function', 'symbol',
14
+ 'number', 'bigint', 'NaN', 'Infinity',
15
+ 'any', '*', 'never', 'unknown', 'const',
16
+ 'this', 'true', 'false',
17
+ 'Array', 'Object', 'RegExp', 'Date', 'Function',
18
+ ];
19
+
20
+ const typescriptGlobals = [
21
+ // https://www.typescriptlang.org/docs/handbook/utility-types.html
22
+ 'Awaited',
23
+ 'Partial',
24
+ 'Required',
25
+ 'Readonly',
26
+ 'Record',
27
+ 'Pick',
28
+ 'Omit',
29
+ 'Exclude',
30
+ 'Extract',
31
+ 'NonNullable',
32
+ 'Parameters',
33
+ 'ConstructorParameters',
34
+ 'ReturnType',
35
+ 'InstanceType',
36
+ 'ThisParameterType',
37
+ 'OmitThisParameter',
38
+ 'ThisType',
39
+ 'Uppercase',
40
+ 'Lowercase',
41
+ 'Capitalize',
42
+ 'Uncapitalize',
43
+ ];
44
+
45
+ /**
46
+ * @param {string|false|undefined} [str]
47
+ * @returns {undefined|string|false}
48
+ */
49
+ const stripPseudoTypes = (str) => {
50
+ return str && str.replace(/(?:\.|<>|\.<>|\[\])$/u, '');
51
+ };
52
+
53
+ export default iterateJsdoc(({
54
+ context,
55
+ node,
56
+ report,
57
+ settings,
58
+ sourceCode,
59
+ utils,
60
+ }) => {
61
+ const {
62
+ scopeManager,
63
+ } = sourceCode;
64
+
65
+ // When is this ever `null`?
66
+ const globalScope = /** @type {import('eslint').Scope.Scope} */ (
67
+ scopeManager.globalScope
68
+ );
69
+
70
+ const
71
+ /**
72
+ * @type {{
73
+ * definedTypes: string[],
74
+ * disableReporting: boolean,
75
+ * markVariablesAsUsed: boolean
76
+ * }}
77
+ */ {
78
+ definedTypes = [],
79
+ disableReporting = false,
80
+ markVariablesAsUsed = true,
81
+ } = context.options[0] || {};
82
+
83
+ /** @type {(string|undefined)[]} */
84
+ let definedPreferredTypes = [];
85
+ const {
86
+ preferredTypes,
87
+ structuredTags,
88
+ mode,
89
+ } = settings;
90
+ if (Object.keys(preferredTypes).length) {
91
+ definedPreferredTypes = /** @type {string[]} */ (Object.values(preferredTypes).map((preferredType) => {
92
+ if (typeof preferredType === 'string') {
93
+ // May become an empty string but will be filtered out below
94
+ return stripPseudoTypes(preferredType);
95
+ }
96
+
97
+ if (!preferredType) {
98
+ return undefined;
99
+ }
100
+
101
+ if (typeof preferredType !== 'object') {
102
+ utils.reportSettings(
103
+ 'Invalid `settings.jsdoc.preferredTypes`. Values must be falsy, a string, or an object.',
104
+ );
105
+ }
106
+
107
+ return stripPseudoTypes(preferredType.replacement);
108
+ })
109
+ .filter(Boolean));
110
+ }
111
+
112
+ const typedefDeclarations = sourceCode.getAllComments()
113
+ .filter((comment) => {
114
+ return (/^\*\s/u).test(comment.value);
115
+ })
116
+ .map((commentNode) => {
117
+ return parseComment(commentNode, '');
118
+ })
119
+ .flatMap((doc) => {
120
+ return doc.tags.filter(({
121
+ tag,
122
+ }) => {
123
+ return utils.isNamepathDefiningTag(tag);
124
+ });
125
+ })
126
+ .map((tag) => {
127
+ return tag.name;
128
+ });
129
+
130
+ const ancestorNodes = [];
131
+
132
+ let currentNode = node;
133
+ // No need for Program node?
134
+ while (currentNode?.parent) {
135
+ ancestorNodes.push(currentNode);
136
+ currentNode = currentNode.parent;
137
+ }
138
+
139
+ /**
140
+ * @param {import('eslint').Rule.Node} ancestorNode
141
+ * @returns {import('comment-parser').Spec[]}
142
+ */
143
+ const getTemplateTags = function (ancestorNode) {
144
+ const commentNode = getJSDocComment(sourceCode, ancestorNode, settings);
145
+ if (!commentNode) {
146
+ return [];
147
+ }
148
+
149
+ const jsdoc = parseComment(commentNode, '');
150
+
151
+ return jsdoc.tags.filter((tag) => {
152
+ return tag.tag === 'template';
153
+ });
154
+ };
155
+
156
+ // `currentScope` may be `null` or `Program`, so in such a case,
157
+ // we look to present tags instead
158
+ const templateTags = ancestorNodes.length ?
159
+ ancestorNodes.flatMap((ancestorNode) => {
160
+ return getTemplateTags(ancestorNode);
161
+ }) :
162
+ utils.getPresentTags([
163
+ 'template',
164
+ ]);
165
+
166
+ const closureGenericTypes = templateTags.flatMap((tag) => {
167
+ return utils.parseClosureTemplateTag(tag);
168
+ });
169
+
170
+ // In modules, including Node, there is a global scope at top with the
171
+ // Program scope inside
172
+ const cjsOrESMScope = globalScope.childScopes[0]?.block?.type === 'Program';
173
+
174
+ const allDefinedTypes = new Set(globalScope.variables.map(({
175
+ name,
176
+ }) => {
177
+ return name;
178
+ })
179
+
180
+ // If the file is a module, concat the variables from the module scope.
181
+ .concat(
182
+ cjsOrESMScope ?
183
+ globalScope.childScopes.flatMap(({
184
+ variables,
185
+ }) => {
186
+ return variables;
187
+ }).map(({
188
+ name,
189
+ }) => {
190
+ return name;
191
+ /* c8 ignore next */
192
+ }) : [],
193
+ )
194
+ .concat(extraTypes)
195
+ .concat(typedefDeclarations)
196
+ .concat(definedTypes)
197
+ .concat(/** @type {string[]} */ (definedPreferredTypes))
198
+ .concat(
199
+ settings.mode === 'jsdoc' ?
200
+ [] :
201
+ [
202
+ ...settings.mode === 'typescript' ? typescriptGlobals : [],
203
+ ...closureGenericTypes,
204
+ ],
205
+ ));
206
+
207
+ /**
208
+ * @typedef {{
209
+ * parsedType: import('jsdoc-type-pratt-parser').RootResult;
210
+ * tag: import('comment-parser').Spec|import('@es-joy/jsdoccomment').JsdocInlineTagNoType & {
211
+ * line?: import('../iterateJsdoc.js').Integer
212
+ * }
213
+ * }} TypeAndTagInfo
214
+ */
215
+
216
+ /**
217
+ * @param {string} propertyName
218
+ * @returns {(tag: (import('@es-joy/jsdoccomment').JsdocInlineTagNoType & {
219
+ * name?: string,
220
+ * type?: string,
221
+ * line?: import('../iterateJsdoc.js').Integer
222
+ * })|import('comment-parser').Spec & {
223
+ * namepathOrURL?: string
224
+ * }
225
+ * ) => undefined|TypeAndTagInfo}
226
+ */
227
+ const tagToParsedType = (propertyName) => {
228
+ return (tag) => {
229
+ try {
230
+ const potentialType = tag[
231
+ /** @type {"type"|"name"|"namepathOrURL"} */ (propertyName)
232
+ ];
233
+ return {
234
+ parsedType: mode === 'permissive' ?
235
+ tryParseType(/** @type {string} */ (potentialType)) :
236
+ parseType(/** @type {string} */ (potentialType), mode),
237
+ tag,
238
+ };
239
+ } catch {
240
+ return undefined;
241
+ }
242
+ };
243
+ };
244
+
245
+ const typeTags = utils.filterTags(({
246
+ tag,
247
+ }) => {
248
+ return utils.tagMightHaveTypePosition(tag) && (tag !== 'suppress' || settings.mode !== 'closure');
249
+ }).map(tagToParsedType('type'));
250
+
251
+ const namepathReferencingTags = utils.filterTags(({
252
+ tag,
253
+ }) => {
254
+ return utils.isNamepathReferencingTag(tag);
255
+ }).map(tagToParsedType('name'));
256
+
257
+ const namepathOrUrlReferencingTags = utils.filterAllTags(({
258
+ tag,
259
+ }) => {
260
+ return utils.isNamepathOrUrlReferencingTag(tag);
261
+ }).map(tagToParsedType('namepathOrURL'));
262
+
263
+ const tagsWithTypes = /** @type {TypeAndTagInfo[]} */ ([
264
+ ...typeTags,
265
+ ...namepathReferencingTags,
266
+ ...namepathOrUrlReferencingTags,
267
+ // Remove types which failed to parse
268
+ ].filter(Boolean));
269
+
270
+ for (const {
271
+ tag,
272
+ parsedType,
273
+ } of tagsWithTypes) {
274
+ traverse(parsedType, (nde) => {
275
+ const {
276
+ type,
277
+ value,
278
+ } = /** @type {import('jsdoc-type-pratt-parser').NameResult} */ (nde);
279
+
280
+ if (type === 'JsdocTypeName') {
281
+ const structuredTypes = structuredTags[tag.tag]?.type;
282
+ if (!allDefinedTypes.has(value) &&
283
+ (!Array.isArray(structuredTypes) || !structuredTypes.includes(value))
284
+ ) {
285
+ if (!disableReporting) {
286
+ report(`The type '${value}' is undefined.`, null, tag);
287
+ }
288
+ } else if (markVariablesAsUsed && !extraTypes.includes(value)) {
289
+ if (sourceCode.markVariableAsUsed) {
290
+ sourceCode.markVariableAsUsed(value);
291
+ /* c8 ignore next 3 */
292
+ } else {
293
+ context.markVariableAsUsed(value);
294
+ }
295
+ }
296
+ }
297
+ });
298
+ }
299
+ }, {
300
+ iterateAllJsdocs: true,
301
+ meta: {
302
+ docs: {
303
+ description: 'Checks that types in jsdoc comments are defined.',
304
+ url: 'https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/no-undefined-types.md#repos-sticky-header',
305
+ },
306
+ schema: [
307
+ {
308
+ additionalProperties: false,
309
+ properties: {
310
+ definedTypes: {
311
+ items: {
312
+ type: 'string',
313
+ },
314
+ type: 'array',
315
+ },
316
+ disableReporting: {
317
+ type: 'boolean',
318
+ },
319
+ markVariablesAsUsed: {
320
+ type: 'boolean',
321
+ },
322
+ },
323
+ type: 'object',
324
+ },
325
+ ],
326
+ type: 'suggestion',
327
+ },
328
+ });
@@ -0,0 +1,189 @@
1
+ import iterateJsdoc from '../iterateJsdoc.js';
2
+
3
+ export default iterateJsdoc(({
4
+ context,
5
+ jsdoc,
6
+ utils,
7
+ indent,
8
+ }) => {
9
+ const [
10
+ defaultRequireValue = 'always',
11
+ {
12
+ tags: tagMap = {},
13
+ } = {},
14
+ ] = context.options;
15
+
16
+ const {
17
+ source,
18
+ } = jsdoc;
19
+
20
+ const always = defaultRequireValue === 'always';
21
+ const never = defaultRequireValue === 'never';
22
+
23
+ /** @type {string} */
24
+ let currentTag;
25
+ source.some(({
26
+ number,
27
+ tokens,
28
+ }) => {
29
+ const {
30
+ delimiter,
31
+ tag,
32
+ end,
33
+ description,
34
+ } = tokens;
35
+
36
+ /**
37
+ * @returns {void}
38
+ */
39
+ const neverFix = () => {
40
+ tokens.delimiter = '';
41
+ tokens.postDelimiter = '';
42
+ };
43
+
44
+ /**
45
+ * @param {string} checkValue
46
+ * @returns {boolean}
47
+ */
48
+ const checkNever = (checkValue) => {
49
+ if (delimiter && delimiter !== '/**' && (
50
+ never && !tagMap.always?.includes(checkValue) ||
51
+ tagMap.never?.includes(checkValue)
52
+ )) {
53
+ utils.reportJSDoc('Expected JSDoc line to have no prefix.', {
54
+ column: 0,
55
+ line: number,
56
+ }, neverFix);
57
+
58
+ return true;
59
+ }
60
+
61
+ return false;
62
+ };
63
+
64
+ /**
65
+ * @returns {void}
66
+ */
67
+ const alwaysFix = () => {
68
+ if (!tokens.start) {
69
+ tokens.start = indent + ' ';
70
+ }
71
+
72
+ tokens.delimiter = '*';
73
+ tokens.postDelimiter = tag || description ? ' ' : '';
74
+ };
75
+
76
+ /**
77
+ * @param {string} checkValue
78
+ * @returns {boolean}
79
+ */
80
+ const checkAlways = (checkValue) => {
81
+ if (
82
+ !delimiter && (
83
+ always && !tagMap.never?.includes(checkValue) ||
84
+ tagMap.always?.includes(checkValue)
85
+ )
86
+ ) {
87
+ utils.reportJSDoc('Expected JSDoc line to have the prefix.', {
88
+ column: 0,
89
+ line: number,
90
+ }, alwaysFix);
91
+
92
+ return true;
93
+ }
94
+
95
+ return false;
96
+ };
97
+
98
+ if (tag) {
99
+ // Remove at sign
100
+ currentTag = tag.slice(1);
101
+ }
102
+
103
+ if (
104
+ // If this is the end but has a tag, the delimiter will also be
105
+ // populated and will be safely ignored later
106
+ end && !tag
107
+ ) {
108
+ return false;
109
+ }
110
+
111
+ if (!currentTag) {
112
+ if (tagMap.any?.includes('*description')) {
113
+ return false;
114
+ }
115
+
116
+ if (checkNever('*description')) {
117
+ return true;
118
+ }
119
+
120
+ if (checkAlways('*description')) {
121
+ return true;
122
+ }
123
+
124
+ return false;
125
+ }
126
+
127
+ if (tagMap.any?.includes(currentTag)) {
128
+ return false;
129
+ }
130
+
131
+ if (checkNever(currentTag)) {
132
+ return true;
133
+ }
134
+
135
+ if (checkAlways(currentTag)) {
136
+ return true;
137
+ }
138
+
139
+ return false;
140
+ });
141
+ }, {
142
+ iterateAllJsdocs: true,
143
+ meta: {
144
+ docs: {
145
+ description:
146
+ 'Requires that each JSDoc line starts with an `*`.',
147
+ url: 'https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/require-asterisk-prefix.md#repos-sticky-header',
148
+ },
149
+ fixable: 'code',
150
+ schema: [
151
+ {
152
+ enum: [
153
+ 'always', 'never', 'any',
154
+ ],
155
+ type: 'string',
156
+ },
157
+ {
158
+ additionalProperties: false,
159
+ properties: {
160
+ tags: {
161
+ properties: {
162
+ always: {
163
+ items: {
164
+ type: 'string',
165
+ },
166
+ type: 'array',
167
+ },
168
+ any: {
169
+ items: {
170
+ type: 'string',
171
+ },
172
+ type: 'array',
173
+ },
174
+ never: {
175
+ items: {
176
+ type: 'string',
177
+ },
178
+ type: 'array',
179
+ },
180
+ },
181
+ type: 'object',
182
+ },
183
+ },
184
+ type: 'object',
185
+ },
186
+ ],
187
+ type: 'layout',
188
+ },
189
+ });
@@ -0,0 +1,161 @@
1
+ import iterateJsdoc from '../iterateJsdoc.js';
2
+
3
+ /**
4
+ * @param {string} description
5
+ * @returns {import('../iterateJsdoc.js').Integer}
6
+ */
7
+ const checkDescription = (description) => {
8
+ return description
9
+ .trim()
10
+ .split('\n')
11
+ .filter(Boolean)
12
+ .length;
13
+ };
14
+
15
+ export default iterateJsdoc(({
16
+ jsdoc,
17
+ report,
18
+ utils,
19
+ context,
20
+ }) => {
21
+ if (utils.avoidDocs()) {
22
+ return;
23
+ }
24
+
25
+ const {
26
+ descriptionStyle = 'body',
27
+ } = context.options[0] || {};
28
+
29
+ let targetTagName = utils.getPreferredTagName({
30
+ // We skip reporting except when `@description` is essential to the rule,
31
+ // so user can block the tag and still meaningfully use this rule
32
+ // even if the tag is present (and `check-tag-names` is the one to
33
+ // normally report the fact that it is blocked but present)
34
+ skipReportingBlockedTag: descriptionStyle !== 'tag',
35
+ tagName: 'description',
36
+ });
37
+ if (!targetTagName) {
38
+ return;
39
+ }
40
+
41
+ const isBlocked = typeof targetTagName === 'object' && 'blocked' in targetTagName && targetTagName.blocked;
42
+ if (isBlocked) {
43
+ targetTagName = /** @type {{blocked: true; tagName: string;}} */ (
44
+ targetTagName
45
+ ).tagName;
46
+ }
47
+
48
+ if (descriptionStyle !== 'tag') {
49
+ const {
50
+ description,
51
+ } = utils.getDescription();
52
+ if (checkDescription(description || '')) {
53
+ return;
54
+ }
55
+
56
+ if (descriptionStyle === 'body') {
57
+ const descTags = utils.getPresentTags([
58
+ 'desc', 'description',
59
+ ]);
60
+ if (descTags.length) {
61
+ const [
62
+ {
63
+ tag: tagName,
64
+ },
65
+ ] = descTags;
66
+ report(`Remove the @${tagName} tag to leave a plain block description or add additional description text above the @${tagName} line.`);
67
+ } else {
68
+ report('Missing JSDoc block description.');
69
+ }
70
+
71
+ return;
72
+ }
73
+ }
74
+
75
+ const functionExamples = isBlocked ?
76
+ [] :
77
+ jsdoc.tags.filter(({
78
+ tag,
79
+ }) => {
80
+ return tag === targetTagName;
81
+ });
82
+
83
+ if (!functionExamples.length) {
84
+ report(
85
+ descriptionStyle === 'any' ?
86
+ `Missing JSDoc block description or @${targetTagName} declaration.` :
87
+ `Missing JSDoc @${targetTagName} declaration.`,
88
+ );
89
+
90
+ return;
91
+ }
92
+
93
+ for (const example of functionExamples) {
94
+ if (!checkDescription(`${example.name} ${utils.getTagDescription(example)}`)) {
95
+ report(`Missing JSDoc @${targetTagName} description.`, null, example);
96
+ }
97
+ }
98
+ }, {
99
+ contextDefaults: true,
100
+ meta: {
101
+ docs: {
102
+ description: 'Requires that all functions have a description.',
103
+ url: 'https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/require-description.md#repos-sticky-header',
104
+ },
105
+ schema: [
106
+ {
107
+ additionalProperties: false,
108
+ properties: {
109
+ checkConstructors: {
110
+ default: true,
111
+ type: 'boolean',
112
+ },
113
+ checkGetters: {
114
+ default: true,
115
+ type: 'boolean',
116
+ },
117
+ checkSetters: {
118
+ default: true,
119
+ type: 'boolean',
120
+ },
121
+ contexts: {
122
+ items: {
123
+ anyOf: [
124
+ {
125
+ type: 'string',
126
+ },
127
+ {
128
+ additionalProperties: false,
129
+ properties: {
130
+ comment: {
131
+ type: 'string',
132
+ },
133
+ context: {
134
+ type: 'string',
135
+ },
136
+ },
137
+ type: 'object',
138
+ },
139
+ ],
140
+ },
141
+ type: 'array',
142
+ },
143
+ descriptionStyle: {
144
+ enum: [
145
+ 'body', 'tag', 'any',
146
+ ],
147
+ type: 'string',
148
+ },
149
+ exemptedBy: {
150
+ items: {
151
+ type: 'string',
152
+ },
153
+ type: 'array',
154
+ },
155
+ },
156
+ type: 'object',
157
+ },
158
+ ],
159
+ type: 'suggestion',
160
+ },
161
+ });