.gitignore added
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / eslint / lib / rules / id-length.js
1 /**
2  * @fileoverview Rule that warns when identifier names are shorter or longer
3  * than the values provided in configuration.
4  * @author Burak Yigit Kaya aka BYK
5  */
6
7 "use strict";
8
9 //------------------------------------------------------------------------------
10 // Rule Definition
11 //------------------------------------------------------------------------------
12
13 module.exports = {
14     meta: {
15         type: "suggestion",
16
17         docs: {
18             description: "enforce minimum and maximum identifier lengths",
19             category: "Stylistic Issues",
20             recommended: false,
21             url: "https://eslint.org/docs/rules/id-length"
22         },
23
24         schema: [
25             {
26                 type: "object",
27                 properties: {
28                     min: {
29                         type: "integer",
30                         default: 2
31                     },
32                     max: {
33                         type: "integer"
34                     },
35                     exceptions: {
36                         type: "array",
37                         uniqueItems: true,
38                         items: {
39                             type: "string"
40                         }
41                     },
42                     exceptionPatterns: {
43                         type: "array",
44                         uniqueItems: true,
45                         items: {
46                             type: "string"
47                         }
48                     },
49                     properties: {
50                         enum: ["always", "never"]
51                     }
52                 },
53                 additionalProperties: false
54             }
55         ],
56         messages: {
57             tooShort: "Identifier name '{{name}}' is too short (< {{min}}).",
58             tooLong: "Identifier name '{{name}}' is too long (> {{max}})."
59         }
60     },
61
62     create(context) {
63         const options = context.options[0] || {};
64         const minLength = typeof options.min !== "undefined" ? options.min : 2;
65         const maxLength = typeof options.max !== "undefined" ? options.max : Infinity;
66         const properties = options.properties !== "never";
67         const exceptions = new Set(options.exceptions);
68         const exceptionPatterns = (options.exceptionPatterns || []).map(pattern => new RegExp(pattern, "u"));
69         const reportedNode = new Set();
70
71         /**
72          * Checks if a string matches the provided exception patterns
73          * @param {string} name The string to check.
74          * @returns {boolean} if the string is a match
75          * @private
76          */
77         function matchesExceptionPattern(name) {
78             return exceptionPatterns.some(pattern => pattern.test(name));
79         }
80
81         const SUPPORTED_EXPRESSIONS = {
82             MemberExpression: properties && function(parent) {
83                 return !parent.computed && (
84
85                     // regular property assignment
86                     (parent.parent.left === parent && parent.parent.type === "AssignmentExpression" ||
87
88                     // or the last identifier in an ObjectPattern destructuring
89                     parent.parent.type === "Property" && parent.parent.value === parent &&
90                     parent.parent.parent.type === "ObjectPattern" && parent.parent.parent.parent.left === parent.parent.parent)
91                 );
92             },
93             AssignmentPattern(parent, node) {
94                 return parent.left === node;
95             },
96             VariableDeclarator(parent, node) {
97                 return parent.id === node;
98             },
99             Property(parent, node) {
100
101                 if (parent.parent.type === "ObjectPattern") {
102                     return (
103                         parent.value !== parent.key && parent.value === node ||
104                         parent.value === parent.key && parent.key === node && properties
105                     );
106                 }
107                 return properties && !parent.computed && parent.key === node;
108             },
109             ImportDefaultSpecifier: true,
110             RestElement: true,
111             FunctionExpression: true,
112             ArrowFunctionExpression: true,
113             ClassDeclaration: true,
114             FunctionDeclaration: true,
115             MethodDefinition: true,
116             CatchClause: true,
117             ArrayPattern: true
118         };
119
120         return {
121             Identifier(node) {
122                 const name = node.name;
123                 const parent = node.parent;
124
125                 const isShort = name.length < minLength;
126                 const isLong = name.length > maxLength;
127
128                 if (!(isShort || isLong) || exceptions.has(name) || matchesExceptionPattern(name)) {
129                     return; // Nothing to report
130                 }
131
132                 const isValidExpression = SUPPORTED_EXPRESSIONS[parent.type];
133
134                 if (isValidExpression && !reportedNode.has(node) && (isValidExpression === true || isValidExpression(parent, node))) {
135                     reportedNode.add(node);
136                     context.report({
137                         node,
138                         messageId: isShort ? "tooShort" : "tooLong",
139                         data: { name, min: minLength, max: maxLength }
140                     });
141                 }
142             }
143         };
144     }
145 };