]> git.proxmox.com Git - pve-eslint.git/blobdiff - eslint/lib/rules/id-length.js
import 8.4.0 source
[pve-eslint.git] / eslint / lib / rules / id-length.js
index a68873ac06289b0b3c28b67a04d0ee064c2756c4..3701c66e347a7287321da25d25d743ca7ff9305f 100644 (file)
 // Rule Definition
 //------------------------------------------------------------------------------
 
+/** @type {import('../shared/types').Rule} */
 module.exports = {
     meta: {
         type: "suggestion",
 
         docs: {
             description: "enforce minimum and maximum identifier lengths",
-            category: "Stylistic Issues",
             recommended: false,
             url: "https://eslint.org/docs/rules/id-length"
         },
@@ -39,6 +39,13 @@ module.exports = {
                             type: "string"
                         }
                     },
+                    exceptionPatterns: {
+                        type: "array",
+                        uniqueItems: true,
+                        items: {
+                            type: "string"
+                        }
+                    },
                     properties: {
                         enum: ["always", "never"]
                     }
@@ -48,7 +55,9 @@ module.exports = {
         ],
         messages: {
             tooShort: "Identifier name '{{name}}' is too short (< {{min}}).",
-            tooLong: "Identifier name '{{name}}' is too long (> {{max}})."
+            tooShortPrivate: "Identifier name '#{{name}}' is too short (< {{min}}).",
+            tooLong: "Identifier name '{{name}}' is too long (> {{max}}).",
+            tooLongPrivate: "Identifier name #'{{name}}' is too long (> {{max}})."
         }
     },
 
@@ -57,13 +66,19 @@ module.exports = {
         const minLength = typeof options.min !== "undefined" ? options.min : 2;
         const maxLength = typeof options.max !== "undefined" ? options.max : Infinity;
         const properties = options.properties !== "never";
-        const exceptions = (options.exceptions ? options.exceptions : [])
-            .reduce((obj, item) => {
-                obj[item] = true;
-
-                return obj;
-            }, {});
-        const reportedNode = new Set();
+        const exceptions = new Set(options.exceptions);
+        const exceptionPatterns = (options.exceptionPatterns || []).map(pattern => new RegExp(pattern, "u"));
+        const reportedNodes = new Set();
+
+        /**
+         * Checks if a string matches the provided exception patterns
+         * @param {string} name The string to check.
+         * @returns {boolean} if the string is a match
+         * @private
+         */
+        function matchesExceptionPattern(name) {
+            return exceptionPatterns.some(pattern => pattern.test(name));
+        }
 
         const SUPPORTED_EXPRESSIONS = {
             MemberExpression: properties && function(parent) {
@@ -86,12 +101,14 @@ module.exports = {
             Property(parent, node) {
 
                 if (parent.parent.type === "ObjectPattern") {
+                    const isKeyAndValueSame = parent.value.name === parent.key.name;
+
                     return (
-                        parent.value !== parent.key && parent.value === node ||
-                        parent.value === parent.key && parent.key === node && properties
+                        !isKeyAndValueSame && parent.value === node ||
+                        isKeyAndValueSame && parent.key === node && properties
                     );
                 }
-                return properties && !parent.computed && parent.key === node;
+                return properties && !parent.computed && parent.key.name === node.name;
             },
             ImportDefaultSpecifier: true,
             RestElement: true,
@@ -100,29 +117,49 @@ module.exports = {
             ClassDeclaration: true,
             FunctionDeclaration: true,
             MethodDefinition: true,
+            PropertyDefinition: true,
             CatchClause: true,
             ArrayPattern: true
         };
 
         return {
-            Identifier(node) {
+            [[
+                "Identifier",
+                "PrivateIdentifier"
+            ]](node) {
                 const name = node.name;
                 const parent = node.parent;
 
                 const isShort = name.length < minLength;
                 const isLong = name.length > maxLength;
 
-                if (!(isShort || isLong) || exceptions[name]) {
+                if (!(isShort || isLong) || exceptions.has(name) || matchesExceptionPattern(name)) {
                     return; // Nothing to report
                 }
 
                 const isValidExpression = SUPPORTED_EXPRESSIONS[parent.type];
 
-                if (isValidExpression && !reportedNode.has(node) && (isValidExpression === true || isValidExpression(parent, node))) {
-                    reportedNode.add(node);
+                /*
+                 * We used the range instead of the node because it's possible
+                 * for the same identifier to be represented by two different
+                 * nodes, with the most clear example being shorthand properties:
+                 * { foo }
+                 * In this case, "foo" is represented by one node for the name
+                 * and one for the value. The only way to know they are the same
+                 * is to look at the range.
+                 */
+                if (isValidExpression && !reportedNodes.has(node.range.toString()) && (isValidExpression === true || isValidExpression(parent, node))) {
+                    reportedNodes.add(node.range.toString());
+
+                    let messageId = isShort ? "tooShort" : "tooLong";
+
+                    if (node.type === "PrivateIdentifier") {
+                        messageId += "Private";
+                    }
+
                     context.report({
                         node,
-                        messageId: isShort ? "tooShort" : "tooLong",
+                        messageId,
                         data: { name, min: minLength, max: maxLength }
                     });
                 }