-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
Normative: Add public and private class fields, static class features, private methods & getters/setters #1668
Conversation
This comment has been minimized.
This comment has been minimized.
I’m confused; #1655 should contain all of this - “static class features” were merged back into the main proposal. |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
I've removed the "needs tests" label from this PR and the related ones as the tests are checked into test262. |
@littledan I’m looking for one PR to review for class fields; i see #1655, #1667, and this one. |
Please review this one for the union of all three proposals. |
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 also have a large pile of edits (at https://github.com/jmdyck/ecma262/tree/1668_ed) that I was planning to submit as a PR against this PR's branch, but github isn't letting me create a PR against the Ms2ger/ecma262 repo.
@danieltroger you can’t. |
Per discussion with @caiolima and @littledan at the editor call I've pushed commits addressing my previous three comments, as well as some other commits addressing most of the outstanding comments. As far as I'm aware, all that's left to be done is for @michaelficarra to suggest better wording than "unique", or decide he's fine with the current wording. |
1. If _entry_.[[Kind]] is ~field~ or ~method~, then | ||
1. Return _entry_.[[Value]]. | ||
1. Assert: _P_.[[Kind]] is ~accessor~. | ||
1. If _P_.[[Get]] is *undefined*, throw a *TypeError* exception. |
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.
A normal accessor property returns undefined
when no getter is present; is it intentional (and noticed in plenary/review) that a private accessor without a getter would throw?
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.
That's been the case for the entire lifetime of the proposal, through a number of revisions and nearly four years of discussion. I'd certainly hope it was noticed by reviewers. I noticed, at any rate.
These semantics are what we got consensus on, and are now web reality, so if you'd like to propose different behavior a separate proposal is probably in order.
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.
Fair enough. It could easily change since it's currently an error, but maybe there's no use case for it to do so.
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.
IIRC, this is intentional based on the same design decision we made for throwing TypeError
when a private field is not installed. I remember discussing in plenary about making this SyntaxError
instead, since we already know at compile time that we are trying to apply [[Get]]
for a not defined private getter, but we decided to keep current semantics. My memory might be tricking me, but I think the reason to throw TypeError
is to make this proposal more friendly to a future decorators proposal.
spec.html
Outdated
<h1>DefineMethodProperty ( _key_, _homeObject_, _closure_, _enumerable_ )</h1> | ||
<p>The abstract operation DefineMethodProperty takes arguments _key_ (a property key or Private Name), _homeObject_ (an Object), _closure_ (a function object), and _enumerable_ (a Boolean). It performs the following steps when called:</p> | ||
<emu-alg> | ||
1. Perform SetFunctionName(_closure_, _key_). |
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.
1. Perform SetFunctionName(_closure_, _key_). | |
1. Perform ! SetFunctionName(_closure_, _key_). |
there are a number of places where this AO is called without an appropriate prefix; i can put up a separate PR to fix those if editors are amenable.
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've added it here, but the prefix is not strictly necessary according to the spec's current rules (since it's just Perform
ing, not consuming the value), so I'd prefer not to change the existing sites now and instead just fix them up as part of #1796.
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.
It'd be necessary if it returned abruptly, no?
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.
SetFunctionName
cannot return abruptly.
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.
sure, but i can't know that at the callsite (pending #1796)
spec.html
Outdated
1. Let _newNames_ be a copy of _names_. | ||
1. Append to _newNames_ the elements of PrivateBoundIdentifiers of |ClassBody|. |
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.
1. Let _newNames_ be a copy of _names_. | |
1. Append to _newNames_ the elements of PrivateBoundIdentifiers of |ClassBody|. | |
1. Let _newNames_ be a copy of _names_ with the elements of PrivateBoundIdentifiers of |ClassBody| appended. |
this shorter form is used already in a few places in the spec.
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.
Eh, I think the alias improves readability in this case.
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.
lgtm, modulo question about what happens with [[ClassFieldInitializerName]] is a Private Name.
<emu-note> | ||
<p>For ease of specification, private methods and accessors are included alongside private fields in the [[PrivateElements]] slot of class instances. However, any given object has either all or none of the private methods and accessors defined by a given class. This feature has been designed so that implementations may choose to implement private methods and accessors using a strategy which does not require tracking each method or accessor individually.</p> | ||
<p>For example, an implementation could directly associate instance private methods with their corresponding Private Name and track, for each object, which class constructors have run with that object as their `this` value. Looking up an instance private method on an object then consists of checking that the class constructor which defines the method has been used to initialize the object, then returning the method associated with the Private Name.</p> | ||
<p>This differs from private fields: because field initializers can throw during class instantiation, an individual object may have some proper subset of the private fields of a given class, and so private fields must in general be tracked individually.</p> |
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 note!
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.
Re:
PrivateElement
vsPrivateElement Record
PrivateEnvironment
vsPrivateEnvironment Record
For any given Record 'subtype', we generally (though with lots of exceptions) either consistently refer to it with the Record
suffix, or consistently without.
I've just pushed a commit which fixes these up to all be
As far as I can tell we're actually consistent about referring to these by " |
Looks good.
Yup, my mistake. |
PR also LGTM. Thank you very much for all the work done there! |
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.
Minor changes suggested.
The last few commits fixed some other stuff I found.
Other than that, no complaints.
…, private methods & getters/setters This includes changes from https://tc39.es/proposal-class-fields/. This includes changes from https://tc39.es/proposal-private-methods/. This includes changes from https://tc39.es/proposal-static-class-features/. Co-authored-by: Ms2ger <[email protected]> Co-authored-by: Ujjwal Sharma <[email protected]> Co-authored-by: Caio Lima <[email protected]> Co-authored-by: Michael Dyck <[email protected]> Co-authored-by: Kevin Gibbons <[email protected]> Co-authored-by: Jordan Harband <[email protected]>
This includes changes from https://tc39.es/proposal-static-class-features/.