Skip to content
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

"var let" should be allowed in non-strict mode [$15] #149

Closed
DanielRosenwasser opened this issue Jun 10, 2015 · 25 comments
Closed

"var let" should be allowed in non-strict mode [$15] #149

DanielRosenwasser opened this issue Jun 10, 2015 · 25 comments

Comments

@DanielRosenwasser
Copy link

Repro:

var let = 10;

See jquery/esprima#1048

There is a $15 open bounty on this issue. Add to the bounty at Bountysource.

@nzakas
Copy link
Member

nzakas commented Jun 10, 2015

I believe this happens because let token is marked as a keyword, so this check fails:

https://github.com/eslint/espree/blob/master/espree.js#L3596

I think this might be as simple as removing "let" from this statement:

https://github.com/eslint/espree/blob/master/lib/syntax.js#L154

@btmills @xjamundx @FredKSchott do any of you have time to look at fixing this?

@xjamundx
Copy link
Contributor

Early next week if no one claims it first.

@xjamundx
Copy link
Contributor

Assuming var const = 10 should also work?

@DanielRosenwasser
Copy link
Author

@xjamundx no, const is a future reserved word. I can send out a PR. My hesitation in doing so was really due to the issue that this behavior was originally supposed to be for compatibility with the SpiderMonkey AST API.

@DanielRosenwasser
Copy link
Author

Actually, there are some implications to that original suggestion that make this a little more involved:

  • The tokenizer now no longer categorizes let as a keyword even though this may be ideal for most purposes.
  • More places must be checked for let as an identifier. See below.

I'll do some more work on this, but given that I'm largely unfamiliar with the code, I might end up handing this back off to you 😄



13.2.1.1 Static Semantics: Early Errors

LexicalDeclaration : LetOrConst BindingList ;

  • It is a Syntax Error if the BoundNames of BindingList contains "let".

13.6.4.1 Static Semantics: Early Errors

IterationStatement :

for ( ForDeclaration in Expression ) Statement

for ( ForDeclaration of AssignmentExpression ) Statement

  • It is a Syntax Error if the BoundNames of ForDeclaration contains "let".

@nzakas
Copy link
Member

nzakas commented Jun 10, 2015

OK, so probably makes sense to keep let as a keyword and just add an exception that looks for an identifier or let in var declarations outside of loops.

@xjamundx
Copy link
Contributor

xjamundx commented Jul 7, 2015

And by "early next week"....I'll try again in the coming week.

@xjamundx xjamundx self-assigned this Jul 7, 2015
@nzakas
Copy link
Member

nzakas commented Jul 8, 2015

👍

@DanielRosenwasser
Copy link
Author

The thing is that something like let + 100 is valid, so it's not always a keyword.

@nzakas
Copy link
Member

nzakas commented Jul 8, 2015

I wonder if Acorn handles this correctly. Might be useful to see what they're doing.

@xjamundx
Copy link
Contributor

Cool. Will check on how they're doing it!

@xjamundx
Copy link
Contributor

With the latest version of acorn 2.1.1:

> require('./dist/acorn').parse('var let = y', {ecmaVersion: '6'})
SyntaxError: Unexpected token (1:4)
    at Parser.pp.raise (/Users/jamuferguson/dev/acorn/dist/acorn.js:975:13)
    at Parser.pp.unexpected (/Users/jamuferguson/dev/acorn/dist/acorn.js:1524:8)
    at Parser.pp.parseBindingAtom (/Users/jamuferguson/dev/acorn/dist/acorn.js:1164:12)
    at Parser.pp.parseVarId (/Users/jamuferguson/dev/acorn/dist/acorn.js:2041:18)
    at Parser.pp.parseVar (/Users/jamuferguson/dev/acorn/dist/acorn.js:2024:10)
    at Parser.pp.parseVarStatement (/Users/jamuferguson/dev/acorn/dist/acorn.js:1913:8)
    at Parser.pp.parseStatement (/Users/jamuferguson/dev/acorn/dist/acorn.js:1713:19)
    at Parser.pp.parseTopLevel (/Users/jamuferguson/dev/acorn/dist/acorn.js:1653:21)
    at Parser.parse (/Users/jamuferguson/dev/acorn/dist/acorn.js:1623:17)
    at Object.parse (/Users/jamuferguson/dev/acorn/dist/acorn.js:937:44)

@xjamundx
Copy link
Contributor

I sort of gave up this when thinking harder about the complexity. May take another stab if I get motivated today though after looking at some of the other espree isues...

@xjamundx
Copy link
Contributor

Going to throw up a PR with broken tests, just to keep me motivated....

xjamundx pushed a commit to xjamundx/espree that referenced this issue Aug 12, 2015
@nzakas nzakas changed the title "var let" should be allowed in non-strict mode "var let" should be allowed in non-strict mode [$15] Sep 7, 2015
@nzakas nzakas added the bounty label Sep 7, 2015
@nzakas
Copy link
Member

nzakas commented Dec 1, 2015

Acorn issue: acornjs/acorn#359

@DanielRosenwasser
Copy link
Author

As a heads up, this was fixed in esprima.

@michaelficarra
Copy link
Member

I just got bit by this with

(let[a] = b);

This should be valid, but is giving me the error "Parsing error: Unexpected token let".

@nzakas
Copy link
Member

nzakas commented Jan 10, 2016

Yup, it's an upstream issue with Acorn.

@RReverser
Copy link

IIUC, this issue can be closed now.

@mysticatea
Copy link
Member

I confirmed it.

"use strict";

const espree = require("espree");
const ast = espree.parse(
    `var let = 0`,
    {
        ecmaVersion: 6,
        sourceType: "script"
    }
);

console.log(JSON.stringify(ast, null, 4));
{
    "type": "Program",
    "start": 0,
    "end": 11,
    "body": [
        {
            "type": "VariableDeclaration",
            "start": 0,
            "end": 11,
            "declarations": [
                {
                    "type": "VariableDeclarator",
                    "start": 4,
                    "end": 11,
                    "id": {
                        "type": "Identifier",
                        "start": 4,
                        "end": 7,
                        "name": "let"
                    },
                    "init": {
                        "type": "Literal",
                        "start": 10,
                        "end": 11,
                        "value": 0,
                        "raw": "0"
                    }
                }
            ],
            "kind": "var"
        }
    ],
    "sourceType": "script"
}

@michaelficarra
Copy link
Member

@mysticatea how about the program I mentioned?

@RReverser
Copy link

@michaelficarra It works http://astexplorer.net/#/5L9D8euj22. Been fixed in acornjs/acorn@8f46eb5 couple of months ago.

@nzakas
Copy link
Member

nzakas commented Mar 14, 2016

I'll add a test case just to be sure.

@RReverser
Copy link

I guess money goes to @marijnh in such case 😄

nzakas added a commit that referenced this issue Mar 14, 2016
@nzakas
Copy link
Member

nzakas commented Mar 14, 2016

Yup. @marijnh, once this is closed, you can claim the bounty on this issue.

@nzakas nzakas closed this as completed in a2b23ca Mar 14, 2016
nzakas added a commit that referenced this issue Mar 14, 2016
Fix: Ensure 'var let' works (fixes #149)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants