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

Fix classNameTDZError in computed prototype methods with class fields #11068

Merged
merged 7 commits into from Feb 12, 2020
48 changes: 26 additions & 22 deletions packages/babel-helper-create-class-features-plugin/src/misc.js
Expand Up @@ -26,25 +26,22 @@ const referenceVisitor = {
},
};

const classFieldDefinitionEvaluationTDZVisitor = traverse.visitors.merge([
{
ReferencedIdentifier(path) {
if (
this.classBinding &&
this.classBinding === path.scope.getBinding(path.node.name)
) {
const classNameTDZError = this.file.addHelper("classNameTDZError");
const throwNode = t.callExpression(classNameTDZError, [
t.stringLiteral(path.node.name),
]);

path.replaceWith(t.sequenceExpression([throwNode, path.node]));
path.skip();
}
},
const classFieldDefinitionEvaluationTDZVisitor = {
ReferencedIdentifier(path) {
if (
this.classBinding &&
this.classBinding === path.scope.getBinding(path.node.name)
) {
const classNameTDZError = this.file.addHelper("classNameTDZError");
const throwNode = t.callExpression(classNameTDZError, [
t.stringLiteral(path.node.name),
]);

path.replaceWith(t.sequenceExpression([throwNode, path.node]));
path.skip();
}
},
environmentVisitor,
sidntrivedi012 marked this conversation as resolved.
Show resolved Hide resolved
]);
};

export function injectInitialization(path, constructor, nodes, renamer) {
if (!nodes.length) return;
Expand Down Expand Up @@ -86,10 +83,17 @@ export function extractComputedKeys(ref, path, computedPaths, file) {
const declarations = [];

for (const computedPath of computedPaths) {
computedPath.traverse(classFieldDefinitionEvaluationTDZVisitor, {
classBinding: path.node.id && path.scope.getBinding(path.node.id.name),
file,
});
if (computedPath.get("key").isReferencedIdentifier()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: can we cache computedPath.get("key")? It is also used in !computedPath.get("key").isConstantExpression() later.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JLHwung Done. PTAL 🙂

classFieldDefinitionEvaluationTDZVisitor.ReferencedIdentifier.call(
computedPath.get("key"),
{
classBinding:
path.node.id && path.scope.getBinding(path.node.id.name),
file,
},
);
}
computedPath.get("key").traverse(classFieldDefinitionEvaluationTDZVisitor);
sidntrivedi012 marked this conversation as resolved.
Show resolved Hide resolved

const computedNode = computedPath.node;
// Make sure computed property names are only evaluated once (upon class definition)
Expand Down
@@ -0,0 +1,6 @@
class Foo {
static nickname = 'Tom';
['HELLO']() {
console.log('>>>>', Foo);
}
}
@@ -0,0 +1,10 @@
{
"plugins": [
[
"proposal-class-properties",
{
"loose": true
sidntrivedi012 marked this conversation as resolved.
Show resolved Hide resolved
}
]
]
}
@@ -0,0 +1,8 @@
class Foo {
['HELLO']() {
console.log('>>>>', Foo);
}

}

Foo.nickname = 'Tom';