diff --git a/README.md b/README.md index c74fb0b25..0c19b8472 100644 --- a/README.md +++ b/README.md @@ -10755,6 +10755,12 @@ export class MyComponentComponent { } // "jsdoc/require-jsdoc": ["error"|"warn", {"contexts":["ClassProperty:has(Decorator[expression.callee.name=\"Input\"])"]}] // Message: Missing JSDoc comment. + +requestAnimationFrame(draw) + +function bench() { +} +// Message: Missing JSDoc comment. ```` The following patterns are not considered problems: @@ -11516,6 +11522,14 @@ const foo = { }) export class UserSettingsState { } // "jsdoc/require-jsdoc": ["error"|"warn", {"require":{"ClassDeclaration":true}}] + +/** + * Entity to represent a user in the system. + */ +@Entity('users') +export class User { +} +// "jsdoc/require-jsdoc": ["error"|"warn", {"contexts":["Decorator"],"require":{"FunctionDeclaration":false}}] ```` diff --git a/src/eslint/getJSDocComment.js b/src/eslint/getJSDocComment.js index 59b89d349..6ef95520f 100644 --- a/src/eslint/getJSDocComment.js +++ b/src/eslint/getJSDocComment.js @@ -14,47 +14,9 @@ const isCommentToken = (token) => { return token.type === 'Line' || token.type === 'Block' || token.type === 'Shebang'; }; -const decoratorMetaTokens = new Map([[')', '('], ['>', '<']]); - -const getDecorator = (token, sourceCode) => { - if (!token) { - return false; - } - if (token.type === 'Punctuator') { - const tokenClose = token.value; - const tokenOpen = decoratorMetaTokens.get(tokenClose); - if (tokenOpen) { - let nested = 0; - let tokenBefore = token; - do { - tokenBefore = sourceCode.getTokenBefore(tokenBefore, {includeComments: true}); - // istanbul ignore if - if (tokenBefore && tokenBefore.type === 'Punctuator') { - if (tokenBefore.value === tokenClose) { - nested++; - } - if (tokenBefore.value === tokenOpen) { - if (nested) { - nested--; - } else { - break; - } - } - } - } while (tokenBefore); - - return tokenBefore; - } - } - - if (token.type === 'Identifier') { - const tokenBefore = sourceCode.getTokenBefore(token, {includeComments: true}); - if (tokenBefore && tokenBefore.type === 'Punctuator' && tokenBefore.value === '@') { - return tokenBefore; - } - } - - return false; +const getDecorator = (node) => { + return node?.declaration?.decorators?.[0] || node?.decorators?.[0] || + node?.parent?.decorators?.[0]; }; /** @@ -224,12 +186,11 @@ const findJSDocComment = (astNode, sourceCode, settings) => { let tokenBefore = null; while (currentNode) { - tokenBefore = sourceCode.getTokenBefore(currentNode, {includeComments: true}); - const decorator = getDecorator(tokenBefore, sourceCode); + const decorator = getDecorator(currentNode); if (decorator) { currentNode = decorator; - continue; } + tokenBefore = sourceCode.getTokenBefore(currentNode, {includeComments: true}); if (!tokenBefore || !isCommentToken(tokenBefore)) { return null; } diff --git a/src/rules/requireJsdoc.js b/src/rules/requireJsdoc.js index 58337e9fc..cf30438e6 100644 --- a/src/rules/requireJsdoc.js +++ b/src/rules/requireJsdoc.js @@ -212,14 +212,10 @@ export default { const lines = settings.minLines === 0 && settings.maxLines >= 1 ? 1 : settings.minLines; let baseNode = getReducedASTNode(node, sourceCode); - let decorator; - do { - const tokenBefore = sourceCode.getTokenBefore(baseNode, {includeComments: true}); - decorator = getDecorator(tokenBefore, sourceCode); - if (decorator) { - baseNode = decorator; - } - } while (decorator); + const decorator = getDecorator(baseNode); + if (decorator) { + baseNode = decorator; + } const indent = jsdocUtils.getIndent({ text: sourceCode.getText( diff --git a/test/rules/assertions/requireJsdoc.js b/test/rules/assertions/requireJsdoc.js index 365afc7c1..d194c74cc 100644 --- a/test/rules/assertions/requireJsdoc.js +++ b/test/rules/assertions/requireJsdoc.js @@ -2971,6 +2971,26 @@ function quux (foo) { `, parser: require.resolve('@typescript-eslint/parser'), }, + { + code: ` + requestAnimationFrame(draw) + + function bench() { + } + `, + errors: [{ + message: 'Missing JSDoc comment.', + }], + output: ` + requestAnimationFrame(draw) + + /** + * + */ + function bench() { + } + `, + }, ], valid: [{ code: ` @@ -4609,5 +4629,27 @@ function quux (foo) { }], parser: require.resolve('@typescript-eslint/parser'), }, + { + code: ` + /** + * Entity to represent a user in the system. + */ + @Entity('users') + export class User { + } + `, + options: [ + { + contexts: ['Decorator'], + require: { + FunctionDeclaration: false, + }, + }, + ], + parser: require.resolve('@typescript-eslint/parser'), + parserOptions: { + sourceType: 'module', + }, + }, ], };