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
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -24382,7 +24382,7 @@ <h1>Runtime Semantics: DecoratorListEvaluation ( ): either a normal completion c | |||||
<h1> | ||||||
CreateDecoratorAccessObject ( | ||||||
_kind_: ~field~, ~method~, ~accessor~, ~getter~, or ~setter~, | ||||||
_name_: a String or Private Name, | ||||||
_name_: either a String, a Symbol, or a Private Name, | ||||||
): an Object | ||||||
</h1> | ||||||
<dl class="header"> | ||||||
|
@@ -24392,20 +24392,27 @@ <h1> | |||||
<emu-alg> | ||||||
1. Let _accessObj_ be OrdinaryObjectCreate(%Object.prototype%). | ||||||
1. If _kind_ is ~field~, ~method~, ~accessor~, or ~getter~, then | ||||||
1. Let _getterClosure_ be a new Abstract Closure with no parameters that captures _name_ and performs the following steps when called: | ||||||
1. Let _o_ be the *this* value. | ||||||
1. If _name_ is a String, return ? Get(_o_, _name_). | ||||||
1. Else, return ? PrivateGet(_name_, _o_). | ||||||
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_). | ||||||
1. Else, return ? PrivateGet(_name_, _obj_). | ||||||
1. Let _getter_ be CreateBuiltinFunction(_getterClosure_, 1, *""*, « »). | ||||||
1. Perform ! CreateDataPropertyOrThrow(_accessObj_, *"get"*, _getter_). | ||||||
1. If _kind_ is ~field~, ~accessor~, or ~setter~, then | ||||||
1. Let _setterClosure_ be a new Abstract Closure with parameters (_value_) that captures _name_ and performs the following steps when called: | ||||||
1. Let _o_ be the *this* value. | ||||||
1. If _name_ is a String, perform ? PrivateSet(_name_, _o_, _value_). | ||||||
1. Else, perform ? Set(_o_, _name_, _value_, *true*). | ||||||
1. Let _setterClosure_ be a new Abstract Closure with parameters (_obj_, _value_) 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, perform ? PrivateSet(_name_, _obj_, _value_). | ||||||
1. Else, perform ? Set(_obj_, _name_, _value_, *true*). | ||||||
rbuckton marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
1. Return *undefined*. | ||||||
1. Let _setter_ be CreateBuiltinFunction(_setterClosure_, 1, *""*, « »). | ||||||
1. Let _setter_ be CreateBuiltinFunction(_setterClosure_, 2, *""*, « »). | ||||||
1. Perform ! CreateDataPropertyOrThrow(_accessObj_, *"set"*, _setter_). | ||||||
1. Let _hasClosure_ 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 ? HasProperty(_obj_, _name_). | ||||||
1. If PrivateElementFind(_obj_, _name_) is not ~empty~, return *true*. | ||||||
1. Return *false*. | ||||||
1. Let _has_ be CreateBuiltinFunction(_hasClosure_, 1, *""*, « »). | ||||||
1. Perform ! CreateDataPropertyOrThrow(_accessObj_, *"has"*, _has_). | ||||||
1. Return _accessObj_. | ||||||
</emu-alg> | ||||||
</emu-clause> | ||||||
|
@@ -25416,15 +25423,16 @@ <h1> | |||||
</emu-clause> | ||||||
|
||||||
<emu-clause id="sec-runtime-semantics-bindingclassdeclarationevaluation" type="sdo"> | ||||||
<h1>Runtime Semantics: BindingClassDeclarationEvaluation ( ): either a normal completion containing a function object or an abrupt completion</h1> | ||||||
<h1> | ||||||
Runtime Semantics: BindingClassDeclarationEvaluation ( | ||||||
_decorators_: a List, | ||||||
): either a normal completion containing a function object or an abrupt completion | ||||||
</h1> | ||||||
<dl class="header"> | ||||||
</dl> | ||||||
<emu-grammar>ClassDeclaration : DecoratorList? `class` BindingIdentifier ClassTail</emu-grammar> | ||||||
<emu-alg> | ||||||
1. Let _className_ be StringValue of |BindingIdentifier|. | ||||||
1. If |DecoratorList?| is present, then | ||||||
1. Let _decorators_ be ? DecoratorListEvaluation of |DecoratorList|. | ||||||
1. Else, let _decorators_ be a new empty List. | ||||||
1. Let _value_ be ? ClassDefinitionEvaluation of |ClassTail| with arguments _className_, _className_, and _decorators_. | ||||||
1. Set _value_.[[SourceText]] to the source text matched by |ClassDeclaration|. | ||||||
1. Let _env_ be the running execution context's LexicalEnvironment. | ||||||
|
@@ -25433,9 +25441,6 @@ <h1>Runtime Semantics: BindingClassDeclarationEvaluation ( ): either a normal co | |||||
</emu-alg> | ||||||
<emu-grammar>ClassDeclaration : DecoratorList? `class` ClassTail</emu-grammar> | ||||||
<emu-alg> | ||||||
1. If |DecoratorList?| is present, then | ||||||
1. Let _decorators_ be ? DecoratorListEvaluation of |DecoratorList|. | ||||||
1. Else, let _decorators_ be a new empty List. | ||||||
1. Let _value_ be ? ClassDefinitionEvaluation of |ClassTail| with arguments *undefined*, *"default"*, and _decorators_. | ||||||
1. Set _value_.[[SourceText]] to the source text matched by |ClassDeclaration|. | ||||||
1. Return _value_. | ||||||
|
@@ -25449,7 +25454,10 @@ <h1>Runtime Semantics: BindingClassDeclarationEvaluation ( ): either a normal co | |||||
<h1>Runtime Semantics: Evaluation</h1> | ||||||
<emu-grammar>ClassDeclaration : DecoratorList? `class` BindingIdentifier ClassTail</emu-grammar> | ||||||
<emu-alg> | ||||||
1. Perform ? BindingClassDeclarationEvaluation of this |ClassDeclaration|. | ||||||
1. If |DecoratorList?| is present, then | ||||||
1. Let _decorators_ be ? DecoratorListEvaluation of |DecoratorList|. | ||||||
1. Else, let _decorators_ be a new empty List. | ||||||
1. Perform ? BindingClassDeclarationEvaluation of this |ClassDeclaration| with argument _decorators_. | ||||||
1. Return ~empty~. | ||||||
</emu-alg> | ||||||
<emu-note> | ||||||
|
@@ -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 commentThe 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 commentThe 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 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There's also a bug in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think I would prefer to have a new 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 commentThe 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- There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 |
||||||
`export` `default` HoistableDeclaration[~Yield, +Await, +Default] | ||||||
`export` `default` ClassDeclaration[~Yield, +Await, +Default] | ||||||
DecoratorList[~Yield, +Await]? `export` `default` ClassDeclaration[~Yield, +Await, +Default] | ||||||
`export` `default` [lookahead ∉ { `function`, `async` [no LineTerminator here] `function`, `class`, `@` }] AssignmentExpression[+In, ~Yield, +Await] `;` | ||||||
|
||||||
ExportFromClause : | ||||||
|
@@ -28691,6 +28699,21 @@ <h1>Static Semantics: Early Errors</h1> | |||||
<emu-note> | ||||||
<p>The above rule means that each ReferencedBindings of |NamedExports| is treated as an |IdentifierReference|.</p> | ||||||
</emu-note> | ||||||
<emu-grammar>ExportDeclaration : DecoratorList? `export` Declaration</emu-grammar> | ||||||
<ul> | ||||||
<li> | ||||||
It is a Syntax Error if |DecoratorList| is present and |Declaration| is not |ClassDeclaration|. | ||||||
</li> | ||||||
<li> | ||||||
It is a Syntax Error if |DecoratorList| is present and |Declaration| is a |ClassDeclaration| and the |DecoratorList| of that |ClassDeclaration| is present. | ||||||
</li> | ||||||
</ul> | ||||||
<emu-grammar>ExportDeclaration : DecoratorList? `export` `default` ClassDeclaration</emu-grammar> | ||||||
<ul> | ||||||
<li> | ||||||
It is a Syntax Error if |DecoratorList| is present and the |DecoratorList| of |ClassDeclaration| is present. | ||||||
</li> | ||||||
</ul> | ||||||
</emu-clause> | ||||||
|
||||||
<emu-clause id="sec-static-semantics-exportedbindings" oldids="sec-module-semantics-static-semantics-exportedbindings,sec-exports-static-semantics-exportedbindings" type="sdo"> | ||||||
|
@@ -29005,17 +29028,26 @@ <h1>Runtime Semantics: Evaluation</h1> | |||||
<emu-alg> | ||||||
1. Return the result of evaluating |VariableStatement|. | ||||||
</emu-alg> | ||||||
<emu-grammar>ExportDeclaration : `export` Declaration</emu-grammar> | ||||||
<emu-grammar>ExportDeclaration : DecoratorList? `export` Declaration</emu-grammar> | ||||||
<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 commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
I personally am neutral on whether the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I can change that, but there are other cases of There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. 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 commentThe 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 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|. |
||||||
1. Perform ? BindingClassDeclarationEvaluation of |ClassDeclaration| with argument _decorators_. | ||||||
1. Return ~empty~. | ||||||
1. Else, | ||||||
1. Return the result of evaluating |Declaration|. | ||||||
</emu-alg> | ||||||
<emu-grammar>ExportDeclaration : `export` `default` HoistableDeclaration</emu-grammar> | ||||||
<emu-alg> | ||||||
1. Return the result of evaluating |HoistableDeclaration|. | ||||||
</emu-alg> | ||||||
<emu-grammar>ExportDeclaration : `export` `default` ClassDeclaration</emu-grammar> | ||||||
<emu-grammar>ExportDeclaration : DecoratorList? `export` `default` ClassDeclaration</emu-grammar> | ||||||
<emu-alg> | ||||||
1. Let _value_ be ? BindingClassDeclarationEvaluation of |ClassDeclaration|. | ||||||
1. If |DecoratorList?| is present, then | ||||||
1. Let _decorators_ be ? DecoratorListEvaluation of |DecoratorList|. | ||||||
1. Else, let _decorators_ be a new empty List. | ||||||
1. Let _value_ be ? BindingClassDeclarationEvaluation of |ClassDeclaration| with argument _decorators_. | ||||||
1. Let _className_ be the sole element of BoundNames of |ClassDeclaration|. | ||||||
1. If _className_ is *"\*default\*"*, then | ||||||
1. Let _env_ be the running execution context's LexicalEnvironment. | ||||||
|
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.
It's a bit of a drive-by bugfix since I needed to rewrite the algorithm steps for both
get
andset
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.
Correction: name could already be a String, Symbol, or Private Name per the name argument to the
CreateDecoratorContextObject
AO.