-
Notifications
You must be signed in to change notification settings - Fork 0
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
Add normative changes from January 2023 plenary #4
Conversation
@pzuraq, we should have these changes reviewed by the editors before merging. |
55d6710
to
1ddcce3
Compare
1ddcce3
to
66bf36b
Compare
@@ -28653,9 +28661,9 @@ <h2>Syntax</h2> | |||
`export` ExportFromClause FromClause `;` | |||
`export` NamedExports `;` | |||
`export` VariableStatement[~Yield, +Await] | |||
`export` Declaration[~Yield, +Await] | |||
DecoratorList[~Yield, +Await]? `export` Declaration[~Yield, +Await] |
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 think it would be slightly easier to follow the grammar if it was defined like this:
`export` LexicalDeclaration[~Yield, +Await]
`export` HoistableDeclaration[~Yield, +Await]
`export` ClassDeclaration[~Yield, +Await, +Decorators]
DecoratorList[~Yield, +Await]? `export` ClassDeclaration[~Yield, +Await, ~Decorators]
`export` `default` HoistableDeclaration[~Yield, +Await, +Default]
`export` `default` ClassDeclaration[~Yield, +Await, +Decorators, +Default]
DecoratorList[~Yield, +Await]? `export` `default` ClassDeclaration[~Yield, +Await, +Decorators, ~Default]
`export` `default` [lookahead ∉ { `function`, `async` [no LineTerminator here] `function`, `class`, `@` }] AssignmentExpression[+In, ~Yield, +Await] `;`
because the grammar rules are in a single place and you don't have to read both the grammar and the syntactic early errors. However, the end result is effectively the same so avoiding the new production parameter as you proposed is also ok 👍
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 considered that, and that was what I'd implemented originally in https://github.com/tc39/proposal-decorators/pull/95/files. The early error seemed a little easier to reason over given that a Decorators
parameter doesn't go very deep.
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.
There's also a bug in esmeta
regarding multiple constraints on an RHS as would be needed here. That bug has since been fixed, but hasn't been released yet. I think there's still some work to go on the decorators PR before it will pass esmeta
anyways, so it doesn't really matter too much either way.
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 think I would prefer to have a new UndecoratedClassDeclaration
nonterminal which derives what ClassDeclaration
currently does in ecma262, and then have ClassDeclaration
derive DecoratorList? UndecoratedClassDeclaration
. Then you can use UndecoratedClassDeclaration
here, no parameters or early errors necessary.
Still, that's an editorial change which can be made later. This change is correct as-is. Only reason to do it now is if it would cause TS or Babel to use a different representation in their ASTs; I know sometimes people like to have the AST shapes stick close to the spec (though this seems like a case where you would not want that).
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 don't know about Babel, but TypeScript won't introduce a new AST node to differentiate. We just store decorators as if they were modifiers now (a change we made in TS 4.9 to support decorators-after-export
syntax), so export
, default
, declare
, abstract
, and decorators all end up in the same bucket. An UndecoratedClassDeclaration
production feels more like a workaround for the grammar, much like cover grammars. I don't expect we would really tie any unique semantics to it, and it might even make handling Function.prototype.toString
a bit more complicated.
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 disagree - using productions which precisely express what you actually want to accept is the normal use of a CFG, and grammar parameters and early errors are the workaround for when that's not practical.
Fair point about Function.prototype.toString
, but I'd have to actually write it out to tell if it will actually be a problem.
@syg, @michaelficarra, @bakkot: Would one of you mind reviewing these changes? I understand the baseline spec in tc39#2417 (which this PR is a diff against) probably needs updating as well, but an editor's review on these individual changes would help so this can be merged into the main PR and unblock microsoft/TypeScript#52582 and babel/babel#15405. |
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.
Couple tiny comments, but LGTM otherwise. Feel free to merge once the ?
and assert
thing are addressed.
1. Let _getter_ be CreateBuiltinFunction(_getterClosure_, 0, *""*, « »). | ||
1. Let _getterClosure_ be a new Abstract Closure with parameter (_obj_) that captures _name_ and performs the following steps when called: | ||
1. If _obj_ is not an Object, throw a *TypeError* exception. | ||
1. If _name_ is either a String or a Symbol, return ? Get(_obj_, _name_). |
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.
The change to accept Symbols looks good, but just to confirm my understanding, that's a bugfix unrelated to the normative changes presented in committee, right?
(I have no problem with it going in with this PR, I just want to make sure I understand why it's 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.
Yes, its a bugfix. Without it, we'd try to do a PrivateGet
using a symbol and not a Private Name, since name is already declared to be a String, Symbol, or Private Name in the AO.
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 have no problem with it going in with this PR, I just want to make sure I understand why it's here.)
It's a bit of a drive-by bugfix since I needed to rewrite the algorithm steps for both get
and set
anyways and noticed the oversight.
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.
Yes, its a bugfix. Without it, we'd try to do a
PrivateGet
using a symbol and not a Private Name, since name is already declared to be a String, Symbol, or Private Name in the AO.
Correction: name could already be a String, Symbol, or Private Name per the name argument to the CreateDecoratorContextObject
AO.
<emu-alg> | ||
1. Return the result of evaluating |Declaration|. | ||
1. If |DecoratorList?| is present, then |
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. If |DecoratorList?| is present, then | |
1. If |DecoratorList| is present, then |
I personally am neutral on whether the ?
should be included in general, but right now the prevailing style is that it is not. (See for example ForLoopEvaluation.)
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 can change that, but there are other cases of |DecoratorList?|
in the main PR we'll need to address at some point as well.
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.
Feel free to leave this as-is and address it as part of the main PR if you'd prefer, then. Either way.
1. Return the result of evaluating |Declaration|. | ||
1. If |DecoratorList?| is present, then | ||
1. Assert: |Declaration| is a |ClassDeclaration|. | ||
1. Let _decorators_ be ? DecoratorListEvaluation of |DecoratorList|. |
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.
Might be worth adding an assert here that |ClassDeclaration| does not have its own |DecoratorList| (and in the export default
case as well, of course).
It's prevented by the early errors, but not by the mere structure of the nonterminals, so if you haven't noticed the early errors it seems like this is just discarding that |DecoratorList|.
@@ -28653,9 +28661,9 @@ <h2>Syntax</h2> | |||
`export` ExportFromClause FromClause `;` | |||
`export` NamedExports `;` | |||
`export` VariableStatement[~Yield, +Await] | |||
`export` Declaration[~Yield, +Await] | |||
DecoratorList[~Yield, +Await]? `export` Declaration[~Yield, +Await] |
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 think I would prefer to have a new UndecoratedClassDeclaration
nonterminal which derives what ClassDeclaration
currently does in ecma262, and then have ClassDeclaration
derive DecoratorList? UndecoratedClassDeclaration
. Then you can use UndecoratedClassDeclaration
here, no parameters or early errors necessary.
Still, that's an editorial change which can be made later. This change is correct as-is. Only reason to do it now is if it would cause TS or Babel to use a different representation in their ASTs; I know sometimes people like to have the AST shapes stick close to the spec (though this seems like a case where you would not want that).
Yes, thanks again for taking this on @rbuckton, super appreciated! |
This adds the normative changes from the January 2023 plenary:
export
export
orexport default
context.access.get.call(obj)
->context.access.get(obj)
context.access.set.call(obj, value)
->context.access.set(obj, value)
context.access.has(obj)
Rather than using a production parameter like, this instead uses early errors to ensure a decorator list prior to
export
is only allowed for class declarations, and to ensure you do not have decorators both before and afterexport
/export default
.