Transform decorated classes from the export visitor (#8047)
Fixes gh-8041 <!-- Before making a PR please make sure to read our contributing guidelines https://github.com/babel/babel/blob/master/CONTRIBUTING.md For issue references: Add a comma-separated list of a [closing word](https://help.github.com/articles/closing-issues-via-commit-messages/) followed by the ticket number fixed by the PR. It should be underlined in the preview if done correctly. --> | Q | A <!--(Can use an emoji 👍) --> | ------------------------ | --- | Fixed Issues? | #8041 | Patch: Bug Fix? |👍 | Major: Breaking Change? | | Minor: New Feature? | | Tests Added + Pass? | Yes | Documentation PR | <!-- If so, add `[skip ci]` to your commit message to skip CI --> | Any Dependency Changes? | | License | MIT <!-- Describe your changes below in as much detail as possible -->
This commit is contained in:
committed by
Logan Smyth
parent
9c707f9670
commit
90a174e7c4
@@ -206,31 +206,42 @@ function applyTargetDecorators(path, state, decoratedProps) {
|
||||
]);
|
||||
}
|
||||
|
||||
function decoratedClassToExpression({ node, scope }) {
|
||||
if (!hasClassDecorators(node) && !hasMethodDecorators(node.body.body)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const ref = node.id
|
||||
? t.cloneNode(node.id)
|
||||
: scope.generateUidIdentifier("class");
|
||||
|
||||
return t.variableDeclaration("let", [
|
||||
t.variableDeclarator(ref, t.toExpression(node)),
|
||||
]);
|
||||
}
|
||||
|
||||
export default {
|
||||
ClassDeclaration(path) {
|
||||
const { node } = path;
|
||||
ExportDefaultDeclaration(path) {
|
||||
const decl = path.get("declaration");
|
||||
if (!decl.isClassDeclaration()) return;
|
||||
|
||||
if (!hasClassDecorators(node) && !hasMethodDecorators(node.body.body)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const ref = node.id
|
||||
? t.cloneNode(node.id)
|
||||
: path.scope.generateUidIdentifier("class");
|
||||
const letDeclaration = t.variableDeclaration("let", [
|
||||
t.variableDeclarator(ref, t.toExpression(node)),
|
||||
]);
|
||||
|
||||
if (path.parentPath.isExportDefaultDeclaration()) {
|
||||
// Split the class declaration and the export into two separate statements.
|
||||
path.parentPath.replaceWithMultiple([
|
||||
letDeclaration,
|
||||
const replacement = decoratedClassToExpression(decl);
|
||||
if (replacement) {
|
||||
path.replaceWithMultiple([
|
||||
replacement,
|
||||
t.exportNamedDeclaration(null, [
|
||||
t.exportSpecifier(t.cloneNode(ref), t.identifier("default")),
|
||||
t.exportSpecifier(
|
||||
t.cloneNode(replacement.declarations[0].id),
|
||||
t.identifier("default"),
|
||||
),
|
||||
]),
|
||||
]);
|
||||
} else {
|
||||
path.replaceWith(letDeclaration);
|
||||
}
|
||||
},
|
||||
ClassDeclaration(path) {
|
||||
const replacement = decoratedClassToExpression(path);
|
||||
if (replacement) {
|
||||
path.replaceWith(replacement);
|
||||
}
|
||||
},
|
||||
ClassExpression(path, state) {
|
||||
|
||||
4
packages/babel-plugin-proposal-decorators/test/fixtures/legacy-regression/8041/input.mjs
vendored
Normal file
4
packages/babel-plugin-proposal-decorators/test/fixtures/legacy-regression/8041/input.mjs
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
export default class {
|
||||
@foo
|
||||
bar() {}
|
||||
}
|
||||
6
packages/babel-plugin-proposal-decorators/test/fixtures/legacy-regression/8041/options.json
vendored
Normal file
6
packages/babel-plugin-proposal-decorators/test/fixtures/legacy-regression/8041/options.json
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"plugins": [
|
||||
["proposal-decorators", { "legacy": true }],
|
||||
"proposal-class-properties"
|
||||
]
|
||||
}
|
||||
10
packages/babel-plugin-proposal-decorators/test/fixtures/legacy-regression/8041/output.mjs
vendored
Normal file
10
packages/babel-plugin-proposal-decorators/test/fixtures/legacy-regression/8041/output.mjs
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
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; }
|
||||
|
||||
let _class = (_class2 = class {
|
||||
bar() {}
|
||||
|
||||
}, (_applyDecoratedDescriptor(_class2.prototype, "bar", [foo], Object.getOwnPropertyDescriptor(_class2.prototype, "bar"), _class2.prototype)), _class2);
|
||||
|
||||
export { _class as default };
|
||||
Reference in New Issue
Block a user