Skip to content

Commit bdd6af2

Browse files
committed
fix(require-returns-check): checks that all branches of final node return; fixes #892
This release expressed as a reversion of a commit (bba377e) in order to fix the commit message to properly trigger a release.
1 parent bba377e commit bdd6af2

File tree

6 files changed

+498
-52
lines changed

6 files changed

+498
-52
lines changed

.README/rules/require-returns-check.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@
22

33
Requires a return statement (or non-`undefined` Promise resolve value) in
44
function bodies if a `@returns` tag (without a `void` or `undefined` type)
5-
is specified in the function's jsdoc comment.
5+
is specified in the function's JSDoc comment.
66

77
Will also report `@returns {void}` and `@returns {undefined}` if `exemptAsync`
8-
is set to `false` no non-`undefined` returned or resolved value is found.
8+
is set to `false` and a non-`undefined` value is returned or a resolved value
9+
is found. Also reports if `@returns {never}` is discovered with a return value.
910

1011
Will also report if multiple `@returns` tags are present.
1112

README.md

Lines changed: 147 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -17208,10 +17208,11 @@ The following patterns are not considered problems:
1720817208

1720917209
Requires a return statement (or non-`undefined` Promise resolve value) in
1721017210
function bodies if a `@returns` tag (without a `void` or `undefined` type)
17211-
is specified in the function's jsdoc comment.
17211+
is specified in the function's JSDoc comment.
1721217212

1721317213
Will also report `@returns {void}` and `@returns {undefined}` if `exemptAsync`
17214-
is set to `false` no non-`undefined` returned or resolved value is found.
17214+
is set to `false` and a non-`undefined` value is returned or a resolved value
17215+
is found. Also reports if `@returns {never}` is discovered with a return value.
1721517216

1721617217
Will also report if multiple `@returns` tags are present.
1721717218

@@ -17437,6 +17438,17 @@ export function readFixture(path: string): void;
1743717438
export function readFixture(path: string);
1743817439
// Message: JSDoc @returns declaration present but return expression not available in function.
1743917440

17441+
/**
17442+
* @returns {SomeType}
17443+
*/
17444+
function quux (path) {
17445+
if (true) {
17446+
return;
17447+
}
17448+
return 15;
17449+
};
17450+
// Message: JSDoc @returns declaration present but return expression not available in function.
17451+
1744017452
/**
1744117453
* Reads a test fixture.
1744217454
*
@@ -17449,6 +17461,87 @@ export function readFixture(path: string): void {
1744917461
return;
1745017462
};
1745117463
// Message: JSDoc @returns declaration present but return expression not available in function.
17464+
17465+
/**
17466+
* @returns {true}
17467+
*/
17468+
function quux () {
17469+
if (true) {
17470+
return true;
17471+
}
17472+
}
17473+
// Message: JSDoc @returns declaration present but return expression not available in function.
17474+
17475+
/**
17476+
* @returns {true}
17477+
*/
17478+
function quux () {
17479+
if (true) {
17480+
} else {
17481+
return;
17482+
}
17483+
}
17484+
// Message: JSDoc @returns declaration present but return expression not available in function.
17485+
17486+
/**
17487+
* @returns {true}
17488+
*/
17489+
function quux (someVar) {
17490+
switch (someVar) {
17491+
case 1:
17492+
return true;
17493+
case 2:
17494+
return;
17495+
}
17496+
}
17497+
// Message: JSDoc @returns declaration present but return expression not available in function.
17498+
17499+
/**
17500+
* @returns {boolean}
17501+
*/
17502+
const quux = (someVar) => {
17503+
if (someVar) {
17504+
return true;
17505+
}
17506+
};
17507+
// Message: JSDoc @returns declaration present but return expression not available in function.
17508+
17509+
/**
17510+
* @returns {true}
17511+
*/
17512+
function quux () {
17513+
try {
17514+
return true;
17515+
} catch (error) {
17516+
}
17517+
}
17518+
// Message: JSDoc @returns declaration present but return expression not available in function.
17519+
17520+
/**
17521+
* @returns {true}
17522+
*/
17523+
function quux () {
17524+
try {
17525+
return true;
17526+
} catch (error) {
17527+
return true;
17528+
} finally {
17529+
return;
17530+
}
17531+
}
17532+
// Message: JSDoc @returns declaration present but return expression not available in function.
17533+
17534+
/**
17535+
* @returns {true}
17536+
*/
17537+
function quux () {
17538+
try {
17539+
} catch (error) {
17540+
} finally {
17541+
return true;
17542+
}
17543+
}
17544+
// Message: JSDoc @returns declaration present but return expression not available in function.
1745217545
````
1745317546

1745417547
The following patterns are not considered problems:
@@ -17614,7 +17707,7 @@ function quux () {
1761417707
return true;
1761517708
} catch (err) {
1761617709
}
17617-
return;
17710+
return true;
1761817711
}
1761917712

