source: imaps-frontend/node_modules/eslint/lib/rules/no-underscore-dangle.js

main
Last change on this file was d565449, checked in by stefan toskovski <stefantoska84@…>, 4 weeks ago

Update repo after prototype presentation

  • Property mode set to 100644
File size: 12.8 KB
Line 
1/**
2 * @fileoverview Rule to flag dangling underscores in variable declarations.
3 * @author Matt DuVall <http://www.mattduvall.com>
4 */
5
6"use strict";
7
8//------------------------------------------------------------------------------
9// Rule Definition
10//------------------------------------------------------------------------------
11
12/** @type {import('../shared/types').Rule} */
13module.exports = {
14 meta: {
15 type: "suggestion",
16
17 docs: {
18 description: "Disallow dangling underscores in identifiers",
19 recommended: false,
20 url: "https://eslint.org/docs/latest/rules/no-underscore-dangle"
21 },
22
23 schema: [
24 {
25 type: "object",
26 properties: {
27 allow: {
28 type: "array",
29 items: {
30 type: "string"
31 }
32 },
33 allowAfterThis: {
34 type: "boolean",
35 default: false
36 },
37 allowAfterSuper: {
38 type: "boolean",
39 default: false
40 },
41 allowAfterThisConstructor: {
42 type: "boolean",
43 default: false
44 },
45 enforceInMethodNames: {
46 type: "boolean",
47 default: false
48 },
49 allowFunctionParams: {
50 type: "boolean",
51 default: true
52 },
53 enforceInClassFields: {
54 type: "boolean",
55 default: false
56 },
57 allowInArrayDestructuring: {
58 type: "boolean",
59 default: true
60 },
61 allowInObjectDestructuring: {
62 type: "boolean",
63 default: true
64 }
65 },
66 additionalProperties: false
67 }
68 ],
69
70 messages: {
71 unexpectedUnderscore: "Unexpected dangling '_' in '{{identifier}}'."
72 }
73 },
74
75 create(context) {
76
77 const options = context.options[0] || {};
78 const ALLOWED_VARIABLES = options.allow ? options.allow : [];
79 const allowAfterThis = typeof options.allowAfterThis !== "undefined" ? options.allowAfterThis : false;
80 const allowAfterSuper = typeof options.allowAfterSuper !== "undefined" ? options.allowAfterSuper : false;
81 const allowAfterThisConstructor = typeof options.allowAfterThisConstructor !== "undefined" ? options.allowAfterThisConstructor : false;
82 const enforceInMethodNames = typeof options.enforceInMethodNames !== "undefined" ? options.enforceInMethodNames : false;
83 const enforceInClassFields = typeof options.enforceInClassFields !== "undefined" ? options.enforceInClassFields : false;
84 const allowFunctionParams = typeof options.allowFunctionParams !== "undefined" ? options.allowFunctionParams : true;
85 const allowInArrayDestructuring = typeof options.allowInArrayDestructuring !== "undefined" ? options.allowInArrayDestructuring : true;
86 const allowInObjectDestructuring = typeof options.allowInObjectDestructuring !== "undefined" ? options.allowInObjectDestructuring : true;
87 const sourceCode = context.sourceCode;
88
89 //-------------------------------------------------------------------------
90 // Helpers
91 //-------------------------------------------------------------------------
92
93 /**
94 * Check if identifier is present inside the allowed option
95 * @param {string} identifier name of the node
96 * @returns {boolean} true if its is present
97 * @private
98 */
99 function isAllowed(identifier) {
100 return ALLOWED_VARIABLES.includes(identifier);
101 }
102
103 /**
104 * Check if identifier has a dangling underscore
105 * @param {string} identifier name of the node
106 * @returns {boolean} true if its is present
107 * @private
108 */
109 function hasDanglingUnderscore(identifier) {
110 const len = identifier.length;
111
112 return identifier !== "_" && (identifier[0] === "_" || identifier[len - 1] === "_");
113 }
114
115 /**
116 * Check if identifier is a special case member expression
117 * @param {string} identifier name of the node
118 * @returns {boolean} true if its is a special case
119 * @private
120 */
121 function isSpecialCaseIdentifierForMemberExpression(identifier) {
122 return identifier === "__proto__";
123 }
124
125 /**
126 * Check if identifier is a special case variable expression
127 * @param {string} identifier name of the node
128 * @returns {boolean} true if its is a special case
129 * @private
130 */
131 function isSpecialCaseIdentifierInVariableExpression(identifier) {
132
133 // Checks for the underscore library usage here
134 return identifier === "_";
135 }
136
137 /**
138 * Check if a node is a member reference of this.constructor
139 * @param {ASTNode} node node to evaluate
140 * @returns {boolean} true if it is a reference on this.constructor
141 * @private
142 */
143 function isThisConstructorReference(node) {
144 return node.object.type === "MemberExpression" &&
145 node.object.property.name === "constructor" &&
146 node.object.object.type === "ThisExpression";
147 }
148
149 /**
150 * Check if function parameter has a dangling underscore.
151 * @param {ASTNode} node function node to evaluate
152 * @returns {void}
153 * @private
154 */
155 function checkForDanglingUnderscoreInFunctionParameters(node) {
156 if (!allowFunctionParams) {
157 node.params.forEach(param => {
158 const { type } = param;
159 let nodeToCheck;
160
161 if (type === "RestElement") {
162 nodeToCheck = param.argument;
163 } else if (type === "AssignmentPattern") {
164 nodeToCheck = param.left;
165 } else {
166 nodeToCheck = param;
167 }
168
169 if (nodeToCheck.type === "Identifier") {
170 const identifier = nodeToCheck.name;
171
172 if (hasDanglingUnderscore(identifier) && !isAllowed(identifier)) {
173 context.report({
174 node: param,
175 messageId: "unexpectedUnderscore",
176 data: {
177 identifier
178 }
179 });
180 }
181 }
182 });
183 }
184 }
185
186 /**
187 * Check if function has a dangling underscore
188 * @param {ASTNode} node node to evaluate
189 * @returns {void}
190 * @private
191 */
192 function checkForDanglingUnderscoreInFunction(node) {
193 if (node.type === "FunctionDeclaration" && node.id) {
194 const identifier = node.id.name;
195
196 if (typeof identifier !== "undefined" && hasDanglingUnderscore(identifier) && !isAllowed(identifier)) {
197 context.report({
198 node,
199 messageId: "unexpectedUnderscore",
200 data: {
201 identifier
202 }
203 });
204 }
205 }
206 checkForDanglingUnderscoreInFunctionParameters(node);
207 }
208
209
210 /**
211 * Check if variable expression has a dangling underscore
212 * @param {ASTNode} node node to evaluate
213 * @returns {void}
214 * @private
215 */
216 function checkForDanglingUnderscoreInVariableExpression(node) {
217 sourceCode.getDeclaredVariables(node).forEach(variable => {
218 const definition = variable.defs.find(def => def.node === node);
219 const identifierNode = definition.name;
220 const identifier = identifierNode.name;
221 let parent = identifierNode.parent;
222
223 while (!["VariableDeclarator", "ArrayPattern", "ObjectPattern"].includes(parent.type)) {
224 parent = parent.parent;
225 }
226
227 if (
228 hasDanglingUnderscore(identifier) &&
229 !isSpecialCaseIdentifierInVariableExpression(identifier) &&
230 !isAllowed(identifier) &&
231 !(allowInArrayDestructuring && parent.type === "ArrayPattern") &&
232 !(allowInObjectDestructuring && parent.type === "ObjectPattern")
233 ) {
234 context.report({
235 node,
236 messageId: "unexpectedUnderscore",
237 data: {
238 identifier
239 }
240 });
241 }
242 });
243 }
244
245 /**
246 * Check if member expression has a dangling underscore
247 * @param {ASTNode} node node to evaluate
248 * @returns {void}
249 * @private
250 */
251 function checkForDanglingUnderscoreInMemberExpression(node) {
252 const identifier = node.property.name,
253 isMemberOfThis = node.object.type === "ThisExpression",
254 isMemberOfSuper = node.object.type === "Super",
255 isMemberOfThisConstructor = isThisConstructorReference(node);
256
257 if (typeof identifier !== "undefined" && hasDanglingUnderscore(identifier) &&
258 !(isMemberOfThis && allowAfterThis) &&
259 !(isMemberOfSuper && allowAfterSuper) &&
260 !(isMemberOfThisConstructor && allowAfterThisConstructor) &&
261 !isSpecialCaseIdentifierForMemberExpression(identifier) && !isAllowed(identifier)) {
262 context.report({
263 node,
264 messageId: "unexpectedUnderscore",
265 data: {
266 identifier
267 }
268 });
269 }
270 }
271
272 /**
273 * Check if method declaration or method property has a dangling underscore
274 * @param {ASTNode} node node to evaluate
275 * @returns {void}
276 * @private
277 */
278 function checkForDanglingUnderscoreInMethod(node) {
279 const identifier = node.key.name;
280 const isMethod = node.type === "MethodDefinition" || node.type === "Property" && node.method;
281
282 if (typeof identifier !== "undefined" && enforceInMethodNames && isMethod && hasDanglingUnderscore(identifier) && !isAllowed(identifier)) {
283 context.report({
284 node,
285 messageId: "unexpectedUnderscore",
286 data: {
287 identifier: node.key.type === "PrivateIdentifier"
288 ? `#${identifier}`
289 : identifier
290 }
291 });
292 }
293 }
294
295 /**
296 * Check if a class field has a dangling underscore
297 * @param {ASTNode} node node to evaluate
298 * @returns {void}
299 * @private
300 */
301 function checkForDanglingUnderscoreInClassField(node) {
302 const identifier = node.key.name;
303
304 if (typeof identifier !== "undefined" && hasDanglingUnderscore(identifier) &&
305 enforceInClassFields &&
306 !isAllowed(identifier)) {
307 context.report({
308 node,
309 messageId: "unexpectedUnderscore",
310 data: {
311 identifier: node.key.type === "PrivateIdentifier"
312 ? `#${identifier}`
313 : identifier
314 }
315 });
316 }
317 }
318
319 //--------------------------------------------------------------------------
320 // Public API
321 //--------------------------------------------------------------------------
322
323 return {
324 FunctionDeclaration: checkForDanglingUnderscoreInFunction,
325 VariableDeclarator: checkForDanglingUnderscoreInVariableExpression,
326 MemberExpression: checkForDanglingUnderscoreInMemberExpression,
327 MethodDefinition: checkForDanglingUnderscoreInMethod,
328 PropertyDefinition: checkForDanglingUnderscoreInClassField,
329 Property: checkForDanglingUnderscoreInMethod,
330 FunctionExpression: checkForDanglingUnderscoreInFunction,
331 ArrowFunctionExpression: checkForDanglingUnderscoreInFunction
332 };
333
334 }
335};
Note: See TracBrowser for help on using the repository browser.