[decorators] Only transform declarations to expressions when needed (#7124)
This commit is contained in:
parent
bb17b72f4f
commit
b93184e430
@ -63,11 +63,11 @@ export default function() {
|
||||
* with the proper decorated behavior.
|
||||
*/
|
||||
function applyClassDecorators(classPath) {
|
||||
if (!hasClassDecorators(classPath.node)) return;
|
||||
|
||||
const decorators = classPath.node.decorators || [];
|
||||
classPath.node.decorators = null;
|
||||
|
||||
if (decorators.length === 0) return;
|
||||
|
||||
const name = classPath.scope.generateDeclaredUidIdentifier("class");
|
||||
|
||||
return decorators
|
||||
@ -82,30 +82,30 @@ export default function() {
|
||||
}, classPath.node);
|
||||
}
|
||||
|
||||
function hasClassDecorators(classNode) {
|
||||
return !!(classNode.decorators && classNode.decorators.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a class expression with method-level decorators, create a new expression
|
||||
* with the proper decorated behavior.
|
||||
*/
|
||||
function applyMethodDecorators(path, state) {
|
||||
const hasMethodDecorators = path.node.body.body.some(function(node) {
|
||||
return (node.decorators || []).length > 0;
|
||||
});
|
||||
|
||||
if (!hasMethodDecorators) return;
|
||||
if (!hasMethodDecorators(path.node.body.body)) return;
|
||||
|
||||
return applyTargetDecorators(path, state, path.node.body.body);
|
||||
}
|
||||
|
||||
function hasMethodDecorators(body) {
|
||||
return body.some(node => node.decorators && node.decorators.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Given an object expression with property decorators, create a new expression
|
||||
* with the proper decorated behavior.
|
||||
*/
|
||||
function applyObjectDecorators(path, state) {
|
||||
const hasMethodDecorators = path.node.properties.some(function(node) {
|
||||
return (node.decorators || []).length > 0;
|
||||
});
|
||||
|
||||
if (!hasMethodDecorators) return;
|
||||
if (!hasMethodDecorators(path.node.properties)) return;
|
||||
|
||||
return applyTargetDecorators(path, state, path.node.properties);
|
||||
}
|
||||
@ -215,32 +215,29 @@ export default function() {
|
||||
inherits: syntaxDecorators,
|
||||
|
||||
visitor: {
|
||||
ExportDefaultDeclaration(path) {
|
||||
if (!path.get("declaration").isClassDeclaration()) return;
|
||||
|
||||
const { node } = path;
|
||||
const ref =
|
||||
node.declaration.id || path.scope.generateUidIdentifier("default");
|
||||
node.declaration.id = ref;
|
||||
|
||||
// Split the class declaration and the export into two separate statements.
|
||||
path.replaceWith(node.declaration);
|
||||
path.insertAfter(
|
||||
t.exportNamedDeclaration(null, [
|
||||
t.exportSpecifier(ref, t.identifier("default")),
|
||||
]),
|
||||
);
|
||||
},
|
||||
ClassDeclaration(path) {
|
||||
const { node } = path;
|
||||
|
||||
const ref = node.id || path.scope.generateUidIdentifier("class");
|
||||
if (!hasClassDecorators(node) && !hasMethodDecorators(node.body.body)) {
|
||||
return;
|
||||
}
|
||||
|
||||
path.replaceWith(
|
||||
t.variableDeclaration("let", [
|
||||
t.variableDeclarator(ref, t.toExpression(node)),
|
||||
]),
|
||||
);
|
||||
const ref = 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,
|
||||
t.exportNamedDeclaration(null, [
|
||||
t.exportSpecifier(ref, t.identifier("default")),
|
||||
]),
|
||||
]);
|
||||
} else {
|
||||
path.replaceWith(letDeclaration);
|
||||
}
|
||||
},
|
||||
ClassExpression(path, state) {
|
||||
// Create a replacement for the class node if there is one. We do one pass to replace classes with
|
||||
|
||||
@ -0,0 +1,2 @@
|
||||
export default @dec class A {}
|
||||
@dec class B {}
|
||||
@ -0,0 +1,5 @@
|
||||
var _class, _class2;
|
||||
|
||||
export default dec(_class = class A {}) || _class;
|
||||
|
||||
let B = dec(_class2 = class B {}) || _class2;
|
||||
@ -0,0 +1,6 @@
|
||||
export default class A {
|
||||
@dec foo() {}
|
||||
}
|
||||
class B {
|
||||
@dec foo() {}
|
||||
}
|
||||
@ -0,0 +1,13 @@
|
||||
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; }
|
||||
|
||||
let A = (_class2 = class A {
|
||||
foo() {}
|
||||
|
||||
}, (_applyDecoratedDescriptor(_class2.prototype, "foo", [dec], Object.getOwnPropertyDescriptor(_class2.prototype, "foo"), _class2.prototype)), _class2);
|
||||
export { A as default };
|
||||
let B = (_class = class B {
|
||||
foo() {}
|
||||
|
||||
}, (_applyDecoratedDescriptor(_class.prototype, "foo", [dec], Object.getOwnPropertyDescriptor(_class.prototype, "foo"), _class.prototype)), _class);
|
||||
@ -0,0 +1,6 @@
|
||||
export default class A {
|
||||
foo() {}
|
||||
}
|
||||
class B {
|
||||
foo() {}
|
||||
}
|
||||
@ -0,0 +1,9 @@
|
||||
export default class A {
|
||||
foo() {}
|
||||
|
||||
}
|
||||
|
||||
class B {
|
||||
foo() {}
|
||||
|
||||
}
|
||||
4
packages/babel-plugin-proposal-decorators/test/fixtures/decl-to-expression/options.json
vendored
Normal file
4
packages/babel-plugin-proposal-decorators/test/fixtures/decl-to-expression/options.json
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"presets": [],
|
||||
"plugins": ["proposal-decorators"]
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user