Skip to content

Commit bfa90a6

Browse files
committed
feat(require-jsdoc): add on-by-default skipInterveningOverloadedDeclarations option; fixes #1434
BREAKING CHANGE: Now requires `skipInterveningOverloadedDeclarations: true` option to get behavior of checking at the top of overloaded functions from #1369
1 parent b4c9b58 commit bfa90a6

File tree

8 files changed

+208
-18
lines changed

8 files changed

+208
-18
lines changed

.README/rules/require-jsdoc.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,14 +113,20 @@ apply to any context; see `contexts` for line counts per context.
113113
An optional message to add to the inserted JSDoc block. Defaults to the
114114
empty string.
115115

116+
### `skipInterveningOverloadedDeclarations`
117+
118+
If `true`, will skip above uncommented overloaded functions to check
119+
for a comment block (e.g., at the top of a set of overloaded functions).
120+
Defaults to `true`.
121+
116122
## Context and settings
117123

118124
|||
119125
|---|---|
120126
|Context|`ArrowFunctionExpression`, `ClassDeclaration`, `ClassExpression`, `FunctionDeclaration`, `FunctionExpression`; others when `contexts` option enabled|
121127
|Tags|N/A|
122128
|Recommended|true|
123-
|Options|`publicOnly`, `require`, `contexts`, `exemptEmptyConstructors`, `exemptEmptyFunctions`, `enableFixer`, `minLineCount`, `fixerMessage`|
129+
|Options|`publicOnly`, `require`, `contexts`, `exemptEmptyConstructors`, `exemptEmptyFunctions`, `enableFixer`, `minLineCount`, `fixerMessage`, `skipInterveningOverloadedDeclarations`|
124130

125131
## Failing examples
126132