1762017713
/**
@@ -17625,15 +17718,15 @@ function quux () {
1762517718
} finally {
1762617719
return true;
1762717720
}
17628-
return;
17721+
return true;
1762917722
}
1763017723

1763117724
/**
1763217725
* @returns {true}
1763317726
*/
1763417727
function quux () {
1763517728
try {
17636-
return;
17729+
return true;
1763717730
} catch (err) {
1763817731
}
1763917732
return true;
@@ -17648,7 +17741,7 @@ function quux () {
1764817741
} catch (err) {
1764917742
return true;
1765017743
}
17651-
return;
17744+
return true;
1765217745
}
1765317746

1765417747
/**
@@ -17659,7 +17752,7 @@ function quux () {
1765917752
case 'abc':
1766017753
return true;
1766117754
}
17662-
return;
17755+
return true;
1766317756
}
1766417757

1766517758
/**
@@ -17668,7 +17761,7 @@ function quux () {
1766817761
function quux () {
1766917762
switch (true) {
1767017763
case 'abc':
17671-
return;
17764+
return true;
1767217765
}
1767317766
return true;
1767417767
}
@@ -17680,7 +17773,7 @@ function quux () {
1768017773
for (const i of abc) {
1768117774
return true;
1768217775
}
17683-
return;
17776+
return true;
1768417777
}
1768517778

1768617779
/**
@@ -17696,7 +17789,7 @@ function quux () {
1769617789
* @returns {true}
1769717790
*/
1769817791
function quux () {
17699-
for (let i=0; i<n; i+=1) {
17792+
for (const a of b) {
1770017793
return true;
1770117794
}
1770217795
}
@@ -17705,29 +17798,37 @@ function quux () {
1770517798
* @returns {true}
1770617799
*/
1770717800
function quux () {
17708-
while(true) {
17709-
return true
17801+
loop: for (const a of b) {
17802+
return true;
1771017803
}
1771117804
}
1771217805

1771317806
/**
1771417807
* @returns {true}
1771517808
*/
1771617809
function quux () {
17717-
do {
17810+
for (let i=0; i<n; i+=1) {
17811+
return true;
17812+
}
17813+
}
17814+
17815+
/**
17816+
* @returns {true}
17817+
*/
17818+
function quux () {
17819+
while(true) {
1771817820
return true
1771917821
}
17720-
while(true)
1772117822
}
1772217823

1772317824
/**
1772417825
* @returns {true}
1772517826
*/
1772617827
function quux () {
17727-
if (true) {
17728-
return;
17828+
do {
17829+
return true
1772917830
}
17730-
return true;
17831+
while(true)
1773117832
}
1773217833

1773317834
/**
@@ -17737,6 +17838,7 @@ function quux () {
1773717838
if (true) {
1773817839
return true;
1773917840
}
17841+
return true;
1774017842
}
1774117843

1774217844
/**
@@ -17754,11 +17856,11 @@ function quux () {
1775417856
*/
1775517857
function quux () {
1775617858
if (true) {
17757-
return;
17859+
return true;
1775817860
} else {
1775917861
return true;
1776017862
}
17761-
return;
17863+
return true;
1776217864
}
1776317865

1776417866
/**
@@ -17865,6 +17967,32 @@ export function readFixture(path: string): Promise<Buffer> {
1786517967
* @returns {void} The file contents as buffer.
1786617968
*/
1786717969
export function readFixture(path: string);
17970+
17971+
/**
17972+
* @returns {SomeType}
17973+
*/
17974+
function quux (path) {
17975+
if (true) {
17976+
return 5;
17977+
}
17978+
return 15;
17979+
};
17980+
17981+
/**
17982+
* @returns {*} Foo.
17983+
*/
17984+
const quux = () => new Promise((resolve) => {
17985+
resolve(3);
17986+
});
17987+
17988+
/**
17989+
* @returns {*} Foo.
17990+
*/
17991+
const quux = function () {
17992+
return new Promise((resolve) => {
17993+
resolve(3);
17994+
});
17995+
};
1786817996
````
1786917997

1787017998

src/iterateJsdoc.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -680,8 +680,8 @@ const getUtils = (
680680
return jsdocUtils.hasDefinedTypeTag(tag);
681681
};
682682

683-
utils.hasValueOrExecutorHasNonEmptyResolveValue = (anyPromiseAsReturn) => {
684-
return jsdocUtils.hasValueOrExecutorHasNonEmptyResolveValue(node, anyPromiseAsReturn);
683+
utils.hasValueOrExecutorHasNonEmptyResolveValue = (anyPromiseAsReturn, allBranches) => {
684+
return jsdocUtils.hasValueOrExecutorHasNonEmptyResolveValue(node, anyPromiseAsReturn, allBranches);
685685
};
686686

687687
utils.hasYieldValue = () => {

src/rules/requireReturnsCheck.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ export default iterateJsdoc(({
9696
) &&
9797
!utils.hasValueOrExecutorHasNonEmptyResolveValue(
9898
exemptAsync,
99+
true,
99100
) && (!exemptGenerators || !node.generator)
100101
) {
101102
report(`JSDoc @${tagName} declaration present but return expression not available in function.`);

0 commit comments

Comments
 (0)