@truenine/eslint9-config
Version:
ESLint 9 configuration package for Compose Client projects with TypeScript, Vue, and modern JavaScript support
92 lines (91 loc) • 2.9 kB
JavaScript
//#region src/rules/code-style/concise-arrow.ts
const MAX_LINE_LENGTH = 160;
/**
* ESLint rule: prefer-concise-arrow
* Detects and fixes arrow functions that can be simplified.
*/
const rule = {
meta: {
type: "layout",
docs: {
description: "Prefer concise arrow function body when possible",
recommended: false
},
fixable: "code",
schema: [],
messages: { preferConciseArrow: "Arrow function body can be simplified to a single expression" }
},
create(context) {
const { sourceCode } = context;
function hasComments(node) {
return sourceCode.getCommentsInside(node).length > 0;
}
function isNodeSingleLine(n) {
return n.loc.start.line === n.loc.end.line;
}
function normalizeText(t) {
return t.split("\n").map((l) => l.trim()).join(" ").replaceAll(/\s+/g, " ").trim();
}
function getIndent(node) {
return " ".repeat(node.loc?.start.column ?? 0);
}
function containsNestedComplexity(node) {
let complexity = false;
const skip = new Set([
"parent",
"loc",
"range",
"start",
"end",
"tokens",
"comments"
]);
const traverse = (n) => {
if (complexity || n == null || typeof n !== "object") return;
if ([
"ArrowFunctionExpression",
"ConditionalExpression",
"LogicalExpression"
].includes(n.type)) {
complexity = true;
return;
}
Object.keys(n).forEach((k) => {
if (skip.has(k)) return;
const v = n[k];
if (Array.isArray(v)) v.forEach(traverse);
else traverse(v);
});
};
traverse(node);
return complexity;
}
function needsParens(params) {
if (params.length !== 1 || params[0].type !== "Identifier") return true;
return params[0].typeAnnotation != null;
}
return { ArrowFunctionExpression(node) {
const arrow = node;
if (arrow.expression || arrow.body.type !== "BlockStatement" || arrow.body.body.length !== 1 || hasComments(arrow.body) || isNodeSingleLine(arrow)) return;
const stmt = arrow.body.body[0];
let expr = null;
if (stmt.type === "ExpressionStatement") expr = stmt.expression;
else if (stmt.type === "ReturnStatement") expr = stmt.argument;
if (expr == null || containsNestedComplexity(expr)) return;
const paramsText = arrow.params.map((p) => sourceCode.getText(p)).join(", ");
const exprText = normalizeText(sourceCode.getText(expr));
const paramsWrapper = needsParens(arrow.params) ? `(${paramsText})` : paramsText;
const bodyText = expr.type === "ObjectExpression" ? `(${exprText})` : exprText;
const result = `${arrow.async === true ? "async " : ""}${paramsWrapper} => ${bodyText}`;
if (getIndent(arrow).length + result.length > MAX_LINE_LENGTH) return;
context.report({
node,
messageId: "preferConciseArrow",
fix: (fixer) => fixer.replaceText(node, result)
});
} };
}
};
//#endregion
export { rule as default };
//# sourceMappingURL=concise-arrow.mjs.map