docs/rules/require-jsdoc.md

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
* [`enableFixer`](#user-content-require-jsdoc-options-enablefixer)
1616
* [`minLineCount`](#user-content-require-jsdoc-options-minlinecount)
1717
* [`fixerMessage`](#user-content-require-jsdoc-options-fixermessage)
18+
* [`skipInterveningOverloadedDeclarations`](#user-content-require-jsdoc-options-skipinterveningoverloadeddeclarations)
1819
* [Context and settings](#user-content-require-jsdoc-context-and-settings)
1920
* [Failing examples](#user-content-require-jsdoc-failing-examples)
2021
* [Passing examples](#user-content-require-jsdoc-passing-examples)
@@ -157,6 +158,14 @@ apply to any context; see `contexts` for line counts per context.
157158
An optional message to add to the inserted JSDoc block. Defaults to the
158159
empty string.
159160

161+
<a name="user-content-require-jsdoc-options-skipinterveningoverloadeddeclarations"></a>
162+
<a name="require-jsdoc-options-skipinterveningoverloadeddeclarations"></a>
163+
### <code>skipInterveningOverloadedDeclarations</code>
164+
165+
If `true`, will skip above uncommented overloaded functions to check
166+
for a comment block (e.g., at the top of a set of overloaded functions).
167+
Defaults to `true`.
168+
160169
<a name="user-content-require-jsdoc-context-and-settings"></a>
161170
<a name="require-jsdoc-context-and-settings"></a>
162171
## Context and settings
@@ -166,7 +175,7 @@ empty string.
166175
|Context|`ArrowFunctionExpression`, `ClassDeclaration`, `ClassExpression`, `FunctionDeclaration`, `FunctionExpression`; others when `contexts` option enabled|
167176
|Tags|N/A|
168177
|Recommended|true|
169-
|Options|`publicOnly`, `require`, `contexts`, `exemptEmptyConstructors`, `exemptEmptyFunctions`, `enableFixer`, `minLineCount`, `fixerMessage`|
178+
|Options|`publicOnly`, `require`, `contexts`, `exemptEmptyConstructors`, `exemptEmptyFunctions`, `enableFixer`, `minLineCount`, `fixerMessage`, `skipInterveningOverloadedDeclarations`|
170179

171180
<a name="user-content-require-jsdoc-failing-examples"></a>
172181
<a name="require-jsdoc-failing-examples"></a>
@@ -1041,6 +1050,32 @@ export class B implements A, B {
10411050
}
10421051
// "jsdoc/require-jsdoc": ["error"|"warn", {"contexts":["MethodDefinition"]}]
10431052
// Message: Missing JSDoc comment.
1053+
1054+
/**
1055+
* Test function with param.
1056+
* @param foo - Test param.
1057+
*/
1058+
function myFunction(foo: string): void;
1059+
/**
1060+
* Test function without param.
1061+
*/
1062+
function myFunction(): void;
1063+
function myFunction(foo?: string) {}
1064+
// "jsdoc/require-jsdoc": ["error"|"warn", {"skipInterveningOverloadedDeclarations":false}]
1065+
// Message: Missing JSDoc comment.
1066+
1067+
/**
1068+
* Test function without param.
1069+
*/
1070+
function myFunction(): void;
1071+
/**
1072+
* Test function with param.
1073+
* @param foo - Test param.
1074+
*/
1075+
function myFunction(foo: string): void;
1076+
function myFunction(foo?: string) {}
1077+
// "jsdoc/require-jsdoc": ["error"|"warn", {"skipInterveningOverloadedDeclarations":false}]
1078+
// Message: Missing JSDoc comment.
10441079
````
10451080

10461081

@@ -1944,6 +1979,7 @@ export function arrayMap<Target, Source extends Array<unknown>>(data: Source, ca
19441979
export function arrayMap<Target, Source extends AnyArrayType>(data: Source, callback: MapCallback<Target, Source>): AnyArrayType<Target> {
19451980
return data.map(callback);
19461981
}
1982+
// "jsdoc/require-jsdoc": ["error"|"warn", {"skipInterveningOverloadedDeclarations":true}]
19471983

19481984
export interface A {
19491985
a: string;
@@ -1960,5 +1996,16 @@ export class B implements A {
19601996
}
19611997
}
19621998
// "jsdoc/require-jsdoc": ["error"|"warn", {"contexts":["MethodDefinition"]}]
1999+
2000+
/**
2001+
* Test function with param.
2002+
* @param foo - Test param.
2003+
*/
2004+
function myFunction(foo: string): void;
2005+
/**
2006+
* Test function without param.
2007+
*/
2008+
function myFunction(): void;
2009+
function myFunction(foo?: string) {}
19632010
````
19642011

docs/rules/require-param.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1842,5 +1842,16 @@ const inner = (c: number, d: string): void => {
18421842
*/
18431843
function quux (a, b) {}
18441844
// "jsdoc/require-param": ["error"|"warn", {"ignoreWhenAllParamsMissing":true}]
1845+
1846+
/**
1847+
* Test function with param.
1848+
* @param foo - Test param.
1849+
*/
1850+
function myFunction(foo: string): void;
1851+
/**
1852+
* Test function without param.
1853+
*/
1854+
function myFunction(): void;
1855+
function myFunction(foo?: string) {}
18451856
````
18461857

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"url": "http://gajus.com"
66
},
77
"dependencies": {
8-
"@es-joy/jsdoccomment": "~0.53.0",
8+
"@es-joy/jsdoccomment": "~0.54.0",
99
"are-docs-informative": "^0.0.2",
1010
"comment-parser": "1.4.1",
1111
"debug": "^4.4.1",

pnpm-lock.yaml

Lines changed: 2 additions & 14 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/rules/requireJsdoc.js

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,10 @@ const OPTIONS_SCHEMA = {
169169
},
170170
type: 'object',
171171
},
172+
skipInterveningOverloadedDeclarations: {
173+
default: true,
174+
type: 'boolean',
175+
},
172176
},
173177
type: 'object',
174178
};
@@ -302,6 +306,7 @@ const getOption = (context, baseObject, option, key) => {
302306
* enableFixer: boolean,
303307
* exemptEmptyConstructors: boolean,
304308
* exemptEmptyFunctions: boolean,
309+
* skipInterveningOverloadedDeclarations: boolean,
305310
* fixerMessage: string,
306311
* minLineCount: undefined|import('../iterateJsdoc.js').Integer,
307312
* publicOnly: boolean|{[key: string]: boolean|undefined}
@@ -317,6 +322,7 @@ const getOptions = (context, settings) => {
317322
fixerMessage = '',
318323
minLineCount = undefined,
319324
publicOnly,
325+
skipInterveningOverloadedDeclarations = true,
320326
} = context.options[0] || {};
321327

322328
return {
@@ -386,6 +392,7 @@ const getOptions = (context, settings) => {
386392
/** @type {import('json-schema').JSONSchema4Object} */
387393
(OPTIONS_SCHEMA.properties).require,
388394
),
395+
skipInterveningOverloadedDeclarations,
389396
};
390397
};
391398

@@ -411,6 +418,7 @@ export default {
411418
fixerMessage,
412419
minLineCount,
413420
require: requireOption,
421+
skipInterveningOverloadedDeclarations,
414422
} = opts;
415423

416424
const publicOnly =
@@ -476,7 +484,11 @@ export default {
476484
}
477485
}
478486

479-
const jsDocNode = getJSDocComment(sourceCode, node, settings);
487+
const jsDocNode = getJSDocComment(
488+
sourceCode, node, settings, {
489+
checkOverloads: skipInterveningOverloadedDeclarations,
490+
},
491+
);
480492

481493
if (jsDocNode) {
482494
return;

test/rules/assertions/requireJsdoc.js

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4296,6 +4296,92 @@ function quux (foo) {
42964296
}
42974297
`,
42984298
},
4299+
{
4300+
code: `
4301+
/**
4302+
* Test function with param.
4303+
* @param foo - Test param.
4304+
*/
4305+
function myFunction(foo: string): void;
4306+
/**
4307+
* Test function without param.
4308+
*/
4309+
function myFunction(): void;
4310+
function myFunction(foo?: string) {}
4311+
`,
4312+
errors: [
4313+
{
4314+
line: 11,
4315+
message: 'Missing JSDoc comment.',
4316+
},
4317+
],
4318+
languageOptions: {
4319+
parser: typescriptEslintParser,
4320+
},
4321+
options: [
4322+
{
4323+
skipInterveningOverloadedDeclarations: false,
4324+
},
4325+
],
4326+
output: `
4327+
/**
4328+
* Test function with param.
4329+
* @param foo - Test param.
4330+
*/
4331+
function myFunction(foo: string): void;
4332+
/**
4333+
* Test function without param.
4334+
*/
4335+
function myFunction(): void;
4336+
/**
4337+
*
4338+
*/
4339+
function myFunction(foo?: string) {}
4340+
`,
4341+
},
4342+
{
4343+
code: `
4344+
/**
4345+
* Test function without param.
4346+
*/
4347+
function myFunction(): void;
4348+
/**
4349+
* Test function with param.
4350+
* @param foo - Test param.
4351+
*/
4352+
function myFunction(foo: string): void;
4353+
function myFunction(foo?: string) {}
4354+
`,
4355+
errors: [
4356+
{
4357+
line: 11,
4358+
message: 'Missing JSDoc comment.',
4359+
},
4360+
],
4361+
languageOptions: {
4362+
parser: typescriptEslintParser,
4363+
},
4364+
options: [
4365+
{
4366+
skipInterveningOverloadedDeclarations: false,
4367+
},
4368+
],
4369+
output: `
4370+
/**
4371+
* Test function without param.
4372+
*/
4373+
function myFunction(): void;
4374+
/**
4375+
* Test function with param.
4376+
* @param foo - Test param.
4377+
*/
4378+
function myFunction(foo: string): void;
4379+
/**
4380+
*
4381+
*/
4382+
function myFunction(foo?: string) {}
4383+
`,
4384+
},
42994385
],
43004386
valid: [
43014387
{
@@ -6442,6 +6528,11 @@ function quux (foo) {
64426528
languageOptions: {
64436529
parser: typescriptEslintParser,
64446530
},
6531+
options: [
6532+
{
6533+
skipInterveningOverloadedDeclarations: true,
6534+
},
6535+
],
64456536
},
64466537
{
64476538
code: `
@@ -6471,5 +6562,22 @@ function quux (foo) {
64716562
},
64726563
],
64736564
},
6565+
{
6566+
code: `
6567+
/**
6568+
* Test function with param.
6569+
* @param foo - Test param.
6570+
*/
6571+
function myFunction(foo: string): void;
6572+
/**
6573+
* Test function without param.
6574+
*/
6575+
function myFunction(): void;
6576+
function myFunction(foo?: string) {}
6577+
`,
6578+
languageOptions: {
6579+
parser: typescriptEslintParser,
6580+
},
6581+
},
64746582
],
64756583
});

test/rules/assertions/requireParam.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3677,5 +3677,23 @@ export default /** @type {import('../index.js').TestCases} */ ({
36773677
},
36783678
],
36793679
},
3680+
{
3681+
code: `
3682+
/**
3683+
* Test function with param.
3684+
* @param foo - Test param.
3685+
*/
3686+
function myFunction(foo: string): void;
3687+
/**
3688+
* Test function without param.
3689+
*/
3690+
function myFunction(): void;
3691+
function myFunction(foo?: string) {}
3692+
`,
3693+
languageOptions: {
3694+
parser: typescriptEslintParser,
3695+
sourceType: 'module',
3696+
},
3697+
},
36803698
],
36813699
});

0 commit comments

Comments
 (0)