5

I'm writting my own ES6 parser. But I don't understand what CoverInitializedName is in ObjectLiteral.

In the section about this in the ECMA-2015 ObjectLiteral spec I see

PropertyDefinition[Yield] :
    IdentifierReference[?Yield]
    CoverInitializedName[?Yield] <-- this is what I dont understand
    PropertyName[?Yield] : AssignmentExpression[In, ?Yield]
    MethodDefinition[?Yield]

Then I look up the definition of CoverInitializedName.

CoverInitializedName[Yield] :
    IdentifierReference[?Yield] Initializer[In, ?Yield]

IdentifierReference[Yield] :
    Identifier
    [~Yield] yield

Initializer[In, Yield] :
    = AssignmentExpression[?In, ?Yield]

Initializer starts with = sign.

Which means I can assign property using assign operator like this.

let o = { prop = value };

If I execute this code it will throw SyntaxError: Invalid shorthand property initializer

I confused and look in the MDN Object initializer docs. There is no such thing. So what is this CoverInitializedName?

[EDIT]

loganfsmyth's answer was

({ prop = value } = {}); // valid destructuring

In this script, the left-hand side { prop = value } is not an ObjectLiteral. Which is ObjectBindingPattern assigning default value 13.3.3 Destructuring Binding Patterns. I think ObjectLiteral is rValue isn't it? So my question remains: what is CoverInitializedName in ObjectLiteral? Or did I misunderstand something?

broomba
  • 109
  • 7
jeefo
  • 164
  • 1
  • 12
  • 1
    maybe related: [Why is `(foo) = "bar"` legal in JavaScript?](https://stackoverflow.com/q/43969489/1048572) – Bergi Aug 21 '19 at 07:53

1 Answers1

7

You are right that let o = { prop = value }; is a syntax error. The key thing to take into account however is that there are other cases where it is allowed, depending on the context. For instance

({ prop = value }); // syntax error
({ prop = value } = {}); // valid destructuring

Since you cannot know whether prop = value is allowed until you finish parsing the object and reach the =, the CoverInitializedName rule is required to parse this code. If you look further down in the section you linked, you'll see:

NOTE 3: 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.

which attempts to answer just the question you are asking.

In the case of an Object literal, like the snippet you posted, and the syntax error case I posted, the early error that applies is 12.2.6.1 Static Semantics: Early Errors which states

PropertyDefinition : CoverInitializedName

  Always throw a Syntax Error if code matches this production.

whereas ({ prop = value} = {}) will parse successfully based on the grammar defined in 12.14.5 Destructuring Assignment which has

AssignmentProperty[Yield] : 
  IdentifierReference[?Yield] Initializer[In,?Yield]opt
  PropertyName : AssignmentElement[?Yield]

which does allow for prop = value.

loganfsmyth
  • 156,129
  • 30
  • 331
  • 251
  • Yesderday I flagged this accepted right answer. But this morning I wake up and remember something. Left hand side { prop = value } is not ObjectLiteral. Which is ObjectBindingPattern [13.3.3 Destructuring Binding Patterns](https://www.ecma-international.org/ecma-262/6.0/#sec-destructuring-binding-patterns). ObjectLiteral is rvalue is not it? – jeefo Aug 22 '19 at 10:01
  • 1
    @jeefo If you look at the main grammar for an expression starting from `Expression` and drilling down, you'll find that ObjectLiteral is mentioned, but destructuring is never mentioned. That is because you don't know whether something is an rvalue or destructuring until after you've already parsed it. If you look at https://www.ecma-international.org/ecma-262/6.0/#sec-destructuring-assignment, it states "In certain circumstances when processing the production [...] the following grammar is used to refine the interpretation". That is the part that applies `AssignmentPattern`. That applies after – loganfsmyth Aug 22 '19 at 15:33
  • My english is bad or what? I don't know... Still confusing and no clarity about CoverInitializedName in ObjectLiteral. But anyway thank you so much. I'm greatly appreciated for try help me. – jeefo Aug 22 '19 at 20:05
  • 1
    The main thing is that `ObjectLiteral` is the starting place and has to cover all the possible token combinations, because until you find the `=` after it, you don't know if it is supposed to be an object or destructuring, and you can't go back afterward and re-parse again because that requires rewinding the whole parser, or unbounded lookahead. The `ObjectLiteral` grammar only becomes a real JS object when it is used in a place in the program where it makes sense to declare an object. – loganfsmyth Aug 22 '19 at 20:13
  • I got it. It is like `for (variable in object)` or `for (variable of object)` or even it can be for statemant too. Until I find what is next and refine things and decide which expression or statement right? Same as like `CoverParenthesizedExpressionAndArrowParameterList`. Thank you. – jeefo Aug 24 '19 at 08:37
  • 1
    The comparison to arrow functions is definitely accurate. The `for` case I wouldn't clasify that way though. Finding `of` vs `in` doesn't change what was allowed to come before it, so you can still fully parse `variable` beforehand reading `of`/`in`. – loganfsmyth Aug 24 '19 at 18:19