@depup/eslint-plugin-jsdoc 62.8.0-depup.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (430) hide show
  1. package/LICENSE +24 -0
  2. package/README.md +33 -0
  3. package/changes.json +18 -0
  4. package/dist/WarnSettings.cjs +38 -0
  5. package/dist/WarnSettings.cjs.map +1 -0
  6. package/dist/WarnSettings.d.ts +17 -0
  7. package/dist/alignTransform.cjs +402 -0
  8. package/dist/alignTransform.cjs.map +1 -0
  9. package/dist/alignTransform.d.ts +34 -0
  10. package/dist/buildForbidRuleDefinition.cjs +101 -0
  11. package/dist/buildForbidRuleDefinition.cjs.map +1 -0
  12. package/dist/buildForbidRuleDefinition.d.ts +15 -0
  13. package/dist/buildRejectOrPreferRuleDefinition.cjs +352 -0
  14. package/dist/buildRejectOrPreferRuleDefinition.cjs.map +1 -0
  15. package/dist/buildRejectOrPreferRuleDefinition.d.ts +9 -0
  16. package/dist/cjs/WarnSettings.d.ts +16 -0
  17. package/dist/cjs/alignTransform.d.ts +33 -0
  18. package/dist/cjs/buildForbidRuleDefinition.d.ts +14 -0
  19. package/dist/cjs/buildRejectOrPreferRuleDefinition.d.ts +8 -0
  20. package/dist/cjs/defaultTagOrder.d.ts +4 -0
  21. package/dist/cjs/exportParser.d.ts +40 -0
  22. package/dist/cjs/getDefaultTagStructureForMode.d.ts +10 -0
  23. package/dist/cjs/getJsdocProcessorPlugin.d.cts +5 -0
  24. package/dist/cjs/getJsdocProcessorPlugin.d.ts +66 -0
  25. package/dist/cjs/index-cjs.d.ts +23 -0
  26. package/dist/cjs/index.cjs.d.cts +2 -0
  27. package/dist/cjs/iterateJsdoc.d.cts +7 -0
  28. package/dist/cjs/iterateJsdoc.d.ts +495 -0
  29. package/dist/cjs/jsdocUtils.d.ts +493 -0
  30. package/dist/cjs/rules/checkAccess.d.ts +2 -0
  31. package/dist/cjs/rules/checkAlignment.d.ts +2 -0
  32. package/dist/cjs/rules/checkExamples.d.ts +3 -0
  33. package/dist/cjs/rules/checkIndentation.d.ts +2 -0
  34. package/dist/cjs/rules/checkLineAlignment.d.ts +9 -0
  35. package/dist/cjs/rules/checkParamNames.d.ts +2 -0
  36. package/dist/cjs/rules/checkPropertyNames.d.ts +2 -0
  37. package/dist/cjs/rules/checkSyntax.d.ts +2 -0
  38. package/dist/cjs/rules/checkTagNames.d.ts +2 -0
  39. package/dist/cjs/rules/checkTemplateNames.d.ts +2 -0
  40. package/dist/cjs/rules/checkTypes.d.ts +7 -0
  41. package/dist/cjs/rules/checkValues.d.ts +2 -0
  42. package/dist/cjs/rules/convertToJsdocComments.d.ts +266 -0
  43. package/dist/cjs/rules/emptyTags.d.ts +2 -0
  44. package/dist/cjs/rules/escapeInlineTags.d.ts +2 -0
  45. package/dist/cjs/rules/implementsOnClasses.d.ts +2 -0
  46. package/dist/cjs/rules/importsAsDependencies.d.ts +2 -0
  47. package/dist/cjs/rules/informativeDocs.d.ts +2 -0
  48. package/dist/cjs/rules/linesBeforeBlock.d.ts +2 -0
  49. package/dist/cjs/rules/matchDescription.d.ts +2 -0
  50. package/dist/cjs/rules/matchName.d.ts +2 -0
  51. package/dist/cjs/rules/multilineBlocks.d.ts +2 -0
  52. package/dist/cjs/rules/noBadBlocks.d.ts +2 -0
  53. package/dist/cjs/rules/noBlankBlockDescriptions.d.ts +2 -0
  54. package/dist/cjs/rules/noBlankBlocks.d.ts +2 -0
  55. package/dist/cjs/rules/noDefaults.d.ts +2 -0
  56. package/dist/cjs/rules/noMissingSyntax.d.ts +9 -0
  57. package/dist/cjs/rules/noMultiAsterisks.d.ts +2 -0
  58. package/dist/cjs/rules/noRestrictedSyntax.d.ts +2 -0
  59. package/dist/cjs/rules/noTypes.d.ts +2 -0
  60. package/dist/cjs/rules/noUndefinedTypes.d.ts +2 -0
  61. package/dist/cjs/rules/preferImportTag.d.ts +2 -0
  62. package/dist/cjs/rules/requireAsteriskPrefix.d.ts +2 -0
  63. package/dist/cjs/rules/requireDescription.d.ts +2 -0
  64. package/dist/cjs/rules/requireDescriptionCompleteSentence.d.ts +2 -0
  65. package/dist/cjs/rules/requireExample.d.ts +2 -0
  66. package/dist/cjs/rules/requireFileOverview.d.ts +2 -0
  67. package/dist/cjs/rules/requireHyphenBeforeParamDescription.d.ts +2 -0
  68. package/dist/cjs/rules/requireJsdoc.d.ts +24 -0
  69. package/dist/cjs/rules/requireParam.d.ts +3 -0
  70. package/dist/cjs/rules/requireParamDescription.d.ts +2 -0
  71. package/dist/cjs/rules/requireParamName.d.ts +2 -0
  72. package/dist/cjs/rules/requireParamType.d.ts +2 -0
  73. package/dist/cjs/rules/requireProperty.d.ts +2 -0
  74. package/dist/cjs/rules/requirePropertyDescription.d.ts +2 -0
  75. package/dist/cjs/rules/requirePropertyName.d.ts +2 -0
  76. package/dist/cjs/rules/requirePropertyType.d.ts +2 -0
  77. package/dist/cjs/rules/requireRejects.d.ts +2 -0
  78. package/dist/cjs/rules/requireReturns.d.ts +2 -0
  79. package/dist/cjs/rules/requireReturnsCheck.d.ts +2 -0
  80. package/dist/cjs/rules/requireReturnsDescription.d.ts +2 -0
  81. package/dist/cjs/rules/requireReturnsType.d.ts +2 -0
  82. package/dist/cjs/rules/requireTags.d.ts +2 -0
  83. package/dist/cjs/rules/requireTemplate.d.ts +2 -0
  84. package/dist/cjs/rules/requireThrows.d.ts +2 -0
  85. package/dist/cjs/rules/requireYields.d.ts +2 -0
  86. package/dist/cjs/rules/requireYieldsCheck.d.ts +2 -0
  87. package/dist/cjs/rules/sortTags.d.ts +2 -0
  88. package/dist/cjs/rules/tagLines.d.ts +2 -0
  89. package/dist/cjs/rules/textEscaping.d.ts +2 -0
  90. package/dist/cjs/rules/tsMethodSignatureStyle.d.ts +2 -0
  91. package/dist/cjs/rules/tsNoEmptyObjectType.d.ts +2 -0
  92. package/dist/cjs/rules/tsNoUnnecessaryTemplateExpression.d.ts +2 -0
  93. package/dist/cjs/rules/tsPreferFunctionType.d.ts +2 -0
  94. package/dist/cjs/rules/typeFormatting.d.ts +2 -0
  95. package/dist/cjs/rules/validTypes.d.ts +2 -0
  96. package/dist/cjs/tagNames.d.ts +15 -0
  97. package/dist/cjs/utils/hasReturnValue.d.ts +19 -0
  98. package/dist/defaultTagOrder.cjs +46 -0
  99. package/dist/defaultTagOrder.cjs.map +1 -0
  100. package/dist/defaultTagOrder.d.ts +5 -0
  101. package/dist/exportParser.cjs +732 -0
  102. package/dist/exportParser.cjs.map +1 -0
  103. package/dist/exportParser.d.ts +41 -0
  104. package/dist/generateDocs.cjs +342 -0
  105. package/dist/generateDocs.cjs.map +1 -0
  106. package/dist/generateOptions.cjs +62 -0
  107. package/dist/generateOptions.cjs.map +1 -0
  108. package/dist/generateRule.cjs +248 -0
  109. package/dist/generateRule.cjs.map +1 -0
  110. package/dist/generateRuleTypes.cjs +24 -0
  111. package/dist/generateRuleTypes.cjs.map +1 -0
  112. package/dist/getDefaultTagStructureForMode.cjs +289 -0
  113. package/dist/getDefaultTagStructureForMode.cjs.map +1 -0
  114. package/dist/getDefaultTagStructureForMode.d.ts +11 -0
  115. package/dist/getJsdocProcessorPlugin.cjs +587 -0
  116. package/dist/getJsdocProcessorPlugin.cjs.map +1 -0
  117. package/dist/getJsdocProcessorPlugin.cts +5 -0
  118. package/dist/getJsdocProcessorPlugin.d.ts +67 -0
  119. package/dist/index-cjs.cjs +595 -0
  120. package/dist/index-cjs.cjs.map +1 -0
  121. package/dist/index-cjs.d.ts +24 -0
  122. package/dist/index-esm.cjs +162 -0
  123. package/dist/index-esm.cjs.map +1 -0
  124. package/dist/index-esm.d.ts +72 -0
  125. package/dist/index.cjs +743 -0
  126. package/dist/index.cjs.cts +3 -0
  127. package/dist/index.cjs.map +1 -0
  128. package/dist/index.d.ts +93 -0
  129. package/dist/iterateJsdoc.cjs +2150 -0
  130. package/dist/iterateJsdoc.cjs.map +1 -0
  131. package/dist/iterateJsdoc.cts +7 -0
  132. package/dist/iterateJsdoc.d.ts +496 -0
  133. package/dist/jsdocUtils.cjs +1725 -0
  134. package/dist/jsdocUtils.cjs.map +1 -0
  135. package/dist/jsdocUtils.d.ts +494 -0
  136. package/dist/rules/checkAccess.cjs +40 -0
  137. package/dist/rules/checkAccess.cjs.map +1 -0
  138. package/dist/rules/checkAccess.d.ts +3 -0
  139. package/dist/rules/checkAlignment.cjs +78 -0
  140. package/dist/rules/checkAlignment.cjs.map +1 -0
  141. package/dist/rules/checkAlignment.d.ts +3 -0
  142. package/dist/rules/checkExamples.cjs +521 -0
  143. package/dist/rules/checkExamples.cjs.map +1 -0
  144. package/dist/rules/checkExamples.d.ts +4 -0
  145. package/dist/rules/checkIndentation.cjs +170 -0
  146. package/dist/rules/checkIndentation.cjs.map +1 -0
  147. package/dist/rules/checkIndentation.d.ts +3 -0
  148. package/dist/rules/checkLineAlignment.cjs +398 -0
  149. package/dist/rules/checkLineAlignment.cjs.map +1 -0
  150. package/dist/rules/checkLineAlignment.d.ts +10 -0
  151. package/dist/rules/checkParamNames.cjs +407 -0
  152. package/dist/rules/checkParamNames.cjs.map +1 -0
  153. package/dist/rules/checkParamNames.d.ts +3 -0
  154. package/dist/rules/checkPropertyNames.cjs +135 -0
  155. package/dist/rules/checkPropertyNames.cjs.map +1 -0
  156. package/dist/rules/checkPropertyNames.d.ts +3 -0
  157. package/dist/rules/checkSyntax.cjs +38 -0
  158. package/dist/rules/checkSyntax.cjs.map +1 -0
  159. package/dist/rules/checkSyntax.d.ts +3 -0
  160. package/dist/rules/checkTagNames.cjs +312 -0
  161. package/dist/rules/checkTagNames.cjs.map +1 -0
  162. package/dist/rules/checkTagNames.d.ts +3 -0
  163. package/dist/rules/checkTemplateNames.cjs +185 -0
  164. package/dist/rules/checkTemplateNames.cjs.map +1 -0
  165. package/dist/rules/checkTemplateNames.d.ts +3 -0
  166. package/dist/rules/checkTypes.cjs +111 -0
  167. package/dist/rules/checkTypes.cjs.map +1 -0
  168. package/dist/rules/checkTypes.d.ts +8 -0
  169. package/dist/rules/checkValues.cjs +166 -0
  170. package/dist/rules/checkValues.cjs.map +1 -0
  171. package/dist/rules/checkValues.d.ts +3 -0
  172. package/dist/rules/convertToJsdocComments.cjs +356 -0
  173. package/dist/rules/convertToJsdocComments.cjs.map +1 -0
  174. package/dist/rules/convertToJsdocComments.d.ts +267 -0
  175. package/dist/rules/emptyTags.cjs +85 -0
  176. package/dist/rules/emptyTags.cjs.map +1 -0
  177. package/dist/rules/emptyTags.d.ts +3 -0
  178. package/dist/rules/escapeInlineTags.cjs +149 -0
  179. package/dist/rules/escapeInlineTags.cjs.map +1 -0
  180. package/dist/rules/escapeInlineTags.d.ts +3 -0
  181. package/dist/rules/implementsOnClasses.cjs +74 -0
  182. package/dist/rules/implementsOnClasses.cjs.map +1 -0
  183. package/dist/rules/implementsOnClasses.d.ts +3 -0
  184. package/dist/rules/importsAsDependencies.cjs +104 -0
  185. package/dist/rules/importsAsDependencies.cjs.map +1 -0
  186. package/dist/rules/importsAsDependencies.d.ts +3 -0
  187. package/dist/rules/informativeDocs.cjs +187 -0
  188. package/dist/rules/informativeDocs.cjs.map +1 -0
  189. package/dist/rules/informativeDocs.d.ts +3 -0
  190. package/dist/rules/linesBeforeBlock.cjs +120 -0
  191. package/dist/rules/linesBeforeBlock.cjs.map +1 -0
  192. package/dist/rules/linesBeforeBlock.d.ts +3 -0
  193. package/dist/rules/matchDescription.cjs +356 -0
  194. package/dist/rules/matchDescription.cjs.map +1 -0
  195. package/dist/rules/matchDescription.d.ts +3 -0
  196. package/dist/rules/matchName.cjs +160 -0
  197. package/dist/rules/matchName.cjs.map +1 -0
  198. package/dist/rules/matchName.d.ts +3 -0
  199. package/dist/rules/multilineBlocks.cjs +431 -0
  200. package/dist/rules/multilineBlocks.cjs.map +1 -0
  201. package/dist/rules/multilineBlocks.d.ts +3 -0
  202. package/dist/rules/noBadBlocks.cjs +100 -0
  203. package/dist/rules/noBadBlocks.cjs.map +1 -0
  204. package/dist/rules/noBadBlocks.d.ts +3 -0
  205. package/dist/rules/noBlankBlockDescriptions.cjs +63 -0
  206. package/dist/rules/noBlankBlockDescriptions.cjs.map +1 -0
  207. package/dist/rules/noBlankBlockDescriptions.d.ts +3 -0
  208. package/dist/rules/noBlankBlocks.cjs +54 -0
  209. package/dist/rules/noBlankBlocks.cjs.map +1 -0
  210. package/dist/rules/noBlankBlocks.d.ts +3 -0
  211. package/dist/rules/noDefaults.cjs +102 -0
  212. package/dist/rules/noDefaults.cjs.map +1 -0
  213. package/dist/rules/noDefaults.d.ts +3 -0
  214. package/dist/rules/noMissingSyntax.cjs +196 -0
  215. package/dist/rules/noMissingSyntax.cjs.map +1 -0
  216. package/dist/rules/noMissingSyntax.d.ts +10 -0
  217. package/dist/rules/noMultiAsterisks.cjs +126 -0
  218. package/dist/rules/noMultiAsterisks.cjs.map +1 -0
  219. package/dist/rules/noMultiAsterisks.d.ts +3 -0
  220. package/dist/rules/noRestrictedSyntax.cjs +68 -0
  221. package/dist/rules/noRestrictedSyntax.cjs.map +1 -0
  222. package/dist/rules/noRestrictedSyntax.d.ts +3 -0
  223. package/dist/rules/noTypes.cjs +101 -0
  224. package/dist/rules/noTypes.cjs.map +1 -0
  225. package/dist/rules/noTypes.d.ts +3 -0
  226. package/dist/rules/noUndefinedTypes.cjs +588 -0
  227. package/dist/rules/noUndefinedTypes.cjs.map +1 -0
  228. package/dist/rules/noUndefinedTypes.d.ts +3 -0
  229. package/dist/rules/preferImportTag.cjs +362 -0
  230. package/dist/rules/preferImportTag.cjs.map +1 -0
  231. package/dist/rules/preferImportTag.d.ts +3 -0
  232. package/dist/rules/requireAsteriskPrefix.cjs +190 -0
  233. package/dist/rules/requireAsteriskPrefix.cjs.map +1 -0
  234. package/dist/rules/requireAsteriskPrefix.d.ts +3 -0
  235. package/dist/rules/requireDescription.cjs +164 -0
  236. package/dist/rules/requireDescription.cjs.map +1 -0
  237. package/dist/rules/requireDescription.d.ts +3 -0
  238. package/dist/rules/requireDescriptionCompleteSentence.cjs +321 -0
  239. package/dist/rules/requireDescriptionCompleteSentence.cjs.map +1 -0
  240. package/dist/rules/requireDescriptionCompleteSentence.d.ts +3 -0
  241. package/dist/rules/requireExample.cjs +133 -0
  242. package/dist/rules/requireExample.cjs.map +1 -0
  243. package/dist/rules/requireExample.d.ts +3 -0
  244. package/dist/rules/requireFileOverview.cjs +194 -0
  245. package/dist/rules/requireFileOverview.cjs.map +1 -0
  246. package/dist/rules/requireFileOverview.d.ts +3 -0
  247. package/dist/rules/requireHyphenBeforeParamDescription.cjs +166 -0
  248. package/dist/rules/requireHyphenBeforeParamDescription.cjs.map +1 -0
  249. package/dist/rules/requireHyphenBeforeParamDescription.d.ts +3 -0
  250. package/dist/rules/requireJsdoc.cjs +722 -0
  251. package/dist/rules/requireJsdoc.cjs.map +1 -0
  252. package/dist/rules/requireJsdoc.d.ts +25 -0
  253. package/dist/rules/requireParam.cjs +772 -0
  254. package/dist/rules/requireParam.cjs.map +1 -0
  255. package/dist/rules/requireParam.d.ts +4 -0
  256. package/dist/rules/requireParamDescription.cjs +105 -0
  257. package/dist/rules/requireParamDescription.cjs.map +1 -0
  258. package/dist/rules/requireParamDescription.d.ts +3 -0
  259. package/dist/rules/requireParamName.cjs +68 -0
  260. package/dist/rules/requireParamName.cjs.map +1 -0
  261. package/dist/rules/requireParamName.d.ts +3 -0
  262. package/dist/rules/requireParamType.cjs +104 -0
  263. package/dist/rules/requireParamType.cjs.map +1 -0
  264. package/dist/rules/requireParamType.d.ts +3 -0
  265. package/dist/rules/requireProperty.cjs +63 -0
  266. package/dist/rules/requireProperty.cjs.map +1 -0
  267. package/dist/rules/requireProperty.d.ts +3 -0
  268. package/dist/rules/requirePropertyDescription.cjs +29 -0
  269. package/dist/rules/requirePropertyDescription.cjs.map +1 -0
  270. package/dist/rules/requirePropertyDescription.d.ts +3 -0
  271. package/dist/rules/requirePropertyName.cjs +29 -0
  272. package/dist/rules/requirePropertyName.cjs.map +1 -0
  273. package/dist/rules/requirePropertyName.d.ts +3 -0
  274. package/dist/rules/requirePropertyType.cjs +29 -0
  275. package/dist/rules/requirePropertyType.cjs.map +1 -0
  276. package/dist/rules/requirePropertyType.d.ts +3 -0
  277. package/dist/rules/requireRejects.cjs +226 -0
  278. package/dist/rules/requireRejects.cjs.map +1 -0
  279. package/dist/rules/requireRejects.d.ts +3 -0
  280. package/dist/rules/requireReturns.cjs +262 -0
  281. package/dist/rules/requireReturns.cjs.map +1 -0
  282. package/dist/rules/requireReturns.d.ts +3 -0
  283. package/dist/rules/requireReturnsCheck.cjs +140 -0
  284. package/dist/rules/requireReturnsCheck.cjs.map +1 -0
  285. package/dist/rules/requireReturnsCheck.d.ts +3 -0
  286. package/dist/rules/requireReturnsDescription.cjs +72 -0
  287. package/dist/rules/requireReturnsDescription.cjs.map +1 -0
  288. package/dist/rules/requireReturnsDescription.d.ts +3 -0
  289. package/dist/rules/requireReturnsType.cjs +68 -0
  290. package/dist/rules/requireReturnsType.cjs.map +1 -0
  291. package/dist/rules/requireReturnsType.d.ts +3 -0
  292. package/dist/rules/requireTags.cjs +74 -0
  293. package/dist/rules/requireTags.cjs.map +1 -0
  294. package/dist/rules/requireTags.d.ts +3 -0
  295. package/dist/rules/requireTemplate.cjs +220 -0
  296. package/dist/rules/requireTemplate.cjs.map +1 -0
  297. package/dist/rules/requireTemplate.d.ts +3 -0
  298. package/dist/rules/requireThrows.cjs +118 -0
  299. package/dist/rules/requireThrows.cjs.map +1 -0
  300. package/dist/rules/requireThrows.d.ts +3 -0
  301. package/dist/rules/requireYields.cjs +224 -0
  302. package/dist/rules/requireYields.cjs.map +1 -0
  303. package/dist/rules/requireYields.d.ts +3 -0
  304. package/dist/rules/requireYieldsCheck.cjs +179 -0
  305. package/dist/rules/requireYieldsCheck.cjs.map +1 -0
  306. package/dist/rules/requireYieldsCheck.d.ts +3 -0
  307. package/dist/rules/sortTags.cjs +656 -0
  308. package/dist/rules/sortTags.cjs.map +1 -0
  309. package/dist/rules/sortTags.d.ts +3 -0
  310. package/dist/rules/tagLines.cjs +374 -0
  311. package/dist/rules/tagLines.cjs.map +1 -0
  312. package/dist/rules/tagLines.d.ts +3 -0
  313. package/dist/rules/textEscaping.cjs +141 -0
  314. package/dist/rules/textEscaping.cjs.map +1 -0
  315. package/dist/rules/textEscaping.d.ts +3 -0
  316. package/dist/rules/tsMethodSignatureStyle.cjs +240 -0
  317. package/dist/rules/tsMethodSignatureStyle.cjs.map +1 -0
  318. package/dist/rules/tsMethodSignatureStyle.d.ts +3 -0
  319. package/dist/rules/tsNoEmptyObjectType.cjs +62 -0
  320. package/dist/rules/tsNoEmptyObjectType.cjs.map +1 -0
  321. package/dist/rules/tsNoEmptyObjectType.d.ts +3 -0
  322. package/dist/rules/tsNoUnnecessaryTemplateExpression.cjs +104 -0
  323. package/dist/rules/tsNoUnnecessaryTemplateExpression.cjs.map +1 -0
  324. package/dist/rules/tsNoUnnecessaryTemplateExpression.d.ts +3 -0
  325. package/dist/rules/tsPreferFunctionType.cjs +110 -0
  326. package/dist/rules/tsPreferFunctionType.cjs.map +1 -0
  327. package/dist/rules/tsPreferFunctionType.d.ts +3 -0
  328. package/dist/rules/typeFormatting.cjs +607 -0
  329. package/dist/rules/typeFormatting.cjs.map +1 -0
  330. package/dist/rules/typeFormatting.d.ts +3 -0
  331. package/dist/rules/validTypes.cjs +328 -0
  332. package/dist/rules/validTypes.cjs.map +1 -0
  333. package/dist/rules/validTypes.d.ts +3 -0
  334. package/dist/rules.d.ts +3203 -0
  335. package/dist/tagNames.cjs +244 -0
  336. package/dist/tagNames.cjs.map +1 -0
  337. package/dist/tagNames.d.ts +16 -0
  338. package/dist/to-valid-identifier.cjs +263 -0
  339. package/dist/utils/hasReturnValue.cjs +495 -0
  340. package/dist/utils/hasReturnValue.cjs.map +1 -0
  341. package/dist/utils/hasReturnValue.d.ts +20 -0
  342. package/package.json +220 -0
  343. package/rollup.config.js +16 -0
  344. package/src/WarnSettings.js +34 -0
  345. package/src/alignTransform.js +444 -0
  346. package/src/buildForbidRuleDefinition.js +106 -0
  347. package/src/buildRejectOrPreferRuleDefinition.js +481 -0
  348. package/src/defaultTagOrder.js +169 -0
  349. package/src/exportParser.js +973 -0
  350. package/src/getDefaultTagStructureForMode.js +968 -0
  351. package/src/getJsdocProcessorPlugin.cts +5 -0
  352. package/src/getJsdocProcessorPlugin.js +692 -0
  353. package/src/index-cjs.js +755 -0
  354. package/src/index-esm.js +196 -0
  355. package/src/index.cjs.cts +3 -0
  356. package/src/index.js +940 -0
  357. package/src/iterateJsdoc.cts +7 -0
  358. package/src/iterateJsdoc.js +2612 -0
  359. package/src/jsdocUtils.js +2158 -0
  360. package/src/rules/checkAccess.js +45 -0
  361. package/src/rules/checkAlignment.js +82 -0
  362. package/src/rules/checkExamples.js +613 -0
  363. package/src/rules/checkIndentation.js +176 -0
  364. package/src/rules/checkLineAlignment.js +453 -0
  365. package/src/rules/checkParamNames.js +541 -0
  366. package/src/rules/checkPropertyNames.js +174 -0
  367. package/src/rules/checkSyntax.js +30 -0
  368. package/src/rules/checkTagNames.js +414 -0
  369. package/src/rules/checkTemplateNames.js +208 -0
  370. package/src/rules/checkTypes.js +130 -0
  371. package/src/rules/checkValues.js +264 -0
  372. package/src/rules/convertToJsdocComments.js +444 -0
  373. package/src/rules/emptyTags.js +106 -0
  374. package/src/rules/escapeInlineTags.js +189 -0
  375. package/src/rules/implementsOnClasses.js +78 -0
  376. package/src/rules/importsAsDependencies.js +132 -0
  377. package/src/rules/informativeDocs.js +228 -0
  378. package/src/rules/linesBeforeBlock.js +144 -0
  379. package/src/rules/matchDescription.js +413 -0
  380. package/src/rules/matchName.js +179 -0
  381. package/src/rules/multilineBlocks.js +562 -0
  382. package/src/rules/noBadBlocks.js +127 -0
  383. package/src/rules/noBlankBlockDescriptions.js +69 -0
  384. package/src/rules/noBlankBlocks.js +55 -0
  385. package/src/rules/noDefaults.js +104 -0
  386. package/src/rules/noMissingSyntax.js +215 -0
  387. package/src/rules/noMultiAsterisks.js +162 -0
  388. package/src/rules/noRestrictedSyntax.js +72 -0
  389. package/src/rules/noTypes.js +108 -0
  390. package/src/rules/noUndefinedTypes.js +797 -0
  391. package/src/rules/preferImportTag.js +521 -0
  392. package/src/rules/requireAsteriskPrefix.js +217 -0
  393. package/src/rules/requireDescription.js +190 -0
  394. package/src/rules/requireDescriptionCompleteSentence.js +376 -0
  395. package/src/rules/requireExample.js +143 -0
  396. package/src/rules/requireFileOverview.js +213 -0
  397. package/src/rules/requireHyphenBeforeParamDescription.js +210 -0
  398. package/src/rules/requireJsdoc.js +897 -0
  399. package/src/rules/requireParam.js +848 -0
  400. package/src/rules/requireParamDescription.js +110 -0
  401. package/src/rules/requireParamName.js +69 -0
  402. package/src/rules/requireParamType.js +109 -0
  403. package/src/rules/requireProperty.js +66 -0
  404. package/src/rules/requirePropertyDescription.js +25 -0
  405. package/src/rules/requirePropertyName.js +25 -0
  406. package/src/rules/requirePropertyType.js +25 -0
  407. package/src/rules/requireRejects.js +246 -0
  408. package/src/rules/requireReturns.js +291 -0
  409. package/src/rules/requireReturnsCheck.js +180 -0
  410. package/src/rules/requireReturnsDescription.js +73 -0
  411. package/src/rules/requireReturnsType.js +65 -0
  412. package/src/rules/requireTags.js +85 -0
  413. package/src/rules/requireTemplate.js +246 -0
  414. package/src/rules/requireThrows.js +128 -0
  415. package/src/rules/requireYields.js +265 -0
  416. package/src/rules/requireYieldsCheck.js +226 -0
  417. package/src/rules/sortTags.js +766 -0
  418. package/src/rules/tagLines.js +486 -0
  419. package/src/rules/textEscaping.js +158 -0
  420. package/src/rules/tsMethodSignatureStyle.js +300 -0
  421. package/src/rules/tsNoEmptyObjectType.js +61 -0
  422. package/src/rules/tsNoUnnecessaryTemplateExpression.js +130 -0
  423. package/src/rules/tsPreferFunctionType.js +127 -0
  424. package/src/rules/typeFormatting.js +690 -0
  425. package/src/rules/validTypes.js +466 -0
  426. package/src/rules.d.ts +3203 -0
  427. package/src/tagNames.js +301 -0
  428. package/src/utils/hasReturnValue.js +572 -0
  429. package/typings/babel__eslint-parser.d.ts +1 -0
  430. package/typings/gitdown.d.ts +16 -0
