From aa1486c1f7380bb69ea4d283f1cbb48b923eff98 Mon Sep 17 00:00:00 2001 From: Brett Zamir Date: Mon, 15 Dec 2025 11:07:59 -0700 Subject: [PATCH] feat(`require-jsdoc`): add `checkAllFunctionExpressions` option to force check `FunctionExpression`'s regardless of context; fixes #1613 --- docs/rules/require-jsdoc.md | 18 +++++++++++++ src/rules.d.ts | 6 +++++ src/rules/requireJsdoc.js | 15 +++++++++-- test/rules/assertions/requireJsdoc.js | 38 +++++++++++++++++++++++++++ 4 files changed, 75 insertions(+), 2 deletions(-) diff --git a/docs/rules/require-jsdoc.md b/docs/rules/require-jsdoc.md index d0c10559d..3481fe15d 100644 --- a/docs/rules/require-jsdoc.md +++ b/docs/rules/require-jsdoc.md @@ -4,6 +4,7 @@ * [Fixer](#user-content-require-jsdoc-fixer) * [Options](#user-content-require-jsdoc-options) + * [`checkAllFunctionExpressions`](#user-content-require-jsdoc-options-checkallfunctionexpressions) * [`checkConstructors`](#user-content-require-jsdoc-options-checkconstructors) * [`checkGetters`](#user-content-require-jsdoc-options-checkgetters) * [`checkSetters`](#user-content-require-jsdoc-options-checksetters) @@ -43,6 +44,14 @@ A single options object has the following properties. Has the following optional keys. + + +### checkAllFunctionExpressions + +Normally, when `FunctionExpression` is checked, additional checks are +added to check the parent contexts where reporting is likely to be desired. If you really +want to check *all* function expressions, then set this to `true`. + ### checkConstructors @@ -1151,6 +1160,15 @@ function myFunction(): void; function myFunction(foo?: string) {} // "jsdoc/require-jsdoc": ["error"|"warn", {"contexts":["TSDeclareFunction"],"exemptOverloadedImplementations":true,"skipInterveningOverloadedDeclarations":false}] // Message: Missing JSDoc comment. + +const foo = autolog( + function foo() { + log.debug('inside foo', 'this is a test helper function') + }, + { withGovernance: true, withProfiling: true }, +) +// "jsdoc/require-jsdoc": ["error"|"warn", {"checkAllFunctionExpressions":true,"contexts":["FunctionExpression"],"require":{"FunctionExpression":false}}] +// Message: Missing JSDoc comment. ```` diff --git a/src/rules.d.ts b/src/rules.d.ts index 885713f9f..c905ddac1 100644 --- a/src/rules.d.ts +++ b/src/rules.d.ts @@ -1639,6 +1639,12 @@ export interface Rules { | [] | [ { + /** + * Normally, when `FunctionExpression` is checked, additional checks are + * added to check the parent contexts where reporting is likely to be desired. If you really + * want to check *all* function expressions, then set this to `true`. + */ + checkAllFunctionExpressions?: boolean; /** * A value indicating whether `constructor`s should be checked. Defaults to * `true`. When `true`, `exemptEmptyConstructors` may still avoid reporting when diff --git a/src/rules/requireJsdoc.js b/src/rules/requireJsdoc.js index f458987ed..c2fd689b3 100644 --- a/src/rules/requireJsdoc.js +++ b/src/rules/requireJsdoc.js @@ -36,6 +36,13 @@ const OPTIONS_SCHEMA = { additionalProperties: false, description: 'Has the following optional keys.\n', properties: { + checkAllFunctionExpressions: { + default: false, + description: `Normally, when \`FunctionExpression\` is checked, additional checks are +added to check the parent contexts where reporting is likely to be desired. If you really +want to check *all* function expressions, then set this to \`true\`.`, + type: 'boolean', + }, checkConstructors: { default: true, description: `A value indicating whether \`constructor\`s should be checked. Defaults to @@ -378,6 +385,7 @@ const getOption = (context, baseObject, option, key) => { * @param {import('eslint').Rule.RuleContext} context * @param {import('../iterateJsdoc.js').Settings} settings * @returns {{ + * checkAllFunctionExpressions: boolean, * contexts: (string|{ * context: string, * inlineCommentBlock: boolean, @@ -396,6 +404,7 @@ const getOption = (context, baseObject, option, key) => { */ const getOptions = (context, settings) => { const { + checkAllFunctionExpressions = false, contexts = settings.contexts || [], enableFixer = true, exemptEmptyConstructors = true, @@ -408,6 +417,7 @@ const getOptions = (context, settings) => { } = context.options[0] || {}; return { + checkAllFunctionExpressions, contexts, enableFixer, exemptEmptyConstructors, @@ -503,7 +513,7 @@ const isFunctionWithOverload = (node) => { return false; } - const functionName = node.id.name; + const functionName = node.id?.name; const idx = parent.body.indexOf(child); const prevSibling = parent.body[idx - 1]; @@ -536,6 +546,7 @@ export default { const opts = getOptions(context, settings); const { + checkAllFunctionExpressions, contexts, enableFixer, exemptEmptyConstructors, @@ -831,7 +842,7 @@ export default { return; } - if ( + if (checkAllFunctionExpressions || [ 'AssignmentExpression', 'ExportDefaultDeclaration', 'VariableDeclarator', ].includes(node.parent.type) || diff --git a/test/rules/assertions/requireJsdoc.js b/test/rules/assertions/requireJsdoc.js index 0c86a93e1..3bc6e9179 100644 --- a/test/rules/assertions/requireJsdoc.js +++ b/test/rules/assertions/requireJsdoc.js @@ -4420,6 +4420,44 @@ function quux (foo) { function myFunction(foo?: string) {} `, }, + { + code: ` + const foo = autolog( + function foo() { + log.debug('inside foo', 'this is a test helper function') + }, + { withGovernance: true, withProfiling: true }, + ) + `, + errors: [ + { + line: 3, + message: 'Missing JSDoc comment.', + }, + ], + options: [ + { + checkAllFunctionExpressions: true, + contexts: [ + 'FunctionExpression', + ], + require: { + FunctionExpression: false, + }, + }, + ], + output: ` + const foo = autolog( + /** + * + */ + function foo() { + log.debug('inside foo', 'this is a test helper function') + }, + { withGovernance: true, withProfiling: true }, + ) + `, + }, ], valid: [ {