mirror of
https://github.com/naturalcrit/homebrewery.git
synced 2025-12-29 02:32:37 +00:00
103 lines
2.8 KiB
JavaScript
103 lines
2.8 KiB
JavaScript
export default {
|
|
meta: {
|
|
type: "layout",
|
|
docs: {
|
|
description: "Enforce alignment of adjacent useState variable pairs",
|
|
},
|
|
fixable: "whitespace",
|
|
schema: [],
|
|
},
|
|
create(context) {
|
|
const sourceCode = context.getSourceCode();
|
|
const useStateDeclarations = [];
|
|
|
|
return {
|
|
VariableDeclaration(node) {
|
|
for (const decl of node.declarations) {
|
|
const init = decl.init;
|
|
if (
|
|
init &&
|
|
init.type === "CallExpression" &&
|
|
init.callee.name === "useState" &&
|
|
decl.id.type === "ArrayPattern"
|
|
) {
|
|
useStateDeclarations.push(decl);
|
|
}
|
|
}
|
|
},
|
|
"Program:exit"() {
|
|
if (useStateDeclarations.length < 2) return;
|
|
|
|
// Sort by line number
|
|
useStateDeclarations.sort(
|
|
(a, b) => a.loc.start.line - b.loc.start.line
|
|
);
|
|
|
|
// Group adjacent lines
|
|
const groups = [];
|
|
let currentGroup = [useStateDeclarations[0]];
|
|
|
|
for (let i = 1; i < useStateDeclarations.length; i++) {
|
|
const prev = useStateDeclarations[i - 1];
|
|
const curr = useStateDeclarations[i];
|
|
|
|
if (curr.loc.start.line === prev.loc.end.line + 1) {
|
|
currentGroup.push(curr);
|
|
} else {
|
|
if (currentGroup.length > 1) groups.push(currentGroup);
|
|
currentGroup = [curr];
|
|
}
|
|
}
|
|
if (currentGroup.length > 1) groups.push(currentGroup);
|
|
|
|
// Analyze each group
|
|
for (const group of groups) {
|
|
const positions = group.map((decl) => {
|
|
const text = sourceCode.getText(decl);
|
|
const commaIndex = text.indexOf(",");
|
|
const closingBracketIndex = text.lastIndexOf("]");
|
|
return {
|
|
node: decl,
|
|
comma: commaIndex,
|
|
closing: closingBracketIndex,
|
|
};
|
|
});
|
|
|
|
const maxComma = Math.max(...positions.map((p) => p.comma));
|
|
const maxClosing = Math.max(
|
|
...positions.map((p) => p.closing)
|
|
);
|
|
|
|
for (const pos of positions) {
|
|
if (
|
|
pos.comma !== maxComma ||
|
|
pos.closing !== maxClosing
|
|
) {
|
|
console.log(context);
|
|
context.report({
|
|
node: pos.node,
|
|
message: "useState pair is not aligned with others in its block.",
|
|
fix(fixer) {
|
|
const text = sourceCode.getText(pos.node);
|
|
const parts = text.match(/^\[\s*(.+?)\s*,\s*(.+?)\s*\]\s*=\s*useState\((.+)\)$/);
|
|
if (!parts) return null;
|
|
|
|
const [_, left, right, value] = parts;
|
|
|
|
const paddedLeft = left.padEnd(maxComma - 1);
|
|
const paddedRight = right.padEnd(maxClosing - maxComma - 2);
|
|
const aligned = `[${paddedLeft}, ${paddedRight}] = useState(${value})`;
|
|
return [
|
|
fixer.replaceText(pos.node, aligned),
|
|
fixer.insertTextBefore(pos.node.parent, ""),
|
|
fixer.insertTextAfter(pos.node.parent, "")
|
|
];
|
|
}
|
|
});
|
|
}
|
|
}
|
|
}
|
|
},
|
|
};
|
|
},
|
|
}; |