Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[decorators] Set method names at compile time instead of at runtime #9244

Merged
merged 1 commit into from Jan 9, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
@@ -1,5 +1,6 @@
import { types as t, template } from "@babel/core";
import ReplaceSupers from "@babel/helper-replace-supers";
import nameFunction from "@babel/helper-function-name";

export function hasOwnDecorators(node) {
return !!(node.decorators && node.decorators.length);
Expand All @@ -14,11 +15,13 @@ function prop(key, value) {
return t.objectProperty(t.identifier(key), value);
}

function value(body, params = [], async, generator) {
const method = t.objectMethod("method", t.identifier("value"), params, body);
method.async = !!async;
method.generator = !!generator;
return method;
function method(key, body) {
return t.objectMethod(
"method",
t.identifier(key),
[],
t.blockStatement(body),
);
}

function takeDecorators(node) {
Expand Down Expand Up @@ -74,13 +77,20 @@ function extractElementDescriptor(/* this: File, */ classRef, superRef, path) {
prop("decorators", takeDecorators(node)),
prop("static", node.static && t.booleanLiteral(true)),
prop("key", getKey(node)),
isMethod
? value(node.body, node.params, node.async, node.generator)
: node.value
? value(template.ast`{ return ${node.value} }`)
: prop("value", scope.buildUndefinedNode()),
].filter(Boolean);

if (isMethod) {
const id = node.computed ? null : node.key;
t.toExpression(node);
properties.push(prop("value", nameFunction({ node, id, scope }) || node));
} else if (node.value) {
properties.push(
method("value", template.statements.ast`return ${node.value}`),
);
} else {
properties.push(prop("value", scope.buildUndefinedNode()));
}

path.remove();

return t.objectExpression(properties);
Expand Down
4 changes: 0 additions & 4 deletions packages/babel-helpers/src/helpers.js
Expand Up @@ -1246,10 +1246,6 @@ helpers.decorate = helper("7.1.5")`
configurable: true,
enumerable: false,
};
Object.defineProperty(def.value, "name", {
value: typeof key === "symbol" ? "" : key,
configurable: true,
});
} else if (def.kind === "get") {
descriptor = { get: def.value, configurable: true, enumerable: false };
} else if (def.kind === "set") {
Expand Down
Expand Up @@ -13,19 +13,15 @@ let Foo = babelHelpers.decorate([_ => desc = _], function (_initialize) {
d: [{
kind: "method",
key: getKey(),

value() {
value: function () {
return 1;
}

}, {
kind: "method",
key: getKey(),

value() {
value: function () {
return 2;
}

}]
};
});
Expand Up @@ -13,19 +13,15 @@ let Foo = babelHelpers.decorate([_ => desc = _], function (_initialize) {
d: [{
kind: "method",
key: getKeyI(),

value() {
value: function () {
return 1;
}

}, {
kind: "method",
key: getKeyJ(),

value() {
value: function () {
return 2;
}

}]
};
});
@@ -0,0 +1,13 @@
function decorator() {}

var method = 1;

@decorator
class Foo {
method() {
return method;
}
}

expect(new Foo().method()).toBe(1);
expect(Foo.prototype.method.name).toBe("method");
@@ -0,0 +1,8 @@
var method = 1;

@decorator
class Foo {
method() {
return method;
}
}
@@ -0,0 +1,22 @@
var _method = 1;
let Foo = babelHelpers.decorate([decorator], function (_initialize) {
"use strict";

class Foo {
constructor() {
_initialize(this);
}

}

return {
F: Foo,
d: [{
kind: "method",
key: "method",
value: function method() {
return _method;
}
}]
};
});
Expand Up @@ -14,9 +14,7 @@ let A = babelHelpers.decorate([dec(a, b, ...c)], function (_initialize) {
kind: "method",
decorators: [dec(a, b, ...c)],
key: "method",

value() {}

value: function method() {}
}]
};
});
Expand Up @@ -13,21 +13,15 @@ let Foo = babelHelpers.decorate([decorator], function (_initialize) {
d: [{
kind: "method",
key: "f1",

async value() {}

value: async function f1() {}
}, {
kind: "method",
key: "f2",

*value() {}

value: function* f2() {}
}, {
kind: "method",
key: "f3",

async *value() {}

value: async function* f3() {}
}]
};
});
Expand Up @@ -14,9 +14,7 @@
d: [{
kind: "method",
key: "method",

value() {}

value: function method() {}
}]
};
});
Expand All @@ -38,9 +36,7 @@
d: [{
kind: "method",
key: "method",

value() {}

value: function method() {}
}]
};
});
Expand Down