]> git.proxmox.com Git - pve-eslint.git/blob - eslint/lib/rules/no-useless-computed-key.js
import eslint 7.28.0
[pve-eslint.git] / eslint / lib / rules / no-useless-computed-key.js
1 /**
2 * @fileoverview Rule to disallow unnecessary computed property keys in object literals
3 * @author Burak Yigit Kaya
4 */
5 "use strict";
6
7 //------------------------------------------------------------------------------
8 // Requirements
9 //------------------------------------------------------------------------------
10
11 const astUtils = require("./utils/ast-utils");
12
13 //------------------------------------------------------------------------------
14 // Rule Definition
15 //------------------------------------------------------------------------------
16
17 module.exports = {
18 meta: {
19 type: "suggestion",
20
21 docs: {
22 description: "disallow unnecessary computed property keys in objects and classes",
23 category: "ECMAScript 6",
24 recommended: false,
25 url: "https://eslint.org/docs/rules/no-useless-computed-key"
26 },
27
28 schema: [{
29 type: "object",
30 properties: {
31 enforceForClassMembers: {
32 type: "boolean",
33 default: false
34 }
35 },
36 additionalProperties: false
37 }],
38 fixable: "code",
39
40 messages: {
41 unnecessarilyComputedProperty: "Unnecessarily computed property [{{property}}] found."
42 }
43 },
44 create(context) {
45 const sourceCode = context.getSourceCode();
46 const enforceForClassMembers = context.options[0] && context.options[0].enforceForClassMembers;
47
48 /**
49 * Reports a given node if it violated this rule.
50 * @param {ASTNode} node The node to check.
51 * @returns {void}
52 */
53 function check(node) {
54 if (!node.computed) {
55 return;
56 }
57
58 const key = node.key,
59 nodeType = typeof key.value;
60
61 let allowedKey;
62
63 if (node.type === "MethodDefinition") {
64 allowedKey = node.static ? "prototype" : "constructor";
65 } else {
66 allowedKey = "__proto__";
67 }
68
69 if (key.type === "Literal" && (nodeType === "string" || nodeType === "number") && key.value !== allowedKey) {
70 context.report({
71 node,
72 messageId: "unnecessarilyComputedProperty",
73 data: { property: sourceCode.getText(key) },
74 fix(fixer) {
75 const leftSquareBracket = sourceCode.getTokenBefore(key, astUtils.isOpeningBracketToken);
76 const rightSquareBracket = sourceCode.getTokenAfter(key, astUtils.isClosingBracketToken);
77
78 // If there are comments between the brackets and the property name, don't do a fix.
79 if (sourceCode.commentsExistBetween(leftSquareBracket, rightSquareBracket)) {
80 return null;
81 }
82
83 const tokenBeforeLeftBracket = sourceCode.getTokenBefore(leftSquareBracket);
84
85 // Insert a space before the key to avoid changing identifiers, e.g. ({ get[2]() {} }) to ({ get2() {} })
86 const needsSpaceBeforeKey = tokenBeforeLeftBracket.range[1] === leftSquareBracket.range[0] &&
87 !astUtils.canTokensBeAdjacent(tokenBeforeLeftBracket, sourceCode.getFirstToken(key));
88
89 const replacementKey = (needsSpaceBeforeKey ? " " : "") + key.raw;
90
91 return fixer.replaceTextRange([leftSquareBracket.range[0], rightSquareBracket.range[1]], replacementKey);
92 }
93 });
94 }
95 }
96
97 /**
98 * A no-op function to act as placeholder for checking a node when the `enforceForClassMembers` option is `false`.
99 * @returns {void}
100 * @private
101 */
102 function noop() {}
103
104 return {
105 Property: check,
106 MethodDefinition: enforceForClassMembers ? check : noop
107 };
108 }
109 };