Skip to content

Commit 7505604

Browse files
authored
feat: make check-returns ignore abstract methods
Makes "Check Returns" ignore abstract methods.
2 parents 070f535 + b1301d6 commit 7505604

File tree

2 files changed

+63
-12
lines changed

2 files changed

+63
-12
lines changed

src/rules/requireReturnsCheck.js

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import _ from 'lodash';
21
import iterateJsdoc from '../iterateJsdoc';
32

43
export default iterateJsdoc(({
@@ -7,29 +6,52 @@ export default iterateJsdoc(({
76
functionNode,
87
utils
98
}) => {
9+
// Implicit return like `() => foo` is ok
10+
if (functionNode.type === 'ArrowFunctionExpression' && functionNode.expression) {
11+
return;
12+
}
13+
14+
// Async function always returns a promise
15+
if (functionNode.async) {
16+
return;
17+
}
18+
1019
const targetTagName = utils.getPreferredTagName('returns');
1120

12-
const jsdocTags = _.filter(jsdoc.tags, {
13-
tag: targetTagName
21+
// We can skip in case there are no tags defined...
22+
if (typeof jsdoc.tags === 'undefined') {
23+
return;
24+
}
25+
26+
const jsdocTags = jsdoc.tags.filter((item) => {
27+
return item.tag === targetTagName;
1428
});
1529

16-
const sourcecode = utils.getFunctionSourceCode();
30+
if (jsdocTags.length === 0) {
31+
return;
32+
}
1733

18-
const voidReturn = jsdocTags.findIndex((vundef) => {
19-
return ['undefined', 'void'].indexOf(vundef.type) !== -1;
20-
}) === -1;
34+
if (jsdocTags.length > 1) {
35+
report('Found more than one @' + targetTagName + ' declaration.');
2136

22-
// Implicit return like `() => foo` is ok
23-
if (functionNode.type === 'ArrowFunctionExpression' && functionNode.expression) {
2437
return;
2538
}
2639

27-
// Async function always returns a promise
28-
if (functionNode.async) {
40+
// An abstract function is by definition incomplete
41+
// so it is perfectly fine if the return is missing
42+
// a subclass may inherits the doc an implements the
43+
// missing return.
44+
const isAbstract = jsdoc.tags.some((item) => {
45+
return item.tag === utils.getPreferredTagName('abstract');
46+
});
47+
48+
if (isAbstract) {
2949
return;
3050
}
3151

32-
if (JSON.stringify(jsdocTags) !== '[]' && voidReturn && sourcecode.indexOf('return') < 1) {
52+
const sourcecode = utils.getFunctionSourceCode();
53+
54+
if (sourcecode.indexOf('return') === -1) {
3355
report('Present JSDoc @' + targetTagName + ' declaration but not available return expression in function.');
3456
}
3557
});

test/rules/assertions/requireReturnsCheck.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,24 @@ export default {
5252
message: 'Present JSDoc @returns declaration but not available return expression in function.'
5353
}
5454
]
55+
},
56+
{
57+
code: `
58+
/**
59+
* @returns {undefined} Foo.
60+
* @returns {String} Foo.
61+
*/
62+
function quux () {
63+
64+
return foo;
65+
}
66+
`,
67+
errors: [
68+
{
69+
line: 2,
70+
message: 'Found more than one @returns declaration.'
71+
}
72+
]
5573
}
5674
],
5775
valid: [
@@ -126,6 +144,17 @@ export default {
126144
parserOptions: {
127145
ecmaVersion: 8
128146
}
147+
},
148+
{
149+
code: `
150+
/**
151+
* @returns Foo.
152+
* @abstract
153+
*/
154+
function quux () {
155+
throw new Error('must be implemented by subclass!');
156+
}
157+
`
129158
}
130159
]
131160
};

0 commit comments

Comments
 (0)