Skip to content
This repository has been archived by the owner on Sep 8, 2021. It is now read-only.

Stage 3 Editor Specification Review #22

Closed
rbuckton opened this issue Nov 6, 2020 · 19 comments
Closed

Stage 3 Editor Specification Review #22

rbuckton opened this issue Nov 6, 2020 · 19 comments
Assignees
Milestone

Comments

@rbuckton
Copy link
Collaborator

rbuckton commented Nov 6, 2020

This is a placeholder task for Stage 3 Specification Review feedback from an ECMAScript Editor.

@ljharb
Copy link
Member

ljharb commented Nov 6, 2020

just a few early thoughts:

@ljharb
Copy link
Member

ljharb commented Jan 13, 2021

ping @rbuckton there's still a few editorial issues/questions ^

@rbuckton
Copy link
Collaborator Author

Thanks, I'll take a look today.

@rbuckton
Copy link
Collaborator Author

I'll have a PR up shortly for these.

  • Why is IsStatic false on a class static block? it seems like it'd never be called, but i'm not 100% sure.

I think you are correct. We invoke IsStatic in two places:

  • ClassDefinitionEvaluation, but only on the set of methods returned from NonConstructorMethodDefinitions (which will not include static blocks).
  • PrototypePropertyNameList, which is evaluated unconditionally against all class elements, but should short-circuit before IsStatic because PropName of a static block will be ~empty~.

I can remove it since it isn't used.

@rbuckton
Copy link
Collaborator Author

You can find the PR for this feedback in #31.

@syg
Copy link
Contributor

syg commented Jan 14, 2021

@rbuckton
Copy link
Collaborator Author

How would you word this assert? Essentially, the list contains zero or one elements. If I have an Assert, I still need the If (even if worded differently):

1. <ins>Assert: _staticBlocks_ is an empty list or contains a single element.</ins>
2. <ins>If _staticBlocks_ is not an empty list, then</ins>
  ...
  • Where is NewClassStaticBlockEnvironment?

An oversight, I'll add it shortly.

  • F instead of the block is passed to ClassStaticBlockEvaluateBody(F).

Good catch, thanks.

@rbuckton
Copy link
Collaborator Author

Are you describing a note like the one at the top of this section: https://tc39.es/ecma262/#sec-functiondeclarationinstantiation, or a different note entirely?

@rbuckton
Copy link
Collaborator Author

rbuckton commented Jan 14, 2021

I think perhaps you are describing something like this note in FunctionDeclarationInstantiation?

image

As I understand it the rationale behind the extra environment and NOTE in that section has to do with the possibility of parameter initializers performing direct eval that might introduce new bindings. I can add the note, but there are no parameters to a static {} block so there's no opportunity for direct eval to occur within that scope before evaluating the body.

@rbuckton
Copy link
Collaborator Author

@syg - I believe I have addressed your feedback. Please let me know if there's anything I have missed or misunderstood.

@syg
Copy link
Contributor

syg commented Jan 14, 2021

I can add the note, but there are no parameters to a static {} block so there's no opportunity for direct eval to occur within that scope before evaluating the body.

Fair enough, I retract that suggestion.

I believe I have addressed your feedback. Please let me know if there's anything I have missed or misunderstood.

Where are the changes? I don't see an updated render nor commits.

@rbuckton
Copy link
Collaborator Author

See #31. I've addressed both your and @ljharb's feedback in that PR.

@rbuckton
Copy link
Collaborator Author

Closing this per #31. Feel free to comment/reopen if you feel there is additional feedback you feel needs to be addressed prior to possible Stage 3 advancement. Thank you both @ljharb and @syg for your reviews.

@bakkot
Copy link

bakkot commented Jan 15, 2021

Couple last things:

  • The Early Error forbidding await identifiers says "not crossing function or static initialization block boundaries, excluding arrow function boundaries" [emphasis added]. By my reading, that would mean class { static { let x = async () => { await foo(); } } would be illegal, which sounds wrong. I think you want to include arrow function boundaries for this particular error. (Although that's kind of tricky, because of the cover grammar for arrow parameters - should (await) => 0 be legal inside a class static block?)
  • There's a handful of other Early Errors I believe you need.
    • The way I've written those errors, label: { class A { static { label: {} } } } would be legal. (Note the duplicate label.) I assume that's the intent, since it matches how functions work. If you wanted it to be illegal, you'd need other changes.

@rbuckton
Copy link
Collaborator Author

  • The Early Error forbidding await identifiers says "not crossing function or static initialization block boundaries, excluding arrow function boundaries" [emphasis added]. By my reading, that would mean class { static { let x = async () => { await foo(); } } would be illegal, which sounds wrong. I think you want to include arrow function boundaries for this particular error. (Although that's kind of tricky, because of the cover grammar for arrow parameters - should (await) => 0 be legal inside a class static block?)

Agreed, this is tricky to word correctly. The other option might be to parse with [+Await] and forbid AwaitExpression and for-await-of the way that ContinueStatement and BreakStatement are written, but if we add any other [+Await]-specific features in the future we'd be chasing those down.

I plan to look at these today, thanks!

@ptomato
Copy link
Contributor

ptomato commented Jan 15, 2021

  • Why is IsStatic false on a class static block? it seems like it'd never be called, but i'm not 100% sure.

I think you are correct. We invoke IsStatic in two places:

* `ClassDefinitionEvaluation`, but only on the set of methods returned from `NonConstructorMethodDefinitions` (which will not include `static` blocks).

* `PrototypePropertyNameList`, which is evaluated unconditionally against all class elements, but should short-circuit before `IsStatic` because `PropName` of a static block will be `~empty~`.

I can remove it since it isn't used.

I agree with this, but when I was reading the spec text I got confused by ClassStaticBlock not being mentioned in IsStatic until I found this discussion. Maybe add a note similar to the one in "Static Semantics: Contains" saying something like "Static semantic rules using this operation do not consider static initialization blocks" or something like that?

@rbuckton
Copy link
Collaborator Author

I agree with this, but when I was reading the spec text I got confused by ClassStaticBlock not being mentioned in IsStatic until I found this discussion. Maybe add a note similar to the one in "Static Semantics: Contains" saying something like "Static semantic rules using this operation do not consider static initialization blocks" or something like that?

I'll defer to @ljharb on whether to reintroduce it with that wording since it was his recommendation to remove it.

@rbuckton
Copy link
Collaborator Author

rbuckton commented Jan 15, 2021

The reason I had it there in the first place is that we go out of our way to indicate ClassElement: `;` returns false for IsStatic, despite it also never being invoked for that production.

@ljharb
Copy link
Member

ljharb commented Jan 15, 2021

I was fine with removing it if unused, but mainly i was confused to see IsStatic not be “true” for something named “static”.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants