diff --git a/packages/babel-plugin-proposal-decorators/src/transformer-legacy.js b/packages/babel-plugin-proposal-decorators/src/transformer-legacy.js index 0eb0ebdbd87a..594363a38b63 100644 --- a/packages/babel-plugin-proposal-decorators/src/transformer-legacy.js +++ b/packages/babel-plugin-proposal-decorators/src/transformer-legacy.js @@ -252,6 +252,9 @@ export default { const replacement = decoratedClassToExpression(path); if (replacement) { path.replaceWith(replacement); + + const decl = path.get("declarations.0"); + path.scope.updateOwnBinding(decl.node.id, path.node.kind, decl); } }, ClassExpression(path, state) { diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/legacy-regression/8559/input.mjs b/packages/babel-plugin-proposal-decorators/test/fixtures/legacy-regression/8559/input.mjs new file mode 100644 index 000000000000..e0c390921046 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/legacy-regression/8559/input.mjs @@ -0,0 +1,12 @@ +import {autobind} from 'core-decorators'; + +export default function wrap() { + return function() { + class Foo { + @autobind + method() {} + } + + return Foo; + }; +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/legacy-regression/8559/options.json b/packages/babel-plugin-proposal-decorators/test/fixtures/legacy-regression/8559/options.json new file mode 100644 index 000000000000..ea51d6b70917 --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/legacy-regression/8559/options.json @@ -0,0 +1,12 @@ +{ + "plugins": [ + ["proposal-decorators", { "legacy": true }] + ], + "presets": [ + ["env", { + "targets": { + "node": 8 + } + }] + ] +} diff --git a/packages/babel-plugin-proposal-decorators/test/fixtures/legacy-regression/8559/output.js b/packages/babel-plugin-proposal-decorators/test/fixtures/legacy-regression/8559/output.js new file mode 100644 index 000000000000..321fea76385d --- /dev/null +++ b/packages/babel-plugin-proposal-decorators/test/fixtures/legacy-regression/8559/output.js @@ -0,0 +1,22 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = wrap; + +var _coreDecorators = require("core-decorators"); + +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 wrap() { + return function () { + var _class; + + let Foo = (_class = class Foo { + method() {} + + }, (_applyDecoratedDescriptor(_class.prototype, "method", [_coreDecorators.autobind], Object.getOwnPropertyDescriptor(_class.prototype, "method"), _class.prototype)), _class); + return Foo; + }; +} diff --git a/packages/babel-traverse/src/scope/index.js b/packages/babel-traverse/src/scope/index.js index b91eeeb25c4b..e3311031c635 100644 --- a/packages/babel-traverse/src/scope/index.js +++ b/packages/babel-traverse/src/scope/index.js @@ -944,6 +944,17 @@ export default class Scope { return this.parent && this.parent.hasBinding(name, noGlobals); } + updateOwnBinding(id: t.Identifier, kind: string, path: NodePath) { + if (!kind) throw new ReferenceError("no `kind`"); + + const binding = this.getOwnBinding(id.name); + if (!binding) throw new ReferenceError(`Unknown binding: ${id.name}`); + + binding.identifier = id; + binding.kind = kind; + binding.path = path; + } + /** * Move a binding of `name` to another `scope`. */