[decorators] Set method names at compile time instead of at runtime (#9244)
This commit is contained in:
parent
778a61a3c2
commit
8e051cae46
@ -1,5 +1,6 @@
|
|||||||
import { types as t, template } from "@babel/core";
|
import { types as t, template } from "@babel/core";
|
||||||
import ReplaceSupers from "@babel/helper-replace-supers";
|
import ReplaceSupers from "@babel/helper-replace-supers";
|
||||||
|
import nameFunction from "@babel/helper-function-name";
|
||||||
|
|
||||||
export function hasOwnDecorators(node) {
|
export function hasOwnDecorators(node) {
|
||||||
return !!(node.decorators && node.decorators.length);
|
return !!(node.decorators && node.decorators.length);
|
||||||
@ -14,11 +15,13 @@ function prop(key, value) {
|
|||||||
return t.objectProperty(t.identifier(key), value);
|
return t.objectProperty(t.identifier(key), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
function value(body, params = [], async, generator) {
|
function method(key, body) {
|
||||||
const method = t.objectMethod("method", t.identifier("value"), params, body);
|
return t.objectMethod(
|
||||||
method.async = !!async;
|
"method",
|
||||||
method.generator = !!generator;
|
t.identifier(key),
|
||||||
return method;
|
[],
|
||||||
|
t.blockStatement(body),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function takeDecorators(node) {
|
function takeDecorators(node) {
|
||||||
@ -74,13 +77,20 @@ function extractElementDescriptor(/* this: File, */ classRef, superRef, path) {
|
|||||||
prop("decorators", takeDecorators(node)),
|
prop("decorators", takeDecorators(node)),
|
||||||
prop("static", node.static && t.booleanLiteral(true)),
|
prop("static", node.static && t.booleanLiteral(true)),
|
||||||
prop("key", getKey(node)),
|
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);
|
].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();
|
path.remove();
|
||||||
|
|
||||||
return t.objectExpression(properties);
|
return t.objectExpression(properties);
|
||||||
|
|||||||
@ -1653,10 +1653,6 @@ helpers.decorate = helper("7.1.5")`
|
|||||||
configurable: true,
|
configurable: true,
|
||||||
enumerable: false,
|
enumerable: false,
|
||||||
};
|
};
|
||||||
Object.defineProperty(def.value, "name", {
|
|
||||||
value: typeof key === "symbol" ? "" : key,
|
|
||||||
configurable: true,
|
|
||||||
});
|
|
||||||
} else if (def.kind === "get") {
|
} else if (def.kind === "get") {
|
||||||
descriptor = { get: def.value, configurable: true, enumerable: false };
|
descriptor = { get: def.value, configurable: true, enumerable: false };
|
||||||
} else if (def.kind === "set") {
|
} else if (def.kind === "set") {
|
||||||
|
|||||||
@ -13,19 +13,15 @@ let Foo = babelHelpers.decorate([_ => desc = _], function (_initialize) {
|
|||||||
d: [{
|
d: [{
|
||||||
kind: "method",
|
kind: "method",
|
||||||
key: getKey(),
|
key: getKey(),
|
||||||
|
value: function () {
|
||||||
value() {
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
}, {
|
}, {
|
||||||
kind: "method",
|
kind: "method",
|
||||||
key: getKey(),
|
key: getKey(),
|
||||||
|
value: function () {
|
||||||
value() {
|
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
}]
|
}]
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|||||||
@ -13,19 +13,15 @@ let Foo = babelHelpers.decorate([_ => desc = _], function (_initialize) {
|
|||||||
d: [{
|
d: [{
|
||||||
kind: "method",
|
kind: "method",
|
||||||
key: getKeyI(),
|
key: getKeyI(),
|
||||||
|
value: function () {
|
||||||
value() {
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
}, {
|
}, {
|
||||||
kind: "method",
|
kind: "method",
|
||||||
key: getKeyJ(),
|
key: getKeyJ(),
|
||||||
|
value: function () {
|
||||||
value() {
|
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
}]
|
}]
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|||||||
13
packages/babel-plugin-proposal-decorators/test/fixtures/misc/method-name-not-shadow/exec.js
vendored
Normal file
13
packages/babel-plugin-proposal-decorators/test/fixtures/misc/method-name-not-shadow/exec.js
vendored
Normal file
@ -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");
|
||||||
8
packages/babel-plugin-proposal-decorators/test/fixtures/misc/method-name-not-shadow/input.js
vendored
Normal file
8
packages/babel-plugin-proposal-decorators/test/fixtures/misc/method-name-not-shadow/input.js
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
var method = 1;
|
||||||
|
|
||||||
|
@decorator
|
||||||
|
class Foo {
|
||||||
|
method() {
|
||||||
|
return method;
|
||||||
|
}
|
||||||
|
}
|
||||||
22
packages/babel-plugin-proposal-decorators/test/fixtures/misc/method-name-not-shadow/output.js
vendored
Normal file
22
packages/babel-plugin-proposal-decorators/test/fixtures/misc/method-name-not-shadow/output.js
vendored
Normal file
@ -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;
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
});
|
||||||
@ -14,9 +14,7 @@ let A = babelHelpers.decorate([dec(a, b, ...c)], function (_initialize) {
|
|||||||
kind: "method",
|
kind: "method",
|
||||||
decorators: [dec(a, b, ...c)],
|
decorators: [dec(a, b, ...c)],
|
||||||
key: "method",
|
key: "method",
|
||||||
|
value: function method() {}
|
||||||
value() {}
|
|
||||||
|
|
||||||
}]
|
}]
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|||||||
@ -13,21 +13,15 @@ let Foo = babelHelpers.decorate([decorator], function (_initialize) {
|
|||||||
d: [{
|
d: [{
|
||||||
kind: "method",
|
kind: "method",
|
||||||
key: "f1",
|
key: "f1",
|
||||||
|
value: async function f1() {}
|
||||||
async value() {}
|
|
||||||
|
|
||||||
}, {
|
}, {
|
||||||
kind: "method",
|
kind: "method",
|
||||||
key: "f2",
|
key: "f2",
|
||||||
|
value: function* f2() {}
|
||||||
*value() {}
|
|
||||||
|
|
||||||
}, {
|
}, {
|
||||||
kind: "method",
|
kind: "method",
|
||||||
key: "f3",
|
key: "f3",
|
||||||
|
value: async function* f3() {}
|
||||||
async *value() {}
|
|
||||||
|
|
||||||
}]
|
}]
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|||||||
@ -14,9 +14,7 @@
|
|||||||
d: [{
|
d: [{
|
||||||
kind: "method",
|
kind: "method",
|
||||||
key: "method",
|
key: "method",
|
||||||
|
value: function method() {}
|
||||||
value() {}
|
|
||||||
|
|
||||||
}]
|
}]
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
@ -38,9 +36,7 @@
|
|||||||
d: [{
|
d: [{
|
||||||
kind: "method",
|
kind: "method",
|
||||||
key: "method",
|
key: "method",
|
||||||
|
value: function method() {}
|
||||||
value() {}
|
|
||||||
|
|
||||||
}]
|
}]
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user