Skip to content

Commit

Permalink
feat: make check-returns ignore abstract methods
Browse files Browse the repository at this point in the history
Makes "Check Returns" ignore abstract methods.
  • Loading branch information
gajus committed Apr 1, 2019
2 parents 070f535 + b1301d6 commit 7505604
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 12 deletions.
46 changes: 34 additions & 12 deletions src/rules/requireReturnsCheck.js
@@ -1,4 +1,3 @@
import _ from 'lodash';
import iterateJsdoc from '../iterateJsdoc';

export default iterateJsdoc(({
Expand All @@ -7,29 +6,52 @@ export default iterateJsdoc(({
functionNode,
utils
}) => {
// Implicit return like `() => foo` is ok
if (functionNode.type === 'ArrowFunctionExpression' && functionNode.expression) {
return;
}

// Async function always returns a promise
if (functionNode.async) {
return;
}

const targetTagName = utils.getPreferredTagName('returns');

const jsdocTags = _.filter(jsdoc.tags, {
tag: targetTagName
// We can skip in case there are no tags defined...
if (typeof jsdoc.tags === 'undefined') {
return;
}

const jsdocTags = jsdoc.tags.filter((item) => {
return item.tag === targetTagName;
});

const sourcecode = utils.getFunctionSourceCode();
if (jsdocTags.length === 0) {
return;
}

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

// Implicit return like `() => foo` is ok
if (functionNode.type === 'ArrowFunctionExpression' && functionNode.expression) {
return;
}

// Async function always returns a promise
if (functionNode.async) {
// An abstract function is by definition incomplete
// so it is perfectly fine if the return is missing
// a subclass may inherits the doc an implements the
// missing return.
const isAbstract = jsdoc.tags.some((item) => {
return item.tag === utils.getPreferredTagName('abstract');
});

if (isAbstract) {
return;
}

if (JSON.stringify(jsdocTags) !== '[]' && voidReturn && sourcecode.indexOf('return') < 1) {
const sourcecode = utils.getFunctionSourceCode();

if (sourcecode.indexOf('return') === -1) {
report('Present JSDoc @' + targetTagName + ' declaration but not available return expression in function.');
}
});
29 changes: 29 additions & 0 deletions test/rules/assertions/requireReturnsCheck.js
Expand Up @@ -52,6 +52,24 @@ export default {
message: 'Present JSDoc @returns declaration but not available return expression in function.'
}
]
},
{
code: `
/**
* @returns {undefined} Foo.
* @returns {String} Foo.
*/
function quux () {
return foo;
}
`,
errors: [
{
line: 2,
message: 'Found more than one @returns declaration.'
}
]
}
],
valid: [
Expand Down Expand Up @@ -126,6 +144,17 @@ export default {
parserOptions: {
ecmaVersion: 8
}
},
{
code: `
/**
* @returns Foo.
* @abstract
*/
function quux () {
throw new Error('must be implemented by subclass!');
}
`
}
]
};

0 comments on commit 7505604

Please sign in to comment.