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

ES6 feature: Let and Const Declaration #1065

Closed
ariya opened this Issue Feb 18, 2015 · 10 comments

Comments

Projects
None yet
3 participants
@ariya
Contributor

ariya commented Feb 18, 2015

Syntax:

Per Rev 32 (Feb 2, 2015) of the draft spec, the relevant grammar is on Section 13.2.1 on Let and Const Declarations:

LexicalDeclaration[In, Yield] :
  LetOrConst BindingList[?In, ?Yield] ;

LetOrConst :
  let
  const

BindingList[In, Yield] :
  LexicalBinding[?In, ?Yield]
  BindingList[?In, ?Yield] , LexicalBinding[?In, ?Yield]

LexicalBinding[In, Yield] :
  BindingIdentifier[?Yield] Initializer[?In, ?Yield]opt
  BindingPattern[?Yield] Initializer[?In, ?Yield]

Referred to by:

Declaration:

Declaration[Yield] :
  HoistableDeclaration _[?Yield]
  ClassDeclaration[?Yield]
  LexicalDeclaration[In, ?Yield]

StatementListItem:

StatementListItem[Yield, Return] :
  Statement[?Yield, ?Return]
  Declaration[?Yield]

Iteration:

for ( LexicalDeclaration[?Yield] Expression[In, ?Yield]opt ; Expression[In, ?Yield]opt ) Statement[?Yield, ?Return]
for ( ForDeclaration[?Yield] in Expression[In, ?Yield] ) Statement[?Yield, ?Return]

whereas:

ForDeclaration[Yield] :
  LetOrConst ForBinding[?Yield]

ForBinding[Yield] :
  BindingIdentifier[?Yield]
  BindingPattern[?Yield]

Early errors:

  • const without initializer: const x; (from Esprima 1.x)
  • for-in with multiple let identifiers: for (let x,y in z){}
  • for-in with multiple const identifiers: for (const x,y in z){}
  • for-in with let initializer: for (let i = 1 in x){}
  • for-in with const initializer: for (const i = 1 in x){}
    • More TBD

Spec:

13.2.1 Let and Const Declarations.

