Skip to content

Commit 143d429

Browse files
committed
feat: allow contexts (except for no-restricted-syntax) to draw from global settings; fixes #857
Also: - fix(`no-missing-syntax`, `no-restricted-syntax`): error message (`context` -> `contexts`)
1 parent 3c6926e commit 143d429

11 files changed

+222
-52
lines changed

.README/README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,12 @@ values are objects with the following optional properties:
462462
name (`@throws Some text`); does not require that both exist but
463463
disallows just an empty tag.
464464

465+
### `contexts`
466+
467+
`settings.jsdoc.contexts` can be used as the default for any rules
468+
with a `contexts` property option. See the "AST and Selectors" section
469+
for more on this format.
470+
465471
## Advanced
466472

467473
### AST and Selectors

README.md

Lines changed: 74 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ JSDoc linting rules for ESLint.
2121
* [`@override`/`@augments`/`@extends`/`@implements`/`@ignore` Without Accompanying `@param`/`@description`/`@example`/`@returns`/`@throws`/`@yields`](#user-content-eslint-plugin-jsdoc-settings-override-augments-extends-implements-ignore-without-accompanying-param-description-example-returns-throws-yields)
2222
* [Settings to Configure `check-types` and `no-undefined-types`](#user-content-eslint-plugin-jsdoc-settings-settings-to-configure-check-types-and-no-undefined-types)
2323
* [`structuredTags`](#user-content-eslint-plugin-jsdoc-settings-structuredtags)
24+
* [`contexts`](#user-content-eslint-plugin-jsdoc-settings-contexts)
2425
* [Advanced](#user-content-eslint-plugin-jsdoc-advanced)
2526
* [AST and Selectors](#user-content-eslint-plugin-jsdoc-advanced-ast-and-selectors)
2627
* [Rules](#user-content-eslint-plugin-jsdoc-rules)
@@ -553,6 +554,14 @@ values are objects with the following optional properties:
553554
name (`@throws Some text`); does not require that both exist but
554555
disallows just an empty tag.
555556

557+
<a name="user-content-eslint-plugin-jsdoc-settings-contexts"></a>
558+
<a name="eslint-plugin-jsdoc-settings-contexts"></a>
559+
### <code>contexts</code>
560+
561+
`settings.jsdoc.contexts` can be used as the default for any rules
562+
with a `contexts` property option. See the "AST and Selectors" section
563+
for more on this format.
564+
556565
<a name="user-content-eslint-plugin-jsdoc-advanced"></a>
557566
<a name="eslint-plugin-jsdoc-advanced"></a>
558567
## Advanced
@@ -6756,8 +6765,8 @@ function is adhering.
67566765
<a name="eslint-plugin-jsdoc-rules-implements-on-classes-options-10"></a>
67576766
#### Options
67586767

6759-
<a name="user-content-eslint-plugin-jsdoc-rules-implements-on-classes-options-10-contexts"></a>
6760-
<a name="eslint-plugin-jsdoc-rules-implements-on-classes-options-10-contexts"></a>
6768+
<a name="user-content-eslint-plugin-jsdoc-rules-implements-on-classes-options-10-contexts-1"></a>
6769+
<a name="eslint-plugin-jsdoc-rules-implements-on-classes-options-10-contexts-1"></a>
67616770
##### <code>contexts</code>
67626771

67636772
Set this to an array of strings representing the AST context (or an object with
@@ -7091,8 +7100,8 @@ You may also provide an object with `message`:
70917100
}
70927101
```
70937102

7094-
<a name="user-content-eslint-plugin-jsdoc-rules-match-description-options-11-contexts-1"></a>
7095-
<a name="eslint-plugin-jsdoc-rules-match-description-options-11-contexts-1"></a>
7103+
<a name="user-content-eslint-plugin-jsdoc-rules-match-description-options-11-contexts-2"></a>
7104+
<a name="eslint-plugin-jsdoc-rules-match-description-options-11-contexts-2"></a>
70967105
##### <code>contexts</code>
70977106

70987107
Set this to an array of strings representing the AST context (or an object with
@@ -8922,8 +8931,8 @@ the presence of ES6 default parameters (bearing in mind that such
89228931
"defaults" are only applied when the supplied value is missing or
89238932
`undefined` but not for `null` or other "falsey" values).
89248933

8925-
<a name="user-content-eslint-plugin-jsdoc-rules-no-defaults-options-16-contexts-2"></a>
8926-
<a name="eslint-plugin-jsdoc-rules-no-defaults-options-16-contexts-2"></a>
8934+
<a name="user-content-eslint-plugin-jsdoc-rules-no-defaults-options-16-contexts-3"></a>
8935+
<a name="eslint-plugin-jsdoc-rules-no-defaults-options-16-contexts-3"></a>
89278936
##### <code>contexts</code>
89288937

89298938
Set this to an array of strings representing the AST context (or an object with
@@ -9113,8 +9122,8 @@ not report if there were only a function declaration of the name "ignoreMe"
91139122
<a name="eslint-plugin-jsdoc-rules-no-missing-syntax-options-17"></a>
91149123
#### Options
91159124

9116-
<a name="user-content-eslint-plugin-jsdoc-rules-no-missing-syntax-options-17-contexts-3"></a>
9117-
<a name="eslint-plugin-jsdoc-rules-no-missing-syntax-options-17-contexts-3"></a>
9125+
<a name="user-content-eslint-plugin-jsdoc-rules-no-missing-syntax-options-17-contexts-4"></a>
9126+
<a name="eslint-plugin-jsdoc-rules-no-missing-syntax-options-17-contexts-4"></a>
91189127
##### <code>contexts</code>
91199128

91209129
Set this to an array of strings representing the AST context (or an object with
@@ -9159,6 +9168,15 @@ function quux () {
91599168
*/
91609169
function quux () {
91619170

9171+
}
9172+
// Settings: {"jsdoc":{"contexts":[{"comment":"JsdocBlock[postDelimiter=\"\"]:has(JsdocTypeUnion > JsdocTypeName[value=\"Foo\"]:nth-child(1))","context":"FunctionDeclaration"}]}}
9173+
// Message: Syntax is required: FunctionDeclaration with JsdocBlock[postDelimiter=""]:has(JsdocTypeUnion > JsdocTypeName[value="Foo"]:nth-child(1))
9174+
9175+
/**
9176+
* @implements {Bar|Foo}
9177+
*/
9178+
function quux () {
9179+
91629180
}
91639181
// "jsdoc/no-missing-syntax": ["error"|"warn", {"contexts":[{"comment":"JsdocBlock[postDelimiter=\"\"]:has(JsdocTypeUnion > JsdocTypeName[value=\"Bar\"]:nth-child(1))","context":"FunctionDeclaration"},{"comment":"JsdocBlock[postDelimiter=\"\"]:has(JsdocTypeUnion > JsdocTypeName[value=\"Foo\"]:nth-child(1))","context":"FunctionDeclaration"}]}]
91649182
// Message: Syntax is required: FunctionDeclaration with JsdocBlock[postDelimiter=""]:has(JsdocTypeUnion > JsdocTypeName[value="Foo"]:nth-child(1))
@@ -9206,7 +9224,7 @@ function quux () {
92069224
function quux () {
92079225

92089226
}
9209-
// Message: Rule `no-missing-syntax` is missing a `context` option.
9227+
// Message: Rule `no-missing-syntax` is missing a `contexts` option.
92109228

92119229
/**
92129230
* @implements {Bar|Foo}
@@ -9590,8 +9608,8 @@ is designed to do), you can just use ESLint's rule.
95909608
<a name="eslint-plugin-jsdoc-rules-no-restricted-syntax-options-19"></a>
95919609
#### Options
95929610

9593-
<a name="user-content-eslint-plugin-jsdoc-rules-no-restricted-syntax-options-19-contexts-4"></a>
9594-
<a name="eslint-plugin-jsdoc-rules-no-restricted-syntax-options-19-contexts-4"></a>
9611+
<a name="user-content-eslint-plugin-jsdoc-rules-no-restricted-syntax-options-19-contexts-5"></a>
9612+
<a name="eslint-plugin-jsdoc-rules-no-restricted-syntax-options-19-contexts-5"></a>
95959613
##### <code>contexts</code>
95969614

95979615
Set this to an array of strings representing the AST context (or an object with
@@ -9669,7 +9687,16 @@ function quux () {
96699687
function quux () {
96709688

96719689
}
9672-
// Message: Rule `no-restricted-syntax` is missing a `context` option.
9690+
// Message: Rule `no-restricted-syntax` is missing a `contexts` option.
9691+
9692+
/**
9693+
* @implements {Bar|Foo}
9694+
*/
9695+
function quux () {
9696+
9697+
}
9698+
// Settings: {"jsdoc":{"contexts":["FunctionDeclaration"]}}
9699+
// Message: Rule `no-restricted-syntax` is missing a `contexts` option.
96739700

96749701
/**
96759702
* @param opt_a
@@ -9911,8 +9938,8 @@ the type information would be redundant with TypeScript.
99119938
<a name="eslint-plugin-jsdoc-rules-no-types-options-20"></a>
99129939
#### Options
99139940

9914-
<a name="user-content-eslint-plugin-jsdoc-rules-no-types-options-20-contexts-5"></a>
9915-
<a name="eslint-plugin-jsdoc-rules-no-types-options-20-contexts-5"></a>
9941+
<a name="user-content-eslint-plugin-jsdoc-rules-no-types-options-20-contexts-6"></a>
9942+
<a name="eslint-plugin-jsdoc-rules-no-types-options-20-contexts-6"></a>
99169943
##### <code>contexts</code>
99179944

99189945
Set this to an array of strings representing the AST context (or an object with
@@ -11922,6 +11949,16 @@ class quux {
1192211949
// "jsdoc/require-description": ["error"|"warn", {"contexts":["ClassDeclaration"],"descriptionStyle":"tag"}]
1192311950
// Message: Missing JSDoc @description declaration.
1192411951

11952+
/**
11953+
*
11954+
*/
11955+
class quux {
11956+
11957+
}
11958+
// Settings: {"jsdoc":{"contexts":["ClassDeclaration"]}}
11959+
// "jsdoc/require-description": ["error"|"warn", {"descriptionStyle":"tag"}]
11960+
// Message: Missing JSDoc @description declaration.
11961+
1192511962
/**
1192611963
*
1192711964
*/
@@ -12406,8 +12443,8 @@ exemption of the rule.
1240612443
Boolean to indicate that no-argument functions should not be reported for
1240712444
missing `@example` declarations.
1240812445

12409-
<a name="user-content-eslint-plugin-jsdoc-rules-require-example-options-25-contexts-6"></a>
12410-
<a name="eslint-plugin-jsdoc-rules-require-example-options-25-contexts-6"></a>
12446+
<a name="user-content-eslint-plugin-jsdoc-rules-require-example-options-25-contexts-7"></a>
12447+
<a name="eslint-plugin-jsdoc-rules-require-example-options-25-contexts-7"></a>
1241112448
##### <code>contexts</code>
1241212449

1241312450
Set this to an array of strings representing the AST context (or an object with
@@ -13311,8 +13348,8 @@ An object with the following optional boolean keys which all default to
1331113348
- `FunctionExpression`
1331213349
- `MethodDefinition`
1331313350

13314-
<a name="user-content-eslint-plugin-jsdoc-rules-require-jsdoc-options-28-contexts-7"></a>
13315-
<a name="eslint-plugin-jsdoc-rules-require-jsdoc-options-28-contexts-7"></a>
13351+
<a name="user-content-eslint-plugin-jsdoc-rules-require-jsdoc-options-28-contexts-8"></a>
13352+
<a name="eslint-plugin-jsdoc-rules-require-jsdoc-options-28-contexts-8"></a>
1331613353
##### <code>contexts</code>
1331713354

1331813355
Set this to an array of strings or objects representing the additional AST
@@ -13512,6 +13549,13 @@ export const test = () => {
1351213549

1351313550
export const test = () => {
1351413551

13552+
};
13553+
// Settings: {"jsdoc":{"contexts":["ArrowFunctionExpression"]}}
13554+
// "jsdoc/require-jsdoc": ["error"|"warn", {"publicOnly":true}]
13555+
// Message: Missing JSDoc comment.
13556+
13557+
export const test = () => {
13558+
1351513559
};
1351613560
// "jsdoc/require-jsdoc": ["error"|"warn", {"contexts":[{"context":"ArrowFunctionExpression"}],"publicOnly":true}]
1351713561
// Message: Missing JSDoc comment.
@@ -15091,8 +15135,8 @@ string. Defaults to `false`.
1509115135
The description string to set by default for destructured roots. Defaults to
1509215136
"The root object".
1509315137

15094-
<a name="user-content-eslint-plugin-jsdoc-rules-require-param-description-options-29-contexts-8"></a>
15095-
<a name="eslint-plugin-jsdoc-rules-require-param-description-options-29-contexts-8"></a>
15138+
<a name="user-content-eslint-plugin-jsdoc-rules-require-param-description-options-29-contexts-9"></a>
15139+
<a name="eslint-plugin-jsdoc-rules-require-param-description-options-29-contexts-9"></a>
1509615140
##### <code>contexts</code>
1509715141

1509815142
Set this to an array of strings representing the AST context (or an object with
@@ -15289,8 +15333,8 @@ Requires that all function parameters have names.
1528915333
<a name="eslint-plugin-jsdoc-rules-require-param-name-options-30"></a>
1529015334
#### Options
1529115335

15292-
<a name="user-content-eslint-plugin-jsdoc-rules-require-param-name-options-30-contexts-9"></a>
15293-
<a name="eslint-plugin-jsdoc-rules-require-param-name-options-30-contexts-9"></a>
15336+
<a name="user-content-eslint-plugin-jsdoc-rules-require-param-name-options-30-contexts-10"></a>
15337+
<a name="eslint-plugin-jsdoc-rules-require-param-name-options-30-contexts-10"></a>
1529415338
##### <code>contexts</code>
1529515339

1529615340
Set this to an array of strings representing the AST context (or an object with
@@ -15449,8 +15493,8 @@ object. Uses `defaultDestructuredRootType` for the type string. Defaults to
1544915493

1545015494
The type string to set by default for destructured roots. Defaults to "object".
1545115495

15452-
<a name="user-content-eslint-plugin-jsdoc-rules-require-param-type-options-31-contexts-10"></a>
15453-
<a name="eslint-plugin-jsdoc-rules-require-param-type-options-31-contexts-10"></a>
15496+
<a name="user-content-eslint-plugin-jsdoc-rules-require-param-type-options-31-contexts-11"></a>
15497+
<a name="eslint-plugin-jsdoc-rules-require-param-type-options-31-contexts-11"></a>
1545415498
##### <code>contexts</code>
1545515499

1545615500
Set this to an array of strings representing the AST context (or an object with
@@ -15977,8 +16021,8 @@ You could set this regular expression to a more expansive list, or you
1597716021
could restrict it such that even types matching those strings would not
1597816022
need destructuring.
1597916023

15980-
<a name="user-content-eslint-plugin-jsdoc-rules-require-param-options-32-contexts-11"></a>
15981-
<a name="eslint-plugin-jsdoc-rules-require-param-options-32-contexts-11"></a>
16024+
<a name="user-content-eslint-plugin-jsdoc-rules-require-param-options-32-contexts-12"></a>
16025+
<a name="eslint-plugin-jsdoc-rules-require-param-options-32-contexts-12"></a>
1598216026
##### <code>contexts</code>
1598316027

1598416028
Set this to an array of strings representing the AST context (or an object with
@@ -18746,8 +18790,8 @@ or if it is `Promise<void>` or `Promise<undefined>`.
1874618790
<a name="eslint-plugin-jsdoc-rules-require-returns-description-options-34"></a>
1874718791
#### Options
1874818792

18749-
<a name="user-content-eslint-plugin-jsdoc-rules-require-returns-description-options-34-contexts-12"></a>
18750-
<a name="eslint-plugin-jsdoc-rules-require-returns-description-options-34-contexts-12"></a>
18793+
<a name="user-content-eslint-plugin-jsdoc-rules-require-returns-description-options-34-contexts-13"></a>
18794+
<a name="eslint-plugin-jsdoc-rules-require-returns-description-options-34-contexts-13"></a>
1875118795
##### <code>contexts</code>
1875218796

1875318797
Set this to an array of strings representing the AST context (or an object with
@@ -18905,8 +18949,8 @@ Requires that `@returns` tag has `type` value.
1890518949
<a name="eslint-plugin-jsdoc-rules-require-returns-type-options-35"></a>
1890618950
#### Options
1890718951

18908-
<a name="user-content-eslint-plugin-jsdoc-rules-require-returns-type-options-35-contexts-13"></a>
18909-
<a name="eslint-plugin-jsdoc-rules-require-returns-type-options-35-contexts-13"></a>
18952+
<a name="user-content-eslint-plugin-jsdoc-rules-require-returns-type-options-35-contexts-14"></a>
18953+
<a name="eslint-plugin-jsdoc-rules-require-returns-type-options-35-contexts-14"></a>
1891018954
##### <code>contexts</code>
1891118955

1891218956
Set this to an array of strings representing the AST context (or an object with

src/iterateJsdoc.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -873,6 +873,9 @@ const getSettings = (context) => {
873873
// Many rules, e.g., `check-tag-names`
874874
mode: context.settings.jsdoc?.mode ??
875875
(context.parserPath.includes('@typescript-eslint') ? 'typescript' : 'jsdoc'),
876+
877+
// Many rules
878+
contexts: context.settings.jsdoc?.contexts,
876879
};
877880
/* eslint-enable canonical/sort-keys */
878881

@@ -1176,6 +1179,7 @@ const iterateAllJsdocs = (iterator, ruleConfig, contexts, additiveCommentContext
11761179
if (lastCall && ruleConfig.exit) {
11771180
ruleConfig.exit({
11781181
context,
1182+
settings,
11791183
state,
11801184
utils,
11811185
});
@@ -1323,7 +1327,7 @@ export default function iterateJsdoc (iterator, ruleConfig) {
13231327
if (ruleConfig.contextDefaults || ruleConfig.contextSelected || ruleConfig.matchContext) {
13241328
contexts = ruleConfig.matchContext && context.options[0]?.match ?
13251329
context.options[0].match :
1326-
jsdocUtils.enforcedContexts(context, ruleConfig.contextDefaults);
1330+
jsdocUtils.enforcedContexts(context, ruleConfig.contextDefaults, ruleConfig.nonGlobalSettings ? {} : settings);
13271331

13281332
if (contexts) {
13291333
contexts = contexts.map((obj) => {
@@ -1410,6 +1414,7 @@ export default function iterateJsdoc (iterator, ruleConfig) {
14101414
contextObject['Program:exit'] = () => {
14111415
ruleConfig.exit({
14121416
context,
1417+
settings,
14131418
state,
14141419
});
14151420
};

src/jsdocUtils.js

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -997,17 +997,16 @@ const parseClosureTemplateTag = (tag) => {
997997
*
998998
* @param {*} context
999999
* @param {DefaultContexts} defaultContexts
1000+
* @param settings
10001001
* @returns {string[]}
10011002
*/
1002-
const enforcedContexts = (context, defaultContexts) => {
1003-
const {
1004-
contexts = defaultContexts === true ? [
1005-
'ArrowFunctionExpression',
1006-
'FunctionDeclaration',
1007-
'FunctionExpression',
1008-
'TSDeclareFunction',
1009-
] : defaultContexts,
1010-
} = context.options[0] || {};
1003+
const enforcedContexts = (context, defaultContexts, settings) => {
1004+
const contexts = context.options[0]?.contexts || settings.contexts || (defaultContexts === true ? [
1005+
'ArrowFunctionExpression',
1006+
'FunctionDeclaration',
1007+
'FunctionExpression',
1008+
'TSDeclareFunction',
1009+
] : defaultContexts);
10111010

10121011
return contexts;
10131012
};

src/rules/noMissingSyntax.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -59,27 +59,27 @@ export default iterateJsdoc(({
5959
contextSelected: true,
6060
exit ({
6161
context,
62+
settings,
6263
state,
6364
}) {
64-
if (!context.options.length) {
65+
if (!context.options.length && !settings.contexts) {
6566
context.report({
6667
loc: {
6768
start: {
6869
column: 1,
6970
line: 1,
7071
},
7172
},
72-
message: 'Rule `no-missing-syntax` is missing a `context` option.',
73+
message: 'Rule `no-missing-syntax` is missing a `contexts` option.',
7374
});
7475

7576
return;
7677
}
7778

7879
setDefaults(state);
79-
8080
const {
81-
contexts,
82-
} = context.options[0];
81+
contexts = settings?.contexts,
82+
} = context.options[0] || {};
8383

8484
// Report when MISSING
8585
contexts.some((cntxt) => {

src/rules/noRestrictedSyntax.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ export default iterateJsdoc(({
1111
report,
1212
}) => {
1313
if (!context.options.length) {
14-
report('Rule `no-restricted-syntax` is missing a `context` option.');
14+
report('Rule `no-restricted-syntax` is missing a `contexts` option.');
1515

1616
return;
1717
}
@@ -94,4 +94,5 @@ export default iterateJsdoc(({
9494
],
9595
type: 'suggestion',
9696
},
97+
nonGlobalSettings: true,
9798
});

0 commit comments

Comments
 (0)