Website Structure
This commit is contained in:
parent
62812f2090
commit
71f0676a62
22365 changed files with 4265753 additions and 791 deletions
722
Frontend-Learner/node_modules/eslint-plugin-jsdoc/dist/rules/requireJsdoc.cjs
generated
vendored
Normal file
722
Frontend-Learner/node_modules/eslint-plugin-jsdoc/dist/rules/requireJsdoc.cjs
generated
vendored
Normal file
|
|
@ -0,0 +1,722 @@
|
|||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = void 0;
|
||||
var _exportParser = _interopRequireDefault(require("../exportParser.cjs"));
|
||||
var _iterateJsdoc = require("../iterateJsdoc.cjs");
|
||||
var _jsdocUtils = require("../jsdocUtils.cjs");
|
||||
var _jsdoccomment = require("@es-joy/jsdoccomment");
|
||||
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
||||
/**
|
||||
* @typedef {{
|
||||
* ancestorsOnly: boolean,
|
||||
* esm: boolean,
|
||||
* initModuleExports: boolean,
|
||||
* initWindow: boolean
|
||||
* }} RequireJsdocOpts
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {import('eslint').Rule.Node|
|
||||
* import('@typescript-eslint/types').TSESTree.Node} ESLintOrTSNode
|
||||
*/
|
||||
|
||||
/** @type {import('json-schema').JSONSchema4} */
|
||||
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
|
||||
\`true\`. When \`true\`, \`exemptEmptyConstructors\` may still avoid reporting when
|
||||
no parameters or return values are found.`,
|
||||
type: 'boolean'
|
||||
},
|
||||
checkGetters: {
|
||||
anyOf: [{
|
||||
type: 'boolean'
|
||||
}, {
|
||||
enum: ['no-setter'],
|
||||
type: 'string'
|
||||
}],
|
||||
default: true,
|
||||
description: `A value indicating whether getters should be checked. Besides setting as a
|
||||
boolean, this option can be set to the string \`"no-setter"\` to indicate that
|
||||
getters should be checked but only when there is no setter. This may be useful
|
||||
if one only wishes documentation on one of the two accessors. Defaults to
|
||||
\`false\`.`
|
||||
},
|
||||
checkSetters: {
|
||||
anyOf: [{
|
||||
type: 'boolean'
|
||||
}, {
|
||||
enum: ['no-getter'],
|
||||
type: 'string'
|
||||
}],
|
||||
default: true,
|
||||
description: `A value indicating whether setters should be checked. Besides setting as a
|
||||
boolean, this option can be set to the string \`"no-getter"\` to indicate that
|
||||
setters should be checked but only when there is no getter. This may be useful
|
||||
if one only wishes documentation on one of the two accessors. Defaults to
|
||||
\`false\`.`
|
||||
},
|
||||
contexts: {
|
||||
description: `Set this to an array of strings or objects representing the additional AST
|
||||
contexts where you wish the rule to be applied (e.g., \`Property\` for
|
||||
properties). If specified as an object, it should have a \`context\` property
|
||||
and can have an \`inlineCommentBlock\` property which, if set to \`true\`, will
|
||||
add an inline \`/** */\` instead of the regular, multi-line, indented jsdoc
|
||||
block which will otherwise be added. Defaults to an empty array. Contexts
|
||||
may also have their own \`minLineCount\` property which is an integer
|
||||
indicating a minimum number of lines expected for a node in order
|
||||
for it to require documentation.
|
||||
|
||||
Note that you may need to disable \`require\` items (e.g., \`MethodDefinition\`)
|
||||
if you are specifying a more precise form in \`contexts\` (e.g., \`MethodDefinition:not([accessibility="private"] > FunctionExpression\`).
|
||||
|
||||
See the ["AST and Selectors"](../#advanced-ast-and-selectors)
|
||||
section of our Advanced docs for more on the expected format.`,
|
||||
items: {
|
||||
anyOf: [{
|
||||
type: 'string'
|
||||
}, {
|
||||
additionalProperties: false,
|
||||
properties: {
|
||||
context: {
|
||||
type: 'string'
|
||||
},
|
||||
inlineCommentBlock: {
|
||||
type: 'boolean'
|
||||
},
|
||||
minLineCount: {
|
||||
type: 'integer'
|
||||
}
|
||||
},
|
||||
type: 'object'
|
||||
}]
|
||||
},
|
||||
type: 'array'
|
||||
},
|
||||
enableFixer: {
|
||||
default: true,
|
||||
description: `A boolean on whether to enable the fixer (which adds an empty JSDoc block).
|
||||
Defaults to \`true\`.`,
|
||||
type: 'boolean'
|
||||
},
|
||||
exemptEmptyConstructors: {
|
||||
default: false,
|
||||
description: `When \`true\`, the rule will not report missing JSDoc blocks above constructors
|
||||
with no parameters or return values (this is enabled by default as the class
|
||||
name or description should be seen as sufficient to convey intent).
|
||||
|
||||
Defaults to \`true\`.`,
|
||||
type: 'boolean'
|
||||
},
|
||||
exemptEmptyFunctions: {
|
||||
default: false,
|
||||
description: `When \`true\`, the rule will not report missing JSDoc blocks above
|
||||
functions/methods with no parameters or return values (intended where
|
||||
function/method names are sufficient for themselves as documentation).
|
||||
|
||||
Defaults to \`false\`.`,
|
||||
type: 'boolean'
|
||||
},
|
||||
exemptOverloadedImplementations: {
|
||||
default: false,
|
||||
description: `If set to \`true\` will avoid checking an overloaded function's implementation.
|
||||
|
||||
Defaults to \`false\`.`,
|
||||
type: 'boolean'
|
||||
},
|
||||
fixerMessage: {
|
||||
default: '',
|
||||
description: `An optional message to add to the inserted JSDoc block. Defaults to the
|
||||
empty string.`,
|
||||
type: 'string'
|
||||
},
|
||||
minLineCount: {
|
||||
description: `An integer to indicate a minimum number of lines expected for a node in order
|
||||
for it to require documentation. Defaults to \`undefined\`. This option will
|
||||
apply to any context; see \`contexts\` for line counts specific to a context.`,
|
||||
type: 'integer'
|
||||
},
|
||||
publicOnly: {
|
||||
description: `This option will insist that missing JSDoc blocks are only reported for
|
||||
function bodies / class declarations that are exported from the module.
|
||||
May be a boolean or object. If set to \`true\`, the defaults below will be
|
||||
used. If unset, JSDoc block reporting will not be limited to exports.
|
||||
|
||||
This object supports the following optional boolean keys (\`false\` unless
|
||||
otherwise noted):
|
||||
|
||||
- \`ancestorsOnly\` - Optimization to only check node ancestors to check if node is exported
|
||||
- \`esm\` - ESM exports are checked for JSDoc comments (Defaults to \`true\`)
|
||||
- \`cjs\` - CommonJS exports are checked for JSDoc comments (Defaults to \`true\`)
|
||||
- \`window\` - Window global exports are checked for JSDoc comments`,
|
||||
oneOf: [{
|
||||
default: false,
|
||||
type: 'boolean'
|
||||
}, {
|
||||
additionalProperties: false,
|
||||
default: {},
|
||||
properties: {
|
||||
ancestorsOnly: {
|
||||
type: 'boolean'
|
||||
},
|
||||
cjs: {
|
||||
type: 'boolean'
|
||||
},
|
||||
esm: {
|
||||
type: 'boolean'
|
||||
},
|
||||
window: {
|
||||
type: 'boolean'
|
||||
}
|
||||
},
|
||||
type: 'object'
|
||||
}]
|
||||
},
|
||||
require: {
|
||||
additionalProperties: false,
|
||||
default: {},
|
||||
description: `An object with the following optional boolean keys which all default to
|
||||
\`false\` except for \`FunctionDeclaration\` which defaults to \`true\`.`,
|
||||
properties: {
|
||||
ArrowFunctionExpression: {
|
||||
default: false,
|
||||
description: 'Whether to check arrow functions like `() => {}`',
|
||||
type: 'boolean'
|
||||
},
|
||||
ClassDeclaration: {
|
||||
default: false,
|
||||
description: 'Whether to check declarations like `class A {}`',
|
||||
type: 'boolean'
|
||||
},
|
||||
ClassExpression: {
|
||||
default: false,
|
||||
description: 'Whether to check class expressions like `const myClass = class {}`',
|
||||
type: 'boolean'
|
||||
},
|
||||
FunctionDeclaration: {
|
||||
default: true,
|
||||
description: 'Whether to check function declarations like `function a {}`',
|
||||
type: 'boolean'
|
||||
},
|
||||
FunctionExpression: {
|
||||
default: false,
|
||||
description: 'Whether to check function expressions like `const a = function {}`',
|
||||
type: 'boolean'
|
||||
},
|
||||
MethodDefinition: {
|
||||
default: false,
|
||||
description: 'Whether to check method definitions like `class A { someMethodDefinition () {} }`',
|
||||
type: 'boolean'
|
||||
}
|
||||
},
|
||||
type: 'object'
|
||||
},
|
||||
skipInterveningOverloadedDeclarations: {
|
||||
default: true,
|
||||
description: `If \`true\`, will skip above uncommented overloaded functions to check
|
||||
for a comment block (e.g., at the top of a set of overloaded functions).
|
||||
|
||||
If \`false\`, will force each overloaded function to be checked for a
|
||||
comment block.
|
||||
|
||||
Defaults to \`true\`.`,
|
||||
type: 'boolean'
|
||||
}
|
||||
},
|
||||
type: 'object'
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} interfaceName
|
||||
* @param {string} methodName
|
||||
* @param {import("eslint").Scope.Scope | null} scope
|
||||
* @returns {import('@typescript-eslint/types').TSESTree.TSMethodSignature|null}
|
||||
*/
|
||||
const getMethodOnInterface = (interfaceName, methodName, scope) => {
|
||||
let scp = scope;
|
||||
while (scp) {
|
||||
for (const {
|
||||
identifiers,
|
||||
name
|
||||
} of scp.variables) {
|
||||
if (interfaceName !== name) {
|
||||
continue;
|
||||
}
|
||||
for (const identifier of identifiers) {
|
||||
const interfaceDeclaration = /** @type {import('@typescript-eslint/types').TSESTree.Identifier & {parent: import('@typescript-eslint/types').TSESTree.TSInterfaceDeclaration}} */identifier.parent;
|
||||
/* c8 ignore next 3 -- TS */
|
||||
if (interfaceDeclaration.type !== 'TSInterfaceDeclaration') {
|
||||
continue;
|
||||
}
|
||||
for (const bodyItem of interfaceDeclaration.body.body) {
|
||||
const methodSig = /** @type {import('@typescript-eslint/types').TSESTree.TSMethodSignature} */
|
||||
bodyItem;
|
||||
if (methodName === /** @type {import('@typescript-eslint/types').TSESTree.Identifier} */methodSig.key.name) {
|
||||
return methodSig;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
scp = scp.upper;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {import('eslint').Rule.Node} node
|
||||
* @param {import('eslint').SourceCode} sourceCode
|
||||
* @param {import('eslint').Rule.RuleContext} context
|
||||
* @param {import('../iterateJsdoc.js').Settings} settings
|
||||
*/
|
||||
const isExemptedImplementer = (node, sourceCode, context, settings) => {
|
||||
if (node.type === 'FunctionExpression' && node.parent.type === 'MethodDefinition' && node.parent.parent.type === 'ClassBody' && node.parent.parent.parent.type === 'ClassDeclaration' && 'implements' in node.parent.parent.parent) {
|
||||
const implments = /** @type {import('@typescript-eslint/types').TSESTree.TSClassImplements[]} */
|
||||
node.parent.parent.parent.implements;
|
||||
const {
|
||||
name: methodName
|
||||
} = /** @type {import('@typescript-eslint/types').TSESTree.Identifier} */
|
||||
node.parent.key;
|
||||
for (const impl of implments) {
|
||||
const {
|
||||
name: interfaceName
|
||||
} = /** @type {import('@typescript-eslint/types').TSESTree.Identifier} */
|
||||
impl.expression;
|
||||
const interfaceMethodNode = getMethodOnInterface(interfaceName, methodName, node && (sourceCode.getScope && /* c8 ignore next 3 */
|
||||
sourceCode.getScope(node) ||
|
||||
// @ts-expect-error ESLint 8
|
||||
context.getScope()));
|
||||
if (interfaceMethodNode) {
|
||||
// @ts-expect-error Ok
|
||||
const comment = (0, _jsdoccomment.getJSDocComment)(sourceCode, interfaceMethodNode, settings);
|
||||
if (comment) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {import('eslint').Rule.RuleContext} context
|
||||
* @param {import('json-schema').JSONSchema4Object} baseObject
|
||||
* @param {string} option
|
||||
* @param {string} key
|
||||
* @returns {boolean|undefined}
|
||||
*/
|
||||
const getOption = (context, baseObject, option, key) => {
|
||||
if (context.options[0] && option in context.options[0] && (
|
||||
// Todo: boolean shouldn't be returning property, but
|
||||
// tests currently require
|
||||
typeof context.options[0][option] === 'boolean' || key in context.options[0][option])) {
|
||||
return context.options[0][option][key];
|
||||
}
|
||||
return /** @type {{[key: string]: {default?: boolean|undefined}}} */baseObject.properties[key].default;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {import('eslint').Rule.RuleContext} context
|
||||
* @param {import('../iterateJsdoc.js').Settings} settings
|
||||
* @returns {{
|
||||
* checkAllFunctionExpressions: boolean,
|
||||
* contexts: (string|{
|
||||
* context: string,
|
||||
* inlineCommentBlock: boolean,
|
||||
* minLineCount: import('../iterateJsdoc.js').Integer
|
||||
* })[],
|
||||
* enableFixer: boolean,
|
||||
* exemptEmptyConstructors: boolean,
|
||||
* exemptEmptyFunctions: boolean,
|
||||
* skipInterveningOverloadedDeclarations: boolean,
|
||||
* exemptOverloadedImplementations: boolean,
|
||||
* fixerMessage: string,
|
||||
* minLineCount: undefined|import('../iterateJsdoc.js').Integer,
|
||||
* publicOnly: boolean|{[key: string]: boolean|undefined}
|
||||
* require: {[key: string]: boolean|undefined}
|
||||
* }}
|
||||
*/
|
||||
const getOptions = (context, settings) => {
|
||||
const {
|
||||
checkAllFunctionExpressions = false,
|
||||
contexts = settings.contexts || [],
|
||||
enableFixer = true,
|
||||
exemptEmptyConstructors = true,
|
||||
exemptEmptyFunctions = false,
|
||||
exemptOverloadedImplementations = false,
|
||||
fixerMessage = '',
|
||||
minLineCount = undefined,
|
||||
publicOnly,
|
||||
skipInterveningOverloadedDeclarations = true
|
||||
} = context.options[0] || {};
|
||||
return {
|
||||
checkAllFunctionExpressions,
|
||||
contexts,
|
||||
enableFixer,
|
||||
exemptEmptyConstructors,
|
||||
exemptEmptyFunctions,
|
||||
exemptOverloadedImplementations,
|
||||
fixerMessage,
|
||||
minLineCount,
|
||||
publicOnly: (baseObj => {
|
||||
if (!publicOnly) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/** @type {{[key: string]: boolean|undefined}} */
|
||||
const properties = {};
|
||||
for (const prop of Object.keys(/** @type {import('json-schema').JSONSchema4Object} */
|
||||
/** @type {import('json-schema').JSONSchema4Object} */baseObj.properties)) {
|
||||
const opt = getOption(context, /** @type {import('json-schema').JSONSchema4Object} */baseObj, 'publicOnly', prop);
|
||||
properties[prop] = opt;
|
||||
}
|
||||
return properties;
|
||||
})(/** @type {import('json-schema').JSONSchema4Object} */
|
||||
(/** @type {import('json-schema').JSONSchema4Object} */
|
||||
(/** @type {import('json-schema').JSONSchema4Object} */
|
||||
OPTIONS_SCHEMA.properties.publicOnly).oneOf)[1]),
|
||||
require: (baseObj => {
|
||||
/** @type {{[key: string]: boolean|undefined}} */
|
||||
const properties = {};
|
||||
for (const prop of Object.keys(/** @type {import('json-schema').JSONSchema4Object} */
|
||||
/** @type {import('json-schema').JSONSchema4Object} */baseObj.properties)) {
|
||||
const opt = getOption(context, /** @type {import('json-schema').JSONSchema4Object} */
|
||||
baseObj, 'require', prop);
|
||||
properties[prop] = opt;
|
||||
}
|
||||
return properties;
|
||||
})(/** @type {import('json-schema').JSONSchema4Object} */
|
||||
OPTIONS_SCHEMA.properties.require),
|
||||
skipInterveningOverloadedDeclarations
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {ESLintOrTSNode} node
|
||||
*/
|
||||
const isFunctionWithOverload = node => {
|
||||
if (node.type !== 'FunctionDeclaration') {
|
||||
return false;
|
||||
}
|
||||
let parent;
|
||||
let child;
|
||||
if (node.parent?.type === 'Program') {
|
||||
parent = node.parent;
|
||||
child = node;
|
||||
} else if (node.parent?.type === 'ExportNamedDeclaration' && node.parent?.parent.type === 'Program') {
|
||||
parent = node.parent?.parent;
|
||||
child = node.parent;
|
||||
}
|
||||
if (!child || !parent) {
|
||||
return false;
|
||||
}
|
||||
const functionName = node.id?.name;
|
||||
const idx = parent.body.indexOf(child);
|
||||
const prevSibling = parent.body[idx - 1];
|
||||
return (
|
||||
// @ts-expect-error Should be ok
|
||||
prevSibling?.type === 'TSDeclareFunction' &&
|
||||
// @ts-expect-error Should be ok
|
||||
functionName === prevSibling.id.name || prevSibling?.type === 'ExportNamedDeclaration' &&
|
||||
// @ts-expect-error Should be ok
|
||||
prevSibling.declaration?.type === 'TSDeclareFunction' &&
|
||||
// @ts-expect-error Should be ok
|
||||
prevSibling.declaration?.id?.name === functionName
|
||||
);
|
||||
};
|
||||
|
||||
/** @type {import('eslint').Rule.RuleModule} */
|
||||
var _default = exports.default = {
|
||||
create(context) {
|
||||
/* c8 ignore next -- Fallback to deprecated method */
|
||||
const {
|
||||
sourceCode = context.getSourceCode()
|
||||
} = context;
|
||||
const settings = (0, _iterateJsdoc.getSettings)(context);
|
||||
if (!settings) {
|
||||
return {};
|
||||
}
|
||||
const opts = getOptions(context, settings);
|
||||
const {
|
||||
checkAllFunctionExpressions,
|
||||
contexts,
|
||||
enableFixer,
|
||||
exemptEmptyConstructors,
|
||||
exemptEmptyFunctions,
|
||||
exemptOverloadedImplementations,
|
||||
fixerMessage,
|
||||
minLineCount,
|
||||
require: requireOption,
|
||||
skipInterveningOverloadedDeclarations
|
||||
} = opts;
|
||||
const publicOnly =
|
||||
/**
|
||||
* @type {{
|
||||
* [key: string]: boolean | undefined;
|
||||
* }}
|
||||
*/
|
||||
opts.publicOnly;
|
||||
|
||||
/**
|
||||
* @type {import('../iterateJsdoc.js').CheckJsdoc}
|
||||
*/
|
||||
const checkJsDoc = (info, _handler, node) => {
|
||||
if (
|
||||
// Optimize
|
||||
minLineCount !== undefined || contexts.some(ctxt => {
|
||||
if (typeof ctxt === 'string') {
|
||||
return false;
|
||||
}
|
||||
const {
|
||||
minLineCount: count
|
||||
} = ctxt;
|
||||
return count !== undefined;
|
||||
})) {
|
||||
/**
|
||||
* @param {undefined|import('../iterateJsdoc.js').Integer} count
|
||||
*/
|
||||
const underMinLine = count => {
|
||||
return count !== undefined && count > (sourceCode.getText(node).match(/\n/gv)?.length ?? 0) + 1;
|
||||
};
|
||||
if (underMinLine(minLineCount)) {
|
||||
return;
|
||||
}
|
||||
const {
|
||||
minLineCount: contextMinLineCount
|
||||
} =
|
||||
/**
|
||||
* @type {{
|
||||
* context: string;
|
||||
* inlineCommentBlock: boolean;
|
||||
* minLineCount: number;
|
||||
* }}
|
||||
*/
|
||||
contexts.find(ctxt => {
|
||||
if (typeof ctxt === 'string') {
|
||||
return false;
|
||||
}
|
||||
const {
|
||||
context: ctx
|
||||
} = ctxt;
|
||||
return ctx === (info.selector || node.type);
|
||||
}) || {};
|
||||
if (underMinLine(contextMinLineCount)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (exemptOverloadedImplementations && isFunctionWithOverload(node)) {
|
||||
return;
|
||||
}
|
||||
const jsDocNode = (0, _jsdoccomment.getJSDocComment)(sourceCode, node, settings, {
|
||||
checkOverloads: skipInterveningOverloadedDeclarations
|
||||
});
|
||||
if (jsDocNode) {
|
||||
return;
|
||||
}
|
||||
|
||||
// For those who have options configured against ANY constructors (or
|
||||
// setters or getters) being reported
|
||||
if ((0, _jsdocUtils.exemptSpeciaMethods)({
|
||||
description: '',
|
||||
inlineTags: [],
|
||||
problems: [],
|
||||
source: [],
|
||||
tags: []
|
||||
}, node, context, [OPTIONS_SCHEMA])) {
|
||||
return;
|
||||
}
|
||||
if (
|
||||
// Avoid reporting param-less, return-less functions (when
|
||||
// `exemptEmptyFunctions` option is set)
|
||||
exemptEmptyFunctions && info.isFunctionContext ||
|
||||
// Avoid reporting param-less, return-less constructor methods (when
|
||||
// `exemptEmptyConstructors` option is set)
|
||||
exemptEmptyConstructors && (0, _jsdocUtils.isConstructor)(node)) {
|
||||
const functionParameterNames = (0, _jsdocUtils.getFunctionParameterNames)(node);
|
||||
if (!functionParameterNames.length && !(0, _jsdocUtils.hasReturnValue)(node)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (isExemptedImplementer(node, sourceCode, context, settings)) {
|
||||
return;
|
||||
}
|
||||
const fix = /** @type {import('eslint').Rule.ReportFixer} */fixer => {
|
||||
// Default to one line break if the `minLines`/`maxLines` settings allow
|
||||
const lines = settings.minLines === 0 && settings.maxLines >= 1 ? 1 : settings.minLines;
|
||||
/** @type {ESLintOrTSNode|import('@typescript-eslint/types').TSESTree.Decorator} */
|
||||
let baseNode = (0, _jsdoccomment.getReducedASTNode)(node, sourceCode);
|
||||
const decorator = (0, _jsdoccomment.getDecorator)(/** @type {import('eslint').Rule.Node} */
|
||||
baseNode);
|
||||
if (decorator) {
|
||||
baseNode = decorator;
|
||||
}
|
||||
const indent = (0, _jsdocUtils.getIndent)({
|
||||
text: sourceCode.getText(/** @type {import('eslint').Rule.Node} */baseNode, /** @type {import('eslint').AST.SourceLocation} */
|
||||
(/** @type {import('eslint').Rule.Node} */baseNode.loc).start.column)
|
||||
});
|
||||
const {
|
||||
inlineCommentBlock
|
||||
} =
|
||||
/**
|
||||
* @type {{
|
||||
* context: string,
|
||||
* inlineCommentBlock: boolean,
|
||||
* minLineCount: import('../iterateJsdoc.js').Integer
|
||||
* }}
|
||||
*/
|
||||
contexts.find(contxt => {
|
||||
if (typeof contxt === 'string') {
|
||||
return false;
|
||||
}
|
||||
const {
|
||||
context: ctxt
|
||||
} = contxt;
|
||||
return ctxt === node.type;
|
||||
}) || {};
|
||||
const insertion = (inlineCommentBlock ? `/** ${fixerMessage}` : `/**\n${indent}*${fixerMessage}\n${indent}`) + `*/${'\n'.repeat(lines)}${indent.slice(0, -1)}`;
|
||||
return fixer.insertTextBefore(/** @type {import('eslint').Rule.Node} */
|
||||
baseNode, insertion);
|
||||
};
|
||||
const report = () => {
|
||||
const {
|
||||
start
|
||||
} = /** @type {import('eslint').AST.SourceLocation} */node.loc;
|
||||
const loc = {
|
||||
end: {
|
||||
column: 0,
|
||||
line: start.line + 1
|
||||
},
|
||||
start
|
||||
};
|
||||
context.report({
|
||||
fix: enableFixer ? fix : null,
|
||||
loc,
|
||||
messageId: 'missingJsDoc',
|
||||
node
|
||||
});
|
||||
};
|
||||
if (publicOnly) {
|
||||
/** @type {RequireJsdocOpts} */
|
||||
const opt = {
|
||||
ancestorsOnly: Boolean(publicOnly?.ancestorsOnly ?? false),
|
||||
esm: Boolean(publicOnly?.esm ?? true),
|
||||
initModuleExports: Boolean(publicOnly?.cjs ?? true),
|
||||
initWindow: Boolean(publicOnly?.window ?? false)
|
||||
};
|
||||
const exported = _exportParser.default.isUncommentedExport(node, sourceCode, opt, settings);
|
||||
if (exported) {
|
||||
report();
|
||||
}
|
||||
} else {
|
||||
report();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} prop
|
||||
* @returns {boolean}
|
||||
*/
|
||||
const hasOption = prop => {
|
||||
return requireOption[prop] || contexts.some(ctxt => {
|
||||
return typeof ctxt === 'object' ? ctxt.context === prop : ctxt === prop;
|
||||
});
|
||||
};
|
||||
return {
|
||||
...(0, _jsdocUtils.getContextObject)((0, _jsdocUtils.enforcedContexts)(context, [], settings), checkJsDoc),
|
||||
ArrowFunctionExpression(node) {
|
||||
if (!hasOption('ArrowFunctionExpression')) {
|
||||
return;
|
||||
}
|
||||
if (['AssignmentExpression', 'ExportDefaultDeclaration', 'VariableDeclarator'].includes(node.parent.type) || ['ClassProperty', 'ObjectProperty', 'Property', 'PropertyDefinition'].includes(node.parent.type) && node ===
|
||||
/**
|
||||
* @type {import('@typescript-eslint/types').TSESTree.Property|
|
||||
* import('@typescript-eslint/types').TSESTree.PropertyDefinition
|
||||
* }
|
||||
*/
|
||||
node.parent.value) {
|
||||
checkJsDoc({
|
||||
isFunctionContext: true
|
||||
}, null, node);
|
||||
}
|
||||
},
|
||||
ClassDeclaration(node) {
|
||||
if (!hasOption('ClassDeclaration')) {
|
||||
return;
|
||||
}
|
||||
checkJsDoc({
|
||||
isFunctionContext: false
|
||||
}, null, node);
|
||||
},
|
||||
ClassExpression(node) {
|
||||
if (!hasOption('ClassExpression')) {
|
||||
return;
|
||||
}
|
||||
checkJsDoc({
|
||||
isFunctionContext: false
|
||||
}, null, node);
|
||||
},
|
||||
FunctionDeclaration(node) {
|
||||
if (!hasOption('FunctionDeclaration')) {
|
||||
return;
|
||||
}
|
||||
checkJsDoc({
|
||||
isFunctionContext: true
|
||||
}, null, node);
|
||||
},
|
||||
FunctionExpression(node) {
|
||||
if (!hasOption('FunctionExpression')) {
|
||||
return;
|
||||
}
|
||||
if (checkAllFunctionExpressions || ['AssignmentExpression', 'ExportDefaultDeclaration', 'VariableDeclarator'].includes(node.parent.type) || ['ClassProperty', 'ObjectProperty', 'Property', 'PropertyDefinition'].includes(node.parent.type) && node ===
|
||||
/**
|
||||
* @type {import('@typescript-eslint/types').TSESTree.Property|
|
||||
* import('@typescript-eslint/types').TSESTree.PropertyDefinition
|
||||
* }
|
||||
*/
|
||||
node.parent.value) {
|
||||
checkJsDoc({
|
||||
isFunctionContext: true
|
||||
}, null, node);
|
||||
}
|
||||
},
|
||||
MethodDefinition(node) {
|
||||
if (!hasOption('MethodDefinition')) {
|
||||
return;
|
||||
}
|
||||
checkJsDoc({
|
||||
isFunctionContext: true,
|
||||
selector: 'MethodDefinition'
|
||||
}, null, /** @type {import('eslint').Rule.Node} */node.value);
|
||||
}
|
||||
};
|
||||
},
|
||||
meta: {
|
||||
docs: {
|
||||
category: 'Stylistic Issues',
|
||||
description: 'Checks for presence of JSDoc comments, on functions and potentially other contexts (optionally limited to exports).',
|
||||
recommended: true,
|
||||
url: 'https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/require-jsdoc.md#repos-sticky-header'
|
||||
},
|
||||
fixable: 'code',
|
||||
messages: {
|
||||
missingJsDoc: 'Missing JSDoc comment.'
|
||||
},
|
||||
schema: [OPTIONS_SCHEMA],
|
||||
type: 'suggestion'
|
||||
}
|
||||
};
|
||||
module.exports = exports.default;
|
||||
//# sourceMappingURL=requireJsdoc.cjs.map
|
||||
Loading…
Add table
Add a link
Reference in a new issue