Relevant AST interfaces (from https://github.com/estree/estree):

interface VariableDeclaration <: Declaration {
    type: "VariableDeclaration";
    declarations: [ VariableDeclarator ];
    kind: "var";
}
extend interface VariableDeclaration {
    kind: "var" | "let" | "const";
}

See also

Note that V8 doesn't yet support various early errors for lexical declarations. In the mean time, we may need to use the generic Unexpected token... message for such an error.

@ariya

This comment has been minimized.

Show comment
Hide comment
@ariya

ariya Feb 18, 2015

Contributor

Note that Esprima is always able to parse let and const hitherto (as variable declaration). However, it does not yet have the formalized lexical declaration. Thus, implementing this feature finally allows const to be used in other places (switch case, etc).

Contributor

ariya commented Feb 18, 2015

Note that Esprima is always able to parse let and const hitherto (as variable declaration). However, it does not yet have the formalized lexical declaration. Thus, implementing this feature finally allows const to be used in other places (switch case, etc).

@ariya ariya self-assigned this Feb 18, 2015

@ariya ariya added this to the 2.1 milestone Feb 18, 2015

ariya added a commit to ariya/esprima that referenced this issue Feb 19, 2015

ariya added a commit that referenced this issue Feb 20, 2015

@ariya ariya added the es6 label Feb 20, 2015

@ariya

This comment has been minimized.

Show comment
Hide comment
@ariya

ariya Feb 21, 2015

Contributor

@ikarienator Just to confirm, there is also this grammar:

for ( [lookahead ∉ {let [}] LeftHandSideExpression[?Yield] in Expression[In, ?Yield] ) Statement[?Yield, ?Return]

Does this mean that the code like for (let i in [1, 2, 3]){} is not valid?

Contributor

ariya commented Feb 21, 2015

@ikarienator Just to confirm, there is also this grammar:

for ( [lookahead ∉ {let [}] LeftHandSideExpression[?Yield] in Expression[In, ?Yield] ) Statement[?Yield, ?Return]

Does this mean that the code like for (let i in [1, 2, 3]){} is not valid?

@ikarienator

This comment has been minimized.

Show comment
Hide comment
@ikarienator

ikarienator Feb 21, 2015

Contributor

That example is valid but does not fall into that production. It falls into:

for ( ForDeclaration[?Yield] in Expression[In, ?Yield] ) Statement[?Yield, ?Return]

The lookahead is for disambiguous.
Note that the lookahead is actually of two tokens let and [.

Contributor

ikarienator commented Feb 21, 2015

That example is valid but does not fall into that production. It falls into:

for ( ForDeclaration[?Yield] in Expression[In, ?Yield] ) Statement[?Yield, ?Return]

The lookahead is for disambiguous.
Note that the lookahead is actually of two tokens let and [.

@ariya

This comment has been minimized.

Show comment
Hide comment
@ariya

ariya Feb 21, 2015

Contributor

Ah you're right. And technically it's not even a LexicalDeclaration because ForDeclaration only permits one binding, not multiple.

Contributor

ariya commented Feb 21, 2015

Ah you're right. And technically it's not even a LexicalDeclaration because ForDeclaration only permits one binding, not multiple.

ariya added a commit to ariya/esprima that referenced this issue Feb 22, 2015

Formalize lexical declaration.
This is mostly renaming so that the terms are aligned with the spec:
  ConstLetDeclaration -> LexicalDeclaration
  SourceElement -> StatementListItem
  sourceElement -> statement, sourceElements -> body

Refs #1065

ariya added a commit to ariya/esprima that referenced this issue Feb 22, 2015

Handle ForStatement and ForInStatement with lexical declaration.
Also, to make it explicit, constructing a lexical declaration (const or
let) is separated from the common variable declaration (var).

Refs #1065
@ariya

This comment has been minimized.

Show comment
Hide comment
@ariya

ariya Feb 22, 2015

Contributor

How about for (const i in x) {}? Not sure how valid it should be, using the const there is a bit unnatural.

Contributor

ariya commented Feb 22, 2015

How about for (const i in x) {}? Not sure how valid it should be, using the const there is a bit unnatural.

@ikarienator

This comment has been minimized.

Show comment
Hide comment
@ikarienator

ikarienator Feb 22, 2015

Contributor

Weirdly enough, it is allowed. The semantics is that it can only be assigned once. I think the spec should clarify it more on in what occasion it could be used. https://people.mozilla.org/~jorendorff/es6-draft.html#sec-for-statement-runtime-semantics-labelledevaluation

Contributor

ikarienator commented Feb 22, 2015

Weirdly enough, it is allowed. The semantics is that it can only be assigned once. I think the spec should clarify it more on in what occasion it could be used. https://people.mozilla.org/~jorendorff/es6-draft.html#sec-for-statement-runtime-semantics-labelledevaluation

@ariya

This comment has been minimized.

Show comment
Hide comment
@ariya

ariya Feb 22, 2015

Contributor

Weirdly enough, it is allowed.

Let's keep it invalid for now, until there is a better clarification.

Now with that, please review this PR #1076 @ikarienator 😉

Contributor

ariya commented Feb 22, 2015

Weirdly enough, it is allowed.

Let's keep it invalid for now, until there is a better clarification.

Now with that, please review this PR #1076 @ikarienator 😉

@michaelficarra

This comment has been minimized.

Show comment
Hide comment
@michaelficarra

michaelficarra Feb 22, 2015

Contributor

No clarification needed. It should definitely be allowed.

Contributor

michaelficarra commented Feb 22, 2015

No clarification needed. It should definitely be allowed.

@ikarienator

This comment has been minimized.

Show comment
Hide comment
@ikarienator

ikarienator Feb 22, 2015

Contributor

I meant the clarification on the use case. The definition is clear.
On Sun, Feb 22, 2015 at 10:28 Michael Ficarra notifications@github.com
wrote:

No classification needed. It should definitely be allowed.


Reply to this email directly or view it on GitHub
#1065 (comment).

Contributor

ikarienator commented Feb 22, 2015

I meant the clarification on the use case. The definition is clear.
On Sun, Feb 22, 2015 at 10:28 Michael Ficarra notifications@github.com
wrote:

No classification needed. It should definitely be allowed.


Reply to this email directly or view it on GitHub
#1065 (comment).

ariya added a commit to ariya/esprima that referenced this issue Feb 23, 2015

ariya added a commit to ariya/esprima that referenced this issue Feb 24, 2015

Formalize lexical declaration.
This is mostly renaming so that the terms are aligned with the spec:
  ConstLetDeclaration -> LexicalDeclaration
  SourceElement -> StatementListItem
  sourceElement -> statement, sourceElements -> body

Refs #1065

ariya added a commit to ariya/esprima that referenced this issue Feb 24, 2015

Handle ForStatement and ForInStatement with lexical declaration.
Also, to make it explicit, constructing a lexical declaration (const or
let) is separated from the common variable declaration (var).

Refs #1065

ariya added a commit to ariya/esprima that referenced this issue Feb 24, 2015

ariya added a commit to ariya/esprima that referenced this issue Mar 5, 2015

@ariya

This comment has been minimized.

Show comment
Hide comment
@ariya

ariya Mar 5, 2015

Contributor

Tasks in this ticket have been implemented. Further enhancements and more early errors will be filed separately.

Contributor

ariya commented Mar 5, 2015

Tasks in this ticket have been implemented. Further enhancements and more early errors will be filed separately.

@ariya ariya closed this Mar 5, 2015

@mikesherov mikesherov referenced this issue Mar 7, 2015

Closed

ES6 Main Tracking Issue #1099

25 of 25 tasks complete
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment