Skip to content

Commit

Permalink
feat(require-returns): add publicOnly option; fixes #1137
Browse files Browse the repository at this point in the history
  • Loading branch information
brettz9 committed Sep 14, 2023
1 parent dfd2a8a commit 8dbcb6f
Show file tree
Hide file tree
Showing 6 changed files with 281 additions and 8 deletions.
3 changes: 2 additions & 1 deletion .README/rules/require-returns.md
Expand Up @@ -44,6 +44,7 @@ Will also report if multiple `@returns` tags are present.
cases).
- `enableFixer` - Whether to enable the fixer to add a blank `@returns`.
Defaults to `false`.
- `publicOnly` - See docs for `require-jsdoc`.

## Context and settings

Expand All @@ -53,7 +54,7 @@ Will also report if multiple `@returns` tags are present.
| Tags | `returns` |
| Aliases | `return` |
|Recommended|true|
| Options |`checkConstructors`, `checkGetters`, `contexts`, `enableFixer`, `exemptedBy`, `forceRequireReturn`, `forceReturnsWithAsync`|
| Options |`checkConstructors`, `checkGetters`, `contexts`, `enableFixer`, `exemptedBy`, `forceRequireReturn`, `forceReturnsWithAsync`, `publicOnly`|
| Settings | `ignoreReplacesDocs`, `overrideReplacesDocs`, `augmentsExtendsReplacesDocs`, `implementsReplacesDocs` |

## Failing examples
Expand Down
64 changes: 63 additions & 1 deletion docs/rules/require-returns.md
Expand Up @@ -52,6 +52,7 @@ Will also report if multiple `@returns` tags are present.
cases).
- `enableFixer` - Whether to enable the fixer to add a blank `@returns`.
Defaults to `false`.
- `publicOnly` - See docs for `require-jsdoc`.

<a name="user-content-require-returns-context-and-settings"></a>
<a name="require-returns-context-and-settings"></a>
Expand All @@ -63,7 +64,7 @@ Will also report if multiple `@returns` tags are present.
| Tags | `returns` |
| Aliases | `return` |
|Recommended|true|
| Options |`checkConstructors`, `checkGetters`, `contexts`, `enableFixer`, `exemptedBy`, `forceRequireReturn`, `forceReturnsWithAsync`|
| Options |`checkConstructors`, `checkGetters`, `contexts`, `enableFixer`, `exemptedBy`, `forceRequireReturn`, `forceReturnsWithAsync`, `publicOnly`|
| Settings | `ignoreReplacesDocs`, `overrideReplacesDocs`, `augmentsExtendsReplacesDocs`, `implementsReplacesDocs` |

<a name="user-content-require-returns-failing-examples"></a>
Expand Down Expand Up @@ -660,6 +661,58 @@ class Test {
}
// "jsdoc/require-returns": ["error"|"warn", {"contexts":["FunctionDeclaration",{"context":"TSEmptyBodyFunctionExpression","forceRequireReturn":true}]}]
// Message: Missing JSDoc @returns declaration.

/**
*
*/
module.exports = function quux (foo) {

return foo;
}
// "jsdoc/require-returns": ["error"|"warn", {"publicOnly":true}]
// Message: Missing JSDoc @returns declaration.

/**
*
*/
const a = function quux (foo) {

return foo;
};

export default a;
// "jsdoc/require-returns": ["error"|"warn", {"publicOnly":true}]
// Message: Missing JSDoc @returns declaration.

/**
*
*/
export default function quux (foo) {

return foo;
};
// "jsdoc/require-returns": ["error"|"warn", {"publicOnly":{"ancestorsOnly":true,"esm":true}}]
// Message: Missing JSDoc @returns declaration.

/**
*
*/
exports.quux = function quux (foo) {

return foo;
};
// "jsdoc/require-returns": ["error"|"warn", {"publicOnly":{"cjs":true}}]
// Message: Missing JSDoc @returns declaration.

/**
*
*/
window.quux = function quux (foo) {

return foo;
};
// "jsdoc/require-returns": ["error"|"warn", {"publicOnly":{"window":true}}]
// Message: Missing JSDoc @returns declaration.
````


Expand Down Expand Up @@ -1199,5 +1252,14 @@ class Test {
abstract Test(): string;
}
// "jsdoc/require-returns": ["error"|"warn", {"contexts":["FunctionDeclaration",{"context":"TSEmptyBodyFunctionExpression","forceRequireReturn":true}]}]

