2 * @fileoverview Rule to flag use of duplicate keys in an object.
3 * @author Ian Christian Myers
8 //------------------------------------------------------------------------------
10 //------------------------------------------------------------------------------
12 const astUtils = require("./utils/ast-utils");
14 //------------------------------------------------------------------------------
16 //------------------------------------------------------------------------------
18 const GET_KIND = /^(?:init|get)$/u;
19 const SET_KIND = /^(?:init|set)$/u;
22 * The class which stores properties' information of an object.
26 // eslint-disable-next-line jsdoc/require-description
28 * @param {ObjectInfo|null} upper The information of the outer object.
29 * @param {ASTNode} node The ObjectExpression node of this information.
31 constructor(upper, node) {
34 this.properties = new Map();
38 * Gets the information of the given Property node.
39 * @param {ASTNode} node The Property node to get.
40 * @returns {{get: boolean, set: boolean}} The information of the property.
42 getPropertyInfo(node) {
43 const name = astUtils.getStaticPropertyName(node);
45 if (!this.properties.has(name)) {
46 this.properties.set(name, { get: false, set: false });
48 return this.properties.get(name);
52 * Checks whether the given property has been defined already or not.
53 * @param {ASTNode} node The Property node to check.
54 * @returns {boolean} `true` if the property has been defined.
56 isPropertyDefined(node) {
57 const entry = this.getPropertyInfo(node);
60 (GET_KIND.test(node.kind) && entry.get) ||
61 (SET_KIND.test(node.kind) && entry.set)
66 * Defines the given property.
67 * @param {ASTNode} node The Property node to define.
70 defineProperty(node) {
71 const entry = this.getPropertyInfo(node);
73 if (GET_KIND.test(node.kind)) {
76 if (SET_KIND.test(node.kind)) {
82 //------------------------------------------------------------------------------
84 //------------------------------------------------------------------------------
91 description: "disallow duplicate keys in object literals",
92 category: "Possible Errors",
94 url: "https://eslint.org/docs/rules/no-dupe-keys"
100 unexpected: "Duplicate key '{{name}}'."
108 ObjectExpression(node) {
109 info = new ObjectInfo(info, node);
111 "ObjectExpression:exit"() {
116 const name = astUtils.getStaticPropertyName(node);
118 // Skip destructuring.
119 if (node.parent.type !== "ObjectExpression") {
123 // Skip if the name is not static.
128 // Reports if the name is defined already.
129 if (info.isPropertyDefined(node)) {
133 messageId: "unexpected",
139 info.defineProperty(node);