eslint-plugin-jsdoc 50.6.17 → 50.7.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 (155) hide show
  1. package/dist/alignTransform.cjs +10 -10
  2. package/dist/alignTransform.cjs.map +1 -1
  3. package/dist/exportParser.cjs +141 -135
  4. package/dist/exportParser.cjs.map +1 -1
  5. package/dist/generateRule.cjs +10 -12
  6. package/dist/generateRule.cjs.map +1 -1
  7. package/dist/getDefaultTagStructureForMode.cjs +73 -73
  8. package/dist/getDefaultTagStructureForMode.cjs.map +1 -1
  9. package/dist/getJsdocProcessorPlugin.cjs +121 -110
  10. package/dist/getJsdocProcessorPlugin.cjs.map +1 -1
  11. package/dist/index.cjs +17 -12
  12. package/dist/index.cjs.map +1 -1
  13. package/dist/index.d.ts +4 -3
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/iterateJsdoc.cjs +87 -66
  16. package/dist/iterateJsdoc.cjs.map +1 -1
  17. package/dist/jsdocUtils.cjs +144 -142
  18. package/dist/jsdocUtils.cjs.map +1 -1
  19. package/dist/rules/checkAlignment.cjs +2 -2
  20. package/dist/rules/checkAlignment.cjs.map +1 -1
  21. package/dist/rules/checkExamples.cjs +22 -28
  22. package/dist/rules/checkExamples.cjs.map +1 -1
  23. package/dist/rules/checkIndentation.cjs +2 -2
  24. package/dist/rules/checkIndentation.cjs.map +1 -1
  25. package/dist/rules/checkLineAlignment.cjs +14 -14
  26. package/dist/rules/checkLineAlignment.cjs.map +1 -1
  27. package/dist/rules/checkParamNames.cjs +21 -15
  28. package/dist/rules/checkParamNames.cjs.map +1 -1
  29. package/dist/rules/checkPropertyNames.cjs +2 -2
  30. package/dist/rules/checkPropertyNames.cjs.map +1 -1
  31. package/dist/rules/checkTagNames.cjs +11 -11
  32. package/dist/rules/checkTagNames.cjs.map +1 -1
  33. package/dist/rules/checkTemplateNames.cjs +21 -22
  34. package/dist/rules/checkTemplateNames.cjs.map +1 -1
  35. package/dist/rules/checkTypes.cjs +10 -10
  36. package/dist/rules/checkTypes.cjs.map +1 -1
  37. package/dist/rules/checkValues.cjs +11 -14
  38. package/dist/rules/checkValues.cjs.map +1 -1
  39. package/dist/rules/convertToJsdocComments.cjs +26 -27
  40. package/dist/rules/convertToJsdocComments.cjs.map +1 -1
  41. package/dist/rules/emptyTags.cjs +6 -6
  42. package/dist/rules/emptyTags.cjs.map +1 -1
  43. package/dist/rules/importsAsDependencies.cjs.map +1 -1
  44. package/dist/rules/informativeDocs.cjs +12 -12
  45. package/dist/rules/informativeDocs.cjs.map +1 -1
  46. package/dist/rules/linesBeforeBlock.cjs +12 -12
  47. package/dist/rules/linesBeforeBlock.cjs.map +1 -1
  48. package/dist/rules/matchDescription.cjs +1 -1
  49. package/dist/rules/matchDescription.cjs.map +1 -1
  50. package/dist/rules/matchName.cjs +4 -4
  51. package/dist/rules/matchName.cjs.map +1 -1
  52. package/dist/rules/multilineBlocks.cjs +10 -10
  53. package/dist/rules/multilineBlocks.cjs.map +1 -1
  54. package/dist/rules/noBadBlocks.cjs +3 -3
  55. package/dist/rules/noBadBlocks.cjs.map +1 -1
  56. package/dist/rules/noMultiAsterisks.cjs +6 -6
  57. package/dist/rules/noMultiAsterisks.cjs.map +1 -1
  58. package/dist/rules/noRestrictedSyntax.cjs +2 -2
  59. package/dist/rules/noRestrictedSyntax.cjs.map +1 -1
  60. package/dist/rules/noTypes.cjs.map +1 -1
  61. package/dist/rules/noUndefinedTypes.cjs +17 -20
  62. package/dist/rules/noUndefinedTypes.cjs.map +1 -1
  63. package/dist/rules/requireAsteriskPrefix.cjs +4 -4
  64. package/dist/rules/requireAsteriskPrefix.cjs.map +1 -1
  65. package/dist/rules/requireDescription.cjs +2 -2
  66. package/dist/rules/requireDescription.cjs.map +1 -1
  67. package/dist/rules/requireDescriptionCompleteSentence.cjs +8 -8
  68. package/dist/rules/requireDescriptionCompleteSentence.cjs.map +1 -1
  69. package/dist/rules/requireFileOverview.cjs +6 -6
  70. package/dist/rules/requireFileOverview.cjs.map +1 -1
  71. package/dist/rules/requireHyphenBeforeParamDescription.cjs +1 -4
  72. package/dist/rules/requireHyphenBeforeParamDescription.cjs.map +1 -1
  73. package/dist/rules/requireJsdoc.cjs +19 -19
  74. package/dist/rules/requireJsdoc.cjs.map +1 -1
  75. package/dist/rules/requireParam.cjs +12 -12
  76. package/dist/rules/requireParam.cjs.map +1 -1
  77. package/dist/rules/requireProperty.cjs +1 -1
  78. package/dist/rules/requireProperty.cjs.map +1 -1
  79. package/dist/rules/requireReturns.cjs +3 -3
  80. package/dist/rules/requireReturns.cjs.map +1 -1
  81. package/dist/rules/requireReturnsCheck.cjs +1 -1
  82. package/dist/rules/requireReturnsCheck.cjs.map +1 -1
  83. package/dist/rules/requireReturnsDescription.cjs +1 -1
  84. package/dist/rules/requireReturnsDescription.cjs.map +1 -1
  85. package/dist/rules/requireTemplate.cjs +16 -15
  86. package/dist/rules/requireTemplate.cjs.map +1 -1
  87. package/dist/rules/requireYields.cjs +4 -4
  88. package/dist/rules/requireYields.cjs.map +1 -1
  89. package/dist/rules/requireYieldsCheck.cjs +6 -6
  90. package/dist/rules/requireYieldsCheck.cjs.map +1 -1
  91. package/dist/rules/sortTags.cjs +13 -13
  92. package/dist/rules/sortTags.cjs.map +1 -1
  93. package/dist/rules/tagLines.cjs +11 -11
  94. package/dist/rules/tagLines.cjs.map +1 -1
  95. package/dist/rules/textEscaping.cjs +2 -2
  96. package/dist/rules/textEscaping.cjs.map +1 -1
  97. package/dist/rules/validTypes.cjs +15 -15
  98. package/dist/rules/validTypes.cjs.map +1 -1
  99. package/dist/tagNames.cjs +1 -1
  100. package/dist/tagNames.cjs.map +1 -1
  101. package/dist/utils/hasReturnValue.cjs +176 -176
  102. package/dist/utils/hasReturnValue.cjs.map +1 -1
  103. package/eslint.config.js +36 -32
  104. package/package.json +30 -30
  105. package/pnpm-workspace.yaml +1 -0
  106. package/src/alignTransform.js +15 -15
  107. package/src/exportParser.js +386 -373
  108. package/src/getDefaultTagStructureForMode.js +45 -45
  109. package/src/getJsdocProcessorPlugin.js +175 -128
  110. package/src/index.js +66 -37
  111. package/src/iterateJsdoc.js +61 -28
  112. package/src/jsdocUtils.js +354 -338
  113. package/src/rules/checkAlignment.js +2 -2
  114. package/src/rules/checkExamples.js +16 -20
  115. package/src/rules/checkIndentation.js +2 -2
  116. package/src/rules/checkLineAlignment.js +10 -10
  117. package/src/rules/checkParamNames.js +22 -14
  118. package/src/rules/checkPropertyNames.js +1 -1
  119. package/src/rules/checkTagNames.js +7 -7
  120. package/src/rules/checkTemplateNames.js +52 -38
  121. package/src/rules/checkTypes.js +7 -7
  122. package/src/rules/checkValues.js +16 -17
  123. package/src/rules/convertToJsdocComments.js +47 -37
  124. package/src/rules/emptyTags.js +14 -7
  125. package/src/rules/importsAsDependencies.js +3 -1
  126. package/src/rules/informativeDocs.js +58 -58
  127. package/src/rules/linesBeforeBlock.js +25 -17
  128. package/src/rules/matchDescription.js +1 -1
  129. package/src/rules/matchName.js +2 -2
  130. package/src/rules/multilineBlocks.js +10 -10
  131. package/src/rules/noBadBlocks.js +3 -3
  132. package/src/rules/noMultiAsterisks.js +4 -4
  133. package/src/rules/noRestrictedSyntax.js +1 -1
  134. package/src/rules/noTypes.js +1 -1
  135. package/src/rules/noUndefinedTypes.js +29 -23
  136. package/src/rules/requireAsteriskPrefix.js +3 -3
  137. package/src/rules/requireDescription.js +1 -1
  138. package/src/rules/requireDescriptionCompleteSentence.js +6 -6
  139. package/src/rules/requireFileOverview.js +3 -3
  140. package/src/rules/requireHyphenBeforeParamDescription.js +2 -5
  141. package/src/rules/requireJsdoc.js +14 -14
  142. package/src/rules/requireParam.js +9 -9
  143. package/src/rules/requireProperty.js +1 -1
  144. package/src/rules/requireReturns.js +1 -1
  145. package/src/rules/requireReturnsCheck.js +1 -1
  146. package/src/rules/requireReturnsDescription.js +1 -1
  147. package/src/rules/requireTemplate.js +59 -38
  148. package/src/rules/requireYields.js +3 -3
  149. package/src/rules/requireYieldsCheck.js +1 -1
  150. package/src/rules/sortTags.js +7 -7
  151. package/src/rules/tagLines.js +8 -8
  152. package/src/rules/textEscaping.js +2 -0
  153. package/src/rules/validTypes.js +29 -29
  154. package/src/tagNames.js +2 -2
  155. package/src/utils/hasReturnValue.js +298 -283