@@ -0,0 +1,2158 @@
1
+ import getDefaultTagStructureForMode from './getDefaultTagStructureForMode.js';
2
+ import {
3
+ closureTags,
4
+ jsdocTags,
5
+ typeScriptTags,
6
+ } from './tagNames.js';
7
+ import WarnSettings from './WarnSettings.js';
8
+ import {
9
+ stringify,
10
+ tryParse,
11
+ } from '@es-joy/jsdoccomment';
12
+
13
+ /**
14
+ * @typedef {number} Integer
15
+ */
16
+ /**
17
+ * @typedef {import('./utils/hasReturnValue.js').ESTreeOrTypeScriptNode} ESTreeOrTypeScriptNode
18
+ */
19
+
20
+ /**
21
+ * @typedef {"jsdoc"|"typescript"|"closure"|"permissive"} ParserMode
22
+ */
23
+
24
+ /**
25
+ * @type {import('./getDefaultTagStructureForMode.js').TagStructure}
26
+ */
27
+ let tagStructure;
28
+
29
+ /**
30
+ * @param {ParserMode} mode
31
+ * @returns {void}
32
+ */
33
+ const setTagStructure = (mode) => {
34
+ tagStructure = getDefaultTagStructureForMode(mode);
35
+ };
36
+
37
+ /**
38
+ * @typedef {undefined|string|{
39
+ * name: Integer,
40
+ * restElement: boolean
41
+ * }|{
42
+ * isRestProperty: boolean|undefined,
43
+ * name: string,
44
+ * restElement: boolean
45
+ * }|{
46
+ * name: string,
47
+ * restElement: boolean
48
+ * }} ParamCommon
49
+ */
50
+ /**
51
+ * @typedef {ParamCommon|[string|undefined, (FlattendRootInfo & {
52
+ * annotationParamName?: string,
53
+ * })]|NestedParamInfo} ParamNameInfo
54
+ */
55
+
56
+ /**
57
+ * @typedef {{
58
+ * hasPropertyRest: boolean,
59
+ * hasRestElement: boolean,
60
+ * names: string[],
61
+ * rests: boolean[],
62
+ * }} FlattendRootInfo
63
+ */
64
+ /**
65
+ * @typedef {[string, (string[]|ParamInfo[])]} NestedParamInfo
66
+ */
67
+ /**
68
+ * @typedef {ParamCommon|
69
+ * [string|undefined, (FlattendRootInfo & {
70
+ * annotationParamName?: string
71
+ * })]|
72
+ * NestedParamInfo} ParamInfo
73
+ */
74
+
75
+ /**
76
+ * Given a nested array of property names, reduce them to a single array,
77
+ * appending the name of the root element along the way if present.
78
+ * @callback FlattenRoots
79
+ * @param {ParamInfo[]} params
80
+ * @param {string} [root]
81
+ * @returns {FlattendRootInfo}
82
+ */
83
+
84
+ /** @type {FlattenRoots} */
85
+ const flattenRoots = (params, root = '') => {
86
+ let hasRestElement = false;
87
+ let hasPropertyRest = false;
88
+
89
+ /**
90
+ * @type {boolean[]}
91
+ */
92
+ const rests = [];
93
+
94
+ const names = params.reduce(
95
+ /**
96
+ * @param {string[]} acc
97
+ * @param {ParamInfo} cur
98
+ * @returns {string[]}
99
+ */
100
+ (acc, cur) => {
101
+ if (Array.isArray(cur)) {
102
+ let nms;
103
+ if (Array.isArray(cur[1])) {
104
+ nms = cur[1];
105
+ } else {
106
+ if (cur[1].hasRestElement) {
107
+ hasRestElement = true;
108
+ }
109
+
110
+ if (cur[1].hasPropertyRest) {
111
+ hasPropertyRest = true;
112
+ }
113
+
114
+ nms = cur[1].names;
115
+ }
116
+
117
+ const flattened = flattenRoots(nms, root ? `${root}.${cur[0]}` : cur[0]);
118
+ if (flattened.hasRestElement) {
119
+ hasRestElement = true;
120
+ }
121
+
122
+ if (flattened.hasPropertyRest) {
123
+ hasPropertyRest = true;
124
+ }
125
+
126
+ const inner = /** @type {string[]} */ ([
127
+ root ? `${root}.${cur[0]}` : cur[0],
128
+ ...flattened.names,
129
+ ].filter(Boolean));
130
+ rests.push(false, ...flattened.rests);
131
+
132
+ return acc.concat(inner);
133
+ }
134
+
135
+ if (typeof cur === 'object') {
136
+ if ('isRestProperty' in cur && cur.isRestProperty) {
137
+ hasPropertyRest = true;
138
+ rests.push(true);
139
+ } else {
140
+ rests.push(false);
141
+ }
142
+
143
+ if ('restElement' in cur && cur.restElement) {
144
+ hasRestElement = true;
145
+ }
146
+
147
+ acc.push(root ? `${root}.${String(cur.name)}` : String(cur.name));
148
+ } else if (typeof cur !== 'undefined') {
149
+ rests.push(false);
150
+ acc.push(root ? `${root}.${cur}` : cur);
151
+ }
152
+
153
+ return acc;
154
+ }, [],
155
+ );
156
+
157
+ return {
158
+ hasPropertyRest,
159
+ hasRestElement,
160
+ names,
161
+ rests,
162
+ };
163
+ };
164
+
165
+ /**
166
+ * @param {import('@typescript-eslint/types').TSESTree.TSIndexSignature|
167
+ * import('@typescript-eslint/types').TSESTree.TSConstructSignatureDeclaration|
168
+ * import('@typescript-eslint/types').TSESTree.TSCallSignatureDeclaration|
169
+ * import('@typescript-eslint/types').TSESTree.TSPropertySignature} propSignature
170
+ * @returns {undefined|string|[string, string[]]}
171
+ */
172
+ const getPropertiesFromPropertySignature = (propSignature) => {
173
+ if (
174
+ propSignature.type === 'TSIndexSignature' ||
175
+ propSignature.type === 'TSConstructSignatureDeclaration' ||
176
+ propSignature.type === 'TSCallSignatureDeclaration'
177
+ ) {
178
+ return undefined;
179
+ }
180
+
181
+ if (propSignature.typeAnnotation && propSignature.typeAnnotation.typeAnnotation.type === 'TSTypeLiteral') {
182
+ return [
183
+ /** @type {import('@typescript-eslint/types').TSESTree.Identifier} */ (
184
+ propSignature.key
185
+ ).name,
186
+ propSignature.typeAnnotation.typeAnnotation.members.map((member) => {
187
+ return /** @type {string} */ (
188
+ getPropertiesFromPropertySignature(
189
+ /** @type {import('@typescript-eslint/types').TSESTree.TSPropertySignature} */ (
190
+ member
191
+ ),
192
+ )
193
+ );
194
+ }),
195
+ ];
196
+ }
197
+
198
+ return /** @type {import('@typescript-eslint/types').TSESTree.Identifier} */ (
199
+ propSignature.key
200
+ ).name;
201
+ };
202
+
203
+ /**
204
+ * @param {ESTreeOrTypeScriptNode|null} functionNode
205
+ * @param {boolean} [checkDefaultObjects]
206
+ * @param {boolean} [ignoreInterfacedParameters]
207
+ * @throws {Error}
208
+ * @returns {ParamNameInfo[]}
209
+ */
210
+ const getFunctionParameterNames = (
211
+ functionNode, checkDefaultObjects, ignoreInterfacedParameters,
212
+ ) => {
213
+ /* eslint-disable complexity -- Temporary */
214
+ /**
215
+ * @param {import('estree').Identifier|import('estree').AssignmentPattern|
216
+ * import('estree').ObjectPattern|import('estree').Property|
217
+ * import('estree').RestElement|import('estree').ArrayPattern|
218
+ * import('@typescript-eslint/types').TSESTree.TSParameterProperty|
219
+ * import('@typescript-eslint/types').TSESTree.Property|
220
+ * import('@typescript-eslint/types').TSESTree.RestElement|
221
+ * import('@typescript-eslint/types').TSESTree.Identifier|
222
+ * import('@typescript-eslint/types').TSESTree.ObjectPattern|
223
+ * import('@typescript-eslint/types').TSESTree.BindingName|
224
+ * import('@typescript-eslint/types').TSESTree.Parameter
225
+ * } param
226
+ * @param {boolean} [isProperty]
227
+ * @returns {ParamNameInfo|[string, ParamNameInfo[]]}
228
+ */
229
+ const getParamName = (param, isProperty) => {
230
+ /* eslint-enable complexity -- Temporary */
231
+ const hasLeftTypeAnnotation = 'left' in param && 'typeAnnotation' in param.left;
232
+
233
+ if ('typeAnnotation' in param || hasLeftTypeAnnotation) {
234
+ if (ignoreInterfacedParameters && 'typeAnnotation' in param &&
235
+ param.typeAnnotation) {
236
+ // No-op
237
+ return [
238
+ undefined, {
239
+ hasPropertyRest: false,
240
+ hasRestElement: false,
241
+ names: [],
242
+ rests: [],
243
+ },
244
+ ];
245
+ }
246
+
247
+ const typeAnnotation = hasLeftTypeAnnotation ?
248
+ /** @type {import('@typescript-eslint/types').TSESTree.Identifier} */ (
249
+ param.left
250
+ ).typeAnnotation :
251
+ /** @type {import('@typescript-eslint/types').TSESTree.Identifier|import('@typescript-eslint/types').TSESTree.ObjectPattern} */
252
+ (param).typeAnnotation;
253
+
254
+ if (typeAnnotation?.typeAnnotation?.type === 'TSTypeLiteral') {
255
+ const propertyNames = typeAnnotation.typeAnnotation.members.map((member) => {
256
+ return getPropertiesFromPropertySignature(
257
+ /** @type {import('@typescript-eslint/types').TSESTree.TSPropertySignature} */
258
+ (member),
259
+ );
260
+ });
261
+
262
+ const flattened = {
263
+ ...flattenRoots(propertyNames),
264
+ annotationParamName: 'name' in param ? param.name : undefined,
265
+ };
266
+ const hasLeftName = 'left' in param && 'name' in param.left;
267
+
268
+ if ('name' in param || hasLeftName) {
269
+ return [
270
+ hasLeftName ?
271
+ /** @type {import('@typescript-eslint/types').TSESTree.Identifier} */ (
272
+ param.left
273
+ ).name :
274
+ /** @type {import('@typescript-eslint/types').TSESTree.Identifier} */ (
275
+ param
276
+ ).name,
277
+ flattened,
278
+ ];
279
+ }
280
+
281
+ return [
282
+ undefined, flattened,
283
+ ];
284
+ }
285
+ }
286
+
287
+ if ('name' in param) {
288
+ return param.name;
289
+ }
290
+
291
+ if ('left' in param && 'name' in param.left) {
292
+ return param.left.name;
293
+ }
294
+
295
+ if (
296
+ param.type === 'ObjectPattern' ||
297
+ ('left' in param &&
298
+ (
299
+ param
300
+ ).left.type === 'ObjectPattern')
301
+ ) {
302
+ const properties = /** @type {import('@typescript-eslint/types').TSESTree.ObjectPattern} */ (
303
+ param
304
+ ).properties ||
305
+ /** @type {import('estree').ObjectPattern} */
306
+ (
307
+ /** @type {import('@typescript-eslint/types').TSESTree.AssignmentPattern} */ (
308
+ param
309
+ ).left
310
+ )?.properties;
311
+ const roots = properties.map((prop) => {
312
+ return getParamName(prop, true);
313
+ });
314
+
315
+ return [
316
+ undefined, flattenRoots(roots),
317
+ ];
318
+ }
319
+
320
+ if (param.type === 'Property') {
321
+ switch (param.value.type) {
322
+ case 'ArrayPattern': {
323
+ return [
324
+ /** @type {import('estree').Identifier} */
325
+ (param.key).name,
326
+ /** @type {import('estree').ArrayPattern} */ (
327
+ param.value
328
+ ).elements.map((prop, idx) => {
329
+ return {
330
+ name: idx,
331
+ restElement: prop?.type === 'RestElement',
332
+ };
333
+ }),
334
+ ];
335
+ }
336
+
337
+ case 'ObjectPattern': {
338
+ return [
339
+ /** @type {import('estree').Identifier} */ (param.key).name,
340
+ /** @type {import('estree').ObjectPattern} */ (
341
+ param.value
342
+ ).properties.map((prop) => {
343
+ return /** @type {string|[string, string[]]} */ (getParamName(prop, isProperty));
344
+ }),
345
+ ];
346
+ }
347
+
348
+ case 'AssignmentPattern': {
349
+ switch (param.value.left.type) {
350
+ case 'ArrayPattern':
351
+ return [
352
+ /** @type {import('estree').Identifier} */
353
+ (param.key).name,
354
+ /** @type {import('estree').ArrayPattern} */ (
355
+ param.value.left
356
+ ).elements.map((prop, idx) => {
357
+ return {
358
+ name: idx,
359
+ restElement: prop?.type === 'RestElement',
360
+ };
361
+ }),
362
+ ];
363
+ case 'Identifier':
364
+ // Default parameter
365
+ if (checkDefaultObjects && param.value.right.type === 'ObjectExpression') {
366
+ return [
367
+ /** @type {import('estree').Identifier} */ (
368
+ param.key
369
+ ).name,
370
+ /** @type {import('estree').AssignmentPattern} */ (
371
+ param.value
372
+ ).right.properties.map((prop) => {
373
+ return /** @type {string} */ (getParamName(
374
+ /** @type {import('estree').Property} */
375
+ (prop),
376
+ isProperty,
377
+ ));
378
+ }),
379
+ ];
380
+ }
381
+
382
+ break;
383
+ case 'ObjectPattern':
384
+ return [
385
+ /** @type {import('estree').Identifier} */
386
+ (param.key).name,
387
+ /** @type {import('estree').ObjectPattern} */ (
388
+ param.value.left
389
+ ).properties.map((prop) => {
390
+ return getParamName(prop, isProperty);
391
+ }),
392
+ ];
393
+ }
394
+ }
395
+ }
396
+
397
+ switch (param.key.type) {
398
+ case 'Identifier':
399
+ return param.key.name;
400
+
401
+ // The key of an object could also be a string or number
402
+ case 'Literal':
403
+ /* c8 ignore next 2 -- `raw` may not be present in all parsers */
404
+ return /** @type {string} */ (param.key.raw ||
405
+ param.key.value);
406
+
407
+ // case 'MemberExpression':
408
+ default:
409
+ // Todo: We should really create a structure (and a corresponding
410
+ // option analogous to `checkRestProperty`) which allows for
411
+ // (and optionally requires) dynamic properties to have a single
412
+ // line of documentation
413
+ return undefined;
414
+ }
415
+ }
416
+
417
+ if (
418
+ param.type === 'ArrayPattern' ||
419
+ /** @type {import('estree').AssignmentPattern} */ (
420
+ param
421
+ ).left?.type === 'ArrayPattern'
422
+ ) {
423
+ const elements = /** @type {import('estree').ArrayPattern} */ (
424
+ param
425
+ ).elements || /** @type {import('estree').ArrayPattern} */ (
426
+ /** @type {import('estree').AssignmentPattern} */ (
427
+ param
428
+ ).left
429
+ )?.elements;
430
+ const roots = elements.map((prop, idx) => {
431
+ return {
432
+ name: `"${idx}"`,
433
+ restElement: prop?.type === 'RestElement',
434
+ };
435
+ });
436
+
437
+ return [
438
+ undefined, flattenRoots(roots),
439
+ ];
440
+ }
441
+
442
+ if ([
443
+ 'ExperimentalRestProperty', 'RestElement',
444
+ ].includes(param.type)) {
445
+ return {
446
+ isRestProperty: isProperty,
447
+ name: /** @type {import('@typescript-eslint/types').TSESTree.Identifier} */ (
448
+ /** @type {import('@typescript-eslint/types').TSESTree.RestElement} */ (
449
+ param
450
+ // @ts-expect-error Ok
451
+ ).argument).name ?? param?.argument?.elements?.map(({
452
+ // @ts-expect-error Ok
453
+ name,
454
+ }) => {
455
+ return name;
456
+ }),
457
+ restElement: true,
458
+ };
459
+ }
460
+
461
+ if (param.type === 'TSParameterProperty') {
462
+ return getParamName(
463
+ /** @type {import('@typescript-eslint/types').TSESTree.Identifier} */ (
464
+ /** @type {import('@typescript-eslint/types').TSESTree.TSParameterProperty} */ (
465
+ param
466
+ ).parameter
467
+ ),
468
+ true,
469
+ );
470
+ }
471
+
472
+ throw new Error(`Unsupported function signature format: \`${param.type}\`.`);
473
+ };
474
+
475
+ if (!functionNode) {
476
+ return [];
477
+ }
478
+
479
+ return (
480
+ /** @type {import('@typescript-eslint/types').TSESTree.TSFunctionType} */
481
+ (/** @type {import('@typescript-eslint/types').TSESTree.TSPropertySignature} */ (functionNode)?.typeAnnotation?.typeAnnotation)?.params ||
482
+ /** @type {import('@typescript-eslint/types').TSESTree.FunctionDeclaration} */ (
483
+ functionNode
484
+ ).params || /** @type {import('@typescript-eslint/types').TSESTree.MethodDefinition} */ (
485
+ functionNode
486
+ ).value?.params || []).map((param) => {
487
+ return getParamName(param);
488
+ });
489
+ };
490
+
491
+ /**
492
+ * @param {ESTreeOrTypeScriptNode} functionNode
493
+ * @returns {Integer}
494
+ */
495
+ const hasParams = (functionNode) => {
496
+ // Should also check `functionNode.value.params` if supporting `MethodDefinition`
497
+ return /** @type {import('@typescript-eslint/types').TSESTree.FunctionDeclaration} */ (
498
+ functionNode
499
+ ).params.length;
500
+ };
501
+
502
+ /**
503
+ * Gets all names of the target type, including those that refer to a path, e.g.
504
+ * `foo` or `foo.bar`.
505
+ * @param {import('comment-parser').Block} jsdoc
506
+ * @param {string} targetTagName
507
+ * @returns {{
508
+ * idx: Integer,
509
+ * name: string,
510
+ * type: string
511
+ * }[]}
512
+ */
513
+ const getJsdocTagsDeep = (jsdoc, targetTagName) => {
514
+ const ret = [];
515
+ for (const [
516
+ idx,
517
+ {
518
+ name,
519
+ tag,
520
+ type,
521
+ },
522
+ ] of jsdoc.tags.entries()) {
523
+ if (tag !== targetTagName) {
524
+ continue;
525
+ }
526
+
527
+ ret.push({
528
+ idx,
529
+ name,
530
+ type,
531
+ });
532
+ }
533
+
534
+ return ret;
535
+ };
536
+
537
+ const modeWarnSettings = WarnSettings();
538
+
539
+ /**
540
+ * @param {ParserMode|undefined} mode
541
+ * @param {import('eslint').Rule.RuleContext} context
542
+ * @returns {import('./tagNames.js').AliasedTags}
543
+ */
544
+ const getTagNamesForMode = (mode, context) => {
545
+ switch (mode) {
546
+ case 'closure':
547
+ case 'permissive':
548
+ return closureTags;
549
+ case 'jsdoc':
550
+ return jsdocTags;
551
+ case 'typescript':
552
+ return typeScriptTags;
553
+ default:
554
+ if (!modeWarnSettings.hasBeenWarned(context, 'mode')) {
555
+ context.report({
556
+ loc: {
557
+ end: {
558
+ column: 1,
559
+ line: 1,
560
+ },
561
+ start: {
562
+ column: 1,
563
+ line: 1,
564
+ },
565
+ },
566
+ message: `Unrecognized value \`${mode}\` for \`settings.jsdoc.mode\`.`,
567
+ });
568
+ modeWarnSettings.markSettingAsWarned(context, 'mode');
569
+ }
570
+
571
+ // We'll avoid breaking too many other rules
572
+ return jsdocTags;
573
+ }
574
+ };
575
+
576
+ /**
577
+ * @param {import('comment-parser').Spec} tg
578
+ * @param {boolean} [returnArray]
579
+ * @returns {string[]|string}
580
+ */
581
+ const getTagDescription = (tg, returnArray) => {
582
+ /**
583
+ * @type {string[]}
584
+ */
585
+ const descriptions = [];
586
+ tg.source.some(({
587
+ tokens: {
588
+ description,
589
+ end,
590
+ lineEnd,
591
+ name,
592
+ postDelimiter,
593
+ postTag,
594
+ tag,
595
+ type,
596
+ },
597
+ }) => {
598
+ const desc = (
599
+ tag && postTag ||
600
+ !tag && !name && !type && postDelimiter || ''
601
+
602
+ // Remove space
603
+ ).slice(1) +
604
+ (description || '') + (lineEnd || '');
605
+
606
+ if (end) {
607
+ if (desc) {
608
+ descriptions.push(desc);
609
+ }
610
+
611
+ return true;
612
+ }
613
+
614
+ descriptions.push(desc);
615
+
616
+ return false;
617
+ });
618
+
619
+ return returnArray ? descriptions : descriptions.join('\n');
620
+ };
621
+
622
+ /**
623
+ * @typedef {{
624
+ * report: (descriptor: import('eslint').Rule.ReportDescriptor) => void
625
+ * }} Reporter
626
+ */
627
+
628
+ /**
629
+ * @param {string} name
630
+ * @param {ParserMode|undefined} mode
631
+ * @param {TagNamePreference} tagPreference
632
+ * @param {import('eslint').Rule.RuleContext} context
633
+ * @returns {string|false|{
634
+ * message: string;
635
+ * replacement?: string|undefined;
636
+ * }}
637
+ */
638
+ const getPreferredTagNameSimple = (
639
+ name,
640
+ mode,
641
+ tagPreference = {},
642
+ // @ts-expect-error Just a no-op
643
+ // eslint-disable-next-line unicorn/no-object-as-default-parameter -- Ok
644
+ context = {
645
+ report () {
646
+ // No-op
647
+ },
648
+ },
649
+ ) => {
650
+ const prefValues = Object.values(tagPreference);
651
+ if (prefValues.includes(name) || prefValues.some((prefVal) => {
652
+ return prefVal && typeof prefVal === 'object' && prefVal.replacement === name;
653
+ })) {
654
+ return name;
655
+ }
656
+
657
+ // Allow keys to have a 'tag ' prefix to avoid upstream bug in ESLint
658
+ // that disallows keys that conflict with Object.prototype,
659
+ // e.g. 'tag constructor' for 'constructor':
660
+ // https://github.com/eslint/eslint/issues/13289
661
+ // https://github.com/gajus/eslint-plugin-jsdoc/issues/537
662
+ const tagPreferenceFixed = Object.fromEntries(
663
+ Object
664
+ .entries(tagPreference)
665
+ .map(([
666
+ key,
667
+ value,
668
+ ]) => {
669
+ return [
670
+ key.replace(/^tag /v, ''), value,
671
+ ];
672
+ }),
673
+ );
674
+
675
+ if (Object.hasOwn(tagPreferenceFixed, name)) {
676
+ return tagPreferenceFixed[name];
677
+ }
678
+
679
+ const tagNames = getTagNamesForMode(mode, context);
680
+
681
+ const preferredTagName = Object.entries(tagNames).find(([
682
+ , aliases,
683
+ ]) => {
684
+ return aliases.includes(name);
685
+ })?.[0];
686
+ if (preferredTagName) {
687
+ return preferredTagName;
688
+ }
689
+
690
+ return name;
691
+ };
692
+
693
+ /**
694
+ * @param {import('eslint').Rule.RuleContext} context
695
+ * @param {ParserMode|undefined} mode
696
+ * @param {string} name
697
+ * @param {string[]} definedTags
698
+ * @returns {boolean}
699
+ */
700
+ const isValidTag = (
701
+ context,
702
+ mode,
703
+ name,
704
+ definedTags,
705
+ ) => {
706
+ const tagNames = getTagNamesForMode(mode, context);
707
+
708
+ const validTagNames = Object.keys(tagNames).concat(Object.values(tagNames).flat());
709
+ const additionalTags = definedTags;
710
+ const allTags = validTagNames.concat(additionalTags);
711
+
712
+ return allTags.includes(name);
713
+ };
714
+
715
+ /**
716
+ * @param {import('./iterateJsdoc.js').JsdocBlockWithInline} jsdoc
717
+ * @param {string} targetTagName
718
+ * @returns {boolean}
719
+ */
720
+ const hasTag = (jsdoc, targetTagName) => {
721
+ const targetTagLower = targetTagName.toLowerCase();
722
+
723
+ return jsdoc.tags.some((doc) => {
724
+ return doc.tag.toLowerCase() === targetTagLower;
725
+ });
726
+ };
727
+
728
+ /**
729
+ * @param {import('./iterateJsdoc.js').JsdocBlockWithInline} jsdoc
730
+ * @param {(tag: import('@es-joy/jsdoccomment').JsdocTagWithInline) => boolean} filter
731
+ * @returns {import('@es-joy/jsdoccomment').JsdocTagWithInline[]}
732
+ */
733
+ const filterTags = (jsdoc, filter) => {
734
+ return jsdoc.tags.filter((tag) => {
735
+ return filter(tag);
736
+ });
737
+ };
738
+
739
+ /**
740
+ * @param {import('./iterateJsdoc.js').JsdocBlockWithInline} jsdoc
741
+ * @param {string} tagName
742
+ * @returns {import('comment-parser').Spec[]}
743
+ */
744
+ const getTags = (jsdoc, tagName) => {
745
+ return filterTags(jsdoc, (item) => {
746
+ return item.tag === tagName;
747
+ });
748
+ };
749
+
750
+ /**
751
+ * @param {import('./iterateJsdoc.js').JsdocBlockWithInline} jsdoc
752
+ * @param {{
753
+ * tagName: string,
754
+ * context?: import('eslint').Rule.RuleContext,
755
+ * mode?: ParserMode,
756
+ * report?: import('./iterateJsdoc.js').Report
757
+ * tagNamePreference?: TagNamePreference
758
+ * skipReportingBlockedTag?: boolean,
759
+ * allowObjectReturn?: boolean,
760
+ * defaultMessage?: string,
761
+ * }} cfg
762
+ * @returns {string|undefined|false|{
763
+ * message: string;
764
+ * replacement?: string|undefined;
765
+ * }|{
766
+ * blocked: true,
767
+ * tagName: string
768
+ * }}
769
+ */
770
+ const getPreferredTagName = (jsdoc, {
771
+ allowObjectReturn = false,
772
+ context,
773
+ tagName,
774
+ defaultMessage = `Unexpected tag \`@${tagName}\``,
775
+ mode,
776
+ report = () => {},
777
+ skipReportingBlockedTag = false,
778
+ tagNamePreference,
779
+ }) => {
780
+ const ret = getPreferredTagNameSimple(tagName, mode, tagNamePreference, context);
781
+ const isObject = ret && typeof ret === 'object';
782
+ if (hasTag(jsdoc, tagName) && (ret === false || isObject && !ret.replacement)) {
783
+ if (skipReportingBlockedTag) {
784
+ return {
785
+ blocked: true,
786
+ tagName,
787
+ };
788
+ }
789
+
790
+ const message = isObject && ret.message || defaultMessage;
791
+ report(message, null, getTags(jsdoc, tagName)[0]);
792
+
793
+ return false;
794
+ }
795
+
796
+ return isObject && !allowObjectReturn ? ret.replacement : ret;
797
+ };
798
+
799
+ /**
800
+ * @param {import('./iterateJsdoc.js').JsdocBlockWithInline} jsdoc
801
+ * @param {string} tagName
802
+ * @param {(
803
+ * matchingJsdocTag: import('@es-joy/jsdoccomment').JsdocTagWithInline,
804
+ * targetTagName: string
805
+ * ) => void} arrayHandler
806
+ * @param {object} cfg
807
+ * @param {import('eslint').Rule.RuleContext} [cfg.context]
808
+ * @param {ParserMode} [cfg.mode]
809
+ * @param {import('./iterateJsdoc.js').Report} [cfg.report]
810
+ * @param {TagNamePreference} [cfg.tagNamePreference]
811
+ * @param {boolean} [cfg.skipReportingBlockedTag]
812
+ * @returns {void}
813
+ */
814
+ const forEachPreferredTag = (
815
+ jsdoc, tagName, arrayHandler,
816
+ {
817
+ context,
818
+ mode,
819
+ report,
820
+ skipReportingBlockedTag = false,
821
+ tagNamePreference,
822
+ } = {},
823
+ ) => {
824
+ const targetTagName = /** @type {string|false} */ (
825
+ getPreferredTagName(jsdoc, {
826
+ context,
827
+ mode,
828
+ report,
829
+ skipReportingBlockedTag,
830
+ tagName,
831
+ tagNamePreference,
832
+ })
833
+ );
834
+ if (!targetTagName ||
835
+ skipReportingBlockedTag && targetTagName && typeof targetTagName === 'object'
836
+ ) {
837
+ return;
838
+ }
839
+
840
+ const matchingJsdocTags = jsdoc.tags.filter(({
841
+ tag,
842
+ }) => {
843
+ return tag === targetTagName;
844
+ });
845
+
846
+ for (const matchingJsdocTag of matchingJsdocTags) {
847
+ arrayHandler(
848
+ /**
849
+ * @type {import('@es-joy/jsdoccomment').JsdocTagWithInline}
850
+ */ (
851
+ matchingJsdocTag
852
+ ), targetTagName,
853
+ );
854
+ }
855
+ };
856
+
857
+ /**
858
+ * Get all inline tags and inline tags in tags
859
+ * @param {import('./iterateJsdoc.js').JsdocBlockWithInline} jsdoc
860
+ * @returns {(import('comment-parser').Spec|
861
+ * import('@es-joy/jsdoccomment').JsdocInlineTagNoType & {
862
+ * line?: number | undefined; column?: number | undefined;
863
+ * })[]}
864
+ */
865
+ const getInlineTags = (jsdoc) => {
866
+ return [
867
+ ...jsdoc.inlineTags.map((inlineTag) => {
868
+ // Tags don't have source or line numbers, so add before returning
869
+ let line = -1;
870
+ for (const {
871
+ tokens: {
872
+ description,
873
+ },
874
+ } of jsdoc.source) {
875
+ line++;
876
+ if (description && description.includes(`{@${inlineTag.tag}`)) {
877
+ break;
878
+ }
879
+ }
880
+
881
+ inlineTag.line = line;
882
+
883
+ return inlineTag;
884
+ }),
885
+ ...jsdoc.tags.flatMap((tag) => {
886
+ for (const inlineTag of tag.inlineTags) {
887
+ /** @type {import('./iterateJsdoc.js').Integer} */
888
+ let line = 0;
889
+ for (const {
890
+ number,
891
+ tokens: {
892
+ description,
893
+ },
894
+ } of tag.source) {
895
+ if (description && description.includes(`{@${inlineTag.tag}`)) {
896
+ line = number;
897
+ break;
898
+ }
899
+ }
900
+
901
+ inlineTag.line = line;
902
+ }
903
+
904
+ return (
905
+ /**
906
+ * @type {import('comment-parser').Spec & {
907
+ * inlineTags: import('@es-joy/jsdoccomment').JsdocInlineTagNoType[]
908
+ * }}
909
+ */ (
910
+ tag
911
+ ).inlineTags
912
+ );
913
+ }),
914
+ ];
915
+ };
916
+
917
+ /**
918
+ * Get all tags, inline tags and inline tags in tags
919
+ * @param {import('./iterateJsdoc.js').JsdocBlockWithInline} jsdoc
920
+ * @returns {(import('comment-parser').Spec|
921
+ * import('@es-joy/jsdoccomment').JsdocInlineTagNoType & {
922
+ * line?: number | undefined; column?: number | undefined;
923
+ * })[]}
924
+ */
925
+ const getAllTags = (jsdoc) => {
926
+ return [
927
+ ...jsdoc.tags,
928
+ ...getInlineTags(jsdoc),
929
+ ];
930
+ };
931
+
932
+ /**
933
+ * @param {import('./iterateJsdoc.js').JsdocBlockWithInline} jsdoc
934
+ * @param {string[]} targetTagNames
935
+ * @returns {boolean}
936
+ */
937
+ const hasATag = (jsdoc, targetTagNames) => {
938
+ return targetTagNames.some((targetTagName) => {
939
+ return hasTag(jsdoc, targetTagName);
940
+ });
941
+ };
942
+
943
+ /**
944
+ * Checks if the JSDoc comment has an undefined type.
945
+ * @param {import('comment-parser').Spec|null|undefined} tag
946
+ * the tag which should be checked.
947
+ * @param {ParserMode} mode
948
+ * @returns {boolean}
949
+ * true in case a defined type is undeclared; otherwise false.
950
+ */
951
+ const mayBeUndefinedTypeTag = (tag, mode) => {
952
+ // The function should not continue in the event the type is not defined...
953
+ if (typeof tag === 'undefined' || tag === null) {
954
+ return true;
955
+ }
956
+
957
+ // .. same applies if it declares an `{undefined}` or `{void}` type
958
+ const tagType = tag.type.trim();
959
+
960
+ // Exit early if matching
961
+ if (
962
+ tagType === 'undefined' || tagType === 'void' ||
963
+ tagType === '*' || tagType === 'any'
964
+ ) {
965
+ return true;
966
+ }
967
+
968
+ let parsedTypes;
969
+ try {
970
+ parsedTypes = tryParse(
971
+ tagType,
972
+ mode === 'permissive' ? undefined : [
973
+ mode,
974
+ ],
975
+ );
976
+ } catch {
977
+ // Ignore
978
+ }
979
+
980
+ if (
981
+ // We do not traverse deeply as it could be, e.g., `Promise<void>`
982
+ parsedTypes &&
983
+ parsedTypes.type === 'JsdocTypeUnion' &&
984
+ parsedTypes.elements.some((elem) => {
985
+ return elem.type === 'JsdocTypeUndefined' ||
986
+ elem.type === 'JsdocTypeName' && elem.value === 'void';
987
+ })) {
988
+ return true;
989
+ }
990
+
991
+ // In any other case, a type is present
992
+ return false;
993
+ };
994
+
995
+ /**
996
+ * @param {import('./getDefaultTagStructureForMode.js').TagStructure} map
997
+ * @param {string} tag
998
+ * @returns {Map<string, string|string[]|boolean|undefined>}
999
+ */
1000
+ const ensureMap = (map, tag) => {
1001
+ if (!map.has(tag)) {
1002
+ map.set(tag, new Map());
1003
+ }
1004
+
1005
+ return /** @type {Map<string, string | boolean>} */ (map.get(tag));
1006
+ };
1007
+
1008
+ /**
1009
+ * @param {import('./iterateJsdoc.js').StructuredTags} structuredTags
1010
+ * @param {import('./getDefaultTagStructureForMode.js').TagStructure} tagMap
1011
+ * @returns {void}
1012
+ */
1013
+ const overrideTagStructure = (structuredTags, tagMap = tagStructure) => {
1014
+ for (const [
1015
+ tag,
1016
+ {
1017
+ name,
1018
+ required = [],
1019
+ type,
1020
+ },
1021
+ ] of Object.entries(structuredTags)) {
1022
+ const tagStruct = ensureMap(tagMap, tag);
1023
+
1024
+ tagStruct.set('namepathRole', name);
1025
+ tagStruct.set('typeAllowed', type);
1026
+
1027
+ const requiredName = required.includes('name');
1028
+ if (requiredName && name === false) {
1029
+ throw new Error('Cannot add "name" to `require` with the tag\'s `name` set to `false`');
1030
+ }
1031
+
1032
+ tagStruct.set('nameRequired', requiredName);
1033
+
1034
+ const requiredType = required.includes('type');
1035
+ if (requiredType && type === false) {
1036
+ throw new Error('Cannot add "type" to `require` with the tag\'s `type` set to `false`');
1037
+ }
1038
+
1039
+ tagStruct.set('typeRequired', requiredType);
1040
+
1041
+ const typeOrNameRequired = required.includes('typeOrNameRequired');
1042
+ if (typeOrNameRequired && name === false) {
1043
+ throw new Error('Cannot add "typeOrNameRequired" to `require` with the tag\'s `name` set to `false`');
1044
+ }
1045
+
1046
+ if (typeOrNameRequired && type === false) {
1047
+ throw new Error('Cannot add "typeOrNameRequired" to `require` with the tag\'s `type` set to `false`');
1048
+ }
1049
+
1050
+ tagStruct.set('typeOrNameRequired', typeOrNameRequired);
1051
+ }
1052
+ };
1053
+
1054
+ /**
1055
+ * @param {ParserMode} mode
1056
+ * @param {import('./iterateJsdoc.js').StructuredTags} structuredTags
1057
+ * @returns {import('./getDefaultTagStructureForMode.js').TagStructure}
1058
+ */
1059
+ const getTagStructureForMode = (mode, structuredTags) => {
1060
+ const tagStruct = getDefaultTagStructureForMode(mode);
1061
+
1062
+ try {
1063
+ overrideTagStructure(structuredTags, tagStruct);
1064
+ /* c8 ignore next 3 */
1065
+ } catch {
1066
+ //
1067
+ }
1068
+
1069
+ return tagStruct;
1070
+ };
1071
+
1072
+ /**
1073
+ * @param {string} tag
1074
+ * @param {import('./getDefaultTagStructureForMode.js').TagStructure} tagMap
1075
+ * @returns {boolean}
1076
+ */
1077
+ const isNameOrNamepathDefiningTag = (tag, tagMap = tagStructure) => {
1078
+ const tagStruct = ensureMap(tagMap, tag);
1079
+
1080
+ return /** @type {(string|boolean|undefined)[]} */ ([
1081
+ 'name-defining',
1082
+ 'namepath-defining',
1083
+ ]).includes(/** @type {string|boolean|undefined} */ (
1084
+ tagStruct.get('namepathRole')));
1085
+ };
1086
+
1087
+ /**
1088
+ * @param {string} tag
1089
+ * @param {import('./getDefaultTagStructureForMode.js').TagStructure} tagMap
1090
+ * @returns {boolean}
1091
+ */
1092
+ const isNamepathReferencingTag = (tag, tagMap = tagStructure) => {
1093
+ const tagStruct = ensureMap(tagMap, tag);
1094
+ return tagStruct.get('namepathRole') === 'namepath-referencing';
1095
+ };
1096
+
1097
+ /**
1098
+ * @param {string} tag
1099
+ * @param {import('./getDefaultTagStructureForMode.js').TagStructure} tagMap
1100
+ * @returns {boolean}
1101
+ */
1102
+ const isNamepathOrUrlReferencingTag = (tag, tagMap = tagStructure) => {
1103
+ const tagStruct = ensureMap(tagMap, tag);
1104
+ return tagStruct.get('namepathRole') === 'namepath-or-url-referencing';
1105
+ };
1106
+
1107
+ /**
1108
+ * @param {string} tag
1109
+ * @param {import('./getDefaultTagStructureForMode.js').TagStructure} tagMap
1110
+ * @returns {boolean|undefined}
1111
+ */
1112
+ const tagMustHaveTypePosition = (tag, tagMap = tagStructure) => {
1113
+ const tagStruct = ensureMap(tagMap, tag);
1114
+
1115
+ return /** @type {boolean|undefined} */ (tagStruct.get('typeRequired'));
1116
+ };
1117
+
1118
+ /**
1119
+ * @param {string} tag
1120
+ * @param {import('./getDefaultTagStructureForMode.js').TagStructure} tagMap
1121
+ * @returns {boolean|string}
1122
+ */
1123
+ const tagMightHaveTypePosition = (tag, tagMap = tagStructure) => {
1124
+ if (tagMustHaveTypePosition(tag, tagMap)) {
1125
+ return true;
1126
+ }
1127
+
1128
+ const tagStruct = ensureMap(tagMap, tag);
1129
+
1130
+ const ret = /** @type {boolean|undefined} */ (tagStruct.get('typeAllowed'));
1131
+
1132
+ return ret === undefined ? true : ret;
1133
+ };
1134
+
1135
+ const namepathTypes = new Set([
1136
+ 'name-defining', 'namepath-defining',
1137
+ 'namepath-referencing',
1138
+ ]);
1139
+
1140
+ /**
1141
+ * @param {string} tag
1142
+ * @param {import('./getDefaultTagStructureForMode.js').TagStructure} tagMap
1143
+ * @returns {boolean}
1144
+ */
1145
+ const tagMightHaveNamePosition = (tag, tagMap = tagStructure) => {
1146
+ const tagStruct = ensureMap(tagMap, tag);
1147
+
1148
+ const ret = tagStruct.get('namepathRole');
1149
+
1150
+ return ret === undefined ? true : Boolean(ret);
1151
+ };
1152
+
1153
+ /**
1154
+ * @param {string} tag
1155
+ * @param {import('./getDefaultTagStructureForMode.js').TagStructure} tagMap
1156
+ * @returns {boolean}
1157
+ */
1158
+ const tagMightHaveNameOrNamepath = (tag, tagMap = tagStructure) => {
1159
+ const tagStruct = ensureMap(tagMap, tag);
1160
+
1161
+ const nampathRole = tagStruct.get('namepathRole');
1162
+
1163
+ return nampathRole !== false &&
1164
+ namepathTypes.has(/** @type {string} */ (nampathRole));
1165
+ };
1166
+
1167
+ /**
1168
+ * @param {string} tag
1169
+ * @param {import('./getDefaultTagStructureForMode.js').TagStructure} tagMap
1170
+ * @returns {boolean}
1171
+ */
1172
+ const tagMightHaveNamepath = (tag, tagMap = tagStructure) => {
1173
+ const tagStruct = ensureMap(tagMap, tag);
1174
+
1175
+ const nampathRole = tagStruct.get('namepathRole');
1176
+
1177
+ return nampathRole !== false &&
1178
+ [
1179
+ 'namepath-defining',
1180
+ 'namepath-referencing',
1181
+ ].includes(/** @type {string} */ (nampathRole));
1182
+ };
1183
+
1184
+ /**
1185
+ * @param {string} tag
1186
+ * @param {import('./getDefaultTagStructureForMode.js').TagStructure} tagMap
1187
+ * @returns {boolean}
1188
+ */
1189
+ const tagMightHaveName = (tag, tagMap = tagStructure) => {
1190
+ const tagStruct = ensureMap(tagMap, tag);
1191
+
1192
+ const nampathRole = tagStruct.get('namepathRole');
1193
+
1194
+ return nampathRole !== false &&
1195
+ nampathRole === 'name-defining';
1196
+ };
1197
+
1198
+ /**
1199
+ * @param {string} tag
1200
+ * @param {import('./getDefaultTagStructureForMode.js').TagStructure} tagMap
1201
+ * @returns {boolean|undefined}
1202
+ */
1203
+ const tagMustHaveNamePosition = (tag, tagMap = tagStructure) => {
1204
+ const tagStruct = ensureMap(tagMap, tag);
1205
+
1206
+ return /** @type {boolean|undefined} */ (tagStruct.get('nameRequired'));
1207
+ };
1208
+
1209
+ /**
1210
+ * @param {string} tag
1211
+ * @param {import('./getDefaultTagStructureForMode.js').TagStructure} tagMap
1212
+ * @returns {boolean}
1213
+ */
1214
+ const tagMightHaveEitherTypeOrNamePosition = (tag, tagMap) => {
1215
+ return Boolean(tagMightHaveTypePosition(tag, tagMap)) || tagMightHaveNameOrNamepath(tag, tagMap);
1216
+ };
1217
+
1218
+ /**
1219
+ * @param {string} tag
1220
+ * @param {import('./getDefaultTagStructureForMode.js').TagStructure} tagMap
1221
+ * @returns {boolean|undefined}
1222
+ */
1223
+ const tagMustHaveEitherTypeOrNamePosition = (tag, tagMap) => {
1224
+ const tagStruct = ensureMap(tagMap, tag);
1225
+
1226
+ return /** @type {boolean} */ (tagStruct.get('typeOrNameRequired'));
1227
+ };
1228
+
1229
+ /**
1230
+ * @param {import('comment-parser').Spec} tag
1231
+ * @param {import('./getDefaultTagStructureForMode.js').TagStructure} tagMap
1232
+ * @returns {boolean|undefined}
1233
+ */
1234
+ const tagMissingRequiredTypeOrNamepath = (tag, tagMap = tagStructure) => {
1235
+ const mustHaveTypePosition = tagMustHaveTypePosition(tag.tag, tagMap);
1236
+ const mightHaveTypePosition = tagMightHaveTypePosition(tag.tag, tagMap);
1237
+ const hasTypePosition = mightHaveTypePosition && Boolean(tag.type);
1238
+ const hasNameOrNamepathPosition = (
1239
+ tagMustHaveNamePosition(tag.tag, tagMap) ||
1240
+ tagMightHaveNameOrNamepath(tag.tag, tagMap)
1241
+ ) && Boolean(tag.name);
1242
+ const mustHaveEither = tagMustHaveEitherTypeOrNamePosition(tag.tag, tagMap);
1243
+ const hasEither = tagMightHaveEitherTypeOrNamePosition(tag.tag, tagMap) &&
1244
+ (hasTypePosition || hasNameOrNamepathPosition);
1245
+
1246
+ return mustHaveEither && !hasEither && !mustHaveTypePosition;
1247
+ };
1248
+
1249
+ /* eslint-disable complexity -- Temporary */
1250
+ /**
1251
+ * @param {ESTreeOrTypeScriptNode|null|undefined} node
1252
+ * @param {boolean} [checkYieldReturnValue]
1253
+ * @returns {boolean}
1254
+ */
1255
+ const hasNonFunctionYield = (node, checkYieldReturnValue) => {
1256
+ /* eslint-enable complexity -- Temporary */
1257
+ if (!node) {
1258
+ return false;
1259
+ }
1260
+
1261
+ switch (node.type) {
1262
+ case 'ArrayExpression':
1263
+
1264
+ case 'ArrayPattern':
1265
+ return node.elements.some((element) => {
1266
+ return hasNonFunctionYield(element, checkYieldReturnValue);
1267
+ });
1268
+ case 'AssignmentExpression':
1269
+ case 'BinaryExpression':
1270
+ case 'LogicalExpression': {
1271
+ return hasNonFunctionYield(node.left, checkYieldReturnValue) ||
1272
+ hasNonFunctionYield(node.right, checkYieldReturnValue);
1273
+ }
1274
+
1275
+ case 'AssignmentPattern':
1276
+ return hasNonFunctionYield(node.right, checkYieldReturnValue);
1277
+ case 'BlockStatement': {
1278
+ return node.body.some((bodyNode) => {
1279
+ return ![
1280
+ 'ArrowFunctionExpression',
1281
+ 'FunctionDeclaration',
1282
+ 'FunctionExpression',
1283
+ ].includes(bodyNode.type) && hasNonFunctionYield(
1284
+ bodyNode, checkYieldReturnValue,
1285
+ );
1286
+ });
1287
+ }
1288
+
1289
+ /* c8 ignore next 2 -- In Babel? */
1290
+ case 'CallExpression':
1291
+ // @ts-expect-error In Babel?
1292
+ case 'OptionalCallExpression':
1293
+ return node.arguments.some((element) => {
1294
+ return hasNonFunctionYield(element, checkYieldReturnValue);
1295
+ });
1296
+ case 'ChainExpression':
1297
+ case 'ExpressionStatement': {
1298
+ return hasNonFunctionYield(node.expression, checkYieldReturnValue);
1299
+ }
1300
+
1301
+ /* c8 ignore next 2 -- In Babel? */
1302
+ // @ts-expect-error In Babel?
1303
+ case 'ClassProperty':
1304
+
1305
+ /* c8 ignore next 2 -- In Babel? */
1306
+ // @ts-expect-error In Babel?
1307
+ case 'ObjectProperty':
1308
+ /* c8 ignore next 2 -- In Babel? */
1309
+ case 'Property':
1310
+
1311
+ case 'PropertyDefinition':
1312
+ return node.computed && hasNonFunctionYield(node.key, checkYieldReturnValue) ||
1313
+ hasNonFunctionYield(node.value, checkYieldReturnValue);
1314
+
1315
+ case 'ConditionalExpression':
1316
+
1317
+ case 'IfStatement': {
1318
+ return hasNonFunctionYield(node.test, checkYieldReturnValue) ||
1319
+ hasNonFunctionYield(node.consequent, checkYieldReturnValue) ||
1320
+ hasNonFunctionYield(node.alternate, checkYieldReturnValue);
1321
+ }
1322
+
1323
+ case 'DoWhileStatement':
1324
+ case 'ForInStatement':
1325
+
1326
+ case 'ForOfStatement':
1327
+
1328
+ case 'ForStatement':
1329
+
1330
+ case 'LabeledStatement':
1331
+ case 'WhileStatement':
1332
+ case 'WithStatement': {
1333
+ return hasNonFunctionYield(node.body, checkYieldReturnValue);
1334
+ }
1335
+
1336
+ /* c8 ignore next 2 -- In Babel? */
1337
+ // @ts-expect-error In Babel?
1338
+ case 'Import':
1339
+ case 'ImportExpression':
1340
+ return hasNonFunctionYield(node.source, checkYieldReturnValue);
1341
+
1342
+ // ?.
1343
+ /* c8 ignore next 2 -- In Babel? */
1344
+ case 'MemberExpression':
1345
+ // @ts-expect-error In Babel?
1346
+ case 'OptionalMemberExpression':
1347
+ return hasNonFunctionYield(node.object, checkYieldReturnValue) ||
1348
+ hasNonFunctionYield(node.property, checkYieldReturnValue);
1349
+
1350
+ case 'ObjectExpression':
1351
+ case 'ObjectPattern':
1352
+ return node.properties.some((property) => {
1353
+ return hasNonFunctionYield(property, checkYieldReturnValue);
1354
+ });
1355
+ /* c8 ignore next 2 -- In Babel? */
1356
+ // @ts-expect-error In Babel?
1357
+ case 'ObjectMethod':
1358
+ /* c8 ignore next 6 -- In Babel? */
1359
+ // @ts-expect-error In Babel?
1360
+ return node.computed && hasNonFunctionYield(node.key, checkYieldReturnValue) ||
1361
+ // @ts-expect-error In Babel?
1362
+ node.arguments.some((nde) => {
1363
+ return hasNonFunctionYield(nde, checkYieldReturnValue);
1364
+ });
1365
+ case 'ReturnStatement': {
1366
+ if (node.argument === null) {
1367
+ return false;
1368
+ }
1369
+
1370
+ return hasNonFunctionYield(node.argument, checkYieldReturnValue);
1371
+ }
1372
+
1373
+ // Comma
1374
+ case 'SequenceExpression':
1375
+
1376
+ case 'TemplateLiteral':
1377
+ return node.expressions.some((subExpression) => {
1378
+ return hasNonFunctionYield(subExpression, checkYieldReturnValue);
1379
+ });
1380
+ case 'SpreadElement':
1381
+
1382
+ case 'UnaryExpression':
1383
+ return hasNonFunctionYield(node.argument, checkYieldReturnValue);
1384
+
1385
+ case 'SwitchStatement': {
1386
+ return node.cases.some(
1387
+ (someCase) => {
1388
+ return someCase.consequent.some((nde) => {
1389
+ return hasNonFunctionYield(nde, checkYieldReturnValue);
1390
+ });
1391
+ },
1392
+ );
1393
+ }
1394
+
1395
+ case 'TaggedTemplateExpression':
1396
+ return hasNonFunctionYield(node.quasi, checkYieldReturnValue);
1397
+
1398
+ case 'TryStatement': {
1399
+ return hasNonFunctionYield(node.block, checkYieldReturnValue) ||
1400
+ hasNonFunctionYield(
1401
+ node.handler && node.handler.body, checkYieldReturnValue,
1402
+ ) ||
1403
+ hasNonFunctionYield(
1404
+ /** @type {import('@typescript-eslint/types').TSESTree.BlockStatement} */
1405
+ (node.finalizer),
1406
+ checkYieldReturnValue,
1407
+ );
1408
+ }
1409
+
1410
+ case 'VariableDeclaration': {
1411
+ return node.declarations.some((nde) => {
1412
+ return hasNonFunctionYield(nde, checkYieldReturnValue);
1413
+ });
1414
+ }
1415
+
1416
+ case 'VariableDeclarator': {
1417
+ return hasNonFunctionYield(node.id, checkYieldReturnValue) ||
1418
+ hasNonFunctionYield(node.init, checkYieldReturnValue);
1419
+ }
1420
+
1421
+ case 'YieldExpression': {
1422
+ if (checkYieldReturnValue) {
1423
+ if (
1424
+ /** @type {import('eslint').Rule.Node} */ (
1425
+ node
1426
+ ).parent?.type === 'VariableDeclarator'
1427
+ ) {
1428
+ return true;
1429
+ }
1430
+
1431
+ return false;
1432
+ }
1433
+
1434
+ // void return does not count.
1435
+ if (node.argument === null) {
1436
+ return false;
1437
+ }
1438
+
1439
+ return true;
1440
+ }
1441
+
1442
+ default: {
1443
+ return false;
1444
+ }
1445
+ }
1446
+ };
1447
+
1448
+ /**
1449
+ * Checks if a node has a return statement. Void return does not count.
1450
+ * @param {ESTreeOrTypeScriptNode} node
1451
+ * @param {boolean} [checkYieldReturnValue]
1452
+ * @returns {boolean}
1453
+ */
1454
+ const hasYieldValue = (node, checkYieldReturnValue) => {
1455
+ return /** @type {import('@typescript-eslint/types').TSESTree.FunctionDeclaration} */ (
1456
+ node
1457
+ ).generator && (
1458
+ /** @type {import('@typescript-eslint/types').TSESTree.FunctionDeclaration} */ (
1459
+ node
1460
+ ).expression || hasNonFunctionYield(
1461
+ /** @type {import('@typescript-eslint/types').TSESTree.FunctionDeclaration} */
1462
+ (node).body,
1463
+ checkYieldReturnValue,
1464
+ )
1465
+ );
1466
+ };
1467
+
1468
+ /**
1469
+ * Checks if a node has a throws statement.
1470
+ * @param {ESTreeOrTypeScriptNode|null|undefined} node
1471
+ * @param {boolean} [innerFunction]
1472
+ * @returns {boolean}
1473
+ */
1474
+ const hasThrowValue = (node, innerFunction) => {
1475
+ if (!node) {
1476
+ return false;
1477
+ }
1478
+
1479
+ // There are cases where a function may execute its inner function which
1480
+ // throws, but we're treating functions atomically rather than trying to
1481
+ // follow them
1482
+ switch (node.type) {
1483
+ case 'ArrowFunctionExpression':
1484
+ case 'FunctionDeclaration':
1485
+ case 'FunctionExpression': {
1486
+ return !innerFunction && !node.async && hasThrowValue(node.body, true);
1487
+ }
1488
+
1489
+ case 'BlockStatement': {
1490
+ return node.body.some((bodyNode) => {
1491
+ return bodyNode.type !== 'FunctionDeclaration' && hasThrowValue(bodyNode);
1492
+ });
1493
+ }
1494
+
1495
+ case 'DoWhileStatement':
1496
+ case 'ForInStatement':
1497
+ case 'ForOfStatement':
1498
+ case 'ForStatement':
1499
+ case 'LabeledStatement':
1500
+ case 'WhileStatement':
1501
+ case 'WithStatement': {
1502
+ return hasThrowValue(node.body);
1503
+ }
1504
+
1505
+ case 'IfStatement': {
1506
+ return hasThrowValue(node.consequent) || hasThrowValue(node.alternate);
1507
+ }
1508
+
1509
+ case 'SwitchStatement': {
1510
+ return node.cases.some(
1511
+ (someCase) => {
1512
+ return someCase.consequent.some((nde) => {
1513
+ return hasThrowValue(nde);
1514
+ });
1515
+ },
1516
+ );
1517
+ }
1518
+
1519
+ case 'ThrowStatement': {
1520
+ return true;
1521
+ }
1522
+
1523
+ // We only consider it to throw an error if the catch or finally blocks throw an error.
1524
+ case 'TryStatement': {
1525
+ return hasThrowValue(node.handler && node.handler.body) ||
1526
+ hasThrowValue(node.finalizer);
1527
+ }
1528
+
1529
+ default: {
1530
+ return false;
1531
+ }
1532
+ }
1533
+ };
1534
+
1535
+ /**
1536
+ * @param {string} tag
1537
+ */
1538
+ /*
1539
+ const isInlineTag = (tag) => {
1540
+ return /^(@link|@linkcode|@linkplain|@tutorial) /v.test(tag);
1541
+ };
1542
+ */
1543
+
1544
+ /**
1545
+ * Parses GCC Generic/Template types
1546
+ * @see {@link https://github.com/google/closure-compiler/wiki/Generic-Types}
1547
+ * @see {@link https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html#template}
1548
+ * @param {import('comment-parser').Spec} tag
1549
+ * @returns {string[]}
1550
+ */
1551
+ const parseClosureTemplateTag = (tag) => {
1552
+ return tag.name
1553
+ .split(',')
1554
+ .map((type) => {
1555
+ return type.trim().replace(/^\[?(?<name>.*?)=.*$/v, '$<name>');
1556
+ });
1557
+ };
1558
+
1559
+ /**
1560
+ * @typedef {true|string[]} DefaultContexts
1561
+ */
1562
+
1563
+ /**
1564
+ * Checks user option for `contexts` array, defaulting to
1565
+ * contexts designated by the rule. Returns an array of
1566
+ * ESTree AST types, indicating allowable contexts.
1567
+ * @param {import('eslint').Rule.RuleContext} context
1568
+ * @param {DefaultContexts|undefined} defaultContexts
1569
+ * @param {{
1570
+ * contexts?: import('./iterateJsdoc.js').Context[]
1571
+ * }} settings
1572
+ * @returns {(string|import('./iterateJsdoc.js').ContextObject)[]}
1573
+ */
1574
+ const enforcedContexts = (context, defaultContexts, settings) => {
1575
+ const contexts = context.options[0]?.contexts || settings.contexts || (defaultContexts === true ? [
1576
+ 'ArrowFunctionExpression',
1577
+ 'FunctionDeclaration',
1578
+ 'FunctionExpression',
1579
+ 'TSDeclareFunction',
1580
+ ] : defaultContexts);
1581
+
1582
+ return contexts;
1583
+ };
1584
+
1585
+ /**
1586
+ * @param {import('./iterateJsdoc.js').Context[]} contexts
1587
+ * @param {import('./iterateJsdoc.js').CheckJsdoc} checkJsdoc
1588
+ * @param {import('@es-joy/jsdoccomment').CommentHandler} [handler]
1589
+ * @returns {import('eslint').Rule.RuleListener}
1590
+ */
1591
+ const getContextObject = (contexts, checkJsdoc, handler) => {
1592
+ /** @type {import('eslint').Rule.RuleListener} */
1593
+ const properties = {};
1594
+
1595
+ for (const [
1596
+ idx,
1597
+ prop,
1598
+ ] of contexts.entries()) {
1599
+ /** @type {string} */
1600
+ let property;
1601
+
1602
+ /** @type {(node: import('eslint').Rule.Node) => void} */
1603
+ let value;
1604
+
1605
+ if (typeof prop === 'object') {
1606
+ const selInfo = {
1607
+ lastIndex: idx,
1608
+ selector: prop.context,
1609
+ };
1610
+ if (prop.comment) {
1611
+ property = /** @type {string} */ (prop.context);
1612
+ value = checkJsdoc.bind(
1613
+ null,
1614
+ {
1615
+ ...selInfo,
1616
+ comment: prop.comment,
1617
+ },
1618
+ /**
1619
+ * @type {(jsdoc: import('@es-joy/jsdoccomment').JsdocBlockWithInline) => boolean}
1620
+ */
1621
+ (/** @type {import('@es-joy/jsdoccomment').CommentHandler} */ (
1622
+ handler
1623
+ ).bind(null, prop.comment)),
1624
+ );
1625
+ } else {
1626
+ property = /** @type {string} */ (prop.context);
1627
+ value = checkJsdoc.bind(null, selInfo, null);
1628
+ }
1629
+ } else {
1630
+ const selInfo = {
1631
+ lastIndex: idx,
1632
+ selector: prop,
1633
+ };
1634
+ property = prop;
1635
+ value = checkJsdoc.bind(null, selInfo, null);
1636
+ }
1637
+
1638
+ const old = /**
1639
+ * @type {((node: import('eslint').Rule.Node) => void)}
1640
+ */ (properties[property]);
1641
+ properties[property] = old ?
1642
+ /**
1643
+ * @type {((node: import('eslint').Rule.Node) => void)}
1644
+ */
1645
+ function (node) {
1646
+ old(node);
1647
+ value(node);
1648
+ } :
1649
+ value;
1650
+ }
1651
+
1652
+ return properties;
1653
+ };
1654
+
1655
+ const tagsWithNamesAndDescriptions = new Set([
1656
+ 'arg', 'argument', 'param', 'prop', 'property',
1657
+ 'return',
1658
+
1659
+ // These two are parsed by our custom parser as though having a `name`
1660
+ 'returns', 'template',
1661
+ ]);
1662
+
1663
+ /**
1664
+ * @typedef {{
1665
+ * [key: string]: false|string|
1666
+ * {message: string, replacement?: string}
1667
+ * }} TagNamePreference
1668
+ */
1669
+
1670
+ /**
1671
+ * @param {import('eslint').Rule.RuleContext} context
1672
+ * @param {ParserMode|undefined} mode
1673
+ * @param {import('comment-parser').Spec[]} tags
1674
+ * @returns {{
1675
+ * tagsWithNames: import('comment-parser').Spec[],
1676
+ * tagsWithoutNames: import('comment-parser').Spec[]
1677
+ * }}
1678
+ */
1679
+ const getTagsByType = (context, mode, tags) => {
1680
+ /**
1681
+ * @type {import('comment-parser').Spec[]}
1682
+ */
1683
+ const tagsWithoutNames = [];
1684
+ const tagsWithNames = tags.filter((tag) => {
1685
+ const {
1686
+ tag: tagName,
1687
+ } = tag;
1688
+ const tagWithName = tagsWithNamesAndDescriptions.has(tagName);
1689
+ if (!tagWithName) {
1690
+ tagsWithoutNames.push(tag);
1691
+ }
1692
+
1693
+ return tagWithName;
1694
+ });
1695
+
1696
+ return {
1697
+ tagsWithNames,
1698
+ tagsWithoutNames,
1699
+ };
1700
+ };
1701
+
1702
+ /**
1703
+ * @param {import('eslint').SourceCode|{
1704
+ * text: string
1705
+ * }} sourceCode
1706
+ * @returns {string}
1707
+ */
1708
+ const getIndent = (sourceCode) => {
1709
+ return (sourceCode.text.match(/^\n*([ \t]+)/v)?.[1] ?? '') + ' ';
1710
+ };
1711
+
1712
+ /**
1713
+ * @param {import('eslint').Rule.Node|null} node
1714
+ * @returns {boolean}
1715
+ */
1716
+ const isConstructor = (node) => {
1717
+ return node?.type === 'MethodDefinition' && node.kind === 'constructor' ||
1718
+ /** @type {import('@typescript-eslint/types').TSESTree.MethodDefinition} */ (
1719
+ node?.parent
1720
+ )?.kind === 'constructor';
1721
+ };
1722
+
1723
+ /**
1724
+ * @param {import('eslint').Rule.Node|null} node
1725
+ * @returns {boolean}
1726
+ */
1727
+ const isGetter = (node) => {
1728
+ return node !== null &&
1729
+ /**
1730
+ * @type {import('@typescript-eslint/types').TSESTree.MethodDefinition|
1731
+ * import('@typescript-eslint/types').TSESTree.Property}
1732
+ */ (
1733
+ node.parent
1734
+ )?.kind === 'get';
1735
+ };
1736
+
1737
+ /**
1738
+ * @param {import('eslint').Rule.Node|null} node
1739
+ * @returns {boolean}
1740
+ */
1741
+ const isSetter = (node) => {
1742
+ return node !== null &&
1743
+ /**
1744
+ * @type {import('@typescript-eslint/types').TSESTree.MethodDefinition|
1745
+ * import('@typescript-eslint/types').TSESTree.Property}
1746
+ */(
1747
+ node.parent
1748
+ )?.kind === 'set';
1749
+ };
1750
+
1751
+ /**
1752
+ * @param {import('eslint').Rule.Node} node
1753
+ * @returns {boolean}
1754
+ */
1755
+ const hasAccessorPair = (node) => {
1756
+ const {
1757
+ key,
1758
+ kind: sourceKind,
1759
+ type,
1760
+ } =
1761
+ /**
1762
+ * @type {import('@typescript-eslint/types').TSESTree.MethodDefinition|
1763
+ * import('@typescript-eslint/types').TSESTree.Property}
1764
+ */ (node);
1765
+
1766
+ const sourceName =
1767
+ /** @type {import('@typescript-eslint/types').TSESTree.Identifier} */ (
1768
+ key
1769
+ ).name;
1770
+
1771
+ const oppositeKind = sourceKind === 'get' ? 'set' : 'get';
1772
+
1773
+ const sibling = type === 'MethodDefinition' ?
1774
+ /** @type {import('@typescript-eslint/types').TSESTree.ClassBody} */ (
1775
+ node.parent
1776
+ ).body :
1777
+ /** @type {import('@typescript-eslint/types').TSESTree.ObjectExpression} */ (
1778
+ node.parent
1779
+ ).properties;
1780
+
1781
+ return (
1782
+ sibling.some((child) => {
1783
+ const {
1784
+ key: ky,
1785
+ kind,
1786
+ } = /**
1787
+ * @type {import('@typescript-eslint/types').TSESTree.MethodDefinition|
1788
+ * import('@typescript-eslint/types').TSESTree.Property}
1789
+ */ (child);
1790
+
1791
+ const name =
1792
+ /** @type {import('@typescript-eslint/types').TSESTree.Identifier} */ (
1793
+ ky
1794
+ ).name;
1795
+
1796
+ return kind === oppositeKind && name === sourceName;
1797
+ })
1798
+ );
1799
+ };
1800
+
1801
+ /**
1802
+ * @param {import('./iterateJsdoc.js').JsdocBlockWithInline} jsdoc
1803
+ * @param {import('eslint').Rule.Node|null} node
1804
+ * @param {import('eslint').Rule.RuleContext} context
1805
+ * @param {import('json-schema').JSONSchema4} schema
1806
+ * @returns {boolean}
1807
+ */
1808
+ const exemptSpeciaMethods = (jsdoc, node, context, schema) => {
1809
+ /**
1810
+ * @param {"checkGetters"|"checkSetters"|"checkConstructors"} prop
1811
+ * @returns {boolean|"no-setter"|"no-getter"}
1812
+ */
1813
+ const hasSchemaOption = (prop) => {
1814
+ const schemaProperties = schema[0].properties;
1815
+
1816
+ return context.options[0]?.[prop] ??
1817
+ (schemaProperties[prop] && schemaProperties[prop].default);
1818
+ };
1819
+
1820
+ const checkGetters = hasSchemaOption('checkGetters');
1821
+ const checkSetters = hasSchemaOption('checkSetters');
1822
+
1823
+ return !hasSchemaOption('checkConstructors') &&
1824
+ (
1825
+ isConstructor(node) ||
1826
+ hasATag(jsdoc, [
1827
+ 'class',
1828
+ 'constructor',
1829
+ ])) ||
1830
+ isGetter(node) && (
1831
+ !checkGetters ||
1832
+ checkGetters === 'no-setter' && hasAccessorPair(
1833
+ /** @type {import('./iterateJsdoc.js').Node} */
1834
+ (/** @type {import('./iterateJsdoc.js').Node} */ (node).parent),
1835
+ )
1836
+ ) ||
1837
+ isSetter(node) && (
1838
+ !checkSetters ||
1839
+ checkSetters === 'no-getter' && hasAccessorPair(
1840
+ /** @type {import('./iterateJsdoc.js').Node} */
1841
+ (/** @type {import('./iterateJsdoc.js').Node} */ (node).parent),
1842
+ )
1843
+ );
1844
+ };
1845
+
1846
+ /**
1847
+ * Since path segments may be unquoted (if matching a reserved word,
1848
+ * identifier or numeric literal) or single or double quoted, in either
1849
+ * the `@param` or in source, we need to strip the quotes to give a fair
1850
+ * comparison.
1851
+ * @param {string} str
1852
+ * @returns {string}
1853
+ */
1854
+ const dropPathSegmentQuotes = (str) => {
1855
+ return str.replaceAll(/\.(['"])(.*)\1/gv, '.$2');
1856
+ };
1857
+
1858
+ /**
1859
+ * @param {string} name
1860
+ * @returns {(otherPathName: string) => boolean}
1861
+ */
1862
+ const comparePaths = (name) => {
1863
+ return (otherPathName) => {
1864
+ return otherPathName === name ||
1865
+ dropPathSegmentQuotes(otherPathName) === dropPathSegmentQuotes(name);
1866
+ };
1867
+ };
1868
+
1869
+ /**
1870
+ * @callback PathDoesNotBeginWith
1871
+ * @param {string} name
1872
+ * @param {string} otherPathName
1873
+ * @returns {boolean}
1874
+ */
1875
+
1876
+ /** @type {PathDoesNotBeginWith} */
1877
+ const pathDoesNotBeginWith = (name, otherPathName) => {
1878
+ return !name.startsWith(otherPathName) &&
1879
+ !dropPathSegmentQuotes(name).startsWith(dropPathSegmentQuotes(otherPathName));
1880
+ };
1881
+
1882
+ /**
1883
+ * @param {string} regexString
1884
+ * @param {string} [requiredFlags]
1885
+ * @returns {RegExp}
1886
+ */
1887
+ const getRegexFromString = (regexString, requiredFlags) => {
1888
+ const match = regexString.match(/^\/(.*)\/([gimyvus]*)$/vs);
1889
+ let flags = 'v';
1890
+ let regex = regexString;
1891
+ if (match) {
1892
+ [
1893
+ , regex,
1894
+ flags,
1895
+ ] = match;
1896
+ if (!flags) {
1897
+ flags = 'v';
1898
+ }
1899
+ }
1900
+
1901
+ const uniqueFlags = [
1902
+ ...new Set(flags + (requiredFlags || '')),
1903
+ ];
1904
+ flags = uniqueFlags.join('');
1905
+
1906
+ return new RegExp(regex, flags);
1907
+ };
1908
+
1909
+ const strictNativeTypes = [
1910
+ 'undefined',
1911
+ 'null',
1912
+ 'boolean',
1913
+ 'number',
1914
+ 'bigint',
1915
+ 'string',
1916
+ 'symbol',
1917
+ 'object',
1918
+ 'Array',
1919
+ 'Function',
1920
+ 'Date',
1921
+ 'RegExp',
1922
+ ];
1923
+
1924
+ /**
1925
+ * @param {import('@es-joy/jsdoccomment').JsdocBlockWithInline} jsdoc
1926
+ * @param {import('@es-joy/jsdoccomment').JsdocTagWithInline} tag
1927
+ * @param {import('jsdoc-type-pratt-parser').RootResult} parsedType
1928
+ * @param {string} indent
1929
+ * @param {string} typeBracketSpacing
1930
+ */
1931
+ const rewireByParsedType = (jsdoc, tag, parsedType, indent, typeBracketSpacing = '') => {
1932
+ const typeLines = stringify(parsedType).split('\n');
1933
+ const firstTypeLine = typeLines.shift();
1934
+ const lastTypeLine = typeLines.pop();
1935
+
1936
+ const beginNameOrDescIdx = tag.source.findIndex(({
1937
+ tokens,
1938
+ }) => {
1939
+ return tokens.name || tokens.description;
1940
+ });
1941
+
1942
+ const nameAndDesc = beginNameOrDescIdx === -1 ?
1943
+ null :
1944
+ tag.source.slice(beginNameOrDescIdx);
1945
+
1946
+ const initialNumber = tag.source[0].number;
1947
+
1948
+ const src = [
1949
+ // Get inevitably present tag from first `tag.source`
1950
+ {
1951
+ number: initialNumber,
1952
+ source: '',
1953
+ tokens: {
1954
+ ...tag.source[0].tokens,
1955
+ ...(typeLines.length || lastTypeLine ? {
1956
+ end: '',
1957
+ name: '',
1958
+ postName: '',
1959
+ postType: '',
1960
+ } : (nameAndDesc ? {
1961
+ name: nameAndDesc[0].tokens.name,
1962
+ postType: ' ',
1963
+ } : {})),
1964
+ type: '{' + typeBracketSpacing + firstTypeLine + (!typeLines.length && lastTypeLine === undefined ? typeBracketSpacing + '}' : ''),
1965
+ },
1966
+ },
1967
+ // Get any intervening type lines
1968
+ ...(typeLines.length ? typeLines.map((typeLine, idx) => {
1969
+ return {
1970
+ number: initialNumber + idx + 1,
1971
+ source: '',
1972
+ tokens: {
1973
+ // Grab any delimiter info from first item
1974
+ ...tag.source[0].tokens,
1975
+ delimiter: tag.source[0].tokens.delimiter === '/**' ? '*' : tag.source[0].tokens.delimiter,
1976
+ end: '',
1977
+ name: '',
1978
+ postName: '',
1979
+ postTag: '',
1980
+ postType: '',
1981
+ start: indent + ' ',
1982
+ tag: '',
1983
+ type: typeLine,
1984
+ },
1985
+ };
1986
+ }) : []),
1987
+ ];
1988
+
1989
+ // Merge any final type line and name and description
1990
+ if (
1991
+ // Name and description may be already included if present with the tag
1992
+ nameAndDesc && beginNameOrDescIdx > 0
1993
+ ) {
1994
+ if (typeLines.length || lastTypeLine !== undefined) {
1995
+ src.push({
1996
+ number: src.length + 1,
1997
+ source: '',
1998
+ tokens: {
1999
+ ...nameAndDesc[0].tokens,
2000
+ type: lastTypeLine + typeBracketSpacing + '}',
2001
+ },
2002
+ });
2003
+ }
2004
+
2005
+ if (
2006
+ // Get any remaining description lines
2007
+ nameAndDesc.length > 1
2008
+ ) {
2009
+ src.push(
2010
+ ...nameAndDesc.slice(1).map(({
2011
+ source,
2012
+ tokens,
2013
+ }, idx) => {
2014
+ return {
2015
+ number: src.length + idx + 2,
2016
+ source,
2017
+ tokens,
2018
+ };
2019
+ }),
2020
+ );
2021
+ }
2022
+ } else if (nameAndDesc) {
2023
+ if ((typeLines.length || lastTypeLine !== undefined) && lastTypeLine) {
2024
+ src.push({
2025
+ number: src.length + 1,
2026
+ source: '',
2027
+ tokens: {
2028
+ ...nameAndDesc[0].tokens,
2029
+ delimiter: nameAndDesc[0].tokens.delimiter === '/**' ? '*' : nameAndDesc[0].tokens.delimiter,
2030
+ postTag: '',
2031
+ start: indent + ' ',
2032
+ tag: '',
2033
+ type: lastTypeLine + typeBracketSpacing + '}',
2034
+ },
2035
+ });
2036
+ }
2037
+
2038
+ if (
2039
+ // Get any remaining description lines
2040
+ nameAndDesc.length > 1
2041
+ ) {
2042
+ src.push(
2043
+ ...nameAndDesc.slice(1).map(({
2044
+ source,
2045
+ tokens,
2046
+ }, idx) => {
2047
+ return {
2048
+ number: src.length + idx + 2,
2049
+ source,
2050
+ tokens,
2051
+ };
2052
+ }),
2053
+ );
2054
+ }
2055
+ } else if (lastTypeLine) {
2056
+ src.push({
2057
+ number: src.length + 1,
2058
+ source: '',
2059
+ tokens: {
2060
+ ...tag.source[0].tokens,
2061
+ delimiter: tag.source[0].tokens.delimiter === '/**' ? '*' : tag.source[0].tokens.delimiter,
2062
+ postTag: '',
2063
+ start: indent + ' ',
2064
+ tag: '',
2065
+ type: lastTypeLine + typeBracketSpacing + '}',
2066
+ },
2067
+ });
2068
+ }
2069
+
2070
+ tag.source = src;
2071
+
2072
+ // Properly rewire `jsdoc.source`
2073
+ const firstTagIdx = jsdoc.source.findIndex(({
2074
+ tokens: {
2075
+ tag: tg,
2076
+ },
2077
+ }) => {
2078
+ return tg;
2079
+ });
2080
+
2081
+ const initialEndSource = jsdoc.source.find(({
2082
+ tokens: {
2083
+ end,
2084
+ },
2085
+ }) => {
2086
+ return end;
2087
+ });
2088
+
2089
+ jsdoc.source = [
2090
+ ...jsdoc.source.slice(0, firstTagIdx),
2091
+ ...jsdoc.tags.flatMap(({
2092
+ source,
2093
+ }) => {
2094
+ return source;
2095
+ }),
2096
+ ];
2097
+
2098
+ if (initialEndSource && !jsdoc.source.at(-1)?.tokens?.end) {
2099
+ jsdoc.source.push(initialEndSource);
2100
+ }
2101
+ };
2102
+
2103
+ export {
2104
+ comparePaths,
2105
+ dropPathSegmentQuotes,
2106
+ enforcedContexts,
2107
+ exemptSpeciaMethods,
2108
+ filterTags,
2109
+ flattenRoots,
2110
+ forEachPreferredTag,
2111
+ getAllTags,
2112
+ getContextObject,
2113
+ getFunctionParameterNames,
2114
+ getIndent,
2115
+ getInlineTags,
2116
+ getJsdocTagsDeep,
2117
+ getPreferredTagName,
2118
+ getPreferredTagNameSimple,
2119
+ getRegexFromString,
2120
+ getTagDescription,
2121
+ getTags,
2122
+ getTagsByType,
2123
+ getTagStructureForMode,
2124
+ hasATag,
2125
+ hasParams,
2126
+
2127
+ hasTag,
2128
+ hasThrowValue,
2129
+
2130
+ hasYieldValue,
2131
+ isConstructor,
2132
+ isGetter,
2133
+ isNameOrNamepathDefiningTag,
2134
+ isNamepathOrUrlReferencingTag,
2135
+ isNamepathReferencingTag,
2136
+ isSetter,
2137
+ isValidTag,
2138
+ mayBeUndefinedTypeTag,
2139
+ overrideTagStructure,
2140
+ parseClosureTemplateTag,
2141
+ pathDoesNotBeginWith,
2142
+ rewireByParsedType,
2143
+ setTagStructure,
2144
+ strictNativeTypes,
2145
+ tagMightHaveEitherTypeOrNamePosition,
2146
+ tagMightHaveName,
2147
+ tagMightHaveNameOrNamepath,
2148
+ tagMightHaveNamepath,
2149
+ tagMightHaveNamePosition,
2150
+ tagMightHaveTypePosition,
2151
+ tagMissingRequiredTypeOrNamepath,
2152
+ tagMustHaveNamePosition,
2153
+ tagMustHaveTypePosition,
2154
+ };
2155
+ export {
2156
+ hasReturnValue,
2157
+ hasValueOrExecutorHasNonEmptyResolveValue,
2158
+ } from './utils/hasReturnValue.js';