From f521222015936f7a0f5f177c15b0f685d4428c49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hu=C3=A1ng=20J=C3=B9nli=C3=A0ng?= Date: Sat, 30 May 2020 10:14:07 -0400 Subject: [PATCH] fix: add early errors for record and tuple --- .../babel-parser/src/parser/expression.js | 10 +- packages/babel-parser/src/parser/location.js | 2 + .../invalid-record-method/input.js | 7 + .../invalid-record-method/options.json | 3 + .../invalid-record-method/output.json | 146 ++++++++++++++++++ .../invalid-tuple-holes/input.js | 1 + .../invalid-tuple-holes/options.json | 11 ++ .../tuple-trailing-comma/input.js | 1 + .../tuple-trailing-comma/options.json | 3 + .../tuple-trailing-comma/output.json | 35 +++++ 10 files changed, 218 insertions(+), 1 deletion(-) create mode 100644 packages/babel-parser/test/fixtures/experimental/record-and-tuple/invalid-record-method/input.js create mode 100644 packages/babel-parser/test/fixtures/experimental/record-and-tuple/invalid-record-method/options.json create mode 100644 packages/babel-parser/test/fixtures/experimental/record-and-tuple/invalid-record-method/output.json create mode 100644 packages/babel-parser/test/fixtures/experimental/record-and-tuple/invalid-tuple-holes/input.js create mode 100644 packages/babel-parser/test/fixtures/experimental/record-and-tuple/invalid-tuple-holes/options.json create mode 100644 packages/babel-parser/test/fixtures/experimental/record-and-tuple/tuple-trailing-comma/input.js create mode 100644 packages/babel-parser/test/fixtures/experimental/record-and-tuple/tuple-trailing-comma/options.json create mode 100644 packages/babel-parser/test/fixtures/experimental/record-and-tuple/tuple-trailing-comma/output.json diff --git a/packages/babel-parser/src/parser/expression.js b/packages/babel-parser/src/parser/expression.js index 947eccc56a4e..30de1720e35b 100644 --- a/packages/babel-parser/src/parser/expression.js +++ b/packages/babel-parser/src/parser/expression.js @@ -1050,7 +1050,7 @@ export default class ExpressionParser extends LValParser { this.next(); node.elements = this.parseExprList( close, - true, + false, refExpressionErrors, node, ); @@ -1557,6 +1557,14 @@ export default class ExpressionParser extends LValParser { this.checkDuplicatedProto(prop, propHash, refExpressionErrors); } + if ( + isRecord && + prop.type !== "ObjectProperty" && + prop.type !== "SpreadElement" + ) { + this.raise(prop.start, Errors.InvalidRecordProperty); + } + // $FlowIgnore if (prop.shorthand) { this.addExtra(prop, "shorthand", true); diff --git a/packages/babel-parser/src/parser/location.js b/packages/babel-parser/src/parser/location.js index 472fd95f517a..7fe137b0c04a 100644 --- a/packages/babel-parser/src/parser/location.js +++ b/packages/babel-parser/src/parser/location.js @@ -85,6 +85,8 @@ export const Errors = Object.freeze({ InvalidParenthesizedAssignment: "Invalid parenthesized assignment pattern", InvalidPrivateFieldResolution: "Private name #%0 is not defined", InvalidPropertyBindingPattern: "Binding member expression", + InvalidRecordProperty: + "Only properties and spread elements are allowed in record definitions", InvalidRestAssignmentPattern: "Invalid rest operator's argument", LabelRedeclaration: "Label '%0' is already declared", LetInLexicalBinding: diff --git a/packages/babel-parser/test/fixtures/experimental/record-and-tuple/invalid-record-method/input.js b/packages/babel-parser/test/fixtures/experimental/record-and-tuple/invalid-record-method/input.js new file mode 100644 index 000000000000..b8504c1af706 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/record-and-tuple/invalid-record-method/input.js @@ -0,0 +1,7 @@ +#{ + a() {}, + async b() {}, + get c() {}, + set d(_) {}, + *e() {} +} diff --git a/packages/babel-parser/test/fixtures/experimental/record-and-tuple/invalid-record-method/options.json b/packages/babel-parser/test/fixtures/experimental/record-and-tuple/invalid-record-method/options.json new file mode 100644 index 000000000000..703c537be360 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/record-and-tuple/invalid-record-method/options.json @@ -0,0 +1,3 @@ +{ + "plugins": [["recordAndTuple", { "syntaxType": "hash" }]] +} diff --git a/packages/babel-parser/test/fixtures/experimental/record-and-tuple/invalid-record-method/output.json b/packages/babel-parser/test/fixtures/experimental/record-and-tuple/invalid-record-method/output.json new file mode 100644 index 000000000000..b918fb65e408 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/record-and-tuple/invalid-record-method/output.json @@ -0,0 +1,146 @@ +{ + "type": "File", + "start":0,"end":69,"loc":{"start":{"line":1,"column":0},"end":{"line":7,"column":1}}, + "errors": [ + "SyntaxError: Only properties and spread elements are allowed in record definitions (2:2)", + "SyntaxError: Only properties and spread elements are allowed in record definitions (3:2)", + "SyntaxError: Only properties and spread elements are allowed in record definitions (4:2)", + "SyntaxError: Only properties and spread elements are allowed in record definitions (5:2)", + "SyntaxError: Only properties and spread elements are allowed in record definitions (6:2)" + ], + "program": { + "type": "Program", + "start":0,"end":69,"loc":{"start":{"line":1,"column":0},"end":{"line":7,"column":1}}, + "sourceType": "script", + "interpreter": null, + "body": [ + { + "type": "ExpressionStatement", + "start":0,"end":69,"loc":{"start":{"line":1,"column":0},"end":{"line":7,"column":1}}, + "expression": { + "type": "RecordExpression", + "start":0,"end":69,"loc":{"start":{"line":1,"column":0},"end":{"line":7,"column":1}}, + "properties": [ + { + "type": "ObjectMethod", + "start":5,"end":11,"loc":{"start":{"line":2,"column":2},"end":{"line":2,"column":8}}, + "method": true, + "key": { + "type": "Identifier", + "start":5,"end":6,"loc":{"start":{"line":2,"column":2},"end":{"line":2,"column":3},"identifierName":"a"}, + "name": "a" + }, + "computed": false, + "kind": "method", + "id": null, + "generator": false, + "async": false, + "params": [], + "body": { + "type": "BlockStatement", + "start":9,"end":11,"loc":{"start":{"line":2,"column":6},"end":{"line":2,"column":8}}, + "body": [], + "directives": [] + } + }, + { + "type": "ObjectMethod", + "start":15,"end":27,"loc":{"start":{"line":3,"column":2},"end":{"line":3,"column":14}}, + "method": true, + "key": { + "type": "Identifier", + "start":21,"end":22,"loc":{"start":{"line":3,"column":8},"end":{"line":3,"column":9},"identifierName":"b"}, + "name": "b" + }, + "computed": false, + "kind": "method", + "id": null, + "generator": false, + "async": true, + "params": [], + "body": { + "type": "BlockStatement", + "start":25,"end":27,"loc":{"start":{"line":3,"column":12},"end":{"line":3,"column":14}}, + "body": [], + "directives": [] + } + }, + { + "type": "ObjectMethod", + "start":31,"end":41,"loc":{"start":{"line":4,"column":2},"end":{"line":4,"column":12}}, + "method": false, + "key": { + "type": "Identifier", + "start":35,"end":36,"loc":{"start":{"line":4,"column":6},"end":{"line":4,"column":7},"identifierName":"c"}, + "name": "c" + }, + "computed": false, + "kind": "get", + "id": null, + "generator": false, + "async": false, + "params": [], + "body": { + "type": "BlockStatement", + "start":39,"end":41,"loc":{"start":{"line":4,"column":10},"end":{"line":4,"column":12}}, + "body": [], + "directives": [] + } + }, + { + "type": "ObjectMethod", + "start":45,"end":56,"loc":{"start":{"line":5,"column":2},"end":{"line":5,"column":13}}, + "method": false, + "key": { + "type": "Identifier", + "start":49,"end":50,"loc":{"start":{"line":5,"column":6},"end":{"line":5,"column":7},"identifierName":"d"}, + "name": "d" + }, + "computed": false, + "kind": "set", + "id": null, + "generator": false, + "async": false, + "params": [ + { + "type": "Identifier", + "start":51,"end":52,"loc":{"start":{"line":5,"column":8},"end":{"line":5,"column":9},"identifierName":"_"}, + "name": "_" + } + ], + "body": { + "type": "BlockStatement", + "start":54,"end":56,"loc":{"start":{"line":5,"column":11},"end":{"line":5,"column":13}}, + "body": [], + "directives": [] + } + }, + { + "type": "ObjectMethod", + "start":60,"end":67,"loc":{"start":{"line":6,"column":2},"end":{"line":6,"column":9}}, + "method": true, + "key": { + "type": "Identifier", + "start":61,"end":62,"loc":{"start":{"line":6,"column":3},"end":{"line":6,"column":4},"identifierName":"e"}, + "name": "e" + }, + "computed": false, + "kind": "method", + "id": null, + "generator": true, + "async": false, + "params": [], + "body": { + "type": "BlockStatement", + "start":65,"end":67,"loc":{"start":{"line":6,"column":7},"end":{"line":6,"column":9}}, + "body": [], + "directives": [] + } + } + ] + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/experimental/record-and-tuple/invalid-tuple-holes/input.js b/packages/babel-parser/test/fixtures/experimental/record-and-tuple/invalid-tuple-holes/input.js new file mode 100644 index 000000000000..621be6b2e406 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/record-and-tuple/invalid-tuple-holes/input.js @@ -0,0 +1 @@ +#[,] diff --git a/packages/babel-parser/test/fixtures/experimental/record-and-tuple/invalid-tuple-holes/options.json b/packages/babel-parser/test/fixtures/experimental/record-and-tuple/invalid-tuple-holes/options.json new file mode 100644 index 000000000000..98195b85e412 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/record-and-tuple/invalid-tuple-holes/options.json @@ -0,0 +1,11 @@ +{ + "plugins": [ + [ + "recordAndTuple", + { + "syntaxType": "hash" + } + ] + ], + "throws": "Unexpected token (1:2)" +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/experimental/record-and-tuple/tuple-trailing-comma/input.js b/packages/babel-parser/test/fixtures/experimental/record-and-tuple/tuple-trailing-comma/input.js new file mode 100644 index 000000000000..3e938abafda2 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/record-and-tuple/tuple-trailing-comma/input.js @@ -0,0 +1 @@ +#[1,] diff --git a/packages/babel-parser/test/fixtures/experimental/record-and-tuple/tuple-trailing-comma/options.json b/packages/babel-parser/test/fixtures/experimental/record-and-tuple/tuple-trailing-comma/options.json new file mode 100644 index 000000000000..703c537be360 --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/record-and-tuple/tuple-trailing-comma/options.json @@ -0,0 +1,3 @@ +{ + "plugins": [["recordAndTuple", { "syntaxType": "hash" }]] +} diff --git a/packages/babel-parser/test/fixtures/experimental/record-and-tuple/tuple-trailing-comma/output.json b/packages/babel-parser/test/fixtures/experimental/record-and-tuple/tuple-trailing-comma/output.json new file mode 100644 index 000000000000..a28986b48cfb --- /dev/null +++ b/packages/babel-parser/test/fixtures/experimental/record-and-tuple/tuple-trailing-comma/output.json @@ -0,0 +1,35 @@ +{ + "type": "File", + "start":0,"end":5,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":5}}, + "program": { + "type": "Program", + "start":0,"end":5,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":5}}, + "sourceType": "script", + "interpreter": null, + "body": [ + { + "type": "ExpressionStatement", + "start":0,"end":5,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":5}}, + "expression": { + "type": "TupleExpression", + "start":0,"end":5,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":5}}, + "extra": { + "trailingComma": 3 + }, + "elements": [ + { + "type": "NumericLiteral", + "start":2,"end":3,"loc":{"start":{"line":1,"column":2},"end":{"line":1,"column":3}}, + "extra": { + "rawValue": 1, + "raw": "1" + }, + "value": 1 + } + ] + } + } + ], + "directives": [] + } +} \ No newline at end of file