eslint-plugin-jsdoc 63.0.0 → 63.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/dist/cjs/jsdocUtils.d.ts +10 -0
  2. package/dist/jsdocUtils.cjs +30 -2
  3. package/dist/jsdocUtils.cjs.map +1 -1
  4. package/dist/jsdocUtils.d.ts +10 -0
  5. package/dist/rules/emptyTags.cjs +14 -1
  6. package/dist/rules/emptyTags.cjs.map +1 -1
  7. package/dist/rules/implementsOnClasses.cjs +1 -1
  8. package/dist/rules/implementsOnClasses.cjs.map +1 -1
  9. package/dist/rules/matchDescription.cjs +1 -1
  10. package/dist/rules/matchDescription.cjs.map +1 -1
  11. package/dist/rules/matchName.cjs +1 -1
  12. package/dist/rules/matchName.cjs.map +1 -1
  13. package/dist/rules/noDefaults.cjs +1 -1
  14. package/dist/rules/noDefaults.cjs.map +1 -1
  15. package/dist/rules/noMissingSyntax.cjs +1 -1
  16. package/dist/rules/noMissingSyntax.cjs.map +1 -1
  17. package/dist/rules/noRestrictedSyntax.cjs +1 -1
  18. package/dist/rules/noRestrictedSyntax.cjs.map +1 -1
  19. package/dist/rules/noTypes.cjs +1 -1
  20. package/dist/rules/noTypes.cjs.map +1 -1
  21. package/dist/rules/noUndefinedTypes.cjs +3 -12
  22. package/dist/rules/noUndefinedTypes.cjs.map +1 -1
  23. package/dist/rules/requireDescription.cjs +1 -1
  24. package/dist/rules/requireDescription.cjs.map +1 -1
  25. package/dist/rules/requireExample.cjs +1 -1
  26. package/dist/rules/requireExample.cjs.map +1 -1
  27. package/dist/rules/requireJsdoc.cjs +1 -1
  28. package/dist/rules/requireJsdoc.cjs.map +1 -1
  29. package/dist/rules/requireParam.cjs +1 -1
  30. package/dist/rules/requireParam.cjs.map +1 -1
  31. package/dist/rules/requireParamDescription.cjs +1 -1
  32. package/dist/rules/requireParamDescription.cjs.map +1 -1
  33. package/dist/rules/requireParamName.cjs +1 -1
  34. package/dist/rules/requireParamName.cjs.map +1 -1
  35. package/dist/rules/requireParamType.cjs +1 -1
  36. package/dist/rules/requireParamType.cjs.map +1 -1
  37. package/dist/rules/requireReturnsCheck.cjs +86 -1
  38. package/dist/rules/requireReturnsCheck.cjs.map +1 -1
  39. package/dist/rules/requireReturnsDescription.cjs +1 -1
  40. package/dist/rules/requireReturnsDescription.cjs.map +1 -1
  41. package/dist/rules/requireReturnsType.cjs +1 -1
  42. package/dist/rules/requireReturnsType.cjs.map +1 -1
  43. package/dist/rules.d.ts +16 -16
  44. package/package.json +13 -13
  45. package/src/jsdocUtils.js +38 -0
  46. package/src/rules/emptyTags.js +14 -0
  47. package/src/rules/implementsOnClasses.js +1 -1
  48. package/src/rules/matchDescription.js +1 -1
  49. package/src/rules/matchName.js +1 -1
  50. package/src/rules/noDefaults.js +1 -1
  51. package/src/rules/noMissingSyntax.js +1 -1
  52. package/src/rules/noRestrictedSyntax.js +1 -1
  53. package/src/rules/noTypes.js +1 -1
  54. package/src/rules/noUndefinedTypes.js +6 -21
  55. package/src/rules/requireDescription.js +1 -1
  56. package/src/rules/requireExample.js +1 -1
  57. package/src/rules/requireJsdoc.js +1 -1
  58. package/src/rules/requireParam.js +1 -1
  59. package/src/rules/requireParamDescription.js +1 -1
  60. package/src/rules/requireParamName.js +1 -1
  61. package/src/rules/requireParamType.js +1 -1
  62. package/src/rules/requireReturnsCheck.js +110 -1
  63. package/src/rules/requireReturnsDescription.js +1 -1
  64. package/src/rules/requireReturnsType.js +1 -1
  65. package/src/rules.d.ts +16 -16
