UNPKG

eslint-plugin-jsdoc

Version:
1 lines 12.4 kB
{"version":3,"file":"requireRejects.cjs","names":["iterateJsdoc"],"sources":["../../src/rules/requireRejects.js"],"sourcesContent":["import iterateJsdoc from '../iterateJsdoc.js';\n\n/**\n * Checks if a node or its children contain Promise rejection patterns\n * @param {import('eslint').Rule.Node} node\n * @param {boolean} [innerFunction]\n * @param {boolean} [isAsync]\n * @returns {boolean}\n */\n// eslint-disable-next-line complexity -- Temporary\nconst hasRejectValue = (node, innerFunction, isAsync) => {\n if (!node) {\n return false;\n }\n\n switch (node.type) {\n case 'ArrowFunctionExpression':\n case 'FunctionDeclaration':\n case 'FunctionExpression': {\n // For inner functions in async contexts, check if they throw\n // (they could be called and cause rejection)\n if (innerFunction) {\n // Check inner functions for throws - if called from async context, throws become rejections\n const innerIsAsync = node.async;\n // Pass isAsync=true if the inner function is async OR if we're already in an async context\n return hasRejectValue(/** @type {import('eslint').Rule.Node} */ (node.body), false, innerIsAsync || isAsync);\n }\n\n // This is the top-level function we're checking\n return hasRejectValue(/** @type {import('eslint').Rule.Node} */ (node.body), true, node.async);\n }\n\n case 'BlockStatement': {\n return node.body.some((bodyNode) => {\n return hasRejectValue(/** @type {import('eslint').Rule.Node} */ (bodyNode), innerFunction, isAsync);\n });\n }\n\n case 'CallExpression': {\n // Check for Promise.reject()\n if (node.callee.type === 'MemberExpression' &&\n node.callee.object.type === 'Identifier' &&\n node.callee.object.name === 'Promise' &&\n node.callee.property.type === 'Identifier' &&\n node.callee.property.name === 'reject') {\n return true;\n }\n\n // Check for reject() call (in Promise executor context)\n if (node.callee.type === 'Identifier' && node.callee.name === 'reject') {\n return true;\n }\n\n // Check if this is calling an inner function that might reject\n if (innerFunction && node.callee.type === 'Identifier') {\n // We found a function call inside - check if it could be calling a function that rejects\n // We'll handle this in function body traversal\n return false;\n }\n\n return false;\n }\n\n case 'DoWhileStatement':\n case 'ForInStatement':\n case 'ForOfStatement':\n case 'ForStatement':\n case 'LabeledStatement':\n case 'WhileStatement':\n\n case 'WithStatement': {\n return hasRejectValue(/** @type {import('eslint').Rule.Node} */ (node.body), innerFunction, isAsync);\n }\n\n case 'ExpressionStatement': {\n return hasRejectValue(/** @type {import('eslint').Rule.Node} */ (node.expression), innerFunction, isAsync);\n }\n\n case 'IfStatement': {\n return hasRejectValue(/** @type {import('eslint').Rule.Node} */ (node.consequent), innerFunction, isAsync) || hasRejectValue(/** @type {import('eslint').Rule.Node} */ (node.alternate), innerFunction, isAsync);\n }\n\n case 'NewExpression': {\n // Check for new Promise((resolve, reject) => { reject(...) })\n if (node.callee.type === 'Identifier' && node.callee.name === 'Promise' && node.arguments.length > 0) {\n const executor = node.arguments[0];\n if (executor.type === 'ArrowFunctionExpression' || executor.type === 'FunctionExpression') {\n // Check if the executor has reject() calls\n return hasRejectValue(/** @type {import('eslint').Rule.Node} */ (executor.body), false, false);\n }\n }\n\n return false;\n }\n\n case 'ReturnStatement': {\n if (node.argument) {\n return hasRejectValue(/** @type {import('eslint').Rule.Node} */ (node.argument), innerFunction, isAsync);\n }\n\n return false;\n }\n\n case 'SwitchStatement': {\n return node.cases.some(\n (someCase) => {\n return someCase.consequent.some((nde) => {\n return hasRejectValue(/** @type {import('eslint').Rule.Node} */ (nde), innerFunction, isAsync);\n });\n },\n );\n }\n\n // Throw statements in async functions become rejections\n case 'ThrowStatement': {\n return isAsync === true;\n }\n\n case 'TryStatement': {\n return hasRejectValue(/** @type {import('eslint').Rule.Node} */ (node.handler && node.handler.body), innerFunction, isAsync) ||\n hasRejectValue(/** @type {import('eslint').Rule.Node} */ (node.finalizer), innerFunction, isAsync);\n }\n\n default: {\n return false;\n }\n }\n};\n\n/**\n * We can skip checking for a rejects value, in case the documentation is inherited\n * or the method is abstract.\n * @param {import('../iterateJsdoc.js').Utils} utils\n * @returns {boolean}\n */\nconst canSkip = (utils) => {\n return utils.hasATag([\n 'abstract',\n 'virtual',\n 'type',\n ]) ||\n utils.avoidDocs();\n};\n\nexport default iterateJsdoc(({\n node,\n report,\n utils,\n}) => {\n if (canSkip(utils)) {\n return;\n }\n\n const tagName = /** @type {string} */ (utils.getPreferredTagName({\n tagName: 'rejects',\n }));\n if (!tagName) {\n return;\n }\n\n const tags = utils.getTags(tagName);\n const iteratingFunction = utils.isIteratingFunction();\n\n const [\n tag,\n ] = tags;\n const missingRejectsTag = typeof tag === 'undefined' || tag === null;\n\n const shouldReport = () => {\n if (!missingRejectsTag) {\n return false;\n }\n\n // Check if this is an async function or returns a Promise\n const isAsync = utils.isAsync();\n if (!isAsync && !iteratingFunction) {\n return false;\n }\n\n // For async functions, check for throw statements\n // For regular functions, check for Promise.reject or reject calls\n return hasRejectValue(/** @type {import('eslint').Rule.Node} */ (node));\n };\n\n if (shouldReport()) {\n report('Promise-rejecting function requires `@rejects` tag');\n }\n}, {\n contextDefaults: true,\n meta: {\n docs: {\n description: 'Requires that Promise rejections are documented with `@rejects` tags.',\n url: 'https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/require-rejects.md#repos-sticky-header',\n },\n schema: [\n {\n additionalProperties: false,\n properties: {\n contexts: {\n description: `Set this to an array of strings representing the AST context\n(or objects with optional \\`context\\` and \\`comment\\` properties) where you wish\nthe rule to be applied.\n\n\\`context\\` defaults to \\`any\\` and \\`comment\\` defaults to no specific comment context.\n\nOverrides the default contexts (\\`ArrowFunctionExpression\\`, \\`FunctionDeclaration\\`,\n\\`FunctionExpression\\`).`,\n items: {\n anyOf: [\n {\n type: 'string',\n },\n {\n additionalProperties: false,\n properties: {\n comment: {\n type: 'string',\n },\n context: {\n type: 'string',\n },\n },\n type: 'object',\n },\n ],\n },\n type: 'array',\n },\n exemptedBy: {\n description: `Array of tags (e.g., \\`['type']\\`) whose presence on the\ndocument block avoids the need for a \\`@rejects\\`. Defaults to an array\nwith \\`abstract\\`, \\`virtual\\`, and \\`type\\`. If you set this array, it will overwrite the default,\nso be sure to add back those tags if you wish their presence to cause\nexemption of the rule.`,\n items: {\n type: 'string',\n },\n type: 'array',\n },\n },\n type: 'object',\n },\n ],\n type: 'suggestion',\n },\n});\n"],"mappings":"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","ignoreList":[]}