-
-
Notifications
You must be signed in to change notification settings - Fork 5.7k
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
Private class methods stage 3 #8654
Private class methods stage 3 #8654
Conversation
Build successful! You can test your changes in the REPL here: https://babeljs.io/repl/build/9484/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great to see this initial milestone! Some initial comments. (Your list of TODOs looks good to me in addition.)
@@ -131,6 +134,28 @@ defineType("ClassPrivateProperty", { | |||
}, | |||
}); | |||
|
|||
defineType("ClassPrivateMethod", { | |||
builder: ["kind", "key", "params", "body", "computed", "static"], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is "computed" needed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe that I put that there because computed
is a field (from classMethodOrDeclareMethodCommon
). Should it not be here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yah, we need to remove it.
packages/babel-generator/test/fixtures/types/ClassBody-MethodDefinition/input.js
Show resolved
Hide resolved
get(member) { | ||
const { map, file } = this; | ||
|
||
return t.callExpression(file.addHelper("classPrivateMethodGet"), [ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How will this handle getters?
2fcfa3a
to
5565a78
Compare
class A {
#method() {}
getMethod() {
return this.#method;
}
}
console.log(new A().getMethod() === new A().getMethod()); Is this |
@nicolo-ribaudo That should be |
5565a78
to
f3b5369
Compare
0204bd5
to
dfd0bb1
Compare
I've made some updates to switch to a One issue I'm still working on is a potential variable name collision that can occur in the following situation (taking from the class Foo {
constructor(status) {
this.status = status;
}
#getStatus() {
return this.status;
}
getFakeStatus(fakeStatus) {
const getStatus = this.#getStatus;
return function () {
return getStatus.call({ status: fakeStatus });
};
}
} In the var getStatus = function getStatus() {
return this.status;
}; ...and will lead to this error:
I'm working on getting this resolved now. My current thinking is to generate a unique name for the function defined in the outer scope that is then referenced elsewhere. Separately, I've noticed in the REPL for my builds that the helper functions are not getting updated with my most recent changes. Not sure if I'm doing something wrong... |
6248bb3
to
ca44ffd
Compare
I've just pushed up a fix for the name collision issue that I described earlier in #8654 (comment) |
2be5258
to
91acdc7
Compare
@nicolo-ribaudo @jridgewell I'm working on the loose implementation currently, but would be good to get some eyes on the re-worked WeakSet implementation I've pushed for spec. It appears as though the issue I mentioned in my earlier comment re: helpers not getting updated in the REPL has resolved itself somehow. On a related note, I am curious what I should be putting as the version here (and how exactly that works). Also, in terms of the tests that I've added, is the current set sufficiently exhaustive for the purpose of this PR (given that the additions should also be passing 262 tests)? |
72cf153
to
fdabc63
Compare
Now that #8130 has landed, I've updated this branch to take those changes into account. I've also added support for loose mode. @nicolo-ribaudo @jridgewell @littledan |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall looks pretty good, but I think that we should throw if privateFields' loose !== privateMethods' loose
throw path.buildCodeFrameError("Class private methods are not enabled."); | ||
} | ||
|
||
if (path.isClassPrivateMethod() && path.node.static) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should also guard agains private accessors.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added!
Wrong button, I didn't mean to approve 😅
packages/babel-plugin-proposal-private-methods/test/fixtures/private-method/exfiltrated/exec.js
Show resolved
Hide resolved
I have private method accessors ready in a separate branch - is it preferred that I combine that with this PR? @nicolo-ribaudo |
0c42842
to
a84882e
Compare
Nope, let's keep this as-is to make it easy to be reviewed. |
} | ||
|
||
if (path.node.static) { | ||
throw new Error( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
path.buildCodeFrameError
} | ||
|
||
if (path.node.kind !== "method") { | ||
throw new Error( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
path.buildCodeFrameError
.
hasFeature(file, FEATURES.fields) && | ||
isLoose(file, FEATURES.privateMethods) !== isLoose(file, FEATURES.fields) | ||
) { | ||
throw new Error( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
path.buildCodeFrameError
// In loose mode, both static and instance fields hare transpiled using a | ||
for (const [ | ||
name, | ||
{ id, static: isStatic, method: isMethod }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: Let's move this inside the for loop instead of making this uglier.
@@ -131,6 +134,28 @@ defineType("ClassPrivateProperty", { | |||
}, | |||
}); | |||
|
|||
defineType("ClassPrivateMethod", { | |||
builder: ["kind", "key", "params", "body", "computed", "static"], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yah, we need to remove it.
Thanks @jridgewell, pushed up changes. |
Thank you very much 🎉 |
https://babeljs.io/repl/build/9484/ doesnt seem to work with private methods |
@deadlyicon The new plugin needs to be added to babel-standalone. Do you want to open a PR? |
I'm just suggesting that this comment #8654 (comment) be changed so it is more clear on how to play with this new feature. I couldn't get it to work. thanks :) |
cc: @rricard @robpalme @littledan @syg