diff --git a/spec.html b/spec.html index ff628e2564..38b668ba70 100644 --- a/spec.html +++ b/spec.html @@ -678,7 +678,7 @@
The syntactic grammar for ECMAScript is given in clauses
When a stream of code points is to be parsed as an ECMAScript |Script| or |Module|, it is first converted to a stream of input elements by repeated application of the lexical grammar; this stream of input elements is then parsed by a single application of the syntactic grammar. The input stream is syntactically in error if the tokens in the stream of input elements cannot be parsed as a single instance of the goal nonterminal (|Script| or |Module|), with no tokens left over.
-When a parse is successful, it constructs a parse tree, a rooted tree structure in which each node is a Parse Node. Each Parse Node is an instance of a symbol in the grammar; it represents a span of the source text that can be derived from that symbol. The root node of the parse tree, representing the whole of the source text, is an instance of the parse's goal symbol. When a Parse Node is an instance of a nonterminal, it is also an instance of some production that has that nonterminal as its left-hand side. Moreover, it has zero or more children, one for each symbol on the production's right-hand side: each child is a Parse Node that is an instance of the corresponding symbol.
+When a parse is successful, it constructs a parse tree, a rooted tree structure in which each node is a Parse Node. Each Parse Node is an instance of a symbol in the grammar; it represents a span of the source text that can be derived from that symbol. The root node of the parse tree, representing the whole of the source text, is an instance of the parse's goal symbol. When a Parse Node is an instance of a nonterminal, it is also an instance of some production that has that nonterminal as its left-hand side. Moreover, it has zero or more children, one for each symbol on the production's right-hand side: each child is a Parse Node that is an instance of the corresponding symbol. A Parse Node's descendants are its children, and their children, and so on.
New Parse Nodes are instantiated for each invocation of the parser and never reused between parses even of identical source text. Parse Nodes are considered the same Parse Node if and only if they represent the same span of source text, are instances of the same grammar symbol, and resulted from the same parser invocation.
Parsing the same String multiple times will lead to different Parse Nodes. For example, consider:
@@ -694,11 +694,12 @@The syntactic grammar as presented in clauses
In certain cases, in order to avoid ambiguities, the syntactic grammar uses generalized productions that permit token sequences that do not form a valid ECMAScript |Script| or |Module|. For example, this technique is used for object literals and object destructuring patterns. In such cases a more restrictive supplemental grammar is provided that further restricts the acceptable token sequences. Typically, an early error rule will then state that, in certain contexts, "_P_ must cover an _N_", where _P_ is a Parse Node (an instance of the generalized production) and _N_ is a nonterminal from the supplemental grammar. This means:
|MethodDefinition| is defined in
In certain contexts, |ObjectLiteral| is used as a cover grammar for a more restricted secondary grammar. The |CoverInitializedName| production is necessary to fully cover these secondary grammars. However, use of this production results in an early Syntax Error in normal contexts where an actual |ObjectLiteral| is expected.
+See the next section for the significance of |CoverInitializedName|.
The List returned by PropertyNameList does not include property names defined using a |ComputedPropertyName|.
+In addition to describing an actual object initializer the |ObjectLiteral| productions are also used as a cover grammar for |ObjectAssignmentPattern| and may be recognized as part of a |CoverParenthesizedExpressionAndArrowParameterList|. When |ObjectLiteral| appears in a context where |ObjectAssignmentPattern| is required the following Early Error rules are not applied. In addition, they are not applied when initially parsing a |CoverParenthesizedExpressionAndArrowParameterList| or |CoverCallExpressionAndAsyncArrowHead|.
This production exists so that |ObjectLiteral| can serve as a cover grammar for |ObjectAssignmentPattern|. It cannot occur in an actual object initializer.
-The List returned by PropertyNameList does not include property names defined using a |ComputedPropertyName|.
+Elsewhere in this specification, there are early error rules that, under certain circumstances, require that a |LeftHandSideExpression| must cover an |AssignmentPattern|. Consequently, |ObjectLiteral| serves as a cover grammar for |ObjectAssignmentPattern|. The |CoverInitializedName| production is necessary to fully cover |AssignmentProperty|, but is not valid within an actual object initializer.
+Specifically, in a context where an actual |ObjectLiteral| is expected, the above early error rule prevents the use of |CoverInitializedName|. But in cases where |ObjectLiteral| is used as a cover grammar, the semantics of "must cover" state that the Parse Nodes within the |ObjectLiteral| are not subject to early error rules, and so |CoverInitializedName| is allowed.
+For example, consider:
+
+ let o = {f = 1};
+
+ `{f = 1}` is parsed as an |ObjectLiteral| with a |CoverInitializedName|, which results in a Syntax Error via this early error rule.
+In contrast, consider:
+
+ ({f = 1} = {f: 2});
+
+ Here, `{f = 1}` is again initially parsed as an |ObjectLiteral| with a |CoverInitializedName|, but since it's the |LeftHandSideExpression| of an |AssignmentExpression|, it must cover an |AssignmentPattern|, so the |ObjectLiteral| and |CoverInitializedName| are not subject to early error rules. Instead, `{f = 1}` is reparsed as an |ObjectAssignmentPattern| with an |AssignmentProperty|, and there is no Syntax Error.