Skip to content

Commit

Permalink
fix(require-returns-check, require-yields-check); allow * and `…
Browse files Browse the repository at this point in the history
…any` types to avoid reporting of missing return; fixes gajus#950
  • Loading branch information
brettz9 committed Jan 20, 2023
1 parent a71a8ad commit 2b89fd4
Show file tree
Hide file tree
Showing 7 changed files with 48 additions and 22 deletions.
16 changes: 13 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17875,7 +17875,7 @@ function quux () {
}

/**
* @returns {*} Foo.
* @returns {SomeType} Foo.
*/
const quux = () => foo;

Expand Down Expand Up @@ -18276,14 +18276,14 @@ function quux (path) {
};

/**
* @returns {*} Foo.
* @returns {SomeType} Foo.
*/
const quux = () => new Promise((resolve) => {
resolve(3);
});

/**
* @returns {*} Foo.
* @returns {SomeType} Foo.
*/
const quux = function () {
return new Promise((resolve) => {
Expand Down Expand Up @@ -18420,6 +18420,16 @@ export function f(): string {

interface I {}
}

/**
* @param {boolean} bar A fun variable.
* @returns {*} Anything at all!
*/
function foo( bar ) {
if ( bar ) {
return functionWithUnknownReturnType();
}
}
````


Expand Down
4 changes: 2 additions & 2 deletions src/iterateJsdoc.js
Original file line number Diff line number Diff line change
Expand Up @@ -724,8 +724,8 @@ const getUtils = (
return jsdocUtils.getTagStructureForMode(mde, settings.structuredTags);
};

utils.hasDefinedTypeTag = (tag) => {
return jsdocUtils.hasDefinedTypeTag(tag, settings.mode);
utils.mayBeUndefinedTypeTag = (tag) => {
return jsdocUtils.mayBeUndefinedTypeTag(tag, settings.mode);
};

utils.hasValueOrExecutorHasNonEmptyResolveValue = (anyPromiseAsReturn, allBranches) => {
Expand Down
21 changes: 12 additions & 9 deletions src/jsdocUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -464,26 +464,29 @@ const hasATag = (jsdoc, targetTagNames) => {
};

/**
* Checks if the JSDoc comment declares a defined type.
* Checks if the JSDoc comment declares an undefined type.
*
* @param {JsDocTag} tag
* the tag which should be checked.
* @param {"jsdoc"|"closure"|"typescript"} mode
* @returns {boolean}
* true in case a defined type is declared; otherwise false.
* true in case a defined type is undeclared; otherwise false.
*/
const hasDefinedTypeTag = (tag, mode) => {
const mayBeUndefinedTypeTag = (tag, mode) => {
// The function should not continue in the event the type is not defined...
if (typeof tag === 'undefined' || tag === null) {
return false;
return true;
}

// .. same applies if it declares an `{undefined}` or `{void}` type
const tagType = tag.type.trim();

// Exit early if matching
if (tagType === 'undefined' || tagType === 'void') {
return false;
if (
tagType === 'undefined' || tagType === 'void' ||
tagType === '*' || tagType === 'any'
) {
return true;
}

let parsedTypes;
Expand All @@ -506,11 +509,11 @@ const hasDefinedTypeTag = (tag, mode) => {
return elem.type === 'JsdocTypeUndefined' ||
elem.type === 'JsdocTypeName' && elem.value === 'void';
})) {
return false;
return true;
}

// In any other case, a type is present
return true;
return false;
};

/**
Expand Down Expand Up @@ -1239,7 +1242,6 @@ export default {
getTagsByType,
getTagStructureForMode,
hasATag,
hasDefinedTypeTag,
hasParams,
hasReturnValue,
hasTag,
Expand All @@ -1251,6 +1253,7 @@ export default {
isNamepathDefiningTag,
isSetter,
isValidTag,
mayBeUndefinedTypeTag,
overrideTagStructure,
parseClosureTemplateTag,
pathDoesNotBeginWith,
Expand Down
2 changes: 1 addition & 1 deletion src/rules/requireReturnsCheck.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ export default iterateJsdoc(({
!returnNever &&
(
reportMissingReturnForUndefinedTypes ||
utils.hasDefinedTypeTag(tag)
!utils.mayBeUndefinedTypeTag(tag)
) &&
!utils.hasValueOrExecutorHasNonEmptyResolveValue(
exemptAsync,
Expand Down
4 changes: 2 additions & 2 deletions src/rules/requireYieldsCheck.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ export default iterateJsdoc(({
return true;
}

return utils.hasDefinedTypeTag(yieldTag) && !utils.hasYieldValue();
return !utils.mayBeUndefinedTypeTag(yieldTag) && !utils.hasYieldValue();
};

// In case a yield value is declared in JSDoc, we also expect one in the code.
Expand Down Expand Up @@ -120,7 +120,7 @@ export default iterateJsdoc(({
return true;
}

return utils.hasDefinedTypeTag(nextTag) && !utils.hasYieldReturnValue();
return !utils.mayBeUndefinedTypeTag(nextTag) && !utils.hasYieldReturnValue();
};

if (shouldReportNext()) {
Expand Down
4 changes: 2 additions & 2 deletions test/jsdocUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,10 @@ describe('jsdocUtils', () => {
});
});
});
describe('hasDefinedTypeTag()', () => {
describe('mayBeUndefinedTypeTag()', () => {
context('Missing tag', () => {
it('should return `false` with a missing tag', () => {
expect(jsdocUtils.hasDefinedTypeTag(null)).to.equal(false);
expect(jsdocUtils.mayBeUndefinedTypeTag(null)).to.equal(true);
});
});
});
Expand Down
19 changes: 16 additions & 3 deletions test/rules/assertions/requireReturnsCheck.js
Original file line number Diff line number Diff line change
Expand Up @@ -701,7 +701,7 @@ export default {
{
code: `
/**
* @returns {*} Foo.
* @returns {SomeType} Foo.
*/
const quux = () => foo;
`,
Expand Down Expand Up @@ -1306,7 +1306,7 @@ export default {
{
code: `
/**
* @returns {*} Foo.
* @returns {SomeType} Foo.
*/
const quux = () => new Promise((resolve) => {
resolve(3);
Expand All @@ -1316,7 +1316,7 @@ export default {
{
code: `
/**
* @returns {*} Foo.
* @returns {SomeType} Foo.
*/
const quux = function () {
return new Promise((resolve) => {
Expand Down Expand Up @@ -1505,5 +1505,18 @@ export default {
`,
parser: require.resolve('@typescript-eslint/parser'),
},
{
code: `
/**
* @param {boolean} bar A fun variable.
* @returns {*} Anything at all!
*/
function foo( bar ) {
if ( bar ) {
return functionWithUnknownReturnType();
}
}
`,
},
],
};

0 comments on commit 2b89fd4

Please sign in to comment.