UNPKG

@truenine/eslint9-config

Version:

ESLint 9 configuration package for Compose Client projects with TypeScript, Vue, and modern JavaScript support

82 lines (80 loc) 3.14 kB
//#region src/rules/single-line/call.ts const MAX_LINE_LENGTH = 160; const rule = { meta: { type: "layout", docs: { description: "Prefer single-line function calls when the result fits within max line length", recommended: false }, fixable: "code", schema: [{ type: "object", properties: { maxLineLength: { type: "number", default: MAX_LINE_LENGTH } }, additionalProperties: false }], messages: { preferSingleLineCall: "Function call can be written on a single line" } }, create(context) { const { sourceCode } = context; const maxLineLength = (context.options[0] ?? {}).maxLineLength ?? MAX_LINE_LENGTH; function hasComments(node) { return sourceCode.getCommentsInside(node).length > 0; } function isNodeMultiLine(node) { return node.loc.start.line !== node.loc.end.line; } function normalizeText(text) { return text.split("\n").map((l) => l.trim()).join(" ").replaceAll(/\s+/g, " ").trim(); } function getIndent(node) { const line = sourceCode.lines[node.loc.start.line - 1]; return /^(\s*)/.exec(line)?.[1] ?? ""; } function hasNestedObjectLiteral(node) { if (node.type !== "ObjectExpression") return false; const objNode = node; for (const prop of objNode.properties) if (prop.type === "Property" && (prop.value?.type === "ObjectExpression" || prop.value?.type === "ArrayExpression")) return true; return false; } function hasComplexArgument(args) { for (const arg of args) { if (["ArrowFunctionExpression", "FunctionExpression"].includes(arg.type)) return true; if (arg.type === "TemplateLiteral" && sourceCode.getText(arg).includes("\n")) return true; if (arg.type === "ObjectExpression") { if (arg.properties.length >= 5 || hasNestedObjectLiteral(arg)) return true; } if (arg.type === "ArrayExpression" && arg.elements.length >= 4) return true; if (arg.type === "CallExpression" && hasComplexArgument(arg.arguments)) return true; } return false; } function isPartOfChainedCall(node) { const { parent } = node; return parent?.type === "MemberExpression" && parent.parent?.type === "CallExpression"; } function isChainedMethodCall(node) { const callNode = node; return callNode.callee.type === "MemberExpression" && callNode.callee.object.type === "CallExpression"; } return { CallExpression(node) { const callNode = node; if (!isNodeMultiLine(callNode) || hasComments(callNode) || hasComplexArgument(callNode.arguments) || isPartOfChainedCall(callNode) || isChainedMethodCall(callNode)) return; if (callNode.loc.end.line - callNode.loc.start.line + 1 > 4) return; const singleLineText = `${sourceCode.getText(callNode.callee)}(${callNode.arguments.map((arg) => normalizeText(sourceCode.getText(arg))).join(", ")})`; if (singleLineText.length > 80) return; if (getIndent(callNode).length + singleLineText.length > maxLineLength) return; context.report({ node, messageId: "preferSingleLineCall", fix: (fixer) => fixer.replaceText(node, singleLineText) }); } }; } }; //#endregion module.exports = rule; //# sourceMappingURL=call.cjs.map