Files
SnowLuma/.pnpm-store/v11/files/ef/0f3ed261a2b8daf5f49abae9b0edc773a1f8472931ef92adde9f8c1ac493bb62bf87022545605640cf5045e821bafc505813e6904e6c0fee2e540049d5afa1
TanTan 2a69b23b47
Dev Build / cleanup (push) Canceled after 0s
Dev Build / typecheck (push) Canceled after 0s
Dev Build / build (linux-arm64, ubuntu-24.04-arm, linux-arm64) (push) Canceled after 0s
Dev Build / build (linux-x64, ubuntu-latest, linux-x64) (push) Canceled after 0s
Dev Build / build (win-x64, windows-latest, win32-x64) (push) Canceled after 0s
Dev Build / dispatch-dev-docker (push) Skipped
docs: 仓库链接指向本镜像仓库
2026-11-13 09:27:07 +08:00

229 lines
6.6 KiB
Plaintext

import { K as isSingleLine, f as createRule, g as import_ast_utils, o as isJSX } from "../utils.js";
var jsx_wrap_multilines_default = createRule({
name: "jsx-wrap-multilines",
meta: {
type: "layout",
docs: { description: "Disallow missing parentheses around multiline JSX" },
fixable: "code",
schema: [{
type: "object",
properties: {
declaration: {
type: ["string", "boolean"],
enum: [
true,
false,
"ignore",
"parens",
"parens-new-line"
]
},
assignment: {
type: ["string", "boolean"],
enum: [
true,
false,
"ignore",
"parens",
"parens-new-line"
]
},
return: {
type: ["string", "boolean"],
enum: [
true,
false,
"ignore",
"parens",
"parens-new-line"
]
},
arrow: {
type: ["string", "boolean"],
enum: [
true,
false,
"ignore",
"parens",
"parens-new-line"
]
},
condition: {
type: ["string", "boolean"],
enum: [
true,
false,
"ignore",
"parens",
"parens-new-line"
]
},
logical: {
type: ["string", "boolean"],
enum: [
true,
false,
"ignore",
"parens",
"parens-new-line"
]
},
prop: {
type: ["string", "boolean"],
enum: [
true,
false,
"ignore",
"parens",
"parens-new-line"
]
},
propertyValue: {
type: ["string", "boolean"],
enum: [
true,
false,
"ignore",
"parens",
"parens-new-line"
]
}
},
additionalProperties: false
}],
defaultOptions: [{
declaration: "parens",
assignment: "parens",
return: "parens",
arrow: "parens",
condition: "ignore",
logical: "ignore",
prop: "ignore",
propertyValue: "ignore"
}],
messages: {
missingParens: "Missing parentheses around multilines JSX",
parensOnNewLines: "Parentheses around JSX should be on separate lines"
}
},
create(context, [options]) {
function isEnabled(type) {
const option = options[type];
return option && option !== "ignore";
}
const { sourceCode } = context;
function needsOpeningNewLine(node) {
const previousToken = sourceCode.getTokenBefore(node);
if (!(0, import_ast_utils.isParenthesized)(node, sourceCode)) return false;
if ((0, import_ast_utils.isTokenOnSameLine)(previousToken, node)) return true;
return false;
}
function needsClosingNewLine(node) {
const nextToken = sourceCode.getTokenAfter(node);
if (!(0, import_ast_utils.isParenthesized)(node, sourceCode)) return false;
if ((0, import_ast_utils.isTokenOnSameLine)(node, nextToken)) return true;
return false;
}
function trimTokenBeforeNewline(tokenBefore) {
const isBracket = tokenBefore.value === "{" || tokenBefore.value === "[";
return `${tokenBefore.value.trim()}${isBracket ? "" : " "}`;
}
function check(node, type) {
if (!node || !isJSX(node)) return;
const option = options[type];
if ((option === true || option === "parens") && !(0, import_ast_utils.isParenthesized)(node, sourceCode) && !isSingleLine(node)) context.report({
node,
messageId: "missingParens",
fix: (fixer) => fixer.replaceText(node, `(${sourceCode.getText(node)})`)
});
if (option === "parens-new-line" && !isSingleLine(node)) if (!(0, import_ast_utils.isParenthesized)(node, sourceCode)) {
const tokenBefore = sourceCode.getTokenBefore(node);
const tokenAfter = sourceCode.getTokenAfter(node);
const start = node.loc.start;
if (tokenBefore.loc.end.line < start.line) {
const textBefore = sourceCode.getText().slice(tokenBefore.range[1], node.range[0]).trim();
const isTab = /^\t/.test(sourceCode.lines[start.line - 1]);
const INDENT = isTab ? " " : " ";
const indentBefore = INDENT.repeat(start.column);
const indentAfter = INDENT.repeat(Math.max(0, start.column - (isTab ? 1 : 2)));
context.report({
node,
messageId: "missingParens",
fix: (fixer) => fixer.replaceTextRange([tokenBefore.range[0], tokenAfter && (tokenAfter.value === ";" || tokenAfter.value === "}") ? tokenAfter.range[0] : node.range[1]], `${trimTokenBeforeNewline(tokenBefore)}(\n${indentBefore}${textBefore}${textBefore.length > 0 ? `\n${indentBefore}` : ""}${sourceCode.getText(node)}\n${indentAfter})`)
});
} else context.report({
node,
messageId: "missingParens",
fix: (fixer) => fixer.replaceText(node, `(\n${sourceCode.getText(node)}\n)`)
});
} else {
const needsOpening = needsOpeningNewLine(node);
const needsClosing = needsClosingNewLine(node);
if (needsOpening || needsClosing) context.report({
node,
messageId: "parensOnNewLines",
fix: (fixer) => {
let fixed = sourceCode.getText(node);
if (needsOpening) fixed = `\n${fixed}`;
if (needsClosing) fixed = `${fixed}\n`;
return fixer.replaceText(node, fixed);
}
});
}
}
return {
VariableDeclarator(node) {
const type = "declaration";
if (!isEnabled(type)) return;
if (!isEnabled("condition") && node.init?.type === "ConditionalExpression") {
check(node.init.consequent, type);
check(node.init.alternate, type);
return;
}
check(node.init, type);
},
AssignmentExpression(node) {
const type = "assignment";
if (!isEnabled(type)) return;
if (!isEnabled("condition") && node.right.type === "ConditionalExpression") {
check(node.right.consequent, type);
check(node.right.alternate, type);
return;
}
check(node.right, type);
},
ReturnStatement(node) {
const type = "return";
if (isEnabled(type)) check(node.argument, type);
},
"ArrowFunctionExpression:exit": (node) => {
const arrowBody = node.body;
const type = "arrow";
if (isEnabled(type) && arrowBody.type !== "BlockStatement") check(arrowBody, type);
},
ConditionalExpression(node) {
const type = "condition";
if (isEnabled(type)) {
check(node.consequent, type);
check(node.alternate, type);
}
},
LogicalExpression(node) {
const type = "logical";
if (isEnabled(type)) check(node.right, type);
},
JSXAttribute(node) {
const type = "prop";
if (isEnabled(type) && node.value?.type === "JSXExpressionContainer") check(node.value.expression, type);
},
ObjectExpression(node) {
const type = "propertyValue";
if (isEnabled(type)) node.properties.forEach((property) => {
if (property.type === "Property" && property.value.type === "JSXElement") check(property.value, type);
});
}
};
}
});
export { jsx_wrap_multilines_default as t };