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