From 520c7be3e2d848dcfeb3f5aee0817b92d94e743f Mon Sep 17 00:00:00 2001 From: Brett Zamir Date: Tue, 12 Apr 2022 07:08:48 +0800 Subject: [PATCH] fix(`require-jsdoc`): detect ClassDeclaration as referenced public export and ClassExpression methods; fixes #648 --- README.md | 24 +++++ src/exportParser.js | 12 ++- test/rules/assertions/requireJsdoc.js | 129 ++++++++++++++++++++++++++ 3 files changed, 161 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 0b9f7a763..88ae4a5d4 100644 --- a/README.md +++ b/README.md @@ -13652,6 +13652,30 @@ export class Component { } // "jsdoc/require-jsdoc": ["error"|"warn", {"checkConstructors":false,"contexts":["PropertyDefinition"],"publicOnly":true}] // Message: Missing JSDoc comment. + +class Utility { + /** + * + */ + mthd() { + return false; + } +} + +module.exports = Utility; +// "jsdoc/require-jsdoc": ["error"|"warn", {"enableFixer":false,"publicOnly":true,"require":{"ArrowFunctionExpression":true,"ClassDeclaration":true,"ClassExpression":true,"FunctionDeclaration":true,"FunctionExpression":true,"MethodDefinition":true}}] +// Message: Missing JSDoc comment. + +/** + * + */ +module.exports = class Utility { + mthd() { + return false; + } +}; +// "jsdoc/require-jsdoc": ["error"|"warn", {"enableFixer":false,"publicOnly":true,"require":{"ArrowFunctionExpression":true,"ClassDeclaration":true,"ClassExpression":true,"FunctionDeclaration":true,"FunctionExpression":true,"MethodDefinition":true}}] +// Message: Missing JSDoc comment. ```` The following patterns are not considered problems: diff --git a/src/exportParser.js b/src/exportParser.js index 94b0563c4..eb258fc05 100644 --- a/src/exportParser.js +++ b/src/exportParser.js @@ -96,9 +96,13 @@ const getSymbol = function (node, globals, scope, opt) { return null; } + case 'ClassExpression': { + return getSymbol(node.body, globals, scope, opts); + } + case 'TSTypeAliasDeclaration': case 'TSEnumDeclaration': case 'TSInterfaceDeclaration': - case 'ClassDeclaration': case 'ClassExpression': + case 'ClassDeclaration': case 'FunctionExpression': case 'FunctionDeclaration': case 'ArrowFunctionExpression': { const val = createNode(); @@ -123,7 +127,7 @@ const getSymbol = function (node, globals, scope, opt) { } val.type = 'object'; - val.value = node; + val.value = node.parent; return val; } @@ -510,9 +514,9 @@ const findExportedNode = function (block, node, cache) { }; const isNodeExported = function (node, globals, opt) { + const moduleExports = globals.props.module?.props?.exports; if ( - opt.initModuleExports && globals.props.module && globals.props.module.props.exports && - findNode(node, globals.props.module.props.exports) + opt.initModuleExports && moduleExports && findNode(node, moduleExports) ) { return true; } diff --git a/test/rules/assertions/requireJsdoc.js b/test/rules/assertions/requireJsdoc.js index 1e7b0a18e..f2f830258 100644 --- a/test/rules/assertions/requireJsdoc.js +++ b/test/rules/assertions/requireJsdoc.js @@ -3816,6 +3816,73 @@ function quux (foo) { `, parser: require.resolve('@typescript-eslint/parser'), }, + + { + code: ` + class Utility { + /** + * + */ + mthd() { + return false; + } + } + + module.exports = Utility; + `, + errors: [ + { + line: 2, + message: 'Missing JSDoc comment.', + }, + ], + options: [ + { + enableFixer: false, + publicOnly: true, + require: { + ArrowFunctionExpression: true, + ClassDeclaration: true, + ClassExpression: true, + FunctionDeclaration: true, + FunctionExpression: true, + MethodDefinition: true, + }, + }, + ], + }, + { + code: ` + /** + * + */ + module.exports = class Utility { + mthd() { + return false; + } + }; + `, + errors: [ + { + line: 6, + message: 'Missing JSDoc comment.', + }, + ], + options: [ + { + enableFixer: false, + publicOnly: true, + require: { + ArrowFunctionExpression: true, + ClassDeclaration: true, + ClassExpression: true, + FunctionDeclaration: true, + FunctionExpression: true, + MethodDefinition: true, + }, + }, + ], + }, ], valid: [ { @@ -5702,5 +5769,67 @@ function quux (foo) { sourceType: 'module', }, }, + { + code: ` + function main () { + class Utility { + /** + * + */ + mthd() { + return false; + } + } + } + + module.exports = main; + `, + ignoreReadme: true, + options: [ + { + enableFixer: false, + publicOnly: true, + require: { + ArrowFunctionExpression: true, + ClassDeclaration: true, + ClassExpression: true, + FunctionDeclaration: false, + FunctionExpression: true, + MethodDefinition: true, + }, + }, + ], + }, + { + code: ` + function main () { + const a = class Utility { + /** + * + */ + mthd() { + return false; + } + } + } + + module.exports = main; + `, + ignoreReadme: true, + options: [ + { + enableFixer: false, + publicOnly: true, + require: { + ArrowFunctionExpression: true, + ClassDeclaration: true, + ClassExpression: true, + FunctionDeclaration: false, + FunctionExpression: true, + MethodDefinition: true, + }, + }, + ], + }, ], };