Skip to content

Commit

Permalink
fix wrong early errors
Browse files Browse the repository at this point in the history
  • Loading branch information
mysticatea committed Dec 8, 2019
1 parent 0654c72 commit 73e7aa1
Show file tree
Hide file tree
Showing 2 changed files with 178 additions and 22 deletions.
27 changes: 5 additions & 22 deletions acorn/src/lval.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,8 @@ pp.toAssignable = function(node, isBinding, refDestructuringErrors) {

case "MemberExpression":
if (isBinding) this.raise(node.start, "Assigning to rvalue")
if (this.options.ecmaVersion >= 11) {
this.checkOptionalChainingInLVal(node)
if (this.options.ecmaVersion >= 11 && (node.optional || node.shortCircuited)) {
this.raise(node.start, "Optional chaining cannot appear in left-hand side")
}
break

Expand All @@ -87,25 +87,6 @@ pp.toAssignable = function(node, isBinding, refDestructuringErrors) {
return node
}

pp.checkOptionalChainingInLVal = function(node) {
while (node) {
switch (node.type) {
case "CallExpression":
if (node.optional) this.raise(node.start, "Optional chaining cannot appear in left-hand side")
node = node.callee
break

case "MemberExpression":
if (node.optional) this.raise(node.start, "Optional chaining cannot appear in left-hand side")
node = node.object
break

default:
return
}
}
}

// Convert list of expression atoms to binding list.

pp.toAssignableList = function(exprList, isBinding) {
Expand Down Expand Up @@ -226,7 +207,9 @@ pp.checkLVal = function(expr, bindingType = BIND_NONE, checkClashes) {

case "MemberExpression":
if (bindingType) this.raiseRecoverable(expr.start, "Binding member expression")
if (this.options.ecmaVersion >= 11) this.checkOptionalChainingInLVal(expr)
if (this.options.ecmaVersion >= 11 && (expr.optional || expr.shortCircuited)) {
this.raise(expr.start, "Optional chaining cannot appear in left-hand side")
}
break

case "ObjectPattern":
Expand Down
173 changes: 173 additions & 0 deletions test/tests-optional-chaining.js
Original file line number Diff line number Diff line change
Expand Up @@ -888,6 +888,179 @@ test("(obj?.foo)`template`", {
],
"sourceType": "script"
}, { ecmaVersion: 11 })
test("(obj?.foo).bar = 0", {
"type": "Program",
"start": 0,
"end": 18,
"body": [
{
"type": "ExpressionStatement",
"start": 0,
"end": 18,
"expression": {
"type": "AssignmentExpression",
"start": 0,
"end": 18,
"operator": "=",
"left": {
"type": "MemberExpression",
"start": 0,
"end": 14,
"object": {
"type": "MemberExpression",
"start": 1,
"end": 9,
"object": {
"type": "Identifier",
"start": 1,
"end": 4,
"name": "obj"
},
"property": {
"type": "Identifier",
"start": 6,
"end": 9,
"name": "foo"
},
"computed": false,
"optional": true,
"shortCircuited": false
},
"property": {
"type": "Identifier",
"start": 11,
"end": 14,
"name": "bar"
},
"computed": false,
"optional": false,
"shortCircuited": false
},
"right": {
"type": "Literal",
"start": 17,
"end": 18,
"value": 0,
"raw": "0"
}
}
}
],
"sourceType": "script"
}, { ecmaVersion: 11 })
test("(obj?.foo).bar++", {
"type": "Program",
"start": 0,
"end": 16,
"body": [
{
"type": "ExpressionStatement",
"start": 0,
"end": 16,
"expression": {
"type": "UpdateExpression",
"start": 0,
"end": 16,
"operator": "++",
"prefix": false,
"argument": {
"type": "MemberExpression",
"start": 0,
"end": 14,
"object": {
"type": "MemberExpression",
"start": 1,
"end": 9,
"object": {
"type": "Identifier",
"start": 1,
"end": 4,
"name": "obj"
},
"property": {
"type": "Identifier",
"start": 6,
"end": 9,
"name": "foo"
},
"computed": false,
"optional": true,
"shortCircuited": false
},
"property": {
"type": "Identifier",
"start": 11,
"end": 14,
"name": "bar"
},
"computed": false,
"optional": false,
"shortCircuited": false
}
}
}
],
"sourceType": "script"
}, { ecmaVersion: 11 })
test("for ((obj?.foo).bar of []);", {
"type": "Program",
"start": 0,
"end": 27,
"body": [
{
"type": "ForOfStatement",
"start": 0,
"end": 27,
"await": false,
"left": {
"type": "MemberExpression",
"start": 5,
"end": 19,
"object": {
"type": "MemberExpression",
"start": 6,
"end": 14,
"object": {
"type": "Identifier",
"start": 6,
"end": 9,
"name": "obj"
},
"property": {
"type": "Identifier",
"start": 11,
"end": 14,
"name": "foo"
},
"computed": false,
"optional": true,
"shortCircuited": false
},
"property": {
"type": "Identifier",
"start": 16,
"end": 19,
"name": "bar"
},
"computed": false,
"optional": false,
"shortCircuited": false
},
"right": {
"type": "ArrayExpression",
"start": 23,
"end": 25,
"elements": []
},
"body": {
"type": "EmptyStatement",
"start": 26,
"end": 27
}
}
],
"sourceType": "script"
}, { ecmaVersion: 11 })

testFail("obj?.foo", "Unexpected token (1:4)", { ecmaVersion: 10 })
testFail("obj?.[foo]", "Unexpected token (1:4)", { ecmaVersion: 10 })
Expand Down

0 comments on commit 73e7aa1

Please sign in to comment.