Actualizacion maquina principal
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / eslint / lib / rules / new-cap.js
diff --git a/.config/coc/extensions/node_modules/coc-prettier/node_modules/eslint/lib/rules/new-cap.js b/.config/coc/extensions/node_modules/coc-prettier/node_modules/eslint/lib/rules/new-cap.js
new file mode 100644 (file)
index 0000000..cee9793
--- /dev/null
@@ -0,0 +1,283 @@
+/**
+ * @fileoverview Rule to flag use of constructors without capital letters
+ * @author Nicholas C. Zakas
+ */
+
+"use strict";
+
+//------------------------------------------------------------------------------
+// Requirements
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+// Helpers
+//------------------------------------------------------------------------------
+
+const CAPS_ALLOWED = [
+    "Array",
+    "Boolean",
+    "Date",
+    "Error",
+    "Function",
+    "Number",
+    "Object",
+    "RegExp",
+    "String",
+    "Symbol",
+    "BigInt"
+];
+
+/**
+ * Ensure that if the key is provided, it must be an array.
+ * @param {Object} obj Object to check with `key`.
+ * @param {string} key Object key to check on `obj`.
+ * @param {*} fallback If obj[key] is not present, this will be returned.
+ * @returns {string[]} Returns obj[key] if it's an Array, otherwise `fallback`
+ */
+function checkArray(obj, key, fallback) {
+
+    /* istanbul ignore if */
+    if (Object.prototype.hasOwnProperty.call(obj, key) && !Array.isArray(obj[key])) {
+        throw new TypeError(`${key}, if provided, must be an Array`);
+    }
+    return obj[key] || fallback;
+}
+
+/**
+ * A reducer function to invert an array to an Object mapping the string form of the key, to `true`.
+ * @param {Object} map Accumulator object for the reduce.
+ * @param {string} key Object key to set to `true`.
+ * @returns {Object} Returns the updated Object for further reduction.
+ */
+function invert(map, key) {
+    map[key] = true;
+    return map;
+}
+
+/**
+ * Creates an object with the cap is new exceptions as its keys and true as their values.
+ * @param {Object} config Rule configuration
+ * @returns {Object} Object with cap is new exceptions.
+ */
+function calculateCapIsNewExceptions(config) {
+    let capIsNewExceptions = checkArray(config, "capIsNewExceptions", CAPS_ALLOWED);
+
+    if (capIsNewExceptions !== CAPS_ALLOWED) {
+        capIsNewExceptions = capIsNewExceptions.concat(CAPS_ALLOWED);
+    }
+
+    return capIsNewExceptions.reduce(invert, {});
+}
+
+//------------------------------------------------------------------------------
+// Rule Definition
+//------------------------------------------------------------------------------
+
+module.exports = {
+    meta: {
+        type: "suggestion",
+
+        docs: {
+            description: "require constructor names to begin with a capital letter",
+            category: "Stylistic Issues",
+            recommended: false,
+            url: "https://eslint.org/docs/rules/new-cap"
+        },
+
+        schema: [
+            {
+                type: "object",
+                properties: {
+                    newIsCap: {
+                        type: "boolean",
+                        default: true
+                    },
+                    capIsNew: {
+                        type: "boolean",
+                        default: true
+                    },
+                    newIsCapExceptions: {
+                        type: "array",
+                        items: {
+                            type: "string"
+                        }
+                    },
+                    newIsCapExceptionPattern: {
+                        type: "string"
+                    },
+                    capIsNewExceptions: {
+                        type: "array",
+                        items: {
+                            type: "string"
+                        }
+                    },
+                    capIsNewExceptionPattern: {
+                        type: "string"
+                    },
+                    properties: {
+                        type: "boolean",
+                        default: true
+                    }
+                },
+                additionalProperties: false
+            }
+        ],
+        messages: {
+            upper: "A function with a name starting with an uppercase letter should only be used as a constructor.",
+            lower: "A constructor name should not start with a lowercase letter."
+        }
+    },
+
+    create(context) {
+
+        const config = Object.assign({}, context.options[0]);
+
+        config.newIsCap = config.newIsCap !== false;
+        config.capIsNew = config.capIsNew !== false;
+        const skipProperties = config.properties === false;
+
+        const newIsCapExceptions = checkArray(config, "newIsCapExceptions", []).reduce(invert, {});
+        const newIsCapExceptionPattern = config.newIsCapExceptionPattern ? new RegExp(config.newIsCapExceptionPattern, "u") : null;
+
+        const capIsNewExceptions = calculateCapIsNewExceptions(config);
+        const capIsNewExceptionPattern = config.capIsNewExceptionPattern ? new RegExp(config.capIsNewExceptionPattern, "u") : null;
+
+        const listeners = {};
+
+        const sourceCode = context.getSourceCode();
+
+        //--------------------------------------------------------------------------
+        // Helpers
+        //--------------------------------------------------------------------------
+
+        /**
+         * Get exact callee name from expression
+         * @param {ASTNode} node CallExpression or NewExpression node
+         * @returns {string} name
+         */
+        function extractNameFromExpression(node) {
+
+            let name = "";
+
+            if (node.callee.type === "MemberExpression") {
+                const property = node.callee.property;
+
+                if (property.type === "Literal" && (typeof property.value === "string")) {
+                    name = property.value;
+                } else if (property.type === "Identifier" && !node.callee.computed) {
+                    name = property.name;
+                }
+            } else {
+                name = node.callee.name;
+            }
+            return name;
+        }
+
+        /**
+         * Returns the capitalization state of the string -
+         * Whether the first character is uppercase, lowercase, or non-alphabetic
+         * @param {string} str String
+         * @returns {string} capitalization state: "non-alpha", "lower", or "upper"
+         */
+        function getCap(str) {
+            const firstChar = str.charAt(0);
+
+            const firstCharLower = firstChar.toLowerCase();
+            const firstCharUpper = firstChar.toUpperCase();
+
+            if (firstCharLower === firstCharUpper) {
+
+                // char has no uppercase variant, so it's non-alphabetic
+                return "non-alpha";
+            }
+            if (firstChar === firstCharLower) {
+                return "lower";
+            }
+            return "upper";
+
+        }
+
+        /**
+         * Check if capitalization is allowed for a CallExpression
+         * @param {Object} allowedMap Object mapping calleeName to a Boolean
+         * @param {ASTNode} node CallExpression node
+         * @param {string} calleeName Capitalized callee name from a CallExpression
+         * @param {Object} pattern RegExp object from options pattern
+         * @returns {boolean} Returns true if the callee may be capitalized
+         */
+        function isCapAllowed(allowedMap, node, calleeName, pattern) {
+            const sourceText = sourceCode.getText(node.callee);
+
+            if (allowedMap[calleeName] || allowedMap[sourceText]) {
+                return true;
+            }
+
+            if (pattern && pattern.test(sourceText)) {
+                return true;
+            }
+
+            if (calleeName === "UTC" && node.callee.type === "MemberExpression") {
+
+                // allow if callee is Date.UTC
+                return node.callee.object.type === "Identifier" &&
+                    node.callee.object.name === "Date";
+            }
+
+            return skipProperties && node.callee.type === "MemberExpression";
+        }
+
+        /**
+         * Reports the given messageId for the given node. The location will be the start of the property or the callee.
+         * @param {ASTNode} node CallExpression or NewExpression node.
+         * @param {string} messageId The messageId to report.
+         * @returns {void}
+         */
+        function report(node, messageId) {
+            let callee = node.callee;
+
+            if (callee.type === "MemberExpression") {
+                callee = callee.property;
+            }
+
+            context.report({ node, loc: callee.loc.start, messageId });
+        }
+
+        //--------------------------------------------------------------------------
+        // Public
+        //--------------------------------------------------------------------------
+
+        if (config.newIsCap) {
+            listeners.NewExpression = function(node) {
+
+                const constructorName = extractNameFromExpression(node);
+
+                if (constructorName) {
+                    const capitalization = getCap(constructorName);
+                    const isAllowed = capitalization !== "lower" || isCapAllowed(newIsCapExceptions, node, constructorName, newIsCapExceptionPattern);
+
+                    if (!isAllowed) {
+                        report(node, "lower");
+                    }
+                }
+            };
+        }
+
+        if (config.capIsNew) {
+            listeners.CallExpression = function(node) {
+
+                const calleeName = extractNameFromExpression(node);
+
+                if (calleeName) {
+                    const capitalization = getCap(calleeName);
+                    const isAllowed = capitalization !== "upper" || isCapAllowed(capIsNewExceptions, node, calleeName, capIsNewExceptionPattern);
+
+                    if (!isAllowed) {
+                        report(node, "upper");
+                    }
+                }
+            };
+        }
+
+        return listeners;
+    }
+};