diff --git a/espree.js b/espree.js index 7965f9b3..3ce5a43e 100644 --- a/espree.js +++ b/espree.js @@ -353,6 +353,7 @@ acorn.plugins.espree = function(instance) { instance.parseObj = function(isPattern, refShorthandDefaultPos) { var node = this.startNode(), first = true, + hasRestProperty = false, propHash = {}; node.properties = []; this.next(); @@ -362,6 +363,9 @@ acorn.plugins.espree = function(instance) { this.expect(tt.comma); if (this.afterTrailingComma(tt.braceR)) { + if (hasRestProperty) { + this.raise(node.properties[node.properties.length - 1].end, "Unexpected trailing comma after rest property"); + } break; } @@ -378,6 +382,7 @@ acorn.plugins.espree = function(instance) { if (extra.ecmaFeatures.experimentalObjectRestSpread && this.type === tt.ellipsis) { if (isPattern) { prop = this.parseObjectRest(); + hasRestProperty = true; } else { prop = this.parseSpread(); prop.type = "ExperimentalSpreadProperty"; diff --git a/tests/fixtures/ecma-features/experimentalObjectRestSpread/invalid-rest-trailing-comma.result.js b/tests/fixtures/ecma-features/experimentalObjectRestSpread/invalid-rest-trailing-comma.result.js new file mode 100644 index 00000000..741ae54b --- /dev/null +++ b/tests/fixtures/ecma-features/experimentalObjectRestSpread/invalid-rest-trailing-comma.result.js @@ -0,0 +1,6 @@ +module.exports = { + index: 16, + lineNumber: 1, + column: 17, + message: "Unexpected trailing comma after rest property" +}; diff --git a/tests/fixtures/ecma-features/experimentalObjectRestSpread/invalid-rest-trailing-comma.src.js b/tests/fixtures/ecma-features/experimentalObjectRestSpread/invalid-rest-trailing-comma.src.js new file mode 100644 index 00000000..39ef542f --- /dev/null +++ b/tests/fixtures/ecma-features/experimentalObjectRestSpread/invalid-rest-trailing-comma.src.js @@ -0,0 +1 @@ +var { x, y, ...z, } = foo; diff --git a/tests/fixtures/ecma-features/experimentalObjectRestSpread/spread-trailing-comma.result.js b/tests/fixtures/ecma-features/experimentalObjectRestSpread/spread-trailing-comma.result.js new file mode 100644 index 00000000..d0f8b471 --- /dev/null +++ b/tests/fixtures/ecma-features/experimentalObjectRestSpread/spread-trailing-comma.result.js @@ -0,0 +1,449 @@ +module.exports = { + "type": "Program", + "start": 0, + "end": 17, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 17 + } + }, + "range": [ + 0, + 17 + ], + "body": [ + { + "type": "ExpressionStatement", + "start": 0, + "end": 17, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 17 + } + }, + "range": [ + 0, + 17 + ], + "expression": { + "type": "ObjectExpression", + "start": 1, + "end": 16, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 16 + } + }, + "range": [ + 1, + 16 + ], + "properties": [ + { + "type": "Property", + "start": 3, + "end": 4, + "loc": { + "start": { + "line": 1, + "column": 3 + }, + "end": { + "line": 1, + "column": 4 + } + }, + "range": [ + 3, + 4 + ], + "method": false, + "shorthand": true, + "computed": false, + "key": { + "type": "Identifier", + "start": 3, + "end": 4, + "loc": { + "start": { + "line": 1, + "column": 3 + }, + "end": { + "line": 1, + "column": 4 + } + }, + "range": [ + 3, + 4 + ], + "name": "a" + }, + "kind": "init", + "value": { + "type": "Identifier", + "start": 3, + "end": 4, + "loc": { + "start": { + "line": 1, + "column": 3 + }, + "end": { + "line": 1, + "column": 4 + } + }, + "range": [ + 3, + 4 + ], + "name": "a" + } + }, + { + "type": "Property", + "start": 6, + "end": 7, + "loc": { + "start": { + "line": 1, + "column": 6 + }, + "end": { + "line": 1, + "column": 7 + } + }, + "range": [ + 6, + 7 + ], + "method": false, + "shorthand": true, + "computed": false, + "key": { + "type": "Identifier", + "start": 6, + "end": 7, + "loc": { + "start": { + "line": 1, + "column": 6 + }, + "end": { + "line": 1, + "column": 7 + } + }, + "range": [ + 6, + 7 + ], + "name": "b" + }, + "kind": "init", + "value": { + "type": "Identifier", + "start": 6, + "end": 7, + "loc": { + "start": { + "line": 1, + "column": 6 + }, + "end": { + "line": 1, + "column": 7 + } + }, + "range": [ + 6, + 7 + ], + "name": "b" + } + }, + { + "type": "ExperimentalSpreadProperty", + "start": 9, + "end": 13, + "loc": { + "start": { + "line": 1, + "column": 9 + }, + "end": { + "line": 1, + "column": 13 + } + }, + "range": [ + 9, + 13 + ], + "argument": { + "type": "Identifier", + "start": 12, + "end": 13, + "loc": { + "start": { + "line": 1, + "column": 12 + }, + "end": { + "line": 1, + "column": 13 + } + }, + "range": [ + 12, + 13 + ], + "name": "c" + } + } + ] + } + } + ], + "sourceType": "script", + "tokens": [ + { + "type": "Punctuator", + "value": "(", + "start": 0, + "end": 1, + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 1 + } + }, + "range": [ + 0, + 1 + ] + }, + { + "type": "Punctuator", + "value": "{", + "start": 1, + "end": 2, + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 2 + } + }, + "range": [ + 1, + 2 + ] + }, + { + "type": "Identifier", + "value": "a", + "start": 3, + "end": 4, + "loc": { + "start": { + "line": 1, + "column": 3 + }, + "end": { + "line": 1, + "column": 4 + } + }, + "range": [ + 3, + 4 + ] + }, + { + "type": "Punctuator", + "value": ",", + "start": 4, + "end": 5, + "loc": { + "start": { + "line": 1, + "column": 4 + }, + "end": { + "line": 1, + "column": 5 + } + }, + "range": [ + 4, + 5 + ] + }, + { + "type": "Identifier", + "value": "b", + "start": 6, + "end": 7, + "loc": { + "start": { + "line": 1, + "column": 6 + }, + "end": { + "line": 1, + "column": 7 + } + }, + "range": [ + 6, + 7 + ] + }, + { + "type": "Punctuator", + "value": ",", + "start": 7, + "end": 8, + "loc": { + "start": { + "line": 1, + "column": 7 + }, + "end": { + "line": 1, + "column": 8 + } + }, + "range": [ + 7, + 8 + ] + }, + { + "type": "Punctuator", + "value": "...", + "start": 9, + "end": 12, + "loc": { + "start": { + "line": 1, + "column": 9 + }, + "end": { + "line": 1, + "column": 12 + } + }, + "range": [ + 9, + 12 + ] + }, + { + "type": "Identifier", + "value": "c", + "start": 12, + "end": 13, + "loc": { + "start": { + "line": 1, + "column": 12 + }, + "end": { + "line": 1, + "column": 13 + } + }, + "range": [ + 12, + 13 + ] + }, + { + "type": "Punctuator", + "value": ",", + "start": 13, + "end": 14, + "loc": { + "start": { + "line": 1, + "column": 13 + }, + "end": { + "line": 1, + "column": 14 + } + }, + "range": [ + 13, + 14 + ] + }, + { + "type": "Punctuator", + "value": "}", + "start": 15, + "end": 16, + "loc": { + "start": { + "line": 1, + "column": 15 + }, + "end": { + "line": 1, + "column": 16 + } + }, + "range": [ + 15, + 16 + ] + }, + { + "type": "Punctuator", + "value": ")", + "start": 16, + "end": 17, + "loc": { + "start": { + "line": 1, + "column": 16 + }, + "end": { + "line": 1, + "column": 17 + } + }, + "range": [ + 16, + 17 + ] + } + ] +}; diff --git a/tests/fixtures/ecma-features/experimentalObjectRestSpread/spread-trailing-comma.src.js b/tests/fixtures/ecma-features/experimentalObjectRestSpread/spread-trailing-comma.src.js new file mode 100644 index 00000000..a2841df6 --- /dev/null +++ b/tests/fixtures/ecma-features/experimentalObjectRestSpread/spread-trailing-comma.src.js @@ -0,0 +1 @@ +({ a, b, ...c, })