diff --git a/packages/babel-helpers/src/helpers.js b/packages/babel-helpers/src/helpers.js index eda37ef983..2960143099 100644 --- a/packages/babel-helpers/src/helpers.js +++ b/packages/babel-helpers/src/helpers.js @@ -978,9 +978,7 @@ helpers.applyDecoratedDescriptor = helper("7.0.0-beta.0")` }); desc.enumerable = !!desc.enumerable; desc.configurable = !!desc.configurable; - if ('value' in desc || desc.initializer){ - desc.writable = true; - } + desc.writable = !!desc.writable; desc = decorators.slice().reverse().reduce(function(desc, decorator){ return decorator(target, property, desc) || desc; diff --git a/packages/babel-plugin-proposal-decorators/src/transformer-legacy.js b/packages/babel-plugin-proposal-decorators/src/transformer-legacy.js index 6c01069b1a..0eb0ebdbd8 100644 --- a/packages/babel-plugin-proposal-decorators/src/transformer-legacy.js +++ b/packages/babel-plugin-proposal-decorators/src/transformer-legacy.js @@ -168,10 +168,18 @@ function applyTargetDecorators(path, state, decoratedProps) { decorators.map(dec => t.cloneNode(dec.expression)), ), t.objectExpression([ + t.objectProperty( + t.identifier("configurable"), + t.booleanLiteral(true), + ), t.objectProperty( t.identifier("enumerable"), t.booleanLiteral(true), ), + t.objectProperty( + t.identifier("writable"), + t.booleanLiteral(true), + ), t.objectProperty(t.identifier("initializer"), initializer), ]), ]), diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/legacy-class-prototype-properties/mutate-descriptor/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/legacy-class-prototype-properties/mutate-descriptor/exec.js index a037b2abc6..e03bc98fab 100644 --- a/packages/babel-plugin-proposal-decorators/test/fixtures/legacy-class-prototype-properties/mutate-descriptor/exec.js +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/legacy-class-prototype-properties/mutate-descriptor/exec.js @@ -16,6 +16,16 @@ function dec(target, name, descriptor) { }); } +function plainDec(target, name, descriptor) { + expect(target).toBeTruthy(); + expect(typeof name).toBe("string"); + expect(typeof descriptor).toBe("object"); + + target.decoratedProps = (target.decoratedProps || []).concat([name]); + + return descriptor; +} + class Example { @dec enumconfwrite = 1; @@ -40,6 +50,9 @@ class Example { @dec _ = 8; + + @plainDec + plain = 9; } const inst = new Example(); @@ -54,6 +67,7 @@ expect(inst.decoratedProps).toEqual([ "conf", "write", "_", + "plain", ]); const descs = Object.getOwnPropertyDescriptors(inst); @@ -97,3 +111,8 @@ expect(descs._.enumerable).toBe(false); expect(descs._.writable).toBe(false); expect(descs._.configurable).toBe(false); expect(inst._).toBe("__8__"); + +expect(descs.plain.enumerable).toBeTruthy(); +expect(descs.plain.writable).toBeTruthy(); +expect(descs.plain.configurable).toBeTruthy(); +expect(inst.plain).toBe(9); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/legacy-class-prototype-properties/properties-without-initializer/exec.js b/packages/babel-plugin-proposal-decorators/test/fixtures/legacy-class-prototype-properties/properties-without-initializer/exec.js index 85a042a1ed..9b3cff3f6a 100644 --- a/packages/babel-plugin-proposal-decorators/test/fixtures/legacy-class-prototype-properties/properties-without-initializer/exec.js +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/legacy-class-prototype-properties/properties-without-initializer/exec.js @@ -1,5 +1,11 @@ function dec(target, name, descriptor) { + expect(target).toBeTruthy(); + expect(typeof name).toBe("string"); + expect(typeof descriptor).toBe("object"); + target.decoratedProps = (target.decoratedProps || []).concat([name]); + + return descriptor; } class Example { @@ -7,5 +13,17 @@ class Example { } let inst = new Example(); + +expect(Example.prototype).toHaveProperty("decoratedProps"); +expect(inst.decoratedProps).toEqual([ + "prop", +]); + expect(inst).toHaveProperty("prop"); expect(inst.prop).toBeUndefined(); + +const descs = Object.getOwnPropertyDescriptors(inst); + +expect(descs.prop.enumerable).toBeTruthy(); +expect(descs.prop.writable).toBeTruthy(); +expect(descs.prop.configurable).toBeTruthy(); diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/legacy-decl-to-expression/method-decorators/output.mjs b/packages/babel-plugin-proposal-decorators/test/fixtures/legacy-decl-to-expression/method-decorators/output.mjs index 27b1191153..1dcda22f4f 100644 --- a/packages/babel-plugin-proposal-decorators/test/fixtures/legacy-decl-to-expression/method-decorators/output.mjs +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/legacy-decl-to-expression/method-decorators/output.mjs @@ -1,6 +1,6 @@ var _class, _class2; -function _applyDecoratedDescriptor(target, property, decorators, descriptor, context) { var desc = {}; Object['ke' + 'ys'](descriptor).forEach(function (key) { desc[key] = descriptor[key]; }); desc.enumerable = !!desc.enumerable; desc.configurable = !!desc.configurable; if ('value' in desc || desc.initializer) { desc.writable = true; } desc = decorators.slice().reverse().reduce(function (desc, decorator) { return decorator(target, property, desc) || desc; }, desc); if (context && desc.initializer !== void 0) { desc.value = desc.initializer ? desc.initializer.call(context) : void 0; desc.initializer = undefined; } if (desc.initializer === void 0) { Object['define' + 'Property'](target, property, desc); desc = null; } return desc; } +function _applyDecoratedDescriptor(target, property, decorators, descriptor, context) { var desc = {}; Object['ke' + 'ys'](descriptor).forEach(function (key) { desc[key] = descriptor[key]; }); desc.enumerable = !!desc.enumerable; desc.configurable = !!desc.configurable; desc.writable = !!desc.writable; desc = decorators.slice().reverse().reduce(function (desc, decorator) { return decorator(target, property, desc) || desc; }, desc); if (context && desc.initializer !== void 0) { desc.value = desc.initializer ? desc.initializer.call(context) : void 0; desc.initializer = undefined; } if (desc.initializer === void 0) { Object['define' + 'Property'](target, property, desc); desc = null; } return desc; } let A = (_class2 = class A { foo() {} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/legacy-regression/8041/output.mjs b/packages/babel-plugin-proposal-decorators/test/fixtures/legacy-regression/8041/output.mjs index f35dc48db9..85211269c5 100644 --- a/packages/babel-plugin-proposal-decorators/test/fixtures/legacy-regression/8041/output.mjs +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/legacy-regression/8041/output.mjs @@ -1,6 +1,6 @@ var _class2; -function _applyDecoratedDescriptor(target, property, decorators, descriptor, context) { var desc = {}; Object['ke' + 'ys'](descriptor).forEach(function (key) { desc[key] = descriptor[key]; }); desc.enumerable = !!desc.enumerable; desc.configurable = !!desc.configurable; if ('value' in desc || desc.initializer) { desc.writable = true; } desc = decorators.slice().reverse().reduce(function (desc, decorator) { return decorator(target, property, desc) || desc; }, desc); if (context && desc.initializer !== void 0) { desc.value = desc.initializer ? desc.initializer.call(context) : void 0; desc.initializer = undefined; } if (desc.initializer === void 0) { Object['define' + 'Property'](target, property, desc); desc = null; } return desc; } +function _applyDecoratedDescriptor(target, property, decorators, descriptor, context) { var desc = {}; Object['ke' + 'ys'](descriptor).forEach(function (key) { desc[key] = descriptor[key]; }); desc.enumerable = !!desc.enumerable; desc.configurable = !!desc.configurable; desc.writable = !!desc.writable; desc = decorators.slice().reverse().reduce(function (desc, decorator) { return decorator(target, property, desc) || desc; }, desc); if (context && desc.initializer !== void 0) { desc.value = desc.initializer ? desc.initializer.call(context) : void 0; desc.initializer = undefined; } if (desc.initializer === void 0) { Object['define' + 'Property'](target, property, desc); desc = null; } return desc; } let _class = (_class2 = class { bar() {}