Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 54 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16507,6 +16507,22 @@ async function foo() {
function quux () {}
// "jsdoc/require-returns-check": ["error"|"warn", {"reportMissingReturnForUndefinedTypes":true}]
// Message: JSDoc @returns declaration present but return expression not available in function.

/**
* @returns {never} Foo.
*/
function quux () {
return undefined;
}
// Message: JSDoc @returns declaration set with "never" but return expression is present in function.

/**
* @returns {never}
*/
function quux (foo) {
return foo;
}
// Message: JSDoc @returns declaration set with "never" but return expression is present in function.
````

The following patterns are not considered problems:
Expand Down Expand Up @@ -16643,13 +16659,6 @@ function quux () {
function quux () {
}

/**
* @returns {never} Foo.
*/
function quux () {
return undefined;
}

/**
* @returns {void} Foo.
*/
Expand Down Expand Up @@ -18445,6 +18454,14 @@ const directThrowAfterArrow = (b) => {
return a;
};
// Message: Missing JSDoc @throws declaration.

/**
* @throws {never}
*/
function quux (foo) {
throw new Error('err')
}
// Message: JSDoc @throws declaration set to "never" but throw value found.
````

The following patterns are not considered problems:
Expand All @@ -18466,6 +18483,13 @@ function quux (foo) {
} catch(e) {}
}

/**
* @throws {object}
*/
function quux (foo) {
throw new Error('err')
}

/**
* @inheritdoc
*/
Expand Down Expand Up @@ -18509,6 +18533,12 @@ const nested = () => () => {throw new Error('oops');};
async function foo() {
throw Error("bar");
}

/**
* @throws {never}
*/
function quux (foo) {
}
````


Expand Down Expand Up @@ -19493,6 +19523,23 @@ async function * quux() {}
*/
const quux = async function * () {}
// Message: JSDoc @yields declaration present but yield expression not available in function.

/**
* @yields {never} Foo.
*/
function * quux () {
yield 5;
}
// Message: JSDoc @yields declaration set with "never" but yield expression is present in function.

/**
* @next {never}
*/
function * quux (foo) {
const a = yield;
}
// "jsdoc/require-yields-check": ["error"|"warn", {"next":true}]
// Message: JSDoc @next declaration set with "never" but yield expression with return value is present in function.
````

The following patterns are not considered problems:
Expand Down
10 changes: 9 additions & 1 deletion src/rules/requireReturnsCheck.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,17 @@ export default iterateJsdoc(({

const [tag] = tags;

const returnNever = tag.type.trim() === 'never';

if (returnNever && utils.hasValueOrExecutorHasNonEmptyResolveValue(false)) {
report(`JSDoc @${tagName} declaration set with "never" but return expression is present in function.`);

return;
}

// In case a return value is declared in JSDoc, we also expect one in the code.
if (
tag.type.trim() !== 'never' &&
!returnNever &&
(
reportMissingReturnForUndefinedTypes ||
utils.hasDefinedTypeTag(tag)
Expand Down
4 changes: 4 additions & 0 deletions src/rules/requireThrows.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ export default iterateJsdoc(({

const shouldReport = () => {
if (!missingThrowsTag) {
if (tag.type.trim() === 'never' && iteratingFunction && utils.hasThrowValue()) {
report(`JSDoc @${tagName} declaration set to "never" but throw value found.`);
}

return false;
}

Expand Down
8 changes: 8 additions & 0 deletions src/rules/requireYieldsCheck.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,10 @@ export default iterateJsdoc(({
if (preferredYieldTagName) {
const shouldReportYields = () => {
if (yieldTag.type.trim() === 'never') {
if (utils.hasYieldValue()) {
report(`JSDoc @${preferredYieldTagName} declaration set with "never" but yield expression is present in function.`);
}

return false;
}

Expand All @@ -95,6 +99,10 @@ export default iterateJsdoc(({
if (preferredNextTagName) {
const shouldReportNext = () => {
if (nextTag.type.trim() === 'never') {
if (utils.hasYieldReturnValue()) {
report(`JSDoc @${preferredNextTagName} declaration set with "never" but yield expression with return value is present in function.`);
}

return false;
}

Expand Down
42 changes: 32 additions & 10 deletions test/rules/assertions/requireReturnsCheck.js
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,38 @@ export default {
reportMissingReturnForUndefinedTypes: true,
}],
},
{
code: `
/**
* @returns {never} Foo.
*/
function quux () {
return undefined;
}
`,
errors: [
{
line: 2,
message: 'JSDoc @returns declaration set with "never" but return expression is present in function.',
},
],
},
{
code: `
/**
* @returns {never}
*/
function quux (foo) {
return foo;
}
`,
errors: [
{
line: 2,
message: 'JSDoc @returns declaration set with "never" but return expression is present in function.',
},
],
},
],
valid: [
{
Expand Down Expand Up @@ -528,16 +560,6 @@ export default {
}
`,
},
{
code: `
/**
* @returns {never} Foo.
*/
function quux () {
return undefined;
}
`,
},
{
code: `
/**
Expand Down
35 changes: 35 additions & 0 deletions test/rules/assertions/requireThrows.js
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,22 @@ export default {
},
],
},
{
code: `
/**
* @throws {never}
*/
function quux (foo) {
throw new Error('err')
}
`,
errors: [
{
line: 2,
message: 'JSDoc @throws declaration set to "never" but throw value found.',
},
],
},
],
valid: [
{
Expand All @@ -358,6 +374,16 @@ export default {
}
`,
},
{
code: `
/**
* @throws {object}
*/
function quux (foo) {
throw new Error('err')
}
`,
},
{
code: `
/**
Expand Down Expand Up @@ -430,5 +456,14 @@ export default {
ecmaVersion: 8,
},
},
{
code: `
/**
* @throws {never}
*/
function quux (foo) {
}
`,
},
],
};
31 changes: 31 additions & 0 deletions test/rules/assertions/requireYieldsCheck.js
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,37 @@ export default {
ecmaVersion: 2_018,
},
},
{
code: `
/**
* @yields {never} Foo.
*/
function * quux () {
yield 5;
}
`,
errors: [{
line: 2,
message: 'JSDoc @yields declaration set with "never" but yield expression is present in function.',
}],
},
{
code: `
/**
* @next {never}
*/
function * quux (foo) {
const a = yield;
}
`,
errors: [{
line: 2,
message: 'JSDoc @next declaration set with "never" but yield expression with return value is present in function.',
}],
options: [{
next: true,
}],
},
],
valid: [
{
Expand Down