UNPKG

3.96 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(function(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 || // or the last identifier in an ObjectPattern destructuring
65 parent.parent.type === "Property" && parent.parent.value === parent &&
66 parent.parent.parent.type === "ObjectPattern" && parent.parent.parent.parent.left === parent.parent.parent)
67 );
68 },
69 AssignmentPattern(parent, node) {
70 return parent.left === node;
71 },
72 VariableDeclarator(parent, node) {
73 return parent.id === node;
74 },
75 Property: properties && function(parent, node) {
76 return parent.key === node;
77 },
78 ImportDefaultSpecifier: true,
79 RestElement: true,
80 FunctionExpression: true,
81 ArrowFunctionExpression: true,
82 ClassDeclaration: true,
83 FunctionDeclaration: true,
84 MethodDefinition: true,
85 CatchClause: true
86 };
87
88 return {
89 Identifier(node) {
90 const name = node.name;
91 const parent = node.parent;
92
93 const isShort = name.length < minLength;
94 const isLong = name.length > maxLength;
95
96 if (!(isShort || isLong) || exceptions[name]) {
97 return; // Nothing to report
98 }
99
100 const isValidExpression = SUPPORTED_EXPRESSIONS[parent.type];
101
102 if (isValidExpression && (isValidExpression === true || isValidExpression(parent, node))) {
103 context.report(
104 node,
105 isShort ?
106 "Identifier name '{{name}}' is too short (< {{min}})." :
107 "Identifier name '{{name}}' is too long (> {{max}}).",
108 { name, min: minLength, max: maxLength }
109 );
110 }
111 }
112 };
113 }
114};