Actualizacion maquina principal
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / eslint / lib / rules / no-mixed-operators.js
diff --git a/.config/coc/extensions/node_modules/coc-prettier/node_modules/eslint/lib/rules/no-mixed-operators.js b/.config/coc/extensions/node_modules/coc-prettier/node_modules/eslint/lib/rules/no-mixed-operators.js
new file mode 100644 (file)
index 0000000..80fac79
--- /dev/null
@@ -0,0 +1,240 @@
+/**
+ * @fileoverview Rule to disallow mixed binary operators.
+ * @author Toru Nagashima
+ */
+
+"use strict";
+
+//------------------------------------------------------------------------------
+// Requirements
+//------------------------------------------------------------------------------
+
+const astUtils = require("./utils/ast-utils.js");
+
+//------------------------------------------------------------------------------
+// Helpers
+//------------------------------------------------------------------------------
+
+const ARITHMETIC_OPERATORS = ["+", "-", "*", "/", "%", "**"];
+const BITWISE_OPERATORS = ["&", "|", "^", "~", "<<", ">>", ">>>"];
+const COMPARISON_OPERATORS = ["==", "!=", "===", "!==", ">", ">=", "<", "<="];
+const LOGICAL_OPERATORS = ["&&", "||"];
+const RELATIONAL_OPERATORS = ["in", "instanceof"];
+const TERNARY_OPERATOR = ["?:"];
+const ALL_OPERATORS = [].concat(
+    ARITHMETIC_OPERATORS,
+    BITWISE_OPERATORS,
+    COMPARISON_OPERATORS,
+    LOGICAL_OPERATORS,
+    RELATIONAL_OPERATORS,
+    TERNARY_OPERATOR
+);
+const DEFAULT_GROUPS = [
+    ARITHMETIC_OPERATORS,
+    BITWISE_OPERATORS,
+    COMPARISON_OPERATORS,
+    LOGICAL_OPERATORS,
+    RELATIONAL_OPERATORS
+];
+const TARGET_NODE_TYPE = /^(?:Binary|Logical|Conditional)Expression$/u;
+
+/**
+ * Normalizes options.
+ * @param {Object|undefined} options A options object to normalize.
+ * @returns {Object} Normalized option object.
+ */
+function normalizeOptions(options = {}) {
+    const hasGroups = options.groups && options.groups.length > 0;
+    const groups = hasGroups ? options.groups : DEFAULT_GROUPS;
+    const allowSamePrecedence = options.allowSamePrecedence !== false;
+
+    return {
+        groups,
+        allowSamePrecedence
+    };
+}
+
+/**
+ * Checks whether any group which includes both given operator exists or not.
+ * @param {Array.<string[]>} groups A list of groups to check.
+ * @param {string} left An operator.
+ * @param {string} right Another operator.
+ * @returns {boolean} `true` if such group existed.
+ */
+function includesBothInAGroup(groups, left, right) {
+    return groups.some(group => group.indexOf(left) !== -1 && group.indexOf(right) !== -1);
+}
+
+/**
+ * Checks whether the given node is a conditional expression and returns the test node else the left node.
+ * @param {ASTNode} node A node which can be a BinaryExpression or a LogicalExpression node.
+ * This parent node can be BinaryExpression, LogicalExpression
+ *      , or a ConditionalExpression node
+ * @returns {ASTNode} node the appropriate node(left or test).
+ */
+function getChildNode(node) {
+    return node.type === "ConditionalExpression" ? node.test : node.left;
+}
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = {
+    meta: {
+        type: "suggestion",
+
+        docs: {
+            description: "disallow mixed binary operators",
+            category: "Stylistic Issues",
+            recommended: false,
+            url: "https://eslint.org/docs/rules/no-mixed-operators"
+        },
+
+        schema: [
+            {
+                type: "object",
+                properties: {
+                    groups: {
+                        type: "array",
+                        items: {
+                            type: "array",
+                            items: { enum: ALL_OPERATORS },
+                            minItems: 2,
+                            uniqueItems: true
+                        },
+                        uniqueItems: true
+                    },
+                    allowSamePrecedence: {
+                        type: "boolean",
+                        default: true
+                    }
+                },
+                additionalProperties: false
+            }
+        ]
+    },
+
+    create(context) {
+        const sourceCode = context.getSourceCode();
+        const options = normalizeOptions(context.options[0]);
+
+        /**
+         * Checks whether a given node should be ignored by options or not.
+         * @param {ASTNode} node A node to check. This is a BinaryExpression
+         *      node or a LogicalExpression node. This parent node is one of
+         *      them, too.
+         * @returns {boolean} `true` if the node should be ignored.
+         */
+        function shouldIgnore(node) {
+            const a = node;
+            const b = node.parent;
+
+            return (
+                !includesBothInAGroup(options.groups, a.operator, b.type === "ConditionalExpression" ? "?:" : b.operator) ||
+                (
+                    options.allowSamePrecedence &&
+                    astUtils.getPrecedence(a) === astUtils.getPrecedence(b)
+                )
+            );
+        }
+
+        /**
+         * Checks whether the operator of a given node is mixed with parent
+         * node's operator or not.
+         * @param {ASTNode} node A node to check. This is a BinaryExpression
+         *      node or a LogicalExpression node. This parent node is one of
+         *      them, too.
+         * @returns {boolean} `true` if the node was mixed.
+         */
+        function isMixedWithParent(node) {
+
+            return (
+                node.operator !== node.parent.operator &&
+                !astUtils.isParenthesised(sourceCode, node)
+            );
+        }
+
+        /**
+         * Checks whether the operator of a given node is mixed with a
+         * conditional expression.
+         * @param {ASTNode} node A node to check. This is a conditional
+         *      expression node
+         * @returns {boolean} `true` if the node was mixed.
+         */
+        function isMixedWithConditionalParent(node) {
+            return !astUtils.isParenthesised(sourceCode, node) && !astUtils.isParenthesised(sourceCode, node.test);
+        }
+
+        /**
+         * Gets the operator token of a given node.
+         * @param {ASTNode} node A node to check. This is a BinaryExpression
+         *      node or a LogicalExpression node.
+         * @returns {Token} The operator token of the node.
+         */
+        function getOperatorToken(node) {
+            return sourceCode.getTokenAfter(getChildNode(node), astUtils.isNotClosingParenToken);
+        }
+
+        /**
+         * Reports both the operator of a given node and the operator of the
+         * parent node.
+         * @param {ASTNode} node A node to check. This is a BinaryExpression
+         *      node or a LogicalExpression node. This parent node is one of
+         *      them, too.
+         * @returns {void}
+         */
+        function reportBothOperators(node) {
+            const parent = node.parent;
+            const left = (getChildNode(parent) === node) ? node : parent;
+            const right = (getChildNode(parent) !== node) ? node : parent;
+            const message =
+                "Unexpected mix of '{{leftOperator}}' and '{{rightOperator}}'.";
+            const data = {
+                leftOperator: left.operator || "?:",
+                rightOperator: right.operator || "?:"
+            };
+
+            context.report({
+                node: left,
+                loc: getOperatorToken(left).loc,
+                message,
+                data
+            });
+            context.report({
+                node: right,
+                loc: getOperatorToken(right).loc,
+                message,
+                data
+            });
+        }
+
+        /**
+         * Checks between the operator of this node and the operator of the
+         * parent node.
+         * @param {ASTNode} node A node to check.
+         * @returns {void}
+         */
+        function check(node) {
+            if (TARGET_NODE_TYPE.test(node.parent.type)) {
+                if (node.parent.type === "ConditionalExpression" && !shouldIgnore(node) && isMixedWithConditionalParent(node.parent)) {
+                    reportBothOperators(node);
+                } else {
+                    if (TARGET_NODE_TYPE.test(node.parent.type) &&
+                        isMixedWithParent(node) &&
+                        !shouldIgnore(node)
+                    ) {
+                        reportBothOperators(node);
+                    }
+                }
+            }
+
+        }
+
+        return {
+            BinaryExpression: check,
+            LogicalExpression: check
+
+        };
+    }
+};