/**
*
*/
function quux (foo) {

return foo;
}
// "jsdoc/require-returns": ["error"|"warn", {"publicOnly":true}]
````

20 changes: 15 additions & 5 deletions src/iterateJsdoc.js
Expand Up @@ -694,7 +694,9 @@ const getUtils = (
indent,
) => {
const ancestors = /** @type {import('eslint').Rule.Node[]} */ (context.getAncestors());
const sourceCode = context.getSourceCode();
const {
sourceCode,
} = context;

const utils = /** @type {Utils} */ (getBasicUtils(context, settings));

Expand Down Expand Up @@ -2147,7 +2149,9 @@ const iterateAllJsdocs = (iterator, ruleConfig, contexts, additiveCommentContext
* @returns {void}
*/
const callIterator = (context, node, jsdocNodes, state, lastCall) => {
const sourceCode = context.getSourceCode();
const {
sourceCode,
} = context;
const {
lines,
} = sourceCode;
Expand Down Expand Up @@ -2258,7 +2262,9 @@ const iterateAllJsdocs = (iterator, ruleConfig, contexts, additiveCommentContext
return {
// @ts-expect-error ESLint accepts
create (context) {
const sourceCode = context.getSourceCode();
const {
sourceCode,
} = context;
settings = getSettings(context);
if (!settings) {
return {};
Expand Down Expand Up @@ -2334,7 +2340,9 @@ const iterateAllJsdocs = (iterator, ruleConfig, contexts, additiveCommentContext
const checkFile = (iterator, ruleConfig) => {
return {
create (context) {
const sourceCode = context.getSourceCode();
const {
sourceCode,
} = context;
const settings = getSettings(context);
if (!settings) {
return {};
Expand Down Expand Up @@ -2451,7 +2459,9 @@ export default function iterateJsdoc (iterator, ruleConfig) {
}
}

const sourceCode = context.getSourceCode();
const {
sourceCode,
} = context;
const {
lines,
} = sourceCode;
Expand Down
4 changes: 3 additions & 1 deletion src/rules/requireJsdoc.js
Expand Up @@ -288,7 +288,9 @@ const getOptions = (context, settings) => {
/** @type {import('eslint').Rule.RuleModule} */
export default {
create (context) {
const sourceCode = context.getSourceCode();
const {
sourceCode,
} = context;
const settings = getSettings(context);
if (!settings) {
return {};
Expand Down
51 changes: 51 additions & 0 deletions src/rules/requireReturns.js
@@ -1,3 +1,4 @@
import exportParser from '../exportParser.js';
import iterateJsdoc from '../iterateJsdoc.js';

/**
Expand Down Expand Up @@ -38,7 +39,9 @@ export default iterateJsdoc(({
info: {
comment,
},
node,
report,
settings,
utils,
context,
}) => {
Expand All @@ -47,6 +50,7 @@ export default iterateJsdoc(({
enableFixer = false,
forceRequireReturn = false,
forceReturnsWithAsync = false,
publicOnly = false,
} = context.options[0] || {};

// A preflight check. We do not need to run a deep check
Expand Down Expand Up @@ -92,6 +96,26 @@ export default iterateJsdoc(({
return false;
}

if (publicOnly) {
/** @type {import('./requireJsdoc.js').RequireJsdocOpts} */
const opt = {
ancestorsOnly: Boolean(publicOnly?.ancestorsOnly ?? false),
esm: Boolean(publicOnly?.esm ?? true),
initModuleExports: Boolean(publicOnly?.cjs ?? true),
initWindow: Boolean(publicOnly?.window ?? false),
};
const {
sourceCode,
} = context;
const exported = exportParser.isUncommentedExport(
/** @type {import('eslint').Rule.Node} */ (node), sourceCode, opt, settings,
);

if (!exported) {
return false;
}
}

if ((forceRequireReturn || forceRequireReturnContext) && (
iteratingFunction || utils.isVirtualFunction()
)) {
Expand Down Expand Up @@ -177,6 +201,33 @@ export default iterateJsdoc(({
default: false,
type: 'boolean',
},
publicOnly: {
oneOf: [
{
default: false,
type: 'boolean',
},
{
additionalProperties: false,
default: {},
properties: {
ancestorsOnly: {
type: 'boolean',
},
cjs: {
type: 'boolean',
},
esm: {
type: 'boolean',
},
window: {
type: 'boolean',
},
},
type: 'object',
},
],
},
},
type: 'object',
},
Expand Down

0 comments on commit 8dbcb6f

Please sign in to comment.