diff --git a/packages/babel-plugin-transform-es2015-duplicate-keys/src/index.js b/packages/babel-plugin-transform-es2015-duplicate-keys/src/index.js index be9fab7851..551e27a4ec 100644 --- a/packages/babel-plugin-transform-es2015-duplicate-keys/src/index.js +++ b/packages/babel-plugin-transform-es2015-duplicate-keys/src/index.js @@ -14,13 +14,42 @@ export default function() { const { node } = path; const plainProps = node.properties.filter((prop) => !t.isSpreadProperty(prop) && !prop.computed); - const alreadySeenNames = Object.create(null); + // A property is a duplicate key if: + // * the property is a data property, and is preceeded by a data, + // getter, or setter property of the same name. + // * the property is a getter property, and is preceeded by a data or + // getter property of the same name. + // * the property is a setter property, and is preceeded by a data or + // setter property of the same name. + + const alreadySeenData = Object.create(null); + const alreadySeenGetters = Object.create(null); + const alreadySeenSetters = Object.create(null); for (let prop of plainProps) { const name = getName(prop.key); - if (!alreadySeenNames[name]) { - alreadySeenNames[name] = true; - } else { + let isDuplicate = false; + switch (prop.kind) { + case "get": + if (alreadySeenData[name] || alreadySeenGetters[name]) { + isDuplicate = true; + } + alreadySeenGetters[name] = true; + break; + case "set": + if (alreadySeenData[name] || alreadySeenSetters[name]) { + isDuplicate = true; + } + alreadySeenSetters[name] = true; + break; + default: + if (alreadySeenData[name] || alreadySeenGetters[name] || alreadySeenSetters[name]) { + isDuplicate = true; + } + alreadySeenData[name] = true; + } + + if (isDuplicate) { // Rely on the computed properties transform to split the property // assignment out of the object literal. prop.computed = true; diff --git a/packages/babel-plugin-transform-es2015-duplicate-keys/test/fixtures/duplicate-keys/getters-and-setters/actual.js b/packages/babel-plugin-transform-es2015-duplicate-keys/test/fixtures/duplicate-keys/getters-and-setters/actual.js new file mode 100644 index 0000000000..fe9df3aa0e --- /dev/null +++ b/packages/babel-plugin-transform-es2015-duplicate-keys/test/fixtures/duplicate-keys/getters-and-setters/actual.js @@ -0,0 +1,16 @@ +var x = { + get a() {}, + set a(x) {}, + get a() {}, + set a(x) {}, + a: 3, + b: 4, + get b() {}, + set b(x) {}, + get c() {}, + c: 5, + set c(x) {}, + set d(x) {}, + d: 6, + get d() {} +}; diff --git a/packages/babel-plugin-transform-es2015-duplicate-keys/test/fixtures/duplicate-keys/getters-and-setters/expected.js b/packages/babel-plugin-transform-es2015-duplicate-keys/test/fixtures/duplicate-keys/getters-and-setters/expected.js new file mode 100644 index 0000000000..9c5ae8b475 --- /dev/null +++ b/packages/babel-plugin-transform-es2015-duplicate-keys/test/fixtures/duplicate-keys/getters-and-setters/expected.js @@ -0,0 +1,16 @@ +var x = { + get a() {}, + set a(x) {}, + get ["a"]() {}, + set ["a"](x) {}, + ["a"]: 3, + b: 4, + get ["b"]() {}, + set ["b"](x) {}, + get c() {}, + ["c"]: 5, + set ["c"](x) {}, + set d(x) {}, + ["d"]: 6, + get ["d"]() {} +};