package/dist/rules.d.ts CHANGED
@@ -575,7 +575,7 @@ export interface Rules {
575
575
  * expression, i.e., `@callback` or `@function` (or its aliases `@func` or
576
576
  * `@method`) (including those associated with an `@interface`).
577
577
  *
578
- * See the ["AST and Selectors"](../#advanced-ast-and-selectors)
578
+ * See the ["AST and Selectors"](../advanced.md#ast-and-selectors)
579
579
  * section of our Advanced docs for more on the expected format.
580
580
  */
581
581
  contexts?: (
@@ -705,7 +705,7 @@ export interface Rules {
705
705
  * `FunctionExpression`). Set to `"any"` if you want the rule to apply to any
706
706
  * JSDoc block throughout your files.
707
707
  *
708
- * See the ["AST and Selectors"](../#advanced-ast-and-selectors)
708
+ * See the ["AST and Selectors"](../advanced.md#ast-and-selectors)
709
709
  * section of our Advanced docs for more on the expected format.
710
710
  */
711
711
  contexts?: (
@@ -900,7 +900,7 @@ export interface Rules {
900
900
  /**
901
901
  * AST to confine the allowing or disallowing to JSDoc blocks
902
902
  * associated with a particular context. See the
903
- * ["AST and Selectors"](../#advanced-ast-and-selectors)
903
+ * ["AST and Selectors"](../advanced.md#ast-and-selectors)
904
904
  * section of our Advanced docs for more on the expected format.
905
905
  */
906
906
  context?: string;
@@ -1087,7 +1087,7 @@ export interface Rules {
1087
1087
  * expression, i.e., `@callback` or `@function` (or its aliases `@func` or
1088
1088
  * `@method`) (including those associated with an `@interface`).
1089
1089
  *
1090
- * See the ["AST and Selectors"](../#advanced-ast-and-selectors)
1090
+ * See the ["AST and Selectors"](../advanced.md#ast-and-selectors)
1091
1091
  * section of our Advanced docs for more on the expected format.
1092
1092
  */
1093
1093
  contexts?: (
@@ -1133,7 +1133,7 @@ export interface Rules {
1133
1133
  * function declaration or expression, i.e., `@callback` or `@function` (or its
1134
1134
  * aliases `@func` or `@method`) (including those associated with an `@interface`).
1135
1135
  *
1136
- * See the ["AST and Selectors"](../#advanced-ast-and-selectors)
1136
+ * See the ["AST and Selectors"](../advanced.md#ast-and-selectors)
1137
1137
  * section of our Advanced docs for more on the expected format.
1138
1138
  */
1139
1139
  contexts?: (
@@ -1215,7 +1215,7 @@ export interface Rules {
1215
1215
  * function declaration or expression, i.e., `@callback` or `@function` (or its
1216
1216
  * aliases `@func` or `@method`) (including those associated with an `@interface`).
1217
1217
  *
1218
- * See the ["AST and Selectors"](../#advanced-ast-and-selectors)
1218
+ * See the ["AST and Selectors"](../advanced.md#ast-and-selectors)
1219
1219
  * section of our Advanced docs for more on the expected format.
1220
1220
  */
1221
1221
  contexts: (
@@ -1248,7 +1248,7 @@ export interface Rules {
1248
1248
  * expression, i.e., `@callback` or `@function` (or its aliases `@func` or
1249
1249
  * `@method`) (including those associated with an `@interface`).
1250
1250
  *
1251
- * See the ["AST and Selectors"](../#advanced-ast-and-selectors)
1251
+ * See the ["AST and Selectors"](../advanced.md#ast-and-selectors)
1252
1252
  * section of our Advanced docs for more on the expected format.
1253
1253
  */
1254
1254
  contexts?: (
@@ -1396,7 +1396,7 @@ export interface Rules {
1396
1396
  * expression, i.e., `@callback` or `@function` (or its aliases `@func` or
1397
1397
  * `@method`) (including those associated with an `@interface`).
1398
1398
  *
1399
- * See the ["AST and Selectors"](../#advanced-ast-and-selectors)
1399
+ * See the ["AST and Selectors"](../advanced.md#ast-and-selectors)
1400
1400
  * section of our Advanced docs for more on the expected format.
1401
1401
  */
1402
1402
  contexts?: (
@@ -1495,7 +1495,7 @@ export interface Rules {
1495
1495
  * `FunctionExpression`). Set to `"any"` if you want the rule to apply to any
1496
1496
  * JSDoc block throughout your files.
1497
1497
  *
1498
- * See the ["AST and Selectors"](../#advanced-ast-and-selectors)
1498
+ * See the ["AST and Selectors"](../advanced.md#ast-and-selectors)
1499
1499
  * section of our Advanced docs for more on the expected format.
1500
1500
  */
1501
1501
  contexts?: (
@@ -1681,7 +1681,7 @@ export interface Rules {
1681
1681
  * Note that you may need to disable `require` items (e.g., `MethodDefinition`)
1682
1682
  * if you are specifying a more precise form in `contexts` (e.g., `MethodDefinition:not([accessibility="private"] > FunctionExpression`).
1683
1683
  *
1684
- * See the ["AST and Selectors"](../#advanced-ast-and-selectors)
1684
+ * See the ["AST and Selectors"](../advanced.md#ast-and-selectors)
1685
1685
  * section of our Advanced docs for more on the expected format.
1686
1686
  */
1687
1687
  contexts?: (
@@ -1938,7 +1938,7 @@ export interface Rules {
1938
1938
  * `TSMethodSignature` in TypeScript or restricting the contexts
1939
1939
  * which are checked.
1940
1940
  *
1941
- * See the ["AST and Selectors"](../#advanced-ast-and-selectors)
1941
+ * See the ["AST and Selectors"](../advanced.md#ast-and-selectors)
1942
1942
  * section of our Advanced docs for more on the expected format.
1943
1943
  */
1944
1944
  contexts?: (
@@ -2090,7 +2090,7 @@ export interface Rules {
2090
2090
  * expression, i.e., `@callback` or `@function` (or its aliases `@func` or
2091
2091
  * `@method`) (including those associated with an `@interface`).
2092
2092
  *
2093
- * See the ["AST and Selectors"](../#advanced-ast-and-selectors)
2093
+ * See the ["AST and Selectors"](../advanced.md#ast-and-selectors)
2094
2094
  * section of our Advanced docs for more on the expected format.
2095
2095
  */
2096
2096
  contexts?: (
@@ -2134,7 +2134,7 @@ export interface Rules {
2134
2134
  * expression, i.e., `@callback` or `@function` (or its aliases `@func` or
2135
2135
  * `@method`) (including those associated with an `@interface`).
2136
2136
  *
2137
- * See the ["AST and Selectors"](../#advanced-ast-and-selectors)
2137
+ * See the ["AST and Selectors"](../advanced.md#ast-and-selectors)
2138
2138
  * section of our Advanced docs for more on the expected format.
2139
2139
  */
2140
2140
  contexts?: (
@@ -2165,7 +2165,7 @@ export interface Rules {
2165
2165
  * expression, i.e., `@callback` or `@function` (or its aliases `@func` or
2166
2166
  * `@method`) (including those associated with an `@interface`).
2167
2167
  *
2168
- * See the ["AST and Selectors"](../#advanced-ast-and-selectors)
2168
+ * See the ["AST and Selectors"](../advanced.md#ast-and-selectors)
2169
2169
  * section of our Advanced docs for more on the expected format.
2170
2170
  */
2171
2171
  contexts?: (
@@ -2394,7 +2394,7 @@ export interface Rules {
2394
2394
  * expression, i.e., `@callback` or `@function` (or its aliases `@func` or
2395
2395
  * `@method`) (including those associated with an `@interface`).
2396
2396
  *
2397
- * See the ["AST and Selectors"](../#advanced-ast-and-selectors)
2397
+ * See the ["AST and Selectors"](../advanced.md#ast-and-selectors)
2398
2398
  * section of our Advanced docs for more on the expected format.
2399
2399
  */
2400
2400
  contexts?: (
@@ -2425,7 +2425,7 @@ export interface Rules {
2425
2425
  * expression, i.e., `@callback` or `@function` (or its aliases `@func` or
2426
2426
  * `@method`) (including those associated with an `@interface`).
2427
2427
  *
2428
- * See the ["AST and Selectors"](../#advanced-ast-and-selectors)
2428
+ * See the ["AST and Selectors"](../advanced.md#ast-and-selectors)
2429
2429
  * section of our Advanced docs for more on the expected format.
2430
2430
  */
2431
2431
  contexts?: (
package/package.json CHANGED
@@ -5,24 +5,24 @@
5
5
  "url": "http://gajus.com"
6
6
  },
7
7
  "dependencies": {
8
- "@es-joy/jsdoccomment": "~0.86.0",
8
+ "@es-joy/jsdoccomment": "~0.87.0",
9
9
  "@es-joy/resolve.exports": "1.2.0",
10
10
  "are-docs-informative": "^0.0.2",
11
- "comment-parser": "1.4.6",
11
+ "comment-parser": "1.4.7",
12
12
  "debug": "^4.4.3",
13
13
  "escape-string-regexp": "^4.0.0",
14
14
  "espree": "^11.2.0",
15
15
  "esquery": "^1.7.0",
16
16
  "html-entities": "^2.6.0",
17
- "object-deep-merge": "^2.0.0",
17
+ "object-deep-merge": "^2.0.1",
18
18
  "parse-imports-exports": "^0.2.4",
19
- "semver": "^7.8.0",
19
+ "semver": "^7.8.2",
20
20
  "spdx-expression-parse": "^4.0.0",
21
21
  "to-valid-identifier": "^1.0.0"
22
22
  },
23
23
  "description": "JSDoc linting rules for ESLint.",
24
24
  "devDependencies": {
25
- "@arethetypeswrong/cli": "^0.18.2",
25
+ "@arethetypeswrong/cli": "^0.18.3",
26
26
  "@babel/cli": "8.0.0-rc.5",
27
27
  "@babel/core": "8.0.0-rc.5",
28
28
  "@babel/eslint-parser": "8.0.0-rc.5",
@@ -42,10 +42,10 @@
42
42
  "@types/estree": "^1.0.9",
43
43
  "@types/json-schema": "^7.0.15",
44
44
  "@types/mocha": "^10.0.10",
45
- "@types/node": "^25.9.0",
45
+ "@types/node": "^25.9.2",
46
46
  "@types/semver": "^7.7.1",
47
47
  "@types/spdx-expression-parse": "^4.0.0",
48
- "@typescript-eslint/types": "8.59.4",
48
+ "@typescript-eslint/types": "8.60.1",
49
49
  "babel-plugin-add-module-exports": "^1.0.4",
50
50
  "babel-plugin-istanbul": "^8.0.0",
51
51
  "babel-plugin-transform-import-meta": "^2.3.3",
@@ -53,7 +53,7 @@
53
53
  "camelcase": "^9.0.0",
54
54
  "chai": "^6.2.2",
55
55
  "decamelize": "^6.0.1",
56
- "eslint": "10.4.0",
56
+ "eslint": "10.4.1",
57
57
  "eslint-config-canonical": "^47.4.2",
58
58
  "gitdown": "^4.1.1",
59
59
  "glob": "^13.0.6",
@@ -62,18 +62,18 @@
62
62
  "jsdoc-type-pratt-parser": "^7.2.0",
63
63
  "json-schema": "^0.4.0",
64
64
  "json-schema-to-typescript": "^15.0.4",
65
- "lint-staged": "^17.0.5",
66
- "mocha": "^11.7.5",
65
+ "lint-staged": "^17.0.7",
66
+ "mocha": "^11.7.6",
67
67
  "open-editor": "^6.0.0",
68
68
  "playwright": "^1.60.0",
69
69
  "replace": "^1.2.2",
70
70
  "rimraf": "^6.1.3",
71
- "rollup": "^4.60.4",
71
+ "rollup": "^4.61.1",
72
72
  "semantic-release": "^25.0.3",
73
73
  "sinon": "^22.0.0",
74
74
  "ts-api-utils": "^2.5.0",
75
75
  "typescript": "5.9.3",
76
- "typescript-eslint": "8.59.4"
76
+ "typescript-eslint": "8.60.1"
77
77
  },
78
78
  "engines": {
79
79
  "node": "^22.13.0 || >=24"
@@ -179,5 +179,5 @@
179
179
  "test-cov": "TIMING=1 c8 --reporter text pnpm run test-no-cov",
180
180
  "test-index": "pnpm run test-no-cov test/rules/index.js"
181
181
  },
182
- "version": "63.0.0"
182
+ "version": "63.0.2"
183
183
  }
package/src/jsdocUtils.js CHANGED
@@ -6,6 +6,7 @@ import {
6
6
  } from './tagNames.js';
7
7
  import WarnSettings from './WarnSettings.js';
8
8
  import {
9
+ parseComment,
9
10
  stringify,
10
11
  tryParse,
11
12
  } from '@es-joy/jsdoccomment';
@@ -1084,6 +1085,41 @@ const isNameOrNamepathDefiningTag = (tag, tagMap = tagStructure) => {
1084
1085
  tagStruct.get('namepathRole')));
1085
1086
  };
1086
1087
 
1088
+ /**
1089
+ * @param {import('eslint').SourceCode} sourceCode
1090
+ * @returns {import('@es-joy/jsdoccomment').JsdocBlockWithInline[]}
1091
+ */
1092
+ const getJSDocCommentBlocks = (sourceCode) => {
1093
+ return sourceCode.getAllComments()
1094
+ .filter((comment) => {
1095
+ return (/^\*(?!\*)/v).test(comment.value);
1096
+ })
1097
+ .map((commentNode) => {
1098
+ return parseComment(commentNode, '');
1099
+ });
1100
+ };
1101
+
1102
+ /**
1103
+ * @param {import('eslint').SourceCode} sourceCode
1104
+ * @returns {import('comment-parser').Spec[]}
1105
+ */
1106
+ const getDocumentNamepathDefiningTags = (sourceCode) => {
1107
+ return getJSDocCommentBlocks(sourceCode)
1108
+ .flatMap((doc) => {
1109
+ return doc.tags.filter(({
1110
+ tag,
1111
+ }) => {
1112
+ return isNameOrNamepathDefiningTag(tag) && ![
1113
+ 'arg',
1114
+ 'argument',
1115
+ 'param',
1116
+ 'prop',
1117
+ 'property',
1118
+ ].includes(tag);
1119
+ });
1120
+ });
1121
+ };
1122
+
1087
1123
  /**
1088
1124
  * @param {string} tag
1089
1125
  * @param {import('./getDefaultTagStructureForMode.js').TagStructure} tagMap
@@ -2110,9 +2146,11 @@ export {
2110
2146
  forEachPreferredTag,
2111
2147
  getAllTags,
2112
2148
  getContextObject,
2149
+ getDocumentNamepathDefiningTags,
2113
2150
  getFunctionParameterNames,
2114
2151
  getIndent,
2115
2152
  getInlineTags,
2153
+ getJSDocCommentBlocks,
2116
2154
  getJsdocTagsDeep,
2117
2155
  getPreferredTagName,
2118
2156
  getPreferredTagNameSimple,
@@ -55,6 +55,14 @@ export default iterateJsdoc(({
55
55
  // Allow for JSDoc-block final asterisks
56
56
  key !== emptyTags.length - 1 || !(/^\s*\*+$/v).test(content)
57
57
  )) {
58
+ const {
59
+ tokens: {
60
+ delimiter,
61
+ end,
62
+ postName,
63
+ start,
64
+ },
65
+ } = tag.source[0];
58
66
  const fix = () => {
59
67
  // By time of call in fixer, `tag` will have `line` added
60
68
  utils.setTag(
@@ -63,6 +71,12 @@ export default iterateJsdoc(({
63
71
  * line: import('../iterateJsdoc.js').Integer
64
72
  * }}
65
73
  */ (tag),
74
+ {
75
+ delimiter,
76
+ end,
77
+ postName: end ? postName : '',
78
+ start,
79
+ },
66
80
  );
67
81
  };
68
82
 
@@ -46,7 +46,7 @@ for finding function blocks not attached to a function declaration or
46
46
  expression, i.e., \`@callback\` or \`@function\` (or its aliases \`@func\` or
47
47
  \`@method\`) (including those associated with an \`@interface\`).
48
48
 
49
- See the ["AST and Selectors"](../#advanced-ast-and-selectors)
49
+ See the ["AST and Selectors"](../advanced.md#ast-and-selectors)
50
50
  section of our Advanced docs for more on the expected format.`,
51
51
  items: {
52
52
  anyOf: [
@@ -183,7 +183,7 @@ Overrides the default contexts (\`ArrowFunctionExpression\`, \`FunctionDeclarati
183
183
  \`FunctionExpression\`). Set to \`"any"\` if you want the rule to apply to any
184
184
  JSDoc block throughout your files.
185
185
 
186
- See the ["AST and Selectors"](../#advanced-ast-and-selectors)
186
+ See the ["AST and Selectors"](../advanced.md#ast-and-selectors)
187
187
  section of our Advanced docs for more on the expected format.`,
188
188
  items: {
189
189
  anyOf: [
@@ -135,7 +135,7 @@ Accepts a string regular expression (optionally wrapped between two
135
135
  context: {
136
136
  description: `AST to confine the allowing or disallowing to JSDoc blocks
137
137
  associated with a particular context. See the
138
- ["AST and Selectors"](../#advanced-ast-and-selectors)
138
+ ["AST and Selectors"](../advanced.md#ast-and-selectors)
139
139
  section of our Advanced docs for more on the expected format.`,
140
140
  type: 'string',
141
141
  },
@@ -64,7 +64,7 @@ for finding function blocks not attached to a function declaration or
64
64
  expression, i.e., \`@callback\` or \`@function\` (or its aliases \`@func\` or
65
65
  \`@method\`) (including those associated with an \`@interface\`).
66
66
 
67
- See the ["AST and Selectors"](../#advanced-ast-and-selectors)
67
+ See the ["AST and Selectors"](../advanced.md#ast-and-selectors)
68
68
  section of our Advanced docs for more on the expected format.`,
69
69
  items: {
70
70
  anyOf: [
@@ -177,7 +177,7 @@ your files (as is necessary for finding function blocks not attached to a
177
177
  function declaration or expression, i.e., \`@callback\` or \`@function\` (or its
178
178
  aliases \`@func\` or \`@method\`) (including those associated with an \`@interface\`).
179
179
 
180
- See the ["AST and Selectors"](../#advanced-ast-and-selectors)
180
+ See the ["AST and Selectors"](../advanced.md#ast-and-selectors)
181
181
  section of our Advanced docs for more on the expected format.`,
182
182
  items: {
183
183
  anyOf: [
@@ -35,7 +35,7 @@ your files (as is necessary for finding function blocks not attached to a
35
35
  function declaration or expression, i.e., \`@callback\` or \`@function\` (or its
36
36
  aliases \`@func\` or \`@method\`) (including those associated with an \`@interface\`).
37
37
 
38
- See the ["AST and Selectors"](../#advanced-ast-and-selectors)
38
+ See the ["AST and Selectors"](../advanced.md#ast-and-selectors)
39
39
  section of our Advanced docs for more on the expected format.`,
40
40
  items: {
41
41
  anyOf: [
@@ -76,7 +76,7 @@ for finding function blocks not attached to a function declaration or
76
76
  expression, i.e., \`@callback\` or \`@function\` (or its aliases \`@func\` or
77
77
  \`@method\`) (including those associated with an \`@interface\`).
78
78
 
79
- See the ["AST and Selectors"](../#advanced-ast-and-selectors)
79
+ See the ["AST and Selectors"](../advanced.md#ast-and-selectors)
80
80
  section of our Advanced docs for more on the expected format.`,
81
81
  items: {
82
82
  anyOf: [
@@ -1,6 +1,10 @@
1
1
  import iterateJsdoc, {
2
2
  parseComment,
3
3
  } from '../iterateJsdoc.js';
4
+ import {
5
+ getDocumentNamepathDefiningTags,
6
+ getJSDocCommentBlocks,
7
+ } from '../jsdocUtils.js';
4
8
  import {
5
9
  getJSDocComment,
6
10
  parse as parseType,
@@ -123,13 +127,7 @@ export default iterateJsdoc(({
123
127
  }
124
128
 
125
129
  const allComments = sourceCode.getAllComments();
126
- const comments = allComments
127
- .filter((comment) => {
128
- return (/^\*(?!\*)/v).test(comment.value);
129
- })
130
- .map((commentNode) => {
131
- return parseComment(commentNode, '');
132
- });
130
+ const comments = getJSDocCommentBlocks(sourceCode);
133
131
 
134
132
  const globals = allComments
135
133
  .filter((comment) => {
@@ -138,20 +136,7 @@ export default iterateJsdoc(({
138
136
  return commentNode.value.replace(/^\s*globals/v, '').trim().split(/,\s*/v);
139
137
  }).concat(Object.keys(context.languageOptions.globals ?? []));
140
138
 
141
- const typedefs = comments
142
- .flatMap((doc) => {
143
- return doc.tags.filter(({
144
- tag,
145
- }) => {
146
- return utils.isNameOrNamepathDefiningTag(tag) && ![
147
- 'arg',
148
- 'argument',
149
- 'param',
150
- 'prop',
151
- 'property',
152
- ].includes(tag);
153
- });
154
- });
139
+ const typedefs = getDocumentNamepathDefiningTags(sourceCode);
155
140
 
156
141
  const typedefDeclarations = typedefs
157
142
  .map((tag) => {
@@ -138,7 +138,7 @@ for finding function blocks not attached to a function declaration or
138
138
  expression, i.e., \`@callback\` or \`@function\` (or its aliases \`@func\` or
139
139
  \`@method\`) (including those associated with an \`@interface\`).
140
140
 
141
- See the ["AST and Selectors"](../#advanced-ast-and-selectors)
141
+ See the ["AST and Selectors"](../advanced.md#ast-and-selectors)
142
142
  section of our Advanced docs for more on the expected format.`,
143
143
  items: {
144
144
  anyOf: [
@@ -88,7 +88,7 @@ Overrides the default contexts (\`ArrowFunctionExpression\`, \`FunctionDeclarati
88
88
  \`FunctionExpression\`). Set to \`"any"\` if you want the rule to apply to any
89
89
  JSDoc block throughout your files.
90
90
 
91
- See the ["AST and Selectors"](../#advanced-ast-and-selectors)
91
+ See the ["AST and Selectors"](../advanced.md#ast-and-selectors)
92
92
  section of our Advanced docs for more on the expected format.`,
93
93
  items: {
94
94
  anyOf: [
@@ -102,7 +102,7 @@ for it to require documentation.
102
102
  Note that you may need to disable \`require\` items (e.g., \`MethodDefinition\`)
103
103
  if you are specifying a more precise form in \`contexts\` (e.g., \`MethodDefinition:not([accessibility="private"] > FunctionExpression\`).
104
104
 
105
- See the ["AST and Selectors"](../#advanced-ast-and-selectors)
105
+ See the ["AST and Selectors"](../advanced.md#ast-and-selectors)
106
106
  section of our Advanced docs for more on the expected format.`,
107
107
  items: {
108
108
  anyOf: [
@@ -684,7 +684,7 @@ Overrides the default contexts (\`ArrowFunctionExpression\`, \`FunctionDeclarati
684
684
  \`TSMethodSignature\` in TypeScript or restricting the contexts
685
685
  which are checked.
686
686
 
687
- See the ["AST and Selectors"](../#advanced-ast-and-selectors)
687
+ See the ["AST and Selectors"](../advanced.md#ast-and-selectors)
688
688
  section of our Advanced docs for more on the expected format.`,
689
689
  items: {
690
690
  anyOf: [
@@ -65,7 +65,7 @@ for finding function blocks not attached to a function declaration or
65
65
  expression, i.e., \`@callback\` or \`@function\` (or its aliases \`@func\` or
66
66
  \`@method\`) (including those associated with an \`@interface\`).
67
67
 
68
- See the ["AST and Selectors"](../#advanced-ast-and-selectors)
68
+ See the ["AST and Selectors"](../advanced.md#ast-and-selectors)
69
69
  section of our Advanced docs for more on the expected format.`,
70
70
  items: {
71
71
  anyOf: [
@@ -37,7 +37,7 @@ for finding function blocks not attached to a function declaration or
37
37
  expression, i.e., \`@callback\` or \`@function\` (or its aliases \`@func\` or
38
38
  \`@method\`) (including those associated with an \`@interface\`).
39
39
 
40
- See the ["AST and Selectors"](../#advanced-ast-and-selectors)
40
+ See the ["AST and Selectors"](../advanced.md#ast-and-selectors)
41
41
  section of our Advanced docs for more on the expected format.`,
42
42
  items: {
43
43
  anyOf: [
@@ -65,7 +65,7 @@ for finding function blocks not attached to a function declaration or
65
65
  expression, i.e., \`@callback\` or \`@function\` (or its aliases \`@func\` or
66
66
  \`@method\`) (including those associated with an \`@interface\`).
67
67
 
68
- See the ["AST and Selectors"](../#advanced-ast-and-selectors)
68
+ See the ["AST and Selectors"](../advanced.md#ast-and-selectors)
69
69
  section of our Advanced docs for more on the expected format.`,
70
70
  items: {
71
71
  anyOf: [
@@ -1,7 +1,27 @@
1
1
  import iterateJsdoc from '../iterateJsdoc.js';
2
2
  import {
3
+ getDocumentNamepathDefiningTags,
3
4
  strictNativeTypes,
4
5
  } from '../jsdocUtils.js';
6
+ import {
7
+ traverse,
8
+ tryParse as tryParseType,
9
+ } from '@es-joy/jsdoccomment';
10
+
11
+ /**
12
+ * @type {Partial<Record<import('../jsdocUtils.js').ParserMode, import('jsdoc-type-pratt-parser').ParseMode[]>>}
13
+ */
14
+ const parseTypeModes = {
15
+ closure: [
16
+ 'closure',
17
+ ],
18
+ jsdoc: [
19
+ 'jsdoc',
20
+ ],
21
+ typescript: [
22
+ 'typescript',
23
+ ],
24
+ };
5
25
 
6
26
  /**
7
27
  * @param {import('../iterateJsdoc.js').Utils} utils
@@ -36,11 +56,35 @@ const canSkip = (utils, settings) => {
36
56
  settings.mode === 'closure' && utils.classHasTag('record');
37
57
  };
38
58
 
59
+ /**
60
+ * @param {import('jsdoc-type-pratt-parser').RootResult} parsedType
61
+ * @returns {import('jsdoc-type-pratt-parser').RootResult}
62
+ */
63
+ const getReturnTypeLevelNode = (parsedType) => {
64
+ return parsedType.type === 'JsdocTypeParenthesis' ?
65
+ parsedType.element :
66
+ parsedType;
67
+ };
68
+
69
+ /**
70
+ * @param {import('eslint').Rule.RuleContext} context
71
+ * @param {import('../jsdocUtils.js').ParserMode} mode
72
+ * @returns {import('../jsdocUtils.js').ParserMode}
73
+ */
74
+ const getParseMode = (context, mode) => {
75
+ const {
76
+ jsdoc,
77
+ } = /** @type {{jsdoc?: {mode?: import('../jsdocUtils.js').ParserMode}}} */ (context.settings);
78
+
79
+ return jsdoc?.mode ?? mode;
80
+ };
81
+
39
82
  export default iterateJsdoc(({
40
83
  context,
41
84
  node,
42
85
  report,
43
86
  settings,
87
+ sourceCode,
44
88
  utils,
45
89
  }) => {
46
90
  const {
@@ -49,6 +93,10 @@ export default iterateJsdoc(({
49
93
  noNativeTypes = true,
50
94
  reportMissingReturnForUndefinedTypes = false,
51
95
  } = context.options[0] || {};
96
+ const {
97
+ mode,
98
+ } = settings;
99
+ const parseMode = getParseMode(context, mode);
52
100
 
53
101
  if (canSkip(utils, settings)) {
54
102
  return;
@@ -90,6 +138,67 @@ export default iterateJsdoc(({
90
138
  }
91
139
 
92
140
  const returnNever = type === 'never';
141
+ const typedefs = getDocumentNamepathDefiningTags(sourceCode);
142
+
143
+ /**
144
+ * @param {import('comment-parser').Spec} returnTag
145
+ * @returns {boolean}
146
+ */
147
+ const mayReturnUndefined = (returnTag) => {
148
+ if (utils.mayBeUndefinedTypeTag(returnTag)) {
149
+ return true;
150
+ }
151
+
152
+ const returnType = returnTag.type.trim();
153
+ let parsedType;
154
+ try {
155
+ parsedType = tryParseType(returnType, parseTypeModes[parseMode]);
156
+ } catch {
157
+ return false;
158
+ }
159
+
160
+ const returnTypeLevelNode = getReturnTypeLevelNode(parsedType);
161
+ let returnIsUndefined = false;
162
+ traverse(returnTypeLevelNode, (nde, parentNode) => {
163
+ const isReturnLevelNode = !parentNode ||
164
+ returnTypeLevelNode.type === 'JsdocTypeUnion' && parentNode === returnTypeLevelNode;
165
+ if (!isReturnLevelNode) {
166
+ return;
167
+ }
168
+
169
+ const {
170
+ type: nodeType,
171
+ } = /** @type {import('jsdoc-type-pratt-parser').RootResult} */ (nde);
172
+
173
+ if (nodeType === 'JsdocTypeUndefined') {
174
+ returnIsUndefined = true;
175
+ return;
176
+ }
177
+
178
+ if (nodeType !== 'JsdocTypeName') {
179
+ return;
180
+ }
181
+
182
+ const {
183
+ value,
184
+ } = /** @type {import('jsdoc-type-pratt-parser').NameResult} */ (nde);
185
+
186
+ if (value === 'void') {
187
+ returnIsUndefined = true;
188
+ return;
189
+ }
190
+
191
+ const referencedTypedef = typedefs.find((typedefTag) => {
192
+ return typedefTag.name === value;
193
+ });
194
+
195
+ if (referencedTypedef && utils.mayBeUndefinedTypeTag(referencedTypedef)) {
196
+ returnIsUndefined = true;
197
+ }
198
+ });
199
+
200
+ return returnIsUndefined;
201
+ };
93
202
 
94
203
  if (returnNever && utils.hasValueOrExecutorHasNonEmptyResolveValue(false)) {
95
204
  report(`JSDoc @${tagName} declaration set with "never" but return expression is present in function.`);
@@ -107,7 +216,7 @@ export default iterateJsdoc(({
107
216
  !returnNever &&
108
217
  (
109
218
  reportMissingReturnForUndefinedTypes ||
110
- !utils.mayBeUndefinedTypeTag(tag)
219
+ !mayReturnUndefined(tag)
111
220
  ) &&
112
221
  (tag.type === '' && !utils.hasValueOrExecutorHasNonEmptyResolveValue(
113
222
  exemptAsync,
@@ -41,7 +41,7 @@ for finding function blocks not attached to a function declaration or
41
41
  expression, i.e., \`@callback\` or \`@function\` (or its aliases \`@func\` or
42
42
  \`@method\`) (including those associated with an \`@interface\`).
43
43
 
44
- See the ["AST and Selectors"](../#advanced-ast-and-selectors)
44
+ See the ["AST and Selectors"](../advanced.md#ast-and-selectors)
45
45
  section of our Advanced docs for more on the expected format.`,
46
46
  items: {
47
47
  anyOf: [