esprima-dotnet
esprima-dotnet copied to clipboard
Incorrect parse tree during several destructing assignment statements parsing
Input
- DestructuringAssignment.js from examples dir of ANTLR JavaScript grammar.
- Code snippet from http://es6-features.org/#ArrayMatching
var [ a, , b ] = list
[ b, a ] = [ a, b ]
Expected
Parse tree should contain two statements:
{
"Type": "Program",
"Body": [
{
"Type": "VariableDeclaration",
"Declarations": [
{
"Type": "VariableDeclarator",
"Id": {
"Type": "ArrayPattern",
"Elements": [
{
"Type": "Identifier",
"Name": "a",
"Loc": {}
},
null,
{
"Type": "Identifier",
"Name": "b",
"Loc": {}
}
],
"Loc": {}
},
"Init": {
"Type": "Identifier",
"Name": "list",
"Loc": {}
},
"Loc": {}
}
],
"Kind": "var",
"Loc": {}
},
{
"Type": "ExpressionStatement",
"Expression": {
"Left": {
"Type": "ArrayPattern",
"Elements": [
{
"Type": "Identifier",
"Name": "b",
"Loc": {}
},
{
"Type": "Identifier",
"Name": "a",
"Loc": {}
}
],
"Loc": {}
},
"Right": {
"Type": "ArrayExpression",
"Elements": [
{
"Type": "Identifier",
"Name": "a",
"Loc": {}
},
{
"Type": "Identifier",
"Name": "b",
"Loc": {}
}
],
"Loc": {}
},
"Loc": {}
},
"Loc": {}
}
],
"SourceType": "script",
"Loc": {}
}
Just add semicolon ; to the end of the first line to get the correct output:
var [ a, , b ] = list;
[ b, a ] = [ a, b ]
Actual
Code parsed to the following parse tree with nonexistent MemberExpression and only a single declaration:
{
"Type": "Program",
"Body": [
{
"Type": "VariableDeclaration",
"Declarations": [
{
"Type": "VariableDeclarator",
"Id": {
"Type": "ArrayPattern",
"Elements": [
{
"Type": "Identifier",
"Name": "a",
"Loc": {}
},
null,
{
"Type": "Identifier",
"Name": "b",
"Loc": {}
}
],
"Loc": {}
},
"Init": {
"Left": {
"Type": "MemberExpression",
"Object": {
"Type": "Identifier",
"Name": "list",
"Loc": {}
},
"Property": {
"Type": "SequenceExpression",
"Expressions": [
{
"Type": "Identifier",
"Name": "b",
"Loc": {}
},
{
"Type": "Identifier",
"Name": "a",
"Loc": {}
}
],
"Loc": {}
},
"Computed": true,
"Loc": {}
},
"Right": {
"Type": "ArrayExpression",
"Elements": [
{
"Type": "Identifier",
"Name": "a",
"Loc": {}
},
{
"Type": "Identifier",
"Name": "b",
"Loc": {}
}
],
"Loc": {}
},
"Loc": {}
},
"Loc": {}
}
],
"Kind": "var",
"Loc": {}
}
],
"SourceType": "script",
"Loc": {}
}
By the way, I found the same issue exists in the official parser. See demo.
Thanks, at least we won't have to expect it to find the fix there.
I also created an issue in esprima project tracker.
Did some investigation and it seems to me that either this is a non-issue or everyone got it wrong. Both acorn and @babel/parser parse this as a single statement in AstExplorer. According to the output both Firefox and Chrome treat it as a single statement as well (both in legacy and strict mode):
// using octals to make sure we're not in strict mode
var list = [03, 04, 05];
(() => {
var [ a, , b ] = list
[ b, a ] = [ a, b ]
console.log(`a: ${a}`, `b: ${b}`);
})();
(() => {
'use strict';
var [ a, , b ] = list
[ b, a ] = [ a, b ]
console.log(`a: ${a}`, `b: ${b}`);
})();
which logs
a: undefined b: undefined
a: undefined b: undefined
instead of the expected a: 5, b: 3
Am I missing here something or can we close this?
Maybe just close and we can reopen if there's a repro against other parser.