eslint-plugin-jsdoc 52.0.1 → 52.0.3

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 (357) hide show
  1. package/dist/WarnSettings.cjs +18 -35
  2. package/dist/WarnSettings.cjs.map +1 -1
  3. package/dist/WarnSettings.js +20 -0
  4. package/dist/WarnSettings.js.map +1 -0
  5. package/dist/_virtual/rolldown_runtime.cjs +32 -0
  6. package/dist/_virtual/rolldown_runtime.js +11 -0
  7. package/dist/alignTransform.cjs +224 -305
  8. package/dist/alignTransform.cjs.map +1 -1
  9. package/dist/alignTransform.js +241 -0
  10. package/dist/alignTransform.js.map +1 -0
  11. package/dist/defaultTagOrder.cjs +132 -43
  12. package/dist/defaultTagOrder.cjs.map +1 -1
  13. package/dist/defaultTagOrder.js +134 -0
  14. package/dist/defaultTagOrder.js.map +1 -0
  15. package/dist/exportParser.cjs +478 -696
  16. package/dist/exportParser.cjs.map +1 -1
  17. package/dist/exportParser.js +518 -0
  18. package/dist/exportParser.js.map +1 -0
  19. package/dist/getDefaultTagStructureForMode.cjs +184 -288
  20. package/dist/getDefaultTagStructureForMode.cjs.map +1 -1
  21. package/dist/getDefaultTagStructureForMode.js +188 -0
  22. package/dist/getDefaultTagStructureForMode.js.map +1 -0
  23. package/dist/getJsdocProcessorPlugin.cjs +365 -532
  24. package/dist/getJsdocProcessorPlugin.cjs.map +1 -1
  25. package/dist/getJsdocProcessorPlugin.d.cts +70 -0
  26. package/dist/getJsdocProcessorPlugin.d.cts.map +1 -0
  27. package/dist/getJsdocProcessorPlugin.d.ts +68 -90
  28. package/dist/getJsdocProcessorPlugin.d.ts.map +1 -1
  29. package/dist/getJsdocProcessorPlugin.js +383 -0
  30. package/dist/getJsdocProcessorPlugin.js.map +1 -0
  31. package/dist/index.cjs +398 -383
  32. package/dist/index.cjs.map +1 -1
  33. package/dist/index.d.cts +22 -0
  34. package/dist/index.d.cts.map +1 -0
  35. package/dist/index.d.ts +11 -6
  36. package/dist/index.d.ts.map +1 -1
  37. package/dist/index.js +425 -0
  38. package/dist/index.js.map +1 -0
  39. package/dist/iterateJsdoc.cjs +1528 -1988
  40. package/dist/iterateJsdoc.cjs.map +1 -1
  41. package/dist/iterateJsdoc.d.cts +471 -0
  42. package/dist/iterateJsdoc.d.cts.map +1 -0
  43. package/dist/iterateJsdoc.d.ts +358 -349
  44. package/dist/iterateJsdoc.d.ts.map +1 -1
  45. package/dist/iterateJsdoc.js +1617 -0
  46. package/dist/iterateJsdoc.js.map +1 -0
  47. package/dist/jsdocUtils.cjs +1009 -1376
  48. package/dist/jsdocUtils.cjs.map +1 -1
  49. package/dist/jsdocUtils.js +1123 -0
  50. package/dist/jsdocUtils.js.map +1 -0
  51. package/dist/rules/checkAccess.cjs +29 -36
  52. package/dist/rules/checkAccess.cjs.map +1 -1
  53. package/dist/rules/checkAccess.js +33 -0
  54. package/dist/rules/checkAccess.js.map +1 -0
  55. package/dist/rules/checkAlignment.cjs +41 -54
  56. package/dist/rules/checkAlignment.cjs.map +1 -1
  57. package/dist/rules/checkAlignment.js +47 -0
  58. package/dist/rules/checkAlignment.js.map +1 -0
  59. package/dist/rules/checkExamples.cjs +327 -484
  60. package/dist/rules/checkExamples.cjs.map +1 -1
  61. package/dist/rules/checkExamples.js +348 -0
  62. package/dist/rules/checkExamples.js.map +1 -0
  63. package/dist/rules/checkIndentation.cjs +50 -65
  64. package/dist/rules/checkIndentation.cjs.map +1 -1
  65. package/dist/rules/checkIndentation.js +59 -0
  66. package/dist/rules/checkIndentation.js.map +1 -0
  67. package/dist/rules/checkLineAlignment.cjs +220 -311
  68. package/dist/rules/checkLineAlignment.cjs.map +1 -1
  69. package/dist/rules/checkLineAlignment.js +229 -0
  70. package/dist/rules/checkLineAlignment.js.map +1 -0
  71. package/dist/rules/checkParamNames.cjs +227 -335
  72. package/dist/rules/checkParamNames.cjs.map +1 -1
  73. package/dist/rules/checkParamNames.js +237 -0
  74. package/dist/rules/checkParamNames.js.map +1 -0
  75. package/dist/rules/checkPropertyNames.cjs +78 -106
  76. package/dist/rules/checkPropertyNames.cjs.map +1 -1
  77. package/dist/rules/checkPropertyNames.js +88 -0
  78. package/dist/rules/checkPropertyNames.js.map +1 -0
  79. package/dist/rules/checkSyntax.cjs +21 -34
  80. package/dist/rules/checkSyntax.cjs.map +1 -1
  81. package/dist/rules/checkSyntax.js +25 -0
  82. package/dist/rules/checkSyntax.js.map +1 -0
  83. package/dist/rules/checkTagNames.cjs +188 -210
  84. package/dist/rules/checkTagNames.cjs.map +1 -1
  85. package/dist/rules/checkTagNames.js +191 -0
  86. package/dist/rules/checkTagNames.js.map +1 -0
  87. package/dist/rules/checkTemplateNames.cjs +121 -178
  88. package/dist/rules/checkTemplateNames.cjs.map +1 -1
  89. package/dist/rules/checkTemplateNames.js +124 -0
  90. package/dist/rules/checkTemplateNames.js.map +1 -0
  91. package/dist/rules/checkTypes.cjs +291 -385
  92. package/dist/rules/checkTypes.cjs.map +1 -1
  93. package/dist/rules/checkTypes.js +299 -0
  94. package/dist/rules/checkTypes.js.map +1 -0
  95. package/dist/rules/checkValues.cjs +100 -146
  96. package/dist/rules/checkValues.cjs.map +1 -1
  97. package/dist/rules/checkValues.js +103 -0
  98. package/dist/rules/checkValues.js.map +1 -0
  99. package/dist/rules/convertToJsdocComments.cjs +228 -306
  100. package/dist/rules/convertToJsdocComments.cjs.map +1 -1
  101. package/dist/rules/convertToJsdocComments.js +231 -0
  102. package/dist/rules/convertToJsdocComments.js.map +1 -0
  103. package/dist/rules/emptyTags.cjs +62 -72
  104. package/dist/rules/emptyTags.cjs.map +1 -1
  105. package/dist/rules/emptyTags.js +67 -0
  106. package/dist/rules/emptyTags.js.map +1 -0
  107. package/dist/rules/implementsOnClasses.cjs +36 -56
  108. package/dist/rules/implementsOnClasses.cjs.map +1 -1
  109. package/dist/rules/implementsOnClasses.js +40 -0
  110. package/dist/rules/implementsOnClasses.js.map +1 -0
  111. package/dist/rules/importsAsDependencies.cjs +62 -99
  112. package/dist/rules/importsAsDependencies.cjs.map +1 -1
  113. package/dist/rules/importsAsDependencies.js +68 -0
  114. package/dist/rules/importsAsDependencies.js.map +1 -0
  115. package/dist/rules/informativeDocs.cjs +105 -142
  116. package/dist/rules/informativeDocs.cjs.map +1 -1
  117. package/dist/rules/informativeDocs.js +110 -0
  118. package/dist/rules/informativeDocs.js.map +1 -0
  119. package/dist/rules/linesBeforeBlock.cjs +70 -105
  120. package/dist/rules/linesBeforeBlock.cjs.map +1 -1
  121. package/dist/rules/linesBeforeBlock.js +75 -0
  122. package/dist/rules/linesBeforeBlock.js.map +1 -0
  123. package/dist/rules/matchDescription.cjs +160 -222
  124. package/dist/rules/matchDescription.cjs.map +1 -1
  125. package/dist/rules/matchDescription.js +167 -0
  126. package/dist/rules/matchDescription.js.map +1 -0
  127. package/dist/rules/matchName.cjs +73 -128
  128. package/dist/rules/matchName.cjs.map +1 -1
  129. package/dist/rules/matchName.js +77 -0
  130. package/dist/rules/matchName.js.map +1 -0
  131. package/dist/rules/multilineBlocks.cjs +235 -352
  132. package/dist/rules/multilineBlocks.cjs.map +1 -1
  133. package/dist/rules/multilineBlocks.js +245 -0
  134. package/dist/rules/multilineBlocks.js.map +1 -0
  135. package/dist/rules/noBadBlocks.cjs +63 -86
  136. package/dist/rules/noBadBlocks.cjs.map +1 -1
  137. package/dist/rules/noBadBlocks.js +68 -0
  138. package/dist/rules/noBadBlocks.js.map +1 -0
  139. package/dist/rules/noBlankBlockDescriptions.cjs +35 -57
  140. package/dist/rules/noBlankBlockDescriptions.cjs.map +1 -1
  141. package/dist/rules/noBlankBlockDescriptions.js +41 -0
  142. package/dist/rules/noBlankBlockDescriptions.js.map +1 -0
  143. package/dist/rules/noBlankBlocks.cjs +26 -48
  144. package/dist/rules/noBlankBlocks.cjs.map +1 -1
  145. package/dist/rules/noBlankBlocks.js +30 -0
  146. package/dist/rules/noBlankBlocks.js.map +1 -0
  147. package/dist/rules/noDefaults.cjs +52 -79
  148. package/dist/rules/noDefaults.cjs.map +1 -1
  149. package/dist/rules/noDefaults.js +56 -0
  150. package/dist/rules/noDefaults.js.map +1 -0
  151. package/dist/rules/noMissingSyntax.cjs +115 -165
  152. package/dist/rules/noMissingSyntax.cjs.map +1 -1
  153. package/dist/rules/noMissingSyntax.js +126 -0
  154. package/dist/rules/noMissingSyntax.js.map +1 -0
  155. package/dist/rules/noMultiAsterisks.cjs +48 -89
  156. package/dist/rules/noMultiAsterisks.cjs.map +1 -1
  157. package/dist/rules/noMultiAsterisks.js +58 -0
  158. package/dist/rules/noMultiAsterisks.js.map +1 -0
  159. package/dist/rules/noRestrictedSyntax.cjs +45 -79
  160. package/dist/rules/noRestrictedSyntax.cjs.map +1 -1
  161. package/dist/rules/noRestrictedSyntax.js +49 -0
  162. package/dist/rules/noRestrictedSyntax.js.map +1 -0
  163. package/dist/rules/noTypes.cjs +59 -80
  164. package/dist/rules/noTypes.cjs.map +1 -1
  165. package/dist/rules/noTypes.js +65 -0
  166. package/dist/rules/noTypes.js.map +1 -0
  167. package/dist/rules/noUndefinedTypes.cjs +297 -388
  168. package/dist/rules/noUndefinedTypes.cjs.map +1 -1
  169. package/dist/rules/noUndefinedTypes.js +303 -0
  170. package/dist/rules/noUndefinedTypes.js.map +1 -0
  171. package/dist/rules/requireAsteriskPrefix.cjs +108 -159
  172. package/dist/rules/requireAsteriskPrefix.cjs.map +1 -1
  173. package/dist/rules/requireAsteriskPrefix.js +112 -0
  174. package/dist/rules/requireAsteriskPrefix.js.map +1 -0
  175. package/dist/rules/requireDescription.cjs +89 -129
  176. package/dist/rules/requireDescription.cjs.map +1 -1
  177. package/dist/rules/requireDescription.js +95 -0
  178. package/dist/rules/requireDescription.js.map +1 -0
  179. package/dist/rules/requireDescriptionCompleteSentence.cjs +201 -262
  180. package/dist/rules/requireDescriptionCompleteSentence.cjs.map +1 -1
  181. package/dist/rules/requireDescriptionCompleteSentence.js +220 -0
  182. package/dist/rules/requireDescriptionCompleteSentence.js.map +1 -0
  183. package/dist/rules/requireExample.cjs +73 -104
  184. package/dist/rules/requireExample.cjs.map +1 -1
  185. package/dist/rules/requireExample.js +77 -0
  186. package/dist/rules/requireExample.js.map +1 -0
  187. package/dist/rules/requireFileOverview.cjs +75 -129
  188. package/dist/rules/requireFileOverview.cjs.map +1 -1
  189. package/dist/rules/requireFileOverview.js +81 -0
  190. package/dist/rules/requireFileOverview.js.map +1 -0
  191. package/dist/rules/requireHyphenBeforeParamDescription.cjs +85 -133
  192. package/dist/rules/requireHyphenBeforeParamDescription.cjs.map +1 -1
  193. package/dist/rules/requireHyphenBeforeParamDescription.js +89 -0
  194. package/dist/rules/requireHyphenBeforeParamDescription.js.map +1 -0
  195. package/dist/rules/requireJsdoc.cjs +384 -557
  196. package/dist/rules/requireJsdoc.cjs.map +1 -1
  197. package/dist/rules/requireJsdoc.js +404 -0
  198. package/dist/rules/requireJsdoc.js.map +1 -0
  199. package/dist/rules/requireParam.cjs +336 -526
  200. package/dist/rules/requireParam.cjs.map +1 -1
  201. package/dist/rules/requireParam.js +344 -0
  202. package/dist/rules/requireParam.js.map +1 -0
  203. package/dist/rules/requireParamDescription.cjs +55 -80
  204. package/dist/rules/requireParamDescription.cjs.map +1 -1
  205. package/dist/rules/requireParamDescription.js +59 -0
  206. package/dist/rules/requireParamDescription.js.map +1 -0
  207. package/dist/rules/requireParamName.cjs +32 -50
  208. package/dist/rules/requireParamName.cjs.map +1 -1
  209. package/dist/rules/requireParamName.js +36 -0
  210. package/dist/rules/requireParamName.js.map +1 -0
  211. package/dist/rules/requireParamType.cjs +55 -80
  212. package/dist/rules/requireParamType.cjs.map +1 -1
  213. package/dist/rules/requireParamType.js +59 -0
  214. package/dist/rules/requireParamType.js.map +1 -0
  215. package/dist/rules/requireProperty.cjs +31 -42
  216. package/dist/rules/requireProperty.cjs.map +1 -1
  217. package/dist/rules/requireProperty.js +35 -0
  218. package/dist/rules/requireProperty.js.map +1 -0
  219. package/dist/rules/requirePropertyDescription.cjs +17 -25
  220. package/dist/rules/requirePropertyDescription.cjs.map +1 -1
  221. package/dist/rules/requirePropertyDescription.js +21 -0
  222. package/dist/rules/requirePropertyDescription.js.map +1 -0
  223. package/dist/rules/requirePropertyName.cjs +17 -25
  224. package/dist/rules/requirePropertyName.cjs.map +1 -1
  225. package/dist/rules/requirePropertyName.js +21 -0
  226. package/dist/rules/requirePropertyName.js.map +1 -0
  227. package/dist/rules/requirePropertyType.cjs +17 -25
  228. package/dist/rules/requirePropertyType.cjs.map +1 -1
  229. package/dist/rules/requirePropertyType.js +21 -0
  230. package/dist/rules/requirePropertyType.js.map +1 -0
  231. package/dist/rules/requireReturns.cjs +125 -203
  232. package/dist/rules/requireReturns.cjs.map +1 -1
  233. package/dist/rules/requireReturns.js +131 -0
  234. package/dist/rules/requireReturns.js.map +1 -0
  235. package/dist/rules/requireReturnsCheck.cjs +60 -103
  236. package/dist/rules/requireReturnsCheck.cjs.map +1 -1
  237. package/dist/rules/requireReturnsCheck.js +66 -0
  238. package/dist/rules/requireReturnsCheck.js.map +1 -0
  239. package/dist/rules/requireReturnsDescription.cjs +39 -54
  240. package/dist/rules/requireReturnsDescription.cjs.map +1 -1
  241. package/dist/rules/requireReturnsDescription.js +43 -0
  242. package/dist/rules/requireReturnsDescription.js.map +1 -0
  243. package/dist/rules/requireReturnsType.cjs +32 -50
  244. package/dist/rules/requireReturnsType.cjs.map +1 -1
  245. package/dist/rules/requireReturnsType.js +36 -0
  246. package/dist/rules/requireReturnsType.js.map +1 -0
  247. package/dist/rules/requireTemplate.cjs +119 -178
  248. package/dist/rules/requireTemplate.cjs.map +1 -1
  249. package/dist/rules/requireTemplate.js +122 -0
  250. package/dist/rules/requireTemplate.js.map +1 -0
  251. package/dist/rules/requireThrows.cjs +61 -95
  252. package/dist/rules/requireThrows.cjs.map +1 -1
  253. package/dist/rules/requireThrows.js +67 -0
  254. package/dist/rules/requireThrows.js.map +1 -0
  255. package/dist/rules/requireYields.cjs +106 -166
  256. package/dist/rules/requireYields.cjs.map +1 -1
  257. package/dist/rules/requireYields.js +115 -0
  258. package/dist/rules/requireYields.js.map +1 -0
  259. package/dist/rules/requireYieldsCheck.cjs +96 -152
  260. package/dist/rules/requireYieldsCheck.cjs.map +1 -1
  261. package/dist/rules/requireYieldsCheck.js +105 -0
  262. package/dist/rules/requireYieldsCheck.js.map +1 -0
  263. package/dist/rules/sortTags.cjs +258 -444
  264. package/dist/rules/sortTags.cjs.map +1 -1
  265. package/dist/rules/sortTags.js +262 -0
  266. package/dist/rules/sortTags.js.map +1 -0
  267. package/dist/rules/tagLines.cjs +179 -266
  268. package/dist/rules/tagLines.cjs.map +1 -1
  269. package/dist/rules/tagLines.js +183 -0
  270. package/dist/rules/tagLines.js.map +1 -0
  271. package/dist/rules/textEscaping.cjs +92 -127
  272. package/dist/rules/textEscaping.cjs.map +1 -1
  273. package/dist/rules/textEscaping.js +102 -0
  274. package/dist/rules/textEscaping.js.map +1 -0
  275. package/dist/rules/validTypes.cjs +252 -265
  276. package/dist/rules/validTypes.cjs.map +1 -1
  277. package/dist/rules/validTypes.js +259 -0
  278. package/dist/rules/validTypes.js.map +1 -0
  279. package/dist/tagNames.cjs +134 -170
  280. package/dist/tagNames.cjs.map +1 -1
  281. package/dist/tagNames.js +144 -0
  282. package/dist/tagNames.js.map +1 -0
  283. package/dist/utils/hasReturnValue.cjs +246 -474
  284. package/dist/utils/hasReturnValue.cjs.map +1 -1
  285. package/dist/utils/hasReturnValue.js +265 -0
  286. package/dist/utils/hasReturnValue.js.map +1 -0
  287. package/package.json +48 -38
  288. package/dist/generateRule.cjs +0 -242
  289. package/dist/generateRule.cjs.map +0 -1
  290. package/src/WarnSettings.js +0 -34
  291. package/src/alignTransform.js +0 -358
  292. package/src/defaultTagOrder.js +0 -169
  293. package/src/exportParser.js +0 -978
  294. package/src/getDefaultTagStructureForMode.js +0 -969
  295. package/src/getJsdocProcessorPlugin.js +0 -652
  296. package/src/index.js +0 -530
  297. package/src/iterateJsdoc.js +0 -2518
  298. package/src/jsdocUtils.js +0 -1896
  299. package/src/rules/checkAccess.js +0 -45
  300. package/src/rules/checkAlignment.js +0 -63
  301. package/src/rules/checkExamples.js +0 -589
  302. package/src/rules/checkIndentation.js +0 -75
  303. package/src/rules/checkLineAlignment.js +0 -372
  304. package/src/rules/checkParamNames.js +0 -474
  305. package/src/rules/checkPropertyNames.js +0 -152
  306. package/src/rules/checkSyntax.js +0 -30
  307. package/src/rules/checkTagNames.js +0 -314
  308. package/src/rules/checkTemplateNames.js +0 -204
  309. package/src/rules/checkTypes.js +0 -535
  310. package/src/rules/checkValues.js +0 -248
  311. package/src/rules/convertToJsdocComments.js +0 -398
  312. package/src/rules/emptyTags.js +0 -98
  313. package/src/rules/implementsOnClasses.js +0 -64
  314. package/src/rules/importsAsDependencies.js +0 -133
  315. package/src/rules/informativeDocs.js +0 -189
  316. package/src/rules/linesBeforeBlock.js +0 -134
  317. package/src/rules/matchDescription.js +0 -286
  318. package/src/rules/matchName.js +0 -151
  319. package/src/rules/multilineBlocks.js +0 -493
  320. package/src/rules/noBadBlocks.js +0 -119
  321. package/src/rules/noBlankBlockDescriptions.js +0 -69
  322. package/src/rules/noBlankBlocks.js +0 -53
  323. package/src/rules/noDefaults.js +0 -85
  324. package/src/rules/noMissingSyntax.js +0 -195
  325. package/src/rules/noMultiAsterisks.js +0 -134
  326. package/src/rules/noRestrictedSyntax.js +0 -91
  327. package/src/rules/noTypes.js +0 -93
  328. package/src/rules/noUndefinedTypes.js +0 -543
  329. package/src/rules/requireAsteriskPrefix.js +0 -190
  330. package/src/rules/requireDescription.js +0 -161
  331. package/src/rules/requireDescriptionCompleteSentence.js +0 -335
  332. package/src/rules/requireExample.js +0 -118
  333. package/src/rules/requireFileOverview.js +0 -154
  334. package/src/rules/requireHyphenBeforeParamDescription.js +0 -176
  335. package/src/rules/requireJsdoc.js +0 -743
  336. package/src/rules/requireParam.js +0 -602
  337. package/src/rules/requireParamDescription.js +0 -89
  338. package/src/rules/requireParamName.js +0 -55
  339. package/src/rules/requireParamType.js +0 -89
  340. package/src/rules/requireProperty.js +0 -48
  341. package/src/rules/requirePropertyDescription.js +0 -25
  342. package/src/rules/requirePropertyName.js +0 -25
  343. package/src/rules/requirePropertyType.js +0 -25
  344. package/src/rules/requireReturns.js +0 -238
  345. package/src/rules/requireReturnsCheck.js +0 -145
  346. package/src/rules/requireReturnsDescription.js +0 -59
  347. package/src/rules/requireReturnsType.js +0 -51
  348. package/src/rules/requireTemplate.js +0 -201
  349. package/src/rules/requireThrows.js +0 -111
  350. package/src/rules/requireYields.js +0 -216
  351. package/src/rules/requireYieldsCheck.js +0 -208
  352. package/src/rules/sortTags.js +0 -558
  353. package/src/rules/tagLines.js +0 -359
  354. package/src/rules/textEscaping.js +0 -154
  355. package/src/rules/validTypes.js +0 -401
  356. package/src/tagNames.js +0 -238
  357. package/src/utils/hasReturnValue.js +0 -572
