UNPKG

4.04 kBJavaScriptView Raw
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
13module.exports = {
14 meta: {
15 docs: {
16 description: "enforce minimum and maximum identifier lengths",
17 category: "Stylistic Issues",
18 recommended: false
19 },
20
21 schema: [
22 {
23 type: "object",
24 properties: {
25 min: {
26 type: "number"
27 },
28 max: {
29 type: "number"
30 },
31 exceptions: {
32 type: "array",
33 uniqueItems: true,
34 items: {
35 type: "string"
36 }
37 },
38 properties: {
39 enum: ["always", "never"]
40 }
41 },
42 additionalProperties: false
43 }
44 ]
45 },
46
47 create(context) {
48 const options = context.options[0] || {};
49 const minLength = typeof options.min !== "undefined" ? options.min : 2;
50 const maxLength = typeof options.max !== "undefined" ? options.max : Infinity;
51 const properties = options.properties !== "never";
52 const exceptions = (options.exceptions ? options.exceptions : [])
53 .reduce((obj, item) => {
54 obj[item] = true;
55
56 return obj;
57 }, {});
58
59 const SUPPORTED_EXPRESSIONS = {
60 MemberExpression: properties && function(parent) {
61 return !parent.computed && (
62
63 // regular property assignment
64 (parent.parent.left === parent && parent.parent.type === "AssignmentExpression" ||
65
66 // or the last identifier in an ObjectPattern destructuring
67 parent.parent.type === "Property" && parent.parent.value === parent &&
68 parent.parent.parent.type === "ObjectPattern" && parent.parent.parent.parent.left === parent.parent.parent)
69 );
70 },
71 AssignmentPattern(parent, node) {
72 return parent.left === node;
73 },
74 VariableDeclarator(parent, node) {
75 return parent.id === node;
76 },
77 Property: properties && function(parent, node) {
78 return parent.key === node;
79 },
80 ImportDefaultSpecifier: true,
81 RestElement: true,
82 FunctionExpression: true,
83 ArrowFunctionExpression: true,
84 ClassDeclaration: true,
85 FunctionDeclaration: true,
86 MethodDefinition: true,
87 CatchClause: true
88 };
89
90 return {
91 Identifier(node) {
92 const name = node.name;
93 const parent = node.parent;
94
95 const isShort = name.length < minLength;
96 const isLong = name.length > maxLength;
97
98 if (!(isShort || isLong) || exceptions[name]) {
99 return; // Nothing to report
100 }
101
102 const isValidExpression = SUPPORTED_EXPRESSIONS[parent.type];
103
104 if (isValidExpression && (isValidExpression === true || isValidExpression(parent, node))) {
105 context.report({
106 node,
107 message: isShort
108 ? "Identifier name '{{name}}' is too short (< {{min}})."
109 : "Identifier name '{{name}}' is too long (> {{max}}).",
110 data: { name, min: minLength, max: maxLength }
111 });
112 }
113 }
114 };
115 }
116};