/**
							 | 
						|
								 * @fileoverview Operator linebreak - enforces operator linebreak style of two types: after and before
							 | 
						|
								 * @author Benoît Zugmeyer
							 | 
						|
								 * @deprecated in ESLint v8.53.0
							 | 
						|
								 */
							 | 
						|
								
							 | 
						|
								"use strict";
							 | 
						|
								
							 | 
						|
								//------------------------------------------------------------------------------
							 | 
						|
								// Requirements
							 | 
						|
								//------------------------------------------------------------------------------
							 | 
						|
								
							 | 
						|
								const astUtils = require("./utils/ast-utils");
							 | 
						|
								
							 | 
						|
								//------------------------------------------------------------------------------
							 | 
						|
								// Rule Definition
							 | 
						|
								//------------------------------------------------------------------------------
							 | 
						|
								
							 | 
						|
								/** @type {import('../shared/types').Rule} */
							 | 
						|
								module.exports = {
							 | 
						|
								    meta: {
							 | 
						|
								        deprecated: true,
							 | 
						|
								        replacedBy: [],
							 | 
						|
								        type: "layout",
							 | 
						|
								
							 | 
						|
								        docs: {
							 | 
						|
								            description: "Enforce consistent linebreak style for operators",
							 | 
						|
								            recommended: false,
							 | 
						|
								            url: "https://eslint.org/docs/latest/rules/operator-linebreak"
							 | 
						|
								        },
							 | 
						|
								
							 | 
						|
								        schema: [
							 | 
						|
								            {
							 | 
						|
								                enum: ["after", "before", "none", null]
							 | 
						|
								            },
							 | 
						|
								            {
							 | 
						|
								                type: "object",
							 | 
						|
								                properties: {
							 | 
						|
								                    overrides: {
							 | 
						|
								                        type: "object",
							 | 
						|
								                        additionalProperties: {
							 | 
						|
								                            enum: ["after", "before", "none", "ignore"]
							 | 
						|
								                        }
							 | 
						|
								                    }
							 | 
						|
								                },
							 | 
						|
								                additionalProperties: false
							 | 
						|
								            }
							 | 
						|
								        ],
							 | 
						|
								
							 | 
						|
								        fixable: "code",
							 | 
						|
								
							 | 
						|
								        messages: {
							 | 
						|
								            operatorAtBeginning: "'{{operator}}' should be placed at the beginning of the line.",
							 | 
						|
								            operatorAtEnd: "'{{operator}}' should be placed at the end of the line.",
							 | 
						|
								            badLinebreak: "Bad line breaking before and after '{{operator}}'.",
							 | 
						|
								            noLinebreak: "There should be no line break before or after '{{operator}}'."
							 | 
						|
								        }
							 | 
						|
								    },
							 | 
						|
								
							 | 
						|
								    create(context) {
							 | 
						|
								
							 | 
						|
								        const usedDefaultGlobal = !context.options[0];
							 | 
						|
								        const globalStyle = context.options[0] || "after";
							 | 
						|
								        const options = context.options[1] || {};
							 | 
						|
								        const styleOverrides = options.overrides ? Object.assign({}, options.overrides) : {};
							 | 
						|
								
							 | 
						|
								        if (usedDefaultGlobal && !styleOverrides["?"]) {
							 | 
						|
								            styleOverrides["?"] = "before";
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        if (usedDefaultGlobal && !styleOverrides[":"]) {
							 | 
						|
								            styleOverrides[":"] = "before";
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        const sourceCode = context.sourceCode;
							 | 
						|
								
							 | 
						|
								        //--------------------------------------------------------------------------
							 | 
						|
								        // Helpers
							 | 
						|
								        //--------------------------------------------------------------------------
							 | 
						|
								
							 | 
						|
								        /**
							 | 
						|
								         * Gets a fixer function to fix rule issues
							 | 
						|
								         * @param {Token} operatorToken The operator token of an expression
							 | 
						|
								         * @param {string} desiredStyle The style for the rule. One of 'before', 'after', 'none'
							 | 
						|
								         * @returns {Function} A fixer function
							 | 
						|
								         */
							 | 
						|
								        function getFixer(operatorToken, desiredStyle) {
							 | 
						|
								            return fixer => {
							 | 
						|
								                const tokenBefore = sourceCode.getTokenBefore(operatorToken);
							 | 
						|
								                const tokenAfter = sourceCode.getTokenAfter(operatorToken);
							 | 
						|
								                const textBefore = sourceCode.text.slice(tokenBefore.range[1], operatorToken.range[0]);
							 | 
						|
								                const textAfter = sourceCode.text.slice(operatorToken.range[1], tokenAfter.range[0]);
							 | 
						|
								                const hasLinebreakBefore = !astUtils.isTokenOnSameLine(tokenBefore, operatorToken);
							 | 
						|
								                const hasLinebreakAfter = !astUtils.isTokenOnSameLine(operatorToken, tokenAfter);
							 | 
						|
								                let newTextBefore, newTextAfter;
							 | 
						|
								
							 | 
						|
								                if (hasLinebreakBefore !== hasLinebreakAfter && desiredStyle !== "none") {
							 | 
						|
								
							 | 
						|
								                    // If there is a comment before and after the operator, don't do a fix.
							 | 
						|
								                    if (sourceCode.getTokenBefore(operatorToken, { includeComments: true }) !== tokenBefore &&
							 | 
						|
								                        sourceCode.getTokenAfter(operatorToken, { includeComments: true }) !== tokenAfter) {
							 | 
						|
								
							 | 
						|
								                        return null;
							 | 
						|
								                    }
							 | 
						|
								
							 | 
						|
								                    /*
							 | 
						|
								                     * If there is only one linebreak and it's on the wrong side of the operator, swap the text before and after the operator.
							 | 
						|
								                     * foo &&
							 | 
						|
								                     *           bar
							 | 
						|
								                     * would get fixed to
							 | 
						|
								                     * foo
							 | 
						|
								                     *        && bar
							 | 
						|
								                     */
							 | 
						|
								                    newTextBefore = textAfter;
							 | 
						|
								                    newTextAfter = textBefore;
							 | 
						|
								                } else {
							 | 
						|
								                    const LINEBREAK_REGEX = astUtils.createGlobalLinebreakMatcher();
							 | 
						|
								
							 | 
						|
								                    // Otherwise, if no linebreak is desired and no comments interfere, replace the linebreaks with empty strings.
							 | 
						|
								                    newTextBefore = desiredStyle === "before" || textBefore.trim() ? textBefore : textBefore.replace(LINEBREAK_REGEX, "");
							 | 
						|
								                    newTextAfter = desiredStyle === "after" || textAfter.trim() ? textAfter : textAfter.replace(LINEBREAK_REGEX, "");
							 | 
						|
								
							 | 
						|
								                    // If there was no change (due to interfering comments), don't output a fix.
							 | 
						|
								                    if (newTextBefore === textBefore && newTextAfter === textAfter) {
							 | 
						|
								                        return null;
							 | 
						|
								                    }
							 | 
						|
								                }
							 | 
						|
								
							 | 
						|
								                if (newTextAfter === "" && tokenAfter.type === "Punctuator" && "+-".includes(operatorToken.value) && tokenAfter.value === operatorToken.value) {
							 | 
						|
								
							 | 
						|
								                    // To avoid accidentally creating a ++ or -- operator, insert a space if the operator is a +/- and the following token is a unary +/-.
							 | 
						|
								                    newTextAfter += " ";
							 | 
						|
								                }
							 | 
						|
								
							 | 
						|
								                return fixer.replaceTextRange([tokenBefore.range[1], tokenAfter.range[0]], newTextBefore + operatorToken.value + newTextAfter);
							 | 
						|
								            };
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        /**
							 | 
						|
								         * Checks the operator placement
							 | 
						|
								         * @param {ASTNode} node The node to check
							 | 
						|
								         * @param {ASTNode} rightSide The node that comes after the operator in `node`
							 | 
						|
								         * @param {string} operator The operator
							 | 
						|
								         * @private
							 | 
						|
								         * @returns {void}
							 | 
						|
								         */
							 | 
						|
								        function validateNode(node, rightSide, operator) {
							 | 
						|
								
							 | 
						|
								            /*
							 | 
						|
								             * Find the operator token by searching from the right side, because between the left side and the operator
							 | 
						|
								             * there could be additional tokens from type annotations. Search specifically for the token which
							 | 
						|
								             * value equals the operator, in order to skip possible opening parentheses before the right side node.
							 | 
						|
								             */
							 | 
						|
								            const operatorToken = sourceCode.getTokenBefore(rightSide, token => token.value === operator);
							 | 
						|
								            const leftToken = sourceCode.getTokenBefore(operatorToken);
							 | 
						|
								            const rightToken = sourceCode.getTokenAfter(operatorToken);
							 | 
						|
								            const operatorStyleOverride = styleOverrides[operator];
							 | 
						|
								            const style = operatorStyleOverride || globalStyle;
							 | 
						|
								            const fix = getFixer(operatorToken, style);
							 | 
						|
								
							 | 
						|
								            // if single line
							 | 
						|
								            if (astUtils.isTokenOnSameLine(leftToken, operatorToken) &&
							 | 
						|
								                    astUtils.isTokenOnSameLine(operatorToken, rightToken)) {
							 | 
						|
								
							 | 
						|
								                // do nothing.
							 | 
						|
								
							 | 
						|
								            } else if (operatorStyleOverride !== "ignore" && !astUtils.isTokenOnSameLine(leftToken, operatorToken) &&
							 | 
						|
								                    !astUtils.isTokenOnSameLine(operatorToken, rightToken)) {
							 | 
						|
								
							 | 
						|
								                // lone operator
							 | 
						|
								                context.report({
							 | 
						|
								                    node,
							 | 
						|
								                    loc: operatorToken.loc,
							 | 
						|
								                    messageId: "badLinebreak",
							 | 
						|
								                    data: {
							 | 
						|
								                        operator
							 | 
						|
								                    },
							 | 
						|
								                    fix
							 | 
						|
								                });
							 | 
						|
								
							 | 
						|
								            } else if (style === "before" && astUtils.isTokenOnSameLine(leftToken, operatorToken)) {
							 | 
						|
								
							 | 
						|
								                context.report({
							 | 
						|
								                    node,
							 | 
						|
								                    loc: operatorToken.loc,
							 | 
						|
								                    messageId: "operatorAtBeginning",
							 | 
						|
								                    data: {
							 | 
						|
								                        operator
							 | 
						|
								                    },
							 | 
						|
								                    fix
							 | 
						|
								                });
							 | 
						|
								
							 | 
						|
								            } else if (style === "after" && astUtils.isTokenOnSameLine(operatorToken, rightToken)) {
							 | 
						|
								
							 | 
						|
								                context.report({
							 | 
						|
								                    node,
							 | 
						|
								                    loc: operatorToken.loc,
							 | 
						|
								                    messageId: "operatorAtEnd",
							 | 
						|
								                    data: {
							 | 
						|
								                        operator
							 | 
						|
								                    },
							 | 
						|
								                    fix
							 | 
						|
								                });
							 | 
						|
								
							 | 
						|
								            } else if (style === "none") {
							 | 
						|
								
							 | 
						|
								                context.report({
							 | 
						|
								                    node,
							 | 
						|
								                    loc: operatorToken.loc,
							 | 
						|
								                    messageId: "noLinebreak",
							 | 
						|
								                    data: {
							 | 
						|
								                        operator
							 | 
						|
								                    },
							 | 
						|
								                    fix
							 | 
						|
								                });
							 | 
						|
								
							 | 
						|
								            }
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        /**
							 | 
						|
								         * Validates a binary expression using `validateNode`
							 | 
						|
								         * @param {BinaryExpression|LogicalExpression|AssignmentExpression} node node to be validated
							 | 
						|
								         * @returns {void}
							 | 
						|
								         */
							 | 
						|
								        function validateBinaryExpression(node) {
							 | 
						|
								            validateNode(node, node.right, node.operator);
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								        //--------------------------------------------------------------------------
							 | 
						|
								        // Public
							 | 
						|
								        //--------------------------------------------------------------------------
							 | 
						|
								
							 | 
						|
								        return {
							 | 
						|
								            BinaryExpression: validateBinaryExpression,
							 | 
						|
								            LogicalExpression: validateBinaryExpression,
							 | 
						|
								            AssignmentExpression: validateBinaryExpression,
							 | 
						|
								            VariableDeclarator(node) {
							 | 
						|
								                if (node.init) {
							 | 
						|
								                    validateNode(node, node.init, "=");
							 | 
						|
								                }
							 | 
						|
								            },
							 | 
						|
								            PropertyDefinition(node) {
							 | 
						|
								                if (node.value) {
							 | 
						|
								                    validateNode(node, node.value, "=");
							 | 
						|
								                }
							 | 
						|
								            },
							 | 
						|
								            ConditionalExpression(node) {
							 | 
						|
								                validateNode(node, node.consequent, "?");
							 | 
						|
								                validateNode(node, node.alternate, ":");
							 | 
						|
								            }
							 | 
						|
								        };
							 | 
						|
								    }
							 | 
						|
								};
							 |