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 };