@@ -152,14 +152,14 @@ const getDefaultTagStructureForMode = (mode) => {
152
152
 
153
153
  [
154
154
  'class', new Map(/** @type {[string, string|boolean][]} */ ([
155
- // Allows for "name"'s in signature, but indicated as optional
155
+ // Not in use, but should be this value if using to power `empty-tags`
156
156
  [
157
- 'namepathRole', 'namepath-defining',
157
+ 'nameAllowed', true,
158
158
  ],
159
159
 
160
- // Not in use, but should be this value if using to power `empty-tags`
160
+ // Allows for "name"'s in signature, but indicated as optional
161
161
  [
162
- 'nameAllowed', true,
162
+ 'namepathRole', 'namepath-defining',
163
163
  ],
164
164
 
165
165
  [
@@ -258,17 +258,17 @@ const getDefaultTagStructureForMode = (mode) => {
258
258
 
259
259
  [
260
260
  'event', new Map(/** @type {[string, string|boolean][]} */ ([
261
- // The doc signature of `event` seems to require a "name"
262
- [
263
- 'nameRequired', true,
264
- ],
265
-
266
261
  // Appears to require a "name" in its signature, albeit somewhat
267
262
  // different from other "name"'s (including as described
268
263
  // at https://jsdoc.app/about-namepaths.html )
269
264
  [
270
265
  'namepathRole', 'namepath-defining',
271
266
  ],
267
+
268
+ // The doc signature of `event` seems to require a "name"
269
+ [
270
+ 'nameRequired', true,
271
+ ],
272
272
  ])),
273
273
  ],
274
274
 
@@ -313,13 +313,13 @@ const getDefaultTagStructureForMode = (mode) => {
313
313
  'namepathRole', 'namepath-referencing',
314
314
  ],
315
315
 
316
- // Does not show curly brackets in either the signature or examples
317
316
  [
318
- 'typeAllowed', isTypescriptOrClosure || isPermissive,
317
+ 'nameRequired', isJsdoc,
319
318
  ],
320
319
 
320
+ // Does not show curly brackets in either the signature or examples
321
321
  [
322
- 'nameRequired', isJsdoc,
322
+ 'typeAllowed', isTypescriptOrClosure || isPermissive,
323
323
  ],
324
324
 
325
325
  // "namepath"
@@ -367,6 +367,14 @@ const getDefaultTagStructureForMode = (mode) => {
367
367
  ])),
368
368
  ],
369
369
 
370
+ [
371
+ 'func', new Map(/** @type {[string, string|boolean][]} */ ([
372
+ // Allows for "name"'s in signature, but indicated as optional
373
+ [
374
+ 'namepathRole', 'namepath-defining',
375
+ ],
376
+ ])),
377
+ ],
370
378
  [
371
379
  'function', new Map(/** @type {[string, string|boolean][]} */ ([
372
380
  // Allows for "name"'s in signature, but indicated as optional
@@ -383,14 +391,6 @@ const getDefaultTagStructureForMode = (mode) => {
383
391
  ],
384
392
  ])),
385
393
  ],
386
- [
387
- 'func', new Map(/** @type {[string, string|boolean][]} */ ([
388
- // Allows for "name"'s in signature, but indicated as optional
389
- [
390
- 'namepathRole', 'namepath-defining',
391
- ],
392
- ])),
393
- ],
394
394
 
395
395
  [
396
396
  'host', new Map(/** @type {[string, string|boolean][]} */ ([
@@ -413,18 +413,28 @@ const getDefaultTagStructureForMode = (mode) => {
413
413
  ],
414
414
 
415
415
  [
416
- 'interface', new Map(/** @type {[string, string|boolean][]} */ ([
417
- // Allows for "name" in signature, but indicates as optional
416
+ 'implements', new Map(/** @type {[string, string|boolean][]} */ ([
417
+ // Shows curly brackets in the doc signature and examples
418
+ // "typeExpression"
418
419
  [
419
- 'namepathRole',
420
- isJsdocTypescriptOrPermissive ? 'namepath-defining' : false,
420
+ 'typeRequired', true,
421
421
  ],
422
+ ])),
423
+ ],
422
424
 
425
+ [
426
+ 'interface', new Map(/** @type {[string, string|boolean][]} */ ([
423
427
  // Not in use, but should be this value if using to power `empty-tags`
424
428
  [
425
429
  'nameAllowed', isClosure,
426
430
  ],
427
431
 
432
+ // Allows for "name" in signature, but indicates as optional
433
+ [
434
+ 'namepathRole',
435
+ isJsdocTypescriptOrPermissive ? 'namepath-defining' : false,
436
+ ],
437
+
428
438
  [
429
439
  'typeAllowed', false,
430
440
  ],
@@ -433,23 +443,13 @@ const getDefaultTagStructureForMode = (mode) => {
433
443
 
434
444
  [
435
445
  'internal', new Map(/** @type {[string, string|boolean][]} */ ([
436
- // https://www.typescriptlang.org/tsconfig/#stripInternal
437
- [
438
- 'namepathRole', false,
439
- ],
440
446
  // Not in use, but should be this value if using to power `empty-tags`
441
447
  [
442
448
  'nameAllowed', false,
443
449
  ],
444
- ])),
445
- ],
446
-
447
- [
448
- 'implements', new Map(/** @type {[string, string|boolean][]} */ ([
449
- // Shows curly brackets in the doc signature and examples
450
- // "typeExpression"
450
+ // https://www.typescriptlang.org/tsconfig/#stripInternal
451
451
  [
452
- 'typeRequired', true,
452
+ 'namepathRole', false,
453
453
  ],
454
454
  ])),
455
455
  ],
@@ -531,7 +531,7 @@ const getDefaultTagStructureForMode = (mode) => {
531
531
  ],
532
532
 
533
533
  [
534
- 'memberof', new Map(/** @type {[string, string|boolean][]} */ ([
534
+ 'memberof!', new Map(/** @type {[string, string|boolean][]} */ ([
535
535
  // Signature seems to require a "namepath" (and no counter-examples),
536
536
  // though it allows an incomplete namepath ending with connecting symbol
537
537
  [
@@ -545,7 +545,7 @@ const getDefaultTagStructureForMode = (mode) => {
545
545
  ])),
546
546
  ],
547
547
  [
548
- 'memberof!', new Map(/** @type {[string, string|boolean][]} */ ([
548
+ 'memberof', new Map(/** @type {[string, string|boolean][]} */ ([
549
549
  // Signature seems to require a "namepath" (and no counter-examples),
550
550
  // though it allows an incomplete namepath ending with connecting symbol
551
551
  [
@@ -777,7 +777,7 @@ const getDefaultTagStructureForMode = (mode) => {
777
777
  ],
778
778
 
779
779
  [
780
- 'returns', new Map(/** @type {[string, string|boolean][]} */ ([
780
+ 'return', new Map(/** @type {[string, string|boolean][]} */ ([
781
781
  // Shows curly brackets in the signature and in the examples
782
782
  [
783
783
  'typeAllowed', true,
@@ -785,7 +785,7 @@ const getDefaultTagStructureForMode = (mode) => {
785
785
  ])),
786
786
  ],
787
787
  [
788
- 'return', new Map(/** @type {[string, string|boolean][]} */ ([
788
+ 'returns', new Map(/** @type {[string, string|boolean][]} */ ([
789
789
  // Shows curly brackets in the signature and in the examples
790
790
  [
791
791
  'typeAllowed', true,
@@ -859,13 +859,13 @@ const getDefaultTagStructureForMode = (mode) => {
859
859
  'namepathRole', isJsdoc ? 'namepath-referencing' : false,
860
860
  ],
861
861
 
862
+ // namepath
862
863
  [
863
- 'typeRequired', isTypescriptOrClosure,
864
+ 'typeOrNameRequired', isJsdoc,
864
865
  ],
865
866
 
866
- // namepath
867
867
  [
868
- 'typeOrNameRequired', isJsdoc,
868
+ 'typeRequired', isTypescriptOrClosure,
869
869
  ],
870
870
  ])),
871
871
  ],
@@ -948,7 +948,7 @@ const getDefaultTagStructureForMode = (mode) => {
948
948
  ],
949
949
 
950
950
  [
951
- 'yields', new Map(/** @type {[string, string|boolean][]} */ ([
951
+ 'yield', new Map(/** @type {[string, string|boolean][]} */ ([
952
952
  // Shows curly brackets in the signature and in the examples
953
953
  [
954
954
  'typeAllowed', true,
@@ -956,7 +956,7 @@ const getDefaultTagStructureForMode = (mode) => {
956
956
  ])),
957
957
  ],
958
958
  [
959
- 'yield', new Map(/** @type {[string, string|boolean][]} */ ([
959
+ 'yields', new Map(/** @type {[string, string|boolean][]} */ ([
960
960
  // Shows curly brackets in the signature and in the examples
961
961
  [
962
962
  'typeAllowed', true,
@@ -1,25 +1,32 @@
1
- // Todo: Support TS by fenced block type
2
-
3
- import {readFileSync} from 'node:fs';
4
- import { dirname, join } from 'node:path';
5
- import { fileURLToPath } from 'node:url';
6
- import * as espree from 'espree';
7
1
  import {
8
- getRegexFromString,
9
2
  forEachPreferredTag,
10
- getTagDescription,
11
3
  getPreferredTagName,
4
+ getRegexFromString,
5
+ getTagDescription,
12
6
  hasTag,
13
7
  } from './jsdocUtils.js';
14
8
  import {
15
9
  parseComment,
16
10
  } from '@es-joy/jsdoccomment';
11
+ import * as espree from 'espree';
12
+ import {
13
+ readFileSync,
14
+ } from 'node:fs';
15
+ import {
16
+ dirname as getDirname,
17
+ join,
18
+ } from 'node:path';
19
+ import {
20
+ fileURLToPath,
21
+ } from 'node:url';
17
22
 
18
- const __dirname = dirname(fileURLToPath(import.meta.url));
23
+ const dirname = getDirname(fileURLToPath(import.meta.url));
19
24
 
20
- const {version} = JSON.parse(
25
+ const {
26
+ version,
27
+ } = JSON.parse(
21
28
  // @ts-expect-error `Buffer` is ok for `JSON.parse`
22
- readFileSync(join(__dirname, '../package.json'))
29
+ readFileSync(join(dirname, '../package.json')),
23
30
  );
24
31
 
25
32
  // const zeroBasedLineIndexAdjust = -1;
@@ -51,20 +58,20 @@ const countChars = (str, ch) => {
51
58
  /**
52
59
  * @param {string} text
53
60
  * @returns {[
54
- * import('./iterateJsdoc.js').Integer,
55
- * import('./iterateJsdoc.js').Integer
56
- * ]}
57
- */
61
+ * import('./iterateJsdoc.js').Integer,
62
+ * import('./iterateJsdoc.js').Integer
63
+ * ]}
64
+ */
58
65
  const getLinesCols = (text) => {
59
- const matchLines = countChars(text, '\n');
66
+ const matchLines = countChars(text, '\n');
60
67
 
61
- const colDelta = matchLines ?
62
- text.slice(text.lastIndexOf('\n') + 1).length :
63
- text.length;
68
+ const colDelta = matchLines ?
69
+ text.slice(text.lastIndexOf('\n') + 1).length :
70
+ text.length;
64
71
 
65
- return [
66
- matchLines, colDelta,
67
- ];
72
+ return [
73
+ matchLines, colDelta,
74
+ ];
68
75
  };
69
76
 
70
77
  /**
@@ -73,20 +80,21 @@ const getLinesCols = (text) => {
73
80
 
74
81
  /**
75
82
  * @typedef {object} JsdocProcessorOptions
76
- * @property {boolean} [captionRequired]
77
- * @property {Integer} [paddedIndent]
78
- * @property {boolean} [checkDefaults]
79
- * @property {boolean} [checkParams]
80
- * @property {boolean} [checkExamples]
81
- * @property {boolean} [checkProperties]
82
- * @property {string} [matchingFileName]
83
- * @property {string} [matchingFileNameDefaults]
84
- * @property {string} [matchingFileNameParams]
85
- * @property {string} [matchingFileNameProperties]
86
- * @property {string} [exampleCodeRegex]
87
- * @property {string} [rejectExampleCodeRegex]
88
- * @property {"script"|"module"} [sourceType]
89
- * @property {import('eslint').Linter.ESTreeParser|import('eslint').Linter.NonESTreeParser} [parser]
83
+ * @property {boolean} [captionRequired] Require captions for example tags
84
+ * @property {Integer} [paddedIndent] See docs
85
+ * @property {boolean} [checkDefaults] See docs
86
+ * @property {boolean} [checkParams] See docs
87
+ * @property {boolean} [checkExamples] See docs
88
+ * @property {boolean} [checkProperties] See docs
89
+ * @property {string} [matchingFileName] See docs
90
+ * @property {string} [matchingFileNameDefaults] See docs
91
+ * @property {string} [matchingFileNameParams] See docs
92
+ * @property {string} [matchingFileNameProperties] See docs
93
+ * @property {string} [exampleCodeRegex] See docs
94
+ * @property {string} [rejectExampleCodeRegex] See docs
95
+ * @property {string[]} [allowedLanguagesToProcess] See docs
96
+ * @property {"script"|"module"} [sourceType] See docs
97
+ * @property {import('eslint').Linter.ESTreeParser|import('eslint').Linter.NonESTreeParser} [parser] See docs
90
98
  */
91
99
 
92
100
  /**
@@ -96,20 +104,23 @@ const getLinesCols = (text) => {
96
104
  */
97
105
  export const getJsdocProcessorPlugin = (options = {}) => {
98
106
  const {
99
- exampleCodeRegex = null,
100
- rejectExampleCodeRegex = null,
101
- checkExamples = true,
107
+ allowedLanguagesToProcess = [
108
+ 'js', 'ts', 'javascript', 'typescript',
109
+ ],
110
+ captionRequired = false,
102
111
  checkDefaults = false,
112
+ checkExamples = true,
103
113
  checkParams = false,
104
114
  checkProperties = false,
115
+ exampleCodeRegex = null,
105
116
  matchingFileName = null,
106
117
  matchingFileNameDefaults = null,
107
118
  matchingFileNameParams = null,
108
119
  matchingFileNameProperties = null,
109
120
  paddedIndent = 0,
110
- captionRequired = false,
121
+ parser = undefined,
122
+ rejectExampleCodeRegex = null,
111
123
  sourceType = 'module',
112
- parser = undefined
113
124
  } = options;
114
125
 
115
126
  /** @type {RegExp} */
@@ -178,18 +189,18 @@ export const getJsdocProcessorPlugin = (options = {}) => {
178
189
  * }} cfg
179
190
  */
180
191
  const checkSource = ({
181
- filename,
182
- ext,
192
+ cols = 0,
183
193
  defaultFileName,
194
+ ext,
195
+ filename,
184
196
  lines = 0,
185
- cols = 0,
186
197
  skipInit,
187
198
  source,
188
- targetTagName,
189
199
  sources = [],
190
200
  tag = {
191
201
  line: 0,
192
202
  },
203
+ targetTagName,
193
204
  }) => {
194
205
  if (!skipInit) {
195
206
  sources.push({
@@ -231,16 +242,16 @@ export const getJsdocProcessorPlugin = (options = {}) => {
231
242
  const codeStartCol = likelyNestedJSDocIndentSpace;
232
243
 
233
244
  textsAndFileNames.push({
234
- text: src,
235
245
  filename: file,
246
+ text: src,
236
247
  });
237
248
  otherInfo.push({
238
- targetTagName,
239
- ext,
240
- codeStartLine,
241
249
  codeStartCol,
250
+ codeStartLine,
251
+ commentLineCols,
252
+ ext,
242
253
  nonJSPrefacingCols,
243
- commentLineCols
254
+ targetTagName,
244
255
  });
245
256
  };
246
257
 
@@ -272,8 +283,8 @@ export const getJsdocProcessorPlugin = (options = {}) => {
272
283
  }
273
284
 
274
285
  return {
275
- ext,
276
286
  defaultFileName,
287
+ ext,
277
288
  filename,
278
289
  };
279
290
  };
@@ -342,11 +353,11 @@ export const getJsdocProcessorPlugin = (options = {}) => {
342
353
 
343
354
  if (captionRequired && (!match || !match[1].trim())) {
344
355
  extraMessages.push({
345
- line: 1 + commentLineCols[0] + (tag.line ?? tag.source[0].number),
346
356
  column: commentLineCols[1] + 1,
347
- severity: 2,
357
+ line: 1 + commentLineCols[0] + (tag.line ?? tag.source[0].number),
348
358
  message: `@${targetTagName} error - Caption is expected for examples.`,
349
- ruleId: 'jsdoc/example-missing-caption'
359
+ ruleId: 'jsdoc/example-missing-caption',
360
+ severity: 2,
350
361
  });
351
362
  return;
352
363
  }
@@ -365,6 +376,16 @@ export const getJsdocProcessorPlugin = (options = {}) => {
365
376
  return;
366
377
  }
367
378
 
379
+ // If `allowedLanguagesToProcess` is falsy, all languages should be processed.
380
+ if (allowedLanguagesToProcess) {
381
+ const matches = (/^\s*```(?<language>\S+)([\s\S]*)```\s*$/u).exec(source);
382
+ if (matches?.groups && !allowedLanguagesToProcess.includes(
383
+ matches.groups.language.toLowerCase(),
384
+ )) {
385
+ return;
386
+ }
387
+ }
388
+
368
389
  const sources = [];
369
390
  let skipInit = false;
370
391
  if (exampleCodeRegex) {
@@ -378,9 +399,9 @@ export const getJsdocProcessorPlugin = (options = {}) => {
378
399
  exampleCodeRegExp.lastIndex = 0;
379
400
  while ((exampleCode = exampleCodeRegExp.exec(source)) !== null) {
380
401
  const {
381
- index,
382
402
  '0': n0,
383
403
  '1': n1,
404
+ index,
384
405
  } = exampleCode;
385
406
 
386
407
  // Count anything preceding user regex match (can affect line numbering)
@@ -475,6 +496,76 @@ export const getJsdocProcessorPlugin = (options = {}) => {
475
496
  name: 'eslint-plugin-jsdoc/preprocessor',
476
497
  version,
477
498
  },
499
+ /**
500
+ * @param {import('eslint').Linter.LintMessage[][]} messages
501
+ * @param {string} filename
502
+ */
503
+ postprocess ([
504
+ jsMessages,
505
+ ...messages
506
+ // eslint-disable-next-line no-unused-vars -- Placeholder
507
+ ], filename) {
508
+ for (const [
509
+ idx,
510
+ message,
511
+ ] of messages.entries()) {
512
+ const {
513
+ codeStartCol,
514
+ codeStartLine,
515
+ commentLineCols,
516
+ nonJSPrefacingCols,
517
+ targetTagName,
518
+ } = otherInfo[idx];
519
+
520
+ for (const msg of message) {
521
+ const {
522
+ column,
523
+ endColumn,
524
+ endLine,
525
+ fatal,
526
+ line,
527
+ message: messageText,
528
+ ruleId,
529
+ severity,
530
+
531
+ // Todo: Make fixable
532
+ // fix
533
+ // fix: {range: [number, number], text: string}
534
+ // suggestions: {desc: , messageId:, fix: }[],
535
+ } = msg;
536
+
537
+ const [
538
+ codeCtxLine,
539
+ codeCtxColumn,
540
+ ] = commentLineCols;
541
+ const startLine = codeCtxLine + codeStartLine + line;
542
+
543
+ // Seems to need one more now
544
+ const startCol = 1 +
545
+ codeCtxColumn + codeStartCol + (
546
+ // This might not work for line 0, but line 0 is unlikely for examples
547
+ line <= 1 ? nonJSPrefacingCols + firstLinePrefixLength : preTagSpaceLength
548
+ ) + column;
549
+
550
+ msg.message = '@' + targetTagName + ' ' + (severity === 2 ? 'error' : 'warning') +
551
+ (ruleId ? ' (' + ruleId + ')' : '') + ': ' +
552
+ (fatal ? 'Fatal: ' : '') +
553
+ messageText;
554
+ msg.line = startLine;
555
+ msg.column = startCol;
556
+ msg.endLine = endLine ? startLine + endLine : startLine;
557
+ // added `- column` to offset what `endColumn` already seemed to include
558
+ msg.endColumn = endColumn ? startCol - column + endColumn : startCol;
559
+ }
560
+ }
561
+
562
+ const ret = [
563
+ ...jsMessages,
564
+ ].concat(...messages, ...extraMessages);
565
+ extraMessages = [];
566
+ return ret;
567
+ },
568
+
478
569
  /**
479
570
  * @param {string} text
480
571
  * @param {string} filename
@@ -485,20 +576,22 @@ export const getJsdocProcessorPlugin = (options = {}) => {
485
576
 
486
577
  // May be running a second time so catch and ignore
487
578
  try {
488
- ast = parser
579
+ ast = parser ?
489
580
  // @ts-expect-error Should be present
490
- ? parser.parseForESLint(text, {
581
+ parser.parseForESLint(text, {
582
+ comment: true,
491
583
  ecmaVersion: 'latest',
492
584
  sourceType,
493
- comment: true
494
- }).ast
495
- : espree.parse(text, {
585
+ }).ast :
586
+ espree.parse(text, {
587
+ comment: true,
496
588
  ecmaVersion: 'latest',
497
589
  sourceType,
498
- comment: true
499
590
  });
500
- } catch (err) {
501
- return [text];
591
+ } catch {
592
+ return [
593
+ text,
594
+ ];
502
595
  }
503
596
 
504
597
  /** @type {[number, number][]} */
@@ -513,18 +606,25 @@ export const getJsdocProcessorPlugin = (options = {}) => {
513
606
  ).filter((comment) => {
514
607
  return (/^\*\s/u).test(comment.value);
515
608
  }).map((comment) => {
516
- /* c8 ignore next -- Unsupporting processors only? */
517
- const [start] = comment.range ?? [];
609
+ const [
610
+ start,
611
+ /* c8 ignore next -- Unsupporting processors only? */
612
+ ] = comment.range ?? [];
518
613
  const textToStart = text.slice(0, start);
519
614
 
520
- const [lines, cols] = getLinesCols(textToStart);
615
+ const [
616
+ lines,
617
+ cols,
618
+ ] = getLinesCols(textToStart);
521
619
 
522
620
  // const lines = [...textToStart.matchAll(/\n/gu)].length
523
621
  // const lastLinePos = textToStart.lastIndexOf('\n');
524
622
  // const cols = lastLinePos === -1
525
623
  // ? 0
526
624
  // : textToStart.slice(lastLinePos).length;
527
- commentLineCols.push([lines, cols]);
625
+ commentLineCols.push([
626
+ lines, cols,
627
+ ]);
528
628
  return parseComment(comment);
529
629
  });
530
630
 
@@ -534,72 +634,19 @@ export const getJsdocProcessorPlugin = (options = {}) => {
534
634
  return getTextsAndFileNames(
535
635
  jsdoc,
536
636
  filename,
537
- commentLineCols[idx]
637
+ commentLineCols[idx],
538
638
  );
539
- }).filter(Boolean)
639
+ }).filter(Boolean),
540
640
  ];
541
- /* c8 ignore next 3 */
542
- } catch (err) {
543
- console.log('err', filename, err);
641
+ /* c8 ignore next 6 */
642
+ } catch (error) {
643
+ // eslint-disable-next-line no-console -- Debugging
644
+ console.log('err', filename, error);
544
645
  }
545
- },
546
646
 
547
- /**
548
- * @param {import('eslint').Linter.LintMessage[][]} messages
549
- * @param {string} filename
550
- */
551
- postprocess ([jsMessages, ...messages], filename) {
552
- messages.forEach((message, idx) => {
553
- const {
554
- targetTagName,
555
- codeStartLine,
556
- codeStartCol,
557
- nonJSPrefacingCols,
558
- commentLineCols
559
- } = otherInfo[idx];
560
-
561
- message.forEach((msg) => {
562
- const {
563
- message,
564
- ruleId,
565
- severity,
566
- fatal,
567
- line,
568
- column,
569
- endColumn,
570
- endLine,
571
-
572
- // Todo: Make fixable
573
- // fix
574
- // fix: {range: [number, number], text: string}
575
- // suggestions: {desc: , messageId:, fix: }[],
576
- } = msg;
577
-
578
- const [codeCtxLine, codeCtxColumn] = commentLineCols;
579
- const startLine = codeCtxLine + codeStartLine + line;
580
- const startCol = 1 + // Seems to need one more now
581
- codeCtxColumn + codeStartCol + (
582
- // This might not work for line 0, but line 0 is unlikely for examples
583
- line <= 1 ? nonJSPrefacingCols + firstLinePrefixLength : preTagSpaceLength
584
- ) + column;
585
-
586
- msg.message = '@' + targetTagName + ' ' + (severity === 2 ? 'error' : 'warning') +
587
- (ruleId ? ' (' + ruleId + ')' : '') + ': ' +
588
- (fatal ? 'Fatal: ' : '') +
589
- message;
590
- msg.line = startLine;
591
- msg.column = startCol;
592
- msg.endLine = endLine ? startLine + endLine : startLine;
593
- // added `- column` to offset what `endColumn` already seemed to include
594
- msg.endColumn = endColumn ? startCol - column + endColumn : startCol;
595
- });
596
- });
597
-
598
- const ret = [...jsMessages].concat(...messages, ...extraMessages);
599
- extraMessages = [];
600
- return ret;
647
+ return [];
601
648
  },
602
- supportsAutofix: true
649
+ supportsAutofix: true,
603
650
  },
604
651
  },
605
652
  };