@@ -0,0 +1,1617 @@
1
+ import { hasValueOrExecutorHasNonEmptyResolveValue } from "./utils/hasReturnValue.js";
2
+ import { comparePaths, dropPathSegmentQuotes, enforcedContexts, exemptSpeciaMethods, filterTags, flattenRoots, forEachPreferredTag, getAllTags, getContextObject, getFunctionParameterNames, getJsdocTagsDeep, getPreferredTagName, getPreferredTagNameSimple, getRegexFromString, getTagDescription, getTagStructureForMode, getTags, getTagsByType, hasATag, hasParams, hasTag, hasThrowValue, hasYieldValue, isConstructor, isValidTag, jsdocUtils_exports, mayBeUndefinedTypeTag, overrideTagStructure, parseClosureTemplateTag, pathDoesNotBeginWith, setTagStructure, tagMissingRequiredTypeOrNamepath } from "./jsdocUtils.js";
3
+ import { commentHandler, getJSDocComment, parseComment, parseComment as parseComment$1 } from "@es-joy/jsdoccomment";
4
+ import { stringify as stringify$1, util } from "comment-parser";
5
+ import esquery from "esquery";
6
+
7
+ //#region src/iterateJsdoc.js
8
+ /**
9
+ * @typedef {number} Integer
10
+ */
11
+ /**
12
+ * @typedef {import('@es-joy/jsdoccomment').JsdocBlockWithInline} JsdocBlockWithInline
13
+ */
14
+ /**
15
+ * @typedef {{
16
+ * disallowName?: string,
17
+ * allowName?: string,
18
+ * context?: string,
19
+ * comment?: string,
20
+ * tags?: string[],
21
+ * replacement?: string,
22
+ * minimum?: Integer,
23
+ * message?: string,
24
+ * forceRequireReturn?: boolean
25
+ * }} ContextObject
26
+ */
27
+ /**
28
+ * @typedef {string|ContextObject} Context
29
+ */
30
+ /**
31
+ * @callback CheckJsdoc
32
+ * @param {{
33
+ * lastIndex?: Integer,
34
+ * isFunctionContext?: boolean,
35
+ * selector?: string,
36
+ * comment?: string
37
+ * }} info
38
+ * @param {null|((jsdoc: import('@es-joy/jsdoccomment').JsdocBlockWithInline) => boolean|undefined)} handler
39
+ * @param {import('eslint').Rule.Node} node
40
+ * @returns {void}
41
+ */
42
+ /**
43
+ * @callback ForEachPreferredTag
44
+ * @param {string} tagName
45
+ * @param {(
46
+ * matchingJsdocTag: import('@es-joy/jsdoccomment').JsdocTagWithInline,
47
+ * targetTagName: string
48
+ * ) => void} arrayHandler
49
+ * @param {boolean} [skipReportingBlockedTag]
50
+ * @returns {void}
51
+ */
52
+ /**
53
+ * @callback ReportSettings
54
+ * @param {string} message
55
+ * @returns {void}
56
+ */
57
+ /**
58
+ * @callback ParseClosureTemplateTag
59
+ * @param {import('comment-parser').Spec} tag
60
+ * @returns {string[]}
61
+ */
62
+ /**
63
+ * @callback GetPreferredTagNameObject
64
+ * @param {{
65
+ * tagName: string
66
+ * }} cfg
67
+ * @returns {string|false|{
68
+ * message: string;
69
+ * replacement?: string|undefined
70
+ * }|{
71
+ * blocked: true,
72
+ * tagName: string
73
+ * }}
74
+ */
75
+ /**
76
+ * @typedef {{
77
+ * forEachPreferredTag: ForEachPreferredTag,
78
+ * reportSettings: ReportSettings,
79
+ * parseClosureTemplateTag: ParseClosureTemplateTag,
80
+ * getPreferredTagNameObject: GetPreferredTagNameObject,
81
+ * pathDoesNotBeginWith: import('./jsdocUtils.js').PathDoesNotBeginWith
82
+ * }} BasicUtils
83
+ */
84
+ /**
85
+ * @callback IsIteratingFunction
86
+ * @returns {boolean}
87
+ */
88
+ /**
89
+ * @callback IsVirtualFunction
90
+ * @returns {boolean}
91
+ */
92
+ /**
93
+ * @callback Stringify
94
+ * @param {import('comment-parser').Block} tagBlock
95
+ * @param {boolean} [specRewire]
96
+ * @returns {string}
97
+ */
98
+ /**
99
+ * @callback ReportJSDoc
100
+ * @param {string} msg
101
+ * @param {null|import('comment-parser').Spec|{line: Integer, column?: Integer}} [tag]
102
+ * @param {(() => void)|null} [handler]
103
+ * @param {boolean} [specRewire]
104
+ * @param {undefined|{
105
+ * [key: string]: string
106
+ * }} [data]
107
+ */
108
+ /**
109
+ * @callback GetRegexFromString
110
+ * @param {string} str
111
+ * @param {string} [requiredFlags]
112
+ * @returns {RegExp}
113
+ */
114
+ /**
115
+ * @callback GetTagDescription
116
+ * @param {import('comment-parser').Spec} tg
117
+ * @param {boolean} [returnArray]
118
+ * @returns {string[]|string}
119
+ */
120
+ /**
121
+ * @callback SetTagDescription
122
+ * @param {import('comment-parser').Spec} tg
123
+ * @param {RegExp} matcher
124
+ * @param {(description: string) => string} setter
125
+ * @returns {Integer}
126
+ */
127
+ /**
128
+ * @callback GetDescription
129
+ * @returns {{
130
+ * description: string,
131
+ * descriptions: string[],
132
+ * lastDescriptionLine: Integer
133
+ * }}
134
+ */
135
+ /**
136
+ * @callback SetBlockDescription
137
+ * @param {(
138
+ * info: {
139
+ * delimiter: string,
140
+ * postDelimiter: string,
141
+ * start: string
142
+ * },
143
+ * seedTokens: (
144
+ * tokens?: Partial<import('comment-parser').Tokens>
145
+ * ) => import('comment-parser').Tokens,
146
+ * descLines: string[]
147
+ * ) => import('comment-parser').Line[]} setter
148
+ * @returns {void}
149
+ */
150
+ /**
151
+ * @callback SetDescriptionLines
152
+ * @param {RegExp} matcher
153
+ * @param {(description: string) => string} setter
154
+ * @returns {Integer}
155
+ */
156
+ /**
157
+ * @callback ChangeTag
158
+ * @param {import('comment-parser').Spec} tag
159
+ * @param {...Partial<import('comment-parser').Tokens>} tokens
160
+ * @returns {void}
161
+ */
162
+ /**
163
+ * @callback SetTag
164
+ * @param {import('comment-parser').Spec & {
165
+ * line: Integer
166
+ * }} tag
167
+ * @param {Partial<import('comment-parser').Tokens>} [tokens]
168
+ * @returns {void}
169
+ */
170
+ /**
171
+ * @callback RemoveTag
172
+ * @param {Integer} tagIndex
173
+ * @param {{
174
+ * removeEmptyBlock?: boolean,
175
+ * tagSourceOffset?: Integer
176
+ * }} [cfg]
177
+ * @returns {void}
178
+ */
179
+ /**
180
+ * @callback AddTag
181
+ * @param {string} targetTagName
182
+ * @param {Integer} [number]
183
+ * @param {import('comment-parser').Tokens|{}} [tokens]
184
+ * @returns {void}
185
+ */
186
+ /**
187
+ * @callback GetFirstLine
188
+ * @returns {Integer|undefined}
189
+ */
190
+ /**
191
+ * @typedef {(
192
+ * tokens?: Partial<import('comment-parser').Tokens> | undefined
193
+ * ) => import('comment-parser').Tokens} SeedTokens
194
+ */
195
+ /**
196
+ * Sets tokens to empty string.
197
+ * @callback EmptyTokens
198
+ * @param {import('comment-parser').Tokens} tokens
199
+ * @returns {void}
200
+ */
201
+ /**
202
+ * @callback AddLine
203
+ * @param {Integer} sourceIndex
204
+ * @param {Partial<import('comment-parser').Tokens>} tokens
205
+ * @returns {void}
206
+ */
207
+ /**
208
+ * @callback AddLines
209
+ * @param {Integer} tagIndex
210
+ * @param {Integer} tagSourceOffset
211
+ * @param {Integer} numLines
212
+ * @returns {void}
213
+ */
214
+ /**
215
+ * @callback MakeMultiline
216
+ * @returns {void}
217
+ */
218
+ /**
219
+ * @callback GetFunctionParameterNames
220
+ * @param {boolean} [useDefaultObjectProperties]
221
+ * @returns {import('./jsdocUtils.js').ParamNameInfo[]}
222
+ */
223
+ /**
224
+ * @callback HasParams
225
+ * @returns {Integer}
226
+ */
227
+ /**
228
+ * @callback IsGenerator
229
+ * @returns {boolean}
230
+ */
231
+ /**
232
+ * @callback IsConstructor
233
+ * @returns {boolean}
234
+ */
235
+ /**
236
+ * @callback GetJsdocTagsDeep
237
+ * @param {string} tagName
238
+ * @returns {false|{
239
+ * idx: Integer,
240
+ * name: string,
241
+ * type: string
242
+ * }[]}
243
+ */
244
+ /**
245
+ * @callback GetPreferredTagName
246
+ * @param {{
247
+ * tagName: string,
248
+ * skipReportingBlockedTag?: boolean,
249
+ * allowObjectReturn?: boolean,
250
+ * defaultMessage?: string
251
+ * }} cfg
252
+ * @returns {string|undefined|false|{
253
+ * message: string;
254
+ * replacement?: string|undefined;
255
+ * }|{
256
+ * blocked: true,
257
+ * tagName: string
258
+ * }}
259
+ */
260
+ /**
261
+ * @callback IsValidTag
262
+ * @param {string} name
263
+ * @param {string[]} definedTags
264
+ * @returns {boolean}
265
+ */
266
+ /**
267
+ * @callback HasATag
268
+ * @param {string[]} names
269
+ * @returns {boolean}
270
+ */
271
+ /**
272
+ * @callback HasTag
273
+ * @param {string} name
274
+ * @returns {boolean}
275
+ */
276
+ /**
277
+ * @callback ComparePaths
278
+ * @param {string} name
279
+ * @returns {(otherPathName: string) => boolean}
280
+ */
281
+ /**
282
+ * @callback DropPathSegmentQuotes
283
+ * @param {string} name
284
+ * @returns {string}
285
+ */
286
+ /**
287
+ * @callback AvoidDocs
288
+ * @returns {boolean}
289
+ */
290
+ /**
291
+ * @callback TagMightHaveNamePositionTypePosition
292
+ * @param {string} tagName
293
+ * @param {import('./getDefaultTagStructureForMode.js').
294
+ * TagStructure[]} [otherModeMaps]
295
+ * @returns {boolean|{otherMode: true}}
296
+ */
297
+ /**
298
+ * @callback TagMustHave
299
+ * @param {string} tagName
300
+ * @param {import('./getDefaultTagStructureForMode.js').
301
+ * TagStructure[]} otherModeMaps
302
+ * @returns {boolean|{
303
+ * otherMode: false
304
+ * }}
305
+ */
306
+ /**
307
+ * @callback TagMissingRequiredTypeOrNamepath
308
+ * @param {import('comment-parser').Spec} tag
309
+ * @param {import('./getDefaultTagStructureForMode.js').
310
+ * TagStructure[]} otherModeMaps
311
+ * @returns {boolean|{
312
+ * otherMode: false
313
+ * }}
314
+ */
315
+ /**
316
+ * @callback IsNamepathX
317
+ * @param {string} tagName
318
+ * @returns {boolean}
319
+ */
320
+ /**
321
+ * @callback GetTagStructureForMode
322
+ * @param {import('./jsdocUtils.js').ParserMode} mde
323
+ * @returns {import('./getDefaultTagStructureForMode.js').TagStructure}
324
+ */
325
+ /**
326
+ * @callback MayBeUndefinedTypeTag
327
+ * @param {import('comment-parser').Spec} tag
328
+ * @returns {boolean}
329
+ */
330
+ /**
331
+ * @callback HasValueOrExecutorHasNonEmptyResolveValue
332
+ * @param {boolean} anyPromiseAsReturn
333
+ * @param {boolean} [allBranches]
334
+ * @returns {boolean}
335
+ */
336
+ /**
337
+ * @callback HasYieldValue
338
+ * @returns {boolean}
339
+ */
340
+ /**
341
+ * @callback HasYieldReturnValue
342
+ * @returns {boolean}
343
+ */
344
+ /**
345
+ * @callback HasThrowValue
346
+ * @returns {boolean}
347
+ */
348
+ /**
349
+ * @callback IsAsync
350
+ * @returns {boolean|undefined}
351
+ */
352
+ /**
353
+ * @callback GetTags
354
+ * @param {string} tagName
355
+ * @returns {import('comment-parser').Spec[]}
356
+ */
357
+ /**
358
+ * @callback GetPresentTags
359
+ * @param {string[]} tagList
360
+ * @returns {import('@es-joy/jsdoccomment').JsdocTagWithInline[]}
361
+ */
362
+ /**
363
+ * @callback FilterTags
364
+ * @param {(tag: import('@es-joy/jsdoccomment').JsdocTagWithInline) => boolean} filter
365
+ * @returns {import('@es-joy/jsdoccomment').JsdocTagWithInline[]}
366
+ */
367
+ /**
368
+ * @callback FilterAllTags
369
+ * @param {(tag: (import('comment-parser').Spec|
370
+ * import('@es-joy/jsdoccomment').JsdocInlineTagNoType)) => boolean} filter
371
+ * @returns {(import('comment-parser').Spec|
372
+ * import('@es-joy/jsdoccomment').JsdocInlineTagNoType)[]}
373
+ */
374
+ /**
375
+ * @callback GetTagsByType
376
+ * @param {import('comment-parser').Spec[]} tags
377
+ * @returns {{
378
+ * tagsWithNames: import('comment-parser').Spec[],
379
+ * tagsWithoutNames: import('comment-parser').Spec[]
380
+ * }}
381
+ */
382
+ /**
383
+ * @callback HasOptionTag
384
+ * @param {string} tagName
385
+ * @returns {boolean}
386
+ */
387
+ /**
388
+ * @callback GetClassNode
389
+ * @returns {Node|null}
390
+ */
391
+ /**
392
+ * @callback GetClassJsdoc
393
+ * @returns {null|JsdocBlockWithInline}
394
+ */
395
+ /**
396
+ * @callback ClassHasTag
397
+ * @param {string} tagName
398
+ * @returns {boolean}
399
+ */
400
+ /**
401
+ * @callback FindContext
402
+ * @param {Context[]} contexts
403
+ * @param {string|undefined} comment
404
+ * @returns {{
405
+ * foundContext: Context|undefined,
406
+ * contextStr: string
407
+ * }}
408
+ */
409
+ /**
410
+ * @typedef {BasicUtils & {
411
+ * isIteratingFunction: IsIteratingFunction,
412
+ * isVirtualFunction: IsVirtualFunction,
413
+ * stringify: Stringify,
414
+ * reportJSDoc: ReportJSDoc,
415
+ * getRegexFromString: GetRegexFromString,
416
+ * getTagDescription: GetTagDescription,
417
+ * setTagDescription: SetTagDescription,
418
+ * getDescription: GetDescription,
419
+ * setBlockDescription: SetBlockDescription,
420
+ * setDescriptionLines: SetDescriptionLines,
421
+ * changeTag: ChangeTag,
422
+ * setTag: SetTag,
423
+ * removeTag: RemoveTag,
424
+ * addTag: AddTag,
425
+ * getFirstLine: GetFirstLine,
426
+ * seedTokens: SeedTokens,
427
+ * emptyTokens: EmptyTokens,
428
+ * addLine: AddLine,
429
+ * addLines: AddLines,
430
+ * makeMultiline: MakeMultiline,
431
+ * flattenRoots: import('./jsdocUtils.js').FlattenRoots,
432
+ * getFunctionParameterNames: GetFunctionParameterNames,
433
+ * hasParams: HasParams,
434
+ * isGenerator: IsGenerator,
435
+ * isConstructor: IsConstructor,
436
+ * getJsdocTagsDeep: GetJsdocTagsDeep,
437
+ * getPreferredTagName: GetPreferredTagName,
438
+ * isValidTag: IsValidTag,
439
+ * hasATag: HasATag,
440
+ * hasTag: HasTag,
441
+ * comparePaths: ComparePaths,
442
+ * dropPathSegmentQuotes: DropPathSegmentQuotes,
443
+ * avoidDocs: AvoidDocs,
444
+ * tagMightHaveNamePosition: TagMightHaveNamePositionTypePosition,
445
+ * tagMightHaveTypePosition: TagMightHaveNamePositionTypePosition,
446
+ * tagMustHaveNamePosition: TagMustHave,
447
+ * tagMustHaveTypePosition: TagMustHave,
448
+ * tagMissingRequiredTypeOrNamepath: TagMissingRequiredTypeOrNamepath,
449
+ * isNamepathDefiningTag: IsNamepathX,
450
+ * isNamepathReferencingTag: IsNamepathX,
451
+ * isNamepathOrUrlReferencingTag: IsNamepathX,
452
+ * tagMightHaveNamepath: IsNamepathX,
453
+ * getTagStructureForMode: GetTagStructureForMode,
454
+ * mayBeUndefinedTypeTag: MayBeUndefinedTypeTag,
455
+ * hasValueOrExecutorHasNonEmptyResolveValue: HasValueOrExecutorHasNonEmptyResolveValue,
456
+ * hasYieldValue: HasYieldValue,
457
+ * hasYieldReturnValue: HasYieldReturnValue,
458
+ * hasThrowValue: HasThrowValue,
459
+ * isAsync: IsAsync,
460
+ * getTags: GetTags,
461
+ * getPresentTags: GetPresentTags,
462
+ * filterTags: FilterTags,
463
+ * filterAllTags: FilterAllTags,
464
+ * getTagsByType: GetTagsByType,
465
+ * hasOptionTag: HasOptionTag,
466
+ * getClassNode: GetClassNode,
467
+ * getClassJsdoc: GetClassJsdoc,
468
+ * classHasTag: ClassHasTag,
469
+ * findContext: FindContext
470
+ * }} Utils
471
+ */
472
+ const { rewireSpecs, seedTokens } = util;
473
+ /**
474
+ * Should use ESLint rule's typing.
475
+ * @typedef {import('eslint').Rule.RuleMetaData} EslintRuleMeta
476
+ */
477
+ /**
478
+ * A plain object for tracking state as needed by rules across iterations.
479
+ * @typedef {{
480
+ * globalTags: {},
481
+ * hasDuplicates: {
482
+ * [key: string]: boolean
483
+ * },
484
+ * selectorMap: {
485
+ * [selector: string]: {
486
+ * [comment: string]: Integer
487
+ * }
488
+ * },
489
+ * hasTag: {
490
+ * [key: string]: boolean
491
+ * },
492
+ * hasNonComment: number,
493
+ * hasNonCommentBeforeTag: {
494
+ * [key: string]: boolean|number
495
+ * }
496
+ * }} StateObject
497
+ */
498
+ /**
499
+ * The Node AST as supplied by the parser.
500
+ * @typedef {import('eslint').Rule.Node} Node
501
+ */
502
+ const globalState = /* @__PURE__ */ new Map();
503
+ /**
504
+ * @param {import('eslint').Rule.RuleContext} context
505
+ * @param {{
506
+ * tagNamePreference?: import('./jsdocUtils.js').TagNamePreference,
507
+ * mode?: import('./jsdocUtils.js').ParserMode
508
+ * }} cfg
509
+ * @returns {BasicUtils}
510
+ */
511
+ const getBasicUtils = (context, { mode, tagNamePreference }) => {
512
+ /** @type {BasicUtils} */
513
+ const utils = {};
514
+ /** @type {ReportSettings} */
515
+ utils.reportSettings = (message) => {
516
+ context.report({
517
+ loc: {
518
+ end: {
519
+ column: 1,
520
+ line: 1
521
+ },
522
+ start: {
523
+ column: 1,
524
+ line: 1
525
+ }
526
+ },
527
+ message
528
+ });
529
+ };
530
+ /** @type {ParseClosureTemplateTag} */
531
+ utils.parseClosureTemplateTag = (tag) => {
532
+ return parseClosureTemplateTag(tag);
533
+ };
534
+ utils.pathDoesNotBeginWith = pathDoesNotBeginWith;
535
+ /** @type {GetPreferredTagNameObject} */
536
+ utils.getPreferredTagNameObject = ({ tagName }) => {
537
+ const ret = getPreferredTagNameSimple(tagName, mode, tagNamePreference, context);
538
+ const isObject = ret && typeof ret === "object";
539
+ if (ret === false || isObject && !ret.replacement) return {
540
+ blocked: true,
541
+ tagName
542
+ };
543
+ return ret;
544
+ };
545
+ return utils;
546
+ };
547
+ /**
548
+ * @callback Report
549
+ * @param {string} message
550
+ * @param {import('eslint').Rule.ReportFixer|null} [fix]
551
+ * @param {null|
552
+ * {line?: Integer, column?: Integer}|
553
+ * import('comment-parser').Spec & {line?: Integer}
554
+ * } [jsdocLoc]
555
+ * @param {undefined|{
556
+ * [key: string]: string
557
+ * }} [data]
558
+ * @returns {void}
559
+ */
560
+ /**
561
+ * @param {Node|null} node
562
+ * @param {JsdocBlockWithInline} jsdoc
563
+ * @param {import('eslint').AST.Token} jsdocNode
564
+ * @param {Settings} settings
565
+ * @param {Report} report
566
+ * @param {import('eslint').Rule.RuleContext} context
567
+ * @param {import('eslint').SourceCode} sc
568
+ * @param {boolean|undefined} iteratingAll
569
+ * @param {RuleConfig} ruleConfig
570
+ * @param {string} indent
571
+ * @returns {Utils}
572
+ */
573
+ const getUtils = (node, jsdoc, jsdocNode, settings, report, context, sc, iteratingAll, ruleConfig, indent) => {
574
+ const ancestors = node ? sc.getAncestors ? sc.getAncestors(node) : context.getAncestors() : [];
575
+ /* c8 ignore next -- Fallback to deprecated method */
576
+ const { sourceCode = context.getSourceCode() } = context;
577
+ const utils = getBasicUtils(context, settings);
578
+ const { augmentsExtendsReplacesDocs, ignoreReplacesDocs, implementsReplacesDocs, maxLines, minLines, mode, overrideReplacesDocs, tagNamePreference } = settings;
579
+ /** @type {IsIteratingFunction} */
580
+ utils.isIteratingFunction = () => {
581
+ return !iteratingAll || [
582
+ "ArrowFunctionExpression",
583
+ "FunctionDeclaration",
584
+ "FunctionExpression",
585
+ "MethodDefinition"
586
+ ].includes(String(node && node.type));
587
+ };
588
+ /** @type {IsVirtualFunction} */
589
+ utils.isVirtualFunction = () => {
590
+ return Boolean(iteratingAll) && utils.hasATag([
591
+ "callback",
592
+ "function",
593
+ "func",
594
+ "method"
595
+ ]);
596
+ };
597
+ /** @type {Stringify} */
598
+ utils.stringify = (tagBlock, specRewire) => {
599
+ let block;
600
+ if (specRewire) block = rewireSpecs(tagBlock);
601
+ return stringify$1(specRewire ? block : tagBlock);
602
+ };
603
+ /** @type {ReportJSDoc} */
604
+ utils.reportJSDoc = (msg, tag, handler, specRewire, data) => {
605
+ report(msg, handler ? (fixer) => {
606
+ handler();
607
+ const replacement = utils.stringify(jsdoc, specRewire);
608
+ if (!replacement) {
609
+ const text = sourceCode.getText();
610
+ const lastLineBreakPos = text.slice(0, jsdocNode.range[0]).search(/\n[ \t]*$/v);
611
+ if (lastLineBreakPos > -1) return fixer.removeRange([lastLineBreakPos, jsdocNode.range[1]]);
612
+ return fixer.removeRange(/\s/v.test(text.charAt(jsdocNode.range[1])) ? [jsdocNode.range[0], jsdocNode.range[1] + 1] : jsdocNode.range);
613
+ }
614
+ return fixer.replaceText(jsdocNode, replacement);
615
+ } : null, tag, data);
616
+ };
617
+ /** @type {GetRegexFromString} */
618
+ utils.getRegexFromString = (str, requiredFlags) => {
619
+ return getRegexFromString(str, requiredFlags);
620
+ };
621
+ /** @type {GetTagDescription} */
622
+ utils.getTagDescription = (tg, returnArray) => {
623
+ return getTagDescription(tg, returnArray);
624
+ };
625
+ /** @type {SetTagDescription} */
626
+ utils.setTagDescription = (tg, matcher, setter) => {
627
+ let finalIdx = 0;
628
+ tg.source.some(({ tokens: { description } }, idx) => {
629
+ if (description && matcher.test(description)) {
630
+ tg.source[idx].tokens.description = setter(description);
631
+ finalIdx = idx;
632
+ return true;
633
+ }
634
+ return false;
635
+ });
636
+ return finalIdx;
637
+ };
638
+ /** @type {GetDescription} */
639
+ utils.getDescription = () => {
640
+ /** @type {string[]} */
641
+ const descriptions = [];
642
+ let lastDescriptionLine = 0;
643
+ let tagsBegun = false;
644
+ jsdoc.source.some(({ tokens: { description, end, tag } }, idx) => {
645
+ if (tag) tagsBegun = true;
646
+ if (idx && (tag || end)) {
647
+ lastDescriptionLine = idx - 1;
648
+ if (!tagsBegun && description) descriptions.push(description);
649
+ return true;
650
+ }
651
+ if (!tagsBegun && (idx || description)) descriptions.push(description || (descriptions.length ? "" : "\n"));
652
+ return false;
653
+ });
654
+ return {
655
+ description: descriptions.join("\n"),
656
+ descriptions,
657
+ lastDescriptionLine
658
+ };
659
+ };
660
+ /** @type {SetBlockDescription} */
661
+ utils.setBlockDescription = (setter) => {
662
+ /** @type {string[]} */
663
+ const descLines = [];
664
+ /**
665
+ * @type {undefined|Integer}
666
+ */
667
+ let startIdx;
668
+ /**
669
+ * @type {undefined|Integer}
670
+ */
671
+ let endIdx;
672
+ /**
673
+ * @type {undefined|{
674
+ * delimiter: string,
675
+ * postDelimiter: string,
676
+ * start: string
677
+ * }}
678
+ */
679
+ let info;
680
+ jsdoc.source.some(({ tokens: { delimiter, description, end, postDelimiter, start, tag } }, idx) => {
681
+ if (delimiter === "/**") return false;
682
+ if (startIdx === void 0) {
683
+ startIdx = idx;
684
+ info = {
685
+ delimiter,
686
+ postDelimiter,
687
+ start
688
+ };
689
+ }
690
+ if (tag || end) {
691
+ endIdx = idx;
692
+ return true;
693
+ }
694
+ descLines.push(description);
695
+ return false;
696
+ });
697
+ /* c8 ignore else -- Won't be called if missing */
698
+ if (descLines.length) jsdoc.source.splice(
699
+ startIdx,
700
+ /** @type {Integer} */
701
+ endIdx - startIdx,
702
+ ...setter(info, seedTokens, descLines)
703
+ );
704
+ };
705
+ /** @type {SetDescriptionLines} */
706
+ utils.setDescriptionLines = (matcher, setter) => {
707
+ let finalIdx = 0;
708
+ jsdoc.source.some(({ tokens: { description, end, tag } }, idx) => {
709
+ /* c8 ignore next 3 -- Already checked */
710
+ if (idx && (tag || end)) return true;
711
+ if (description && matcher.test(description)) {
712
+ jsdoc.source[idx].tokens.description = setter(description);
713
+ finalIdx = idx;
714
+ return true;
715
+ }
716
+ return false;
717
+ });
718
+ return finalIdx;
719
+ };
720
+ /** @type {ChangeTag} */
721
+ utils.changeTag = (tag, ...tokens) => {
722
+ for (const [idx, src] of tag.source.entries()) src.tokens = {
723
+ ...src.tokens,
724
+ ...tokens[idx]
725
+ };
726
+ };
727
+ /** @type {SetTag} */
728
+ utils.setTag = (tag, tokens) => {
729
+ tag.source = [{
730
+ number: tag.line,
731
+ source: "",
732
+ tokens: seedTokens({
733
+ delimiter: "*",
734
+ postDelimiter: " ",
735
+ start: indent + " ",
736
+ tag: "@" + tag.tag,
737
+ ...tokens
738
+ })
739
+ }];
740
+ };
741
+ /** @type {RemoveTag} */
742
+ utils.removeTag = (tagIndex, { removeEmptyBlock = false, tagSourceOffset = 0 } = {}) => {
743
+ const { source: tagSource } = jsdoc.tags[tagIndex];
744
+ /** @type {Integer|undefined} */
745
+ let lastIndex;
746
+ const firstNumber = jsdoc.source[0].number;
747
+ tagSource.some(({ number }, tagIdx) => {
748
+ const sourceIndex = jsdoc.source.findIndex(({ number: srcNumber }) => {
749
+ return number === srcNumber;
750
+ });
751
+ // c8 ignore else
752
+ if (sourceIndex > -1) {
753
+ let spliceCount = 1;
754
+ tagSource.slice(tagIdx + 1).some(({ tokens: { end: ending, tag } }) => {
755
+ if (!tag && !ending) {
756
+ spliceCount++;
757
+ return false;
758
+ }
759
+ return true;
760
+ });
761
+ const spliceIdx = sourceIndex + tagSourceOffset;
762
+ const { delimiter, end } = jsdoc.source[spliceIdx].tokens;
763
+ if (spliceIdx === 0 && jsdoc.tags.length >= 2 || !removeEmptyBlock && (end || delimiter === "/**")) {
764
+ const { tokens } = jsdoc.source[spliceIdx];
765
+ for (const item of [
766
+ "postDelimiter",
767
+ "tag",
768
+ "postTag",
769
+ "type",
770
+ "postType",
771
+ "name",
772
+ "postName",
773
+ "description"
774
+ ]) tokens[item] = "";
775
+ } else {
776
+ jsdoc.source.splice(spliceIdx, spliceCount - tagSourceOffset + (spliceIdx ? 0 : jsdoc.source.length));
777
+ tagSource.splice(tagIdx + tagSourceOffset, spliceCount - tagSourceOffset + (spliceIdx ? 0 : jsdoc.source.length));
778
+ }
779
+ lastIndex = sourceIndex;
780
+ return true;
781
+ }
782
+ /* c8 ignore next 2 */
783
+ return false;
784
+ });
785
+ for (const [idx, src] of jsdoc.source.slice(lastIndex).entries()) src.number = firstNumber + lastIndex + idx;
786
+ };
787
+ /** @type {AddTag} */
788
+ utils.addTag = (targetTagName, number = (jsdoc.tags[jsdoc.tags.length - 1]?.source[0]?.number ?? jsdoc.source.findIndex(({ tokens: { tag } }) => {
789
+ return tag;
790
+ }) - 1) + 1, tokens = {}) => {
791
+ jsdoc.source.splice(number, 0, {
792
+ number,
793
+ source: "",
794
+ tokens: seedTokens({
795
+ delimiter: "*",
796
+ postDelimiter: " ",
797
+ start: indent + " ",
798
+ tag: `@${targetTagName}`,
799
+ ...tokens
800
+ })
801
+ });
802
+ for (const src of jsdoc.source.slice(number + 1)) src.number++;
803
+ };
804
+ /** @type {GetFirstLine} */
805
+ utils.getFirstLine = () => {
806
+ let firstLine;
807
+ for (const { number, tokens: { tag } } of jsdoc.source) if (tag) {
808
+ firstLine = number;
809
+ break;
810
+ }
811
+ return firstLine;
812
+ };
813
+ /** @type {SeedTokens} */
814
+ utils.seedTokens = seedTokens;
815
+ /** @type {EmptyTokens} */
816
+ utils.emptyTokens = (tokens) => {
817
+ for (const prop of [
818
+ "start",
819
+ "postDelimiter",
820
+ "tag",
821
+ "type",
822
+ "postType",
823
+ "postTag",
824
+ "name",
825
+ "postName",
826
+ "description",
827
+ "end",
828
+ "lineEnd"
829
+ ]) tokens[prop] = "";
830
+ };
831
+ /** @type {AddLine} */
832
+ utils.addLine = (sourceIndex, tokens) => {
833
+ const number = (jsdoc.source[sourceIndex - 1]?.number || 0) + 1;
834
+ jsdoc.source.splice(sourceIndex, 0, {
835
+ number,
836
+ source: "",
837
+ tokens: seedTokens(tokens)
838
+ });
839
+ for (const src of jsdoc.source.slice(number + 1)) src.number++;
840
+ };
841
+ /** @type {AddLines} */
842
+ utils.addLines = (tagIndex, tagSourceOffset, numLines) => {
843
+ const { source: tagSource } = jsdoc.tags[tagIndex];
844
+ /** @type {Integer|undefined} */
845
+ let lastIndex;
846
+ const firstNumber = jsdoc.source[0].number;
847
+ tagSource.some(({ number }) => {
848
+ const makeLine = () => {
849
+ return {
850
+ number,
851
+ source: "",
852
+ tokens: seedTokens({
853
+ delimiter: "*",
854
+ start: indent + " "
855
+ })
856
+ };
857
+ };
858
+ const makeLines = () => {
859
+ return Array.from({ length: numLines }, makeLine);
860
+ };
861
+ const sourceIndex = jsdoc.source.findIndex(({ number: srcNumber, tokens: { end } }) => {
862
+ return number === srcNumber && !end;
863
+ });
864
+ // c8 ignore else
865
+ if (sourceIndex > -1) {
866
+ const lines = makeLines();
867
+ jsdoc.source.splice(sourceIndex + tagSourceOffset, 0, ...lines);
868
+ lastIndex = sourceIndex;
869
+ return true;
870
+ }
871
+ /* c8 ignore next 2 */
872
+ return false;
873
+ });
874
+ for (const [idx, src] of jsdoc.source.slice(lastIndex).entries()) src.number = firstNumber + lastIndex + idx;
875
+ };
876
+ /** @type {MakeMultiline} */
877
+ utils.makeMultiline = () => {
878
+ const { source: [{ tokens }] } = jsdoc;
879
+ const { description, lineEnd, name, postDelimiter, tag, type } = tokens;
880
+ let { tokens: { postName, postTag, postType } } = jsdoc.source[0];
881
+ if (!description) {
882
+ if (postName) postName = "";
883
+ else if (postType) postType = "";
884
+ else if (postTag) postTag = "";
885
+ }
886
+ utils.emptyTokens(tokens);
887
+ utils.addLine(1, {
888
+ delimiter: "*",
889
+ description: description.trimEnd(),
890
+ name,
891
+ postDelimiter,
892
+ postName,
893
+ postTag,
894
+ postType,
895
+ start: indent + " ",
896
+ tag,
897
+ type
898
+ });
899
+ utils.addLine(2, {
900
+ end: "*/",
901
+ lineEnd,
902
+ start: indent + " "
903
+ });
904
+ };
905
+ /**
906
+ * @type {import('./jsdocUtils.js').FlattenRoots}
907
+ */
908
+ utils.flattenRoots = flattenRoots;
909
+ /** @type {GetFunctionParameterNames} */
910
+ utils.getFunctionParameterNames = (useDefaultObjectProperties) => {
911
+ return getFunctionParameterNames(node, useDefaultObjectProperties);
912
+ };
913
+ /** @type {HasParams} */
914
+ utils.hasParams = () => {
915
+ return hasParams(node);
916
+ };
917
+ /** @type {IsGenerator} */
918
+ utils.isGenerator = () => {
919
+ return node !== null && Boolean(
920
+ /**
921
+ * @type {import('estree').FunctionDeclaration|
922
+ * import('estree').FunctionExpression}
923
+ */
924
+ node.generator || node.type === "MethodDefinition" && node.value.generator || ["ExportDefaultDeclaration", "ExportNamedDeclaration"].includes(node.type) && node.declaration?.generator
925
+ );
926
+ };
927
+ /** @type {IsConstructor} */
928
+ utils.isConstructor = () => {
929
+ return isConstructor(node);
930
+ };
931
+ /** @type {GetJsdocTagsDeep} */
932
+ utils.getJsdocTagsDeep = (tagName) => {
933
+ const name = utils.getPreferredTagName({ tagName });
934
+ if (!name) return false;
935
+ return getJsdocTagsDeep(jsdoc, name);
936
+ };
937
+ /** @type {GetPreferredTagName} */
938
+ utils.getPreferredTagName = (args) => {
939
+ return getPreferredTagName(jsdoc, {
940
+ ...args,
941
+ context,
942
+ mode,
943
+ report,
944
+ tagNamePreference
945
+ });
946
+ };
947
+ /** @type {IsValidTag} */
948
+ utils.isValidTag = (name, definedTags) => {
949
+ return isValidTag(context, mode, name, definedTags);
950
+ };
951
+ /** @type {HasATag} */
952
+ utils.hasATag = (names) => {
953
+ return hasATag(jsdoc, names);
954
+ };
955
+ /** @type {HasTag} */
956
+ utils.hasTag = (name) => {
957
+ return hasTag(jsdoc, name);
958
+ };
959
+ /** @type {ComparePaths} */
960
+ utils.comparePaths = (name) => {
961
+ return comparePaths(name);
962
+ };
963
+ /** @type {DropPathSegmentQuotes} */
964
+ utils.dropPathSegmentQuotes = (name) => {
965
+ return dropPathSegmentQuotes(name);
966
+ };
967
+ /** @type {AvoidDocs} */
968
+ utils.avoidDocs = () => {
969
+ if (ignoreReplacesDocs !== false && (utils.hasTag("ignore") || utils.classHasTag("ignore")) || overrideReplacesDocs !== false && (utils.hasTag("override") || utils.classHasTag("override")) || implementsReplacesDocs !== false && (utils.hasTag("implements") || utils.classHasTag("implements")) || augmentsExtendsReplacesDocs && (utils.hasATag(["augments", "extends"]) || utils.classHasTag("augments") || utils.classHasTag("extends"))) return true;
970
+ if (exemptSpeciaMethods(jsdoc, node, context, ruleConfig.meta.schema)) return true;
971
+ const exemptedBy = context.options[0]?.exemptedBy ?? ["inheritDoc", ...mode === "closure" ? [] : ["inheritdoc"]];
972
+ if (exemptedBy.length && utils.getPresentTags(exemptedBy).length) return true;
973
+ return false;
974
+ };
975
+ for (const method of ["tagMightHaveNamePosition", "tagMightHaveTypePosition"])
976
+ /** @type {TagMightHaveNamePositionTypePosition} */
977
+ utils[method] = (tagName, otherModeMaps) => {
978
+ const result = jsdocUtils_exports[method](tagName);
979
+ if (result) return true;
980
+ if (!otherModeMaps) return false;
981
+ const otherResult = otherModeMaps.some((otherModeMap) => {
982
+ return jsdocUtils_exports[method](tagName, otherModeMap);
983
+ });
984
+ return otherResult ? { otherMode: true } : false;
985
+ };
986
+ /** @type {TagMissingRequiredTypeOrNamepath} */
987
+ utils.tagMissingRequiredTypeOrNamepath = (tagName, otherModeMaps) => {
988
+ const result = tagMissingRequiredTypeOrNamepath(tagName);
989
+ if (!result) return false;
990
+ const otherResult = otherModeMaps.every((otherModeMap) => {
991
+ return tagMissingRequiredTypeOrNamepath(tagName, otherModeMap);
992
+ });
993
+ return otherResult ? true : { otherMode: false };
994
+ };
995
+ for (const method of ["tagMustHaveNamePosition", "tagMustHaveTypePosition"])
996
+ /** @type {TagMustHave} */
997
+ utils[method] = (tagName, otherModeMaps) => {
998
+ const result = jsdocUtils_exports[method](tagName);
999
+ if (!result) return false;
1000
+ const otherResult = otherModeMaps.every((otherModeMap) => {
1001
+ return jsdocUtils_exports[method](tagName, otherModeMap);
1002
+ });
1003
+ return otherResult ? true : { otherMode: false };
1004
+ };
1005
+ for (const method of [
1006
+ "isNamepathDefiningTag",
1007
+ "isNamepathReferencingTag",
1008
+ "isNamepathOrUrlReferencingTag",
1009
+ "tagMightHaveNamepath"
1010
+ ])
1011
+ /** @type {IsNamepathX} */
1012
+ utils[method] = (tagName) => {
1013
+ return jsdocUtils_exports[method](tagName);
1014
+ };
1015
+ /** @type {GetTagStructureForMode} */
1016
+ utils.getTagStructureForMode = (mde) => {
1017
+ return getTagStructureForMode(mde, settings.structuredTags);
1018
+ };
1019
+ /** @type {MayBeUndefinedTypeTag} */
1020
+ utils.mayBeUndefinedTypeTag = (tag) => {
1021
+ return mayBeUndefinedTypeTag(tag, settings.mode);
1022
+ };
1023
+ /** @type {HasValueOrExecutorHasNonEmptyResolveValue} */
1024
+ utils.hasValueOrExecutorHasNonEmptyResolveValue = (anyPromiseAsReturn, allBranches) => {
1025
+ return hasValueOrExecutorHasNonEmptyResolveValue(node, anyPromiseAsReturn, allBranches);
1026
+ };
1027
+ /** @type {HasYieldValue} */
1028
+ utils.hasYieldValue = () => {
1029
+ if (["ExportDefaultDeclaration", "ExportNamedDeclaration"].includes(
1030
+ /** @type {Node} */
1031
+ node.type
1032
+ )) return hasYieldValue(
1033
+ /** @type {import('estree').ExportNamedDeclaration|import('estree').ExportDefaultDeclaration} */
1034
+ node.declaration
1035
+ );
1036
+ return hasYieldValue(node);
1037
+ };
1038
+ /** @type {HasYieldReturnValue} */
1039
+ utils.hasYieldReturnValue = () => {
1040
+ return hasYieldValue(node, true);
1041
+ };
1042
+ /** @type {HasThrowValue} */
1043
+ utils.hasThrowValue = () => {
1044
+ return hasThrowValue(node);
1045
+ };
1046
+ /** @type {IsAsync} */
1047
+ utils.isAsync = () => {
1048
+ return Boolean(node && "async" in node && node.async);
1049
+ };
1050
+ /** @type {GetTags} */
1051
+ utils.getTags = (tagName) => {
1052
+ return getTags(jsdoc, tagName);
1053
+ };
1054
+ /** @type {GetPresentTags} */
1055
+ utils.getPresentTags = (tagList) => {
1056
+ return filterTags(jsdoc, (tag) => {
1057
+ return tagList.includes(tag.tag);
1058
+ });
1059
+ };
1060
+ /** @type {FilterTags} */
1061
+ utils.filterTags = (filter) => {
1062
+ return filterTags(jsdoc, (tag) => {
1063
+ return filter(tag);
1064
+ });
1065
+ };
1066
+ /** @type {FilterAllTags} */
1067
+ utils.filterAllTags = (filter) => {
1068
+ const tags = getAllTags(jsdoc);
1069
+ return tags.filter((tag) => {
1070
+ return filter(tag);
1071
+ });
1072
+ };
1073
+ /** @type {GetTagsByType} */
1074
+ utils.getTagsByType = (tags) => {
1075
+ return getTagsByType(context, mode, tags);
1076
+ };
1077
+ /** @type {HasOptionTag} */
1078
+ utils.hasOptionTag = (tagName) => {
1079
+ const { tags } = context.options[0] ?? {};
1080
+ return Boolean(tags && tags.includes(tagName));
1081
+ };
1082
+ /** @type {GetClassNode} */
1083
+ utils.getClassNode = () => {
1084
+ return [...ancestors, node].reverse().find((parent) => {
1085
+ return parent && ["ClassDeclaration", "ClassExpression"].includes(parent.type);
1086
+ }) ?? null;
1087
+ };
1088
+ /** @type {GetClassJsdoc} */
1089
+ utils.getClassJsdoc = () => {
1090
+ const classNode = utils.getClassNode();
1091
+ if (!classNode) return null;
1092
+ const classJsdocNode = getJSDocComment(sourceCode, classNode, {
1093
+ maxLines,
1094
+ minLines
1095
+ });
1096
+ if (classJsdocNode) return parseComment$1(classJsdocNode, "");
1097
+ return null;
1098
+ };
1099
+ /** @type {ClassHasTag} */
1100
+ utils.classHasTag = (tagName) => {
1101
+ const classJsdoc = utils.getClassJsdoc();
1102
+ return classJsdoc !== null && hasTag(classJsdoc, tagName);
1103
+ };
1104
+ /** @type {ForEachPreferredTag} */
1105
+ utils.forEachPreferredTag = (tagName, arrayHandler, skipReportingBlockedTag) => {
1106
+ return forEachPreferredTag(jsdoc, tagName, arrayHandler, {
1107
+ context,
1108
+ mode,
1109
+ report,
1110
+ skipReportingBlockedTag,
1111
+ tagNamePreference
1112
+ });
1113
+ };
1114
+ /** @type {FindContext} */
1115
+ utils.findContext = (contexts, comment) => {
1116
+ const foundContext = contexts.find((cntxt) => {
1117
+ return typeof cntxt === "string" ? esquery.matches(node, esquery.parse(cntxt), void 0, { visitorKeys: sourceCode.visitorKeys }) : (!cntxt.context || cntxt.context === "any" || esquery.matches(node, esquery.parse(cntxt.context), void 0, { visitorKeys: sourceCode.visitorKeys })) && comment === cntxt.comment;
1118
+ });
1119
+ const contextStr = typeof foundContext === "object" ? foundContext.context ?? "any" : String(foundContext);
1120
+ return {
1121
+ contextStr,
1122
+ foundContext
1123
+ };
1124
+ };
1125
+ return utils;
1126
+ };
1127
+ /**
1128
+ * @typedef {{
1129
+ * [key: string]: false|string|{
1130
+ * message: string,
1131
+ * replacement?: false|string
1132
+ * skipRootChecking?: boolean
1133
+ * }
1134
+ * }} PreferredTypes
1135
+ */
1136
+ /**
1137
+ * @typedef {{
1138
+ * [key: string]: {
1139
+ * name?: "text"|"namepath-defining"|"namepath-referencing"|false,
1140
+ * type?: boolean|string[],
1141
+ * required?: ("name"|"type"|"typeOrNameRequired")[]
1142
+ * }
1143
+ * }} StructuredTags
1144
+ */
1145
+ /**
1146
+ * Settings from ESLint types.
1147
+ * @typedef {{
1148
+ * maxLines: Integer,
1149
+ * minLines: Integer,
1150
+ * tagNamePreference: import('./jsdocUtils.js').TagNamePreference,
1151
+ * mode: import('./jsdocUtils.js').ParserMode,
1152
+ * preferredTypes: PreferredTypes,
1153
+ * structuredTags: StructuredTags,
1154
+ * [name: string]: any,
1155
+ * contexts?: Context[]
1156
+ * }} Settings
1157
+ */
1158
+ /**
1159
+ * @typedef {{
1160
+ * settings?: {
1161
+ * jsdoc?: {
1162
+ * ignorePrivate: boolean,
1163
+ * ignoreInternal: boolean,
1164
+ * maxLines: Integer,
1165
+ * minLines: Integer,
1166
+ * tagNamePreference: import('./jsdocUtils.js').TagNamePreference,
1167
+ * preferredTypes: PreferredTypes,
1168
+ * structuredTags: StructuredTags,
1169
+ * overrideReplacesDocs: boolean,
1170
+ * ignoreReplacesDocs: boolean,
1171
+ * implementsReplacesDocs: boolean,
1172
+ * augmentsExtendsReplacesDocs: boolean,
1173
+ * exemptDestructuredRootsFromChecks: boolean,
1174
+ * mode: import('./jsdocUtils.js').ParserMode,
1175
+ * contexts: Context[],
1176
+ * }
1177
+ * }
1178
+ * }} JSDocSettings
1179
+ */
1180
+ /**
1181
+ * @param {import('eslint').Rule.RuleContext & JSDocSettings} context
1182
+ * @returns {Settings|false}
1183
+ */
1184
+ const getSettings = (context) => {
1185
+ const settings = {
1186
+ ignorePrivate: Boolean(context.settings.jsdoc?.ignorePrivate),
1187
+ ignoreInternal: Boolean(context.settings.jsdoc?.ignoreInternal),
1188
+ maxLines: Number(context.settings.jsdoc?.maxLines ?? 1),
1189
+ minLines: Number(context.settings.jsdoc?.minLines ?? 0),
1190
+ tagNamePreference: context.settings.jsdoc?.tagNamePreference ?? {},
1191
+ preferredTypes: context.settings.jsdoc?.preferredTypes ?? {},
1192
+ structuredTags: context.settings.jsdoc?.structuredTags ?? {},
1193
+ overrideReplacesDocs: context.settings.jsdoc?.overrideReplacesDocs,
1194
+ ignoreReplacesDocs: context.settings.jsdoc?.ignoreReplacesDocs,
1195
+ implementsReplacesDocs: context.settings.jsdoc?.implementsReplacesDocs,
1196
+ augmentsExtendsReplacesDocs: context.settings.jsdoc?.augmentsExtendsReplacesDocs,
1197
+ exemptDestructuredRootsFromChecks: context.settings.jsdoc?.exemptDestructuredRootsFromChecks,
1198
+ mode: context.settings.jsdoc?.mode ?? "typescript",
1199
+ contexts: context.settings.jsdoc?.contexts
1200
+ };
1201
+ setTagStructure(settings.mode);
1202
+ try {
1203
+ overrideTagStructure(settings.structuredTags);
1204
+ } catch (error) {
1205
+ context.report({
1206
+ loc: {
1207
+ end: {
1208
+ column: 1,
1209
+ line: 1
1210
+ },
1211
+ start: {
1212
+ column: 1,
1213
+ line: 1
1214
+ }
1215
+ },
1216
+ message: error.message
1217
+ });
1218
+ return false;
1219
+ }
1220
+ return settings;
1221
+ };
1222
+ /**
1223
+ * Create the report function
1224
+ * @callback MakeReport
1225
+ * @param {import('eslint').Rule.RuleContext} context
1226
+ * @param {import('estree').Node} commentNode
1227
+ * @returns {Report}
1228
+ */
1229
+ /** @type {MakeReport} */
1230
+ const makeReport = (context, commentNode) => {
1231
+ /** @type {Report} */
1232
+ const report = (message, fix = null, jsdocLoc = null, data = void 0) => {
1233
+ let loc;
1234
+ if (jsdocLoc) {
1235
+ if (!("line" in jsdocLoc)) jsdocLoc.line = jsdocLoc.source[0].number;
1236
+ const lineNumber = commentNode.loc.start.line + jsdocLoc.line;
1237
+ loc = {
1238
+ end: {
1239
+ column: 0,
1240
+ line: lineNumber
1241
+ },
1242
+ start: {
1243
+ column: 0,
1244
+ line: lineNumber
1245
+ }
1246
+ };
1247
+ if ("column" in jsdocLoc && typeof jsdocLoc.column === "number") {
1248
+ const colNumber = commentNode.loc.start.column + jsdocLoc.column;
1249
+ loc.end.column = colNumber;
1250
+ loc.start.column = colNumber;
1251
+ }
1252
+ }
1253
+ context.report({
1254
+ data,
1255
+ fix,
1256
+ loc,
1257
+ message,
1258
+ node: commentNode
1259
+ });
1260
+ };
1261
+ return report;
1262
+ };
1263
+ /**
1264
+ * @typedef {(
1265
+ * arg: {
1266
+ * context: import('eslint').Rule.RuleContext,
1267
+ * sourceCode: import('eslint').SourceCode,
1268
+ * indent?: string,
1269
+ * info?: {
1270
+ * comment?: string|undefined,
1271
+ * lastIndex?: Integer|undefined
1272
+ * },
1273
+ * state?: StateObject,
1274
+ * globalState?: Map<string, Map<string, string>>,
1275
+ * jsdoc?: JsdocBlockWithInline,
1276
+ * jsdocNode?: import('eslint').Rule.Node & {
1277
+ * range: [number, number]
1278
+ * },
1279
+ * node?: Node,
1280
+ * allComments?: import('estree').Node[]
1281
+ * report?: Report,
1282
+ * makeReport?: MakeReport,
1283
+ * settings: Settings,
1284
+ * utils: BasicUtils,
1285
+ * }
1286
+ * ) => any } JsdocVisitorBasic
1287
+ */
1288
+ /**
1289
+ * @typedef {(
1290
+ * arg: {
1291
+ * context: import('eslint').Rule.RuleContext,
1292
+ * sourceCode: import('eslint').SourceCode,
1293
+ * indent: string,
1294
+ * info: {
1295
+ * comment?: string|undefined,
1296
+ * lastIndex?: Integer|undefined
1297
+ * },
1298
+ * state: StateObject,
1299
+ * globalState: Map<string, Map<string, string>>,
1300
+ * jsdoc: JsdocBlockWithInline,
1301
+ * jsdocNode: import('eslint').Rule.Node & {
1302
+ * range: [number, number]
1303
+ * },
1304
+ * node: Node|null,
1305
+ * allComments?: import('estree').Node[]
1306
+ * report: Report,
1307
+ * makeReport?: MakeReport,
1308
+ * settings: Settings,
1309
+ * utils: Utils,
1310
+ * }
1311
+ * ) => any } JsdocVisitor
1312
+ */
1313
+ /**
1314
+ * @param {{
1315
+ * comment?: string,
1316
+ * lastIndex?: Integer,
1317
+ * selector?: string,
1318
+ * isFunctionContext?: boolean,
1319
+ * }} info
1320
+ * @param {string} indent
1321
+ * @param {JsdocBlockWithInline} jsdoc
1322
+ * @param {RuleConfig} ruleConfig
1323
+ * @param {import('eslint').Rule.RuleContext} context
1324
+ * @param {import('@es-joy/jsdoccomment').Token} jsdocNode
1325
+ * @param {Node|null} node
1326
+ * @param {Settings} settings
1327
+ * @param {import('eslint').SourceCode} sourceCode
1328
+ * @param {JsdocVisitor} iterator
1329
+ * @param {StateObject} state
1330
+ * @param {boolean} [iteratingAll]
1331
+ * @returns {void}
1332
+ */
1333
+ const iterate = (info, indent, jsdoc, ruleConfig, context, jsdocNode, node, settings, sourceCode, iterator, state, iteratingAll) => {
1334
+ const jsdocNde = jsdocNode;
1335
+ const report = makeReport(context, jsdocNde);
1336
+ const utils = getUtils(node, jsdoc, jsdocNode, settings, report, context, sourceCode, iteratingAll, ruleConfig, indent);
1337
+ if (!ruleConfig.checkInternal && settings.ignoreInternal && utils.hasTag("internal")) return;
1338
+ if (!ruleConfig.checkPrivate && settings.ignorePrivate && (utils.hasTag("private") || filterTags(jsdoc, ({ tag }) => {
1339
+ return tag === "access";
1340
+ }).some(({ description }) => {
1341
+ return description === "private";
1342
+ }))) return;
1343
+ iterator({
1344
+ context,
1345
+ globalState,
1346
+ indent,
1347
+ info,
1348
+ jsdoc,
1349
+ jsdocNode: jsdocNde,
1350
+ node,
1351
+ report,
1352
+ settings,
1353
+ sourceCode,
1354
+ state,
1355
+ utils
1356
+ });
1357
+ };
1358
+ /**
1359
+ * @param {string[]} lines
1360
+ * @param {import('estree').Comment} jsdocNode
1361
+ * @returns {[indent: string, jsdoc: JsdocBlockWithInline]}
1362
+ */
1363
+ const getIndentAndJSDoc = function(lines, jsdocNode) {
1364
+ const sourceLine = lines[jsdocNode.loc.start.line - 1];
1365
+ let indentChar = sourceLine.charAt(0);
1366
+ if (indentChar !== " " && indentChar !== " ") indentChar = " ";
1367
+ const indnt = indentChar.repeat(
1368
+ /** @type {import('estree').SourceLocation} */
1369
+ jsdocNode.loc.start.column
1370
+ );
1371
+ const jsdc = parseComment$1(jsdocNode, "");
1372
+ return [indnt, jsdc];
1373
+ };
1374
+ /**
1375
+ *
1376
+ * @typedef {{node: Node & {
1377
+ * range: [number, number]
1378
+ * }, state: StateObject}} NonCommentArgs
1379
+ */
1380
+ /**
1381
+ * @typedef {object} RuleConfig
1382
+ * @property {EslintRuleMeta} meta ESLint rule meta
1383
+ * @property {import('./jsdocUtils.js').DefaultContexts} [contextDefaults] Any default contexts
1384
+ * @property {true} [contextSelected] Whether to force a `contexts` check
1385
+ * @property {true} [iterateAllJsdocs] Whether to iterate all JSDoc blocks by default
1386
+ * regardless of context
1387
+ * @property {true} [checkPrivate] Whether to check `@private` blocks (normally exempted)
1388
+ * @property {true} [checkInternal] Whether to check `@internal` blocks (normally exempted)
1389
+ * @property {true} [checkFile] Whether to iterates over all JSDoc blocks regardless of attachment
1390
+ * @property {true} [nonGlobalSettings] Whether to avoid relying on settings for global contexts
1391
+ * @property {true} [noTracking] Whether to disable the tracking of visited comment nodes (as
1392
+ * non-tracked may conduct further actions)
1393
+ * @property {true} [matchContext] Whether the rule expects contexts to be based on a match option
1394
+ * @property {(args: {
1395
+ * context: import('eslint').Rule.RuleContext,
1396
+ * state: StateObject,
1397
+ * settings: Settings,
1398
+ * utils: BasicUtils
1399
+ * }) => void} [exit] Handler to be executed upon exiting iteration of program AST
1400
+ * @property {(nca: NonCommentArgs) => void} [nonComment] Handler to be executed if rule wishes
1401
+ * to be supplied nodes without comments
1402
+ */
1403
+ /**
1404
+ * Create an eslint rule that iterates over all JSDocs, regardless of whether
1405
+ * they are attached to a function-like node.
1406
+ * @param {JsdocVisitor} iterator
1407
+ * @param {RuleConfig} ruleConfig The rule's configuration
1408
+ * @param {ContextObject[]|null} [contexts] The `contexts` containing relevant `comment` info.
1409
+ * @param {boolean} [additiveCommentContexts] If true, will have a separate
1410
+ * iteration for each matching comment context. Otherwise, will iterate
1411
+ * once if there is a single matching comment context.
1412
+ * @returns {import('eslint').Rule.RuleModule}
1413
+ */
1414
+ const iterateAllJsdocs = (iterator, ruleConfig, contexts, additiveCommentContexts) => {
1415
+ const trackedJsdocs = /* @__PURE__ */ new Set();
1416
+ /** @type {import('@es-joy/jsdoccomment').CommentHandler} */
1417
+ let handler;
1418
+ /** @type {Settings|false} */
1419
+ let settings;
1420
+ /**
1421
+ * @param {import('eslint').Rule.RuleContext} context
1422
+ * @param {Node|null} node
1423
+ * @param {import('estree').Comment[]} jsdocNodes
1424
+ * @param {StateObject} state
1425
+ * @param {boolean} [lastCall]
1426
+ * @returns {void}
1427
+ */
1428
+ const callIterator = (context, node, jsdocNodes, state, lastCall) => {
1429
+ /* c8 ignore next -- Fallback to deprecated method */
1430
+ const { sourceCode = context.getSourceCode() } = context;
1431
+ const { lines } = sourceCode;
1432
+ const utils = getBasicUtils(context, settings);
1433
+ for (const jsdocNode of jsdocNodes) {
1434
+ const jsdocNde = jsdocNode;
1435
+ if (!/^\/\*\*\s/v.test(sourceCode.getText(jsdocNde))) continue;
1436
+ const [indent, jsdoc] = getIndentAndJSDoc(lines, jsdocNode);
1437
+ if (additiveCommentContexts) {
1438
+ for (const [idx, { comment }] of contexts.entries()) {
1439
+ if (comment && handler(comment, jsdoc) === false) continue;
1440
+ iterate({
1441
+ comment,
1442
+ lastIndex: idx,
1443
+ selector: node?.type
1444
+ }, indent, jsdoc, ruleConfig, context, jsdocNode, node, settings, sourceCode, iterator, state, true);
1445
+ }
1446
+ continue;
1447
+ }
1448
+ let lastComment;
1449
+ let lastIndex;
1450
+ if (contexts && contexts.every(({ comment }, idx) => {
1451
+ lastComment = comment;
1452
+ lastIndex = idx;
1453
+ return comment && handler(comment, jsdoc) === false;
1454
+ })) continue;
1455
+ iterate(lastComment ? {
1456
+ comment: lastComment,
1457
+ lastIndex,
1458
+ selector: node?.type
1459
+ } : {
1460
+ lastIndex,
1461
+ selector: node?.type
1462
+ }, indent, jsdoc, ruleConfig, context, jsdocNode, node, settings, sourceCode, iterator, state, true);
1463
+ }
1464
+ const settngs = settings;
1465
+ if (lastCall && ruleConfig.exit) ruleConfig.exit({
1466
+ context,
1467
+ settings: settngs,
1468
+ state,
1469
+ utils
1470
+ });
1471
+ };
1472
+ return {
1473
+ create(context) {
1474
+ /* c8 ignore next -- Fallback to deprecated method */
1475
+ const { sourceCode = context.getSourceCode() } = context;
1476
+ settings = getSettings(context);
1477
+ if (!settings) return {};
1478
+ if (contexts) handler = commentHandler(settings);
1479
+ const state = {};
1480
+ return {
1481
+ "*:not(Program)"(node) {
1482
+ const commentNode = getJSDocComment(sourceCode, node, settings);
1483
+ if (!ruleConfig.noTracking && trackedJsdocs.has(commentNode)) return;
1484
+ if (!commentNode) {
1485
+ if (ruleConfig.nonComment) {
1486
+ const ste = state;
1487
+ ruleConfig.nonComment({
1488
+ node,
1489
+ state: ste
1490
+ });
1491
+ }
1492
+ return;
1493
+ }
1494
+ trackedJsdocs.add(commentNode);
1495
+ callIterator(context, node, [commentNode], state);
1496
+ },
1497
+ "Program:exit"() {
1498
+ const allComments = sourceCode.getAllComments();
1499
+ const untrackedJSdoc = allComments.filter((node) => {
1500
+ return !trackedJsdocs.has(node);
1501
+ });
1502
+ callIterator(context, null, untrackedJSdoc, state, true);
1503
+ }
1504
+ };
1505
+ },
1506
+ meta: ruleConfig.meta
1507
+ };
1508
+ };
1509
+ /**
1510
+ * Create an eslint rule that iterates over all JSDocs, regardless of whether
1511
+ * they are attached to a function-like node.
1512
+ * @param {JsdocVisitorBasic} iterator
1513
+ * @param {RuleConfig} ruleConfig
1514
+ * @returns {import('eslint').Rule.RuleModule}
1515
+ */
1516
+ const checkFile = (iterator, ruleConfig) => {
1517
+ return {
1518
+ create(context) {
1519
+ /* c8 ignore next -- Fallback to deprecated method */
1520
+ const { sourceCode = context.getSourceCode() } = context;
1521
+ const settings = getSettings(context);
1522
+ if (!settings) return {};
1523
+ return { "Program:exit"() {
1524
+ const allComms = sourceCode.getAllComments();
1525
+ const utils = getBasicUtils(context, settings);
1526
+ iterator({
1527
+ allComments: allComms,
1528
+ context,
1529
+ makeReport,
1530
+ settings,
1531
+ sourceCode,
1532
+ utils
1533
+ });
1534
+ } };
1535
+ },
1536
+ meta: ruleConfig.meta
1537
+ };
1538
+ };
1539
+ /**
1540
+ * @param {JsdocVisitor} iterator
1541
+ * @param {RuleConfig} ruleConfig
1542
+ * @returns {import('eslint').Rule.RuleModule}
1543
+ */
1544
+ function iterateJsdoc(iterator, ruleConfig) {
1545
+ const metaType = ruleConfig?.meta?.type;
1546
+ if (!metaType || ![
1547
+ "layout",
1548
+ "problem",
1549
+ "suggestion"
1550
+ ].includes(metaType)) throw new TypeError("Rule must include `meta.type` option (with value \"problem\", \"suggestion\", or \"layout\")");
1551
+ if (typeof iterator !== "function") throw new TypeError("The iterator argument must be a function.");
1552
+ if (ruleConfig.checkFile) return checkFile(iterator, ruleConfig);
1553
+ if (ruleConfig.iterateAllJsdocs) return iterateAllJsdocs(iterator, ruleConfig);
1554
+ /** @type {import('eslint').Rule.RuleModule} */
1555
+ return {
1556
+ create(context) {
1557
+ const settings = getSettings(context);
1558
+ if (!settings) return {};
1559
+ /**
1560
+ * @type {Context[]|undefined}
1561
+ */
1562
+ let contexts;
1563
+ if (ruleConfig.contextDefaults || ruleConfig.contextSelected || ruleConfig.matchContext) {
1564
+ contexts = ruleConfig.matchContext && context.options[0]?.match ? context.options[0].match : enforcedContexts(context, ruleConfig.contextDefaults, ruleConfig.nonGlobalSettings ? {} : settings);
1565
+ if (contexts) contexts = contexts.map((obj) => {
1566
+ if (typeof obj === "object" && !obj.context) return {
1567
+ ...obj,
1568
+ context: "any"
1569
+ };
1570
+ return obj;
1571
+ });
1572
+ const hasPlainAny = contexts?.includes("any");
1573
+ const hasObjectAny = !hasPlainAny && contexts?.find((ctxt) => {
1574
+ if (typeof ctxt === "string") return false;
1575
+ return ctxt?.context === "any";
1576
+ });
1577
+ if (hasPlainAny || hasObjectAny) return iterateAllJsdocs(iterator, ruleConfig, hasObjectAny ? contexts : null, ruleConfig.matchContext).create(context);
1578
+ }
1579
+ /* c8 ignore next -- Fallback to deprecated method */
1580
+ const { sourceCode = context.getSourceCode() } = context;
1581
+ const { lines } = sourceCode;
1582
+ /** @type {Partial<StateObject>} */
1583
+ const state = {};
1584
+ /** @type {CheckJsdoc} */
1585
+ const checkJsdoc = (info, handler, node) => {
1586
+ const jsdocNode = getJSDocComment(sourceCode, node, settings);
1587
+ if (!jsdocNode) return;
1588
+ const [indent, jsdoc] = getIndentAndJSDoc(lines, jsdocNode);
1589
+ if (handler && handler(jsdoc) === false) return;
1590
+ iterate(info, indent, jsdoc, ruleConfig, context, jsdocNode, node, settings, sourceCode, iterator, state);
1591
+ };
1592
+ /** @type {import('eslint').Rule.RuleListener} */
1593
+ let contextObject = {};
1594
+ if (contexts && (ruleConfig.contextDefaults || ruleConfig.contextSelected || ruleConfig.matchContext)) contextObject = getContextObject(contexts, checkJsdoc, commentHandler(settings));
1595
+ else for (const prop of [
1596
+ "ArrowFunctionExpression",
1597
+ "FunctionDeclaration",
1598
+ "FunctionExpression",
1599
+ "TSDeclareFunction"
1600
+ ]) contextObject[prop] = checkJsdoc.bind(null, { selector: prop }, null);
1601
+ if (typeof ruleConfig.exit === "function") contextObject["Program:exit"] = () => {
1602
+ const ste = state;
1603
+ /** @type {Required<RuleConfig>} */ ruleConfig.exit({
1604
+ context,
1605
+ settings,
1606
+ state: ste
1607
+ });
1608
+ };
1609
+ return contextObject;
1610
+ },
1611
+ meta: ruleConfig.meta
1612
+ };
1613
+ }
1614
+
1615
+ //#endregion
1616
+ export { iterateJsdoc as default, getSettings, parseComment };
1617
+ //# sourceMappingURL=iterateJsdoc.js.map