diff --git a/babel.config.js b/babel.config.js index 110f711a89..e70ac5e721 100644 --- a/babel.config.js +++ b/babel.config.js @@ -177,7 +177,7 @@ module.exports = function (api) { // env vars from the cli are always strings, so !!ENV_VAR returns true for "false" function bool(value) { - return value && value === "false" && value === "0"; + return value && value !== "false" && value !== "0"; } // TODO(Babel 8) This polyfill is only needed for Node.js 6 and 8 diff --git a/packages/babel-parser/src/plugins/jsx/index.js b/packages/babel-parser/src/plugins/jsx/index.js index 923223b976..a14adeffea 100644 --- a/packages/babel-parser/src/plugins/jsx/index.js +++ b/packages/babel-parser/src/plugins/jsx/index.js @@ -24,6 +24,8 @@ const JsxErrors = Object.freeze({ "JSX attributes must only be assigned a non-empty expression", MissingClosingTagFragment: "Expected corresponding JSX closing tag for <>", MissingClosingTagElement: "Expected corresponding JSX closing tag for <%0>", + UnexpectedSequenceExpression: + "Sequence expressions cannot be directly nested inside JSX. Did you mean to wrap it in parentheses (...)?", UnsupportedJsxValue: "JSX value should be either an expression or a quoted JSX text", UnterminatedJsxContent: "Unterminated JSX contents", @@ -344,9 +346,24 @@ export default (superClass: Class): Class => if (this.match(tt.braceR)) { node.expression = this.jsxParseEmptyExpression(); } else { - node.expression = this.parseExpression(); + const expression = this.parseExpression(); + + if (process.env.BABEL_8_BREAKING) { + if ( + expression.type === "SequenceExpression" && + !expression.extra?.parenthesized + ) { + this.raise( + expression.expressions[1].start, + JsxErrors.UnexpectedSequenceExpression, + ); + } + } + + node.expression = expression; } this.expect(tt.braceR); + return this.finishNode(node, "JSXExpressionContainer"); } diff --git a/packages/babel-parser/test/fixtures/jsx/basic/sequence-expression/input.js b/packages/babel-parser/test/fixtures/jsx/basic/sequence-expression/input.js new file mode 100644 index 0000000000..e5828b6334 --- /dev/null +++ b/packages/babel-parser/test/fixtures/jsx/basic/sequence-expression/input.js @@ -0,0 +1 @@ +
{(console.log('foo'), JSON.stringify(props))}
\ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/jsx/basic/sequence-expression/output.json b/packages/babel-parser/test/fixtures/jsx/basic/sequence-expression/output.json new file mode 100644 index 0000000000..1afdb0d06d --- /dev/null +++ b/packages/babel-parser/test/fixtures/jsx/basic/sequence-expression/output.json @@ -0,0 +1,113 @@ +{ + "type": "File", + "start":0,"end":56,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":56}}, + "program": { + "type": "Program", + "start":0,"end":56,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":56}}, + "sourceType": "script", + "interpreter": null, + "body": [ + { + "type": "ExpressionStatement", + "start":0,"end":56,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":56}}, + "expression": { + "type": "JSXElement", + "start":0,"end":56,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":56}}, + "openingElement": { + "type": "JSXOpeningElement", + "start":0,"end":5,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":5}}, + "name": { + "type": "JSXIdentifier", + "start":1,"end":4,"loc":{"start":{"line":1,"column":1},"end":{"line":1,"column":4}}, + "name": "div" + }, + "attributes": [], + "selfClosing": false + }, + "closingElement": { + "type": "JSXClosingElement", + "start":50,"end":56,"loc":{"start":{"line":1,"column":50},"end":{"line":1,"column":56}}, + "name": { + "type": "JSXIdentifier", + "start":52,"end":55,"loc":{"start":{"line":1,"column":52},"end":{"line":1,"column":55}}, + "name": "div" + } + }, + "children": [ + { + "type": "JSXExpressionContainer", + "start":5,"end":50,"loc":{"start":{"line":1,"column":5},"end":{"line":1,"column":50}}, + "expression": { + "type": "SequenceExpression", + "start":7,"end":48,"loc":{"start":{"line":1,"column":7},"end":{"line":1,"column":48}}, + "extra": { + "parenthesized": true, + "parenStart": 6 + }, + "expressions": [ + { + "type": "CallExpression", + "start":7,"end":25,"loc":{"start":{"line":1,"column":7},"end":{"line":1,"column":25}}, + "callee": { + "type": "MemberExpression", + "start":7,"end":18,"loc":{"start":{"line":1,"column":7},"end":{"line":1,"column":18}}, + "object": { + "type": "Identifier", + "start":7,"end":14,"loc":{"start":{"line":1,"column":7},"end":{"line":1,"column":14},"identifierName":"console"}, + "name": "console" + }, + "computed": false, + "property": { + "type": "Identifier", + "start":15,"end":18,"loc":{"start":{"line":1,"column":15},"end":{"line":1,"column":18},"identifierName":"log"}, + "name": "log" + } + }, + "arguments": [ + { + "type": "StringLiteral", + "start":19,"end":24,"loc":{"start":{"line":1,"column":19},"end":{"line":1,"column":24}}, + "extra": { + "rawValue": "foo", + "raw": "'foo'" + }, + "value": "foo" + } + ] + }, + { + "type": "CallExpression", + "start":27,"end":48,"loc":{"start":{"line":1,"column":27},"end":{"line":1,"column":48}}, + "callee": { + "type": "MemberExpression", + "start":27,"end":41,"loc":{"start":{"line":1,"column":27},"end":{"line":1,"column":41}}, + "object": { + "type": "Identifier", + "start":27,"end":31,"loc":{"start":{"line":1,"column":27},"end":{"line":1,"column":31},"identifierName":"JSON"}, + "name": "JSON" + }, + "computed": false, + "property": { + "type": "Identifier", + "start":32,"end":41,"loc":{"start":{"line":1,"column":32},"end":{"line":1,"column":41},"identifierName":"stringify"}, + "name": "stringify" + } + }, + "arguments": [ + { + "type": "Identifier", + "start":42,"end":47,"loc":{"start":{"line":1,"column":42},"end":{"line":1,"column":47},"identifierName":"props"}, + "name": "props" + } + ] + } + ] + } + } + ] + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/jsx/errors/attribute-sequence-expression-babel-7/input.js b/packages/babel-parser/test/fixtures/jsx/errors/attribute-sequence-expression-babel-7/input.js new file mode 100644 index 0000000000..90b46deab9 --- /dev/null +++ b/packages/babel-parser/test/fixtures/jsx/errors/attribute-sequence-expression-babel-7/input.js @@ -0,0 +1 @@ +
\ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/jsx/errors/attribute-sequence-expression-babel-7/options.json b/packages/babel-parser/test/fixtures/jsx/errors/attribute-sequence-expression-babel-7/options.json new file mode 100644 index 0000000000..29a3f0e841 --- /dev/null +++ b/packages/babel-parser/test/fixtures/jsx/errors/attribute-sequence-expression-babel-7/options.json @@ -0,0 +1,3 @@ +{ + "BABEL_8_BREAKING": false +} diff --git a/packages/babel-parser/test/fixtures/jsx/errors/attribute-sequence-expression-babel-7/output.json b/packages/babel-parser/test/fixtures/jsx/errors/attribute-sequence-expression-babel-7/output.json new file mode 100644 index 0000000000..9390806f51 --- /dev/null +++ b/packages/babel-parser/test/fixtures/jsx/errors/attribute-sequence-expression-babel-7/output.json @@ -0,0 +1,110 @@ +{ + "type": "File", + "start":0,"end":55,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":55}}, + "program": { + "type": "Program", + "start":0,"end":55,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":55}}, + "sourceType": "script", + "interpreter": null, + "body": [ + { + "type": "ExpressionStatement", + "start":0,"end":55,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":55}}, + "expression": { + "type": "JSXElement", + "start":0,"end":55,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":55}}, + "openingElement": { + "type": "JSXOpeningElement", + "start":0,"end":55,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":55}}, + "name": { + "type": "JSXIdentifier", + "start":1,"end":4,"loc":{"start":{"line":1,"column":1},"end":{"line":1,"column":4}}, + "name": "div" + }, + "attributes": [ + { + "type": "JSXAttribute", + "start":5,"end":52,"loc":{"start":{"line":1,"column":5},"end":{"line":1,"column":52}}, + "name": { + "type": "JSXIdentifier", + "start":5,"end":8,"loc":{"start":{"line":1,"column":5},"end":{"line":1,"column":8}}, + "name": "key" + }, + "value": { + "type": "JSXExpressionContainer", + "start":9,"end":52,"loc":{"start":{"line":1,"column":9},"end":{"line":1,"column":52}}, + "expression": { + "type": "SequenceExpression", + "start":10,"end":51,"loc":{"start":{"line":1,"column":10},"end":{"line":1,"column":51}}, + "expressions": [ + { + "type": "CallExpression", + "start":10,"end":28,"loc":{"start":{"line":1,"column":10},"end":{"line":1,"column":28}}, + "callee": { + "type": "MemberExpression", + "start":10,"end":21,"loc":{"start":{"line":1,"column":10},"end":{"line":1,"column":21}}, + "object": { + "type": "Identifier", + "start":10,"end":17,"loc":{"start":{"line":1,"column":10},"end":{"line":1,"column":17},"identifierName":"console"}, + "name": "console" + }, + "computed": false, + "property": { + "type": "Identifier", + "start":18,"end":21,"loc":{"start":{"line":1,"column":18},"end":{"line":1,"column":21},"identifierName":"log"}, + "name": "log" + } + }, + "arguments": [ + { + "type": "StringLiteral", + "start":22,"end":27,"loc":{"start":{"line":1,"column":22},"end":{"line":1,"column":27}}, + "extra": { + "rawValue": "foo", + "raw": "'foo'" + }, + "value": "foo" + } + ] + }, + { + "type": "CallExpression", + "start":30,"end":51,"loc":{"start":{"line":1,"column":30},"end":{"line":1,"column":51}}, + "callee": { + "type": "MemberExpression", + "start":30,"end":44,"loc":{"start":{"line":1,"column":30},"end":{"line":1,"column":44}}, + "object": { + "type": "Identifier", + "start":30,"end":34,"loc":{"start":{"line":1,"column":30},"end":{"line":1,"column":34},"identifierName":"JSON"}, + "name": "JSON" + }, + "computed": false, + "property": { + "type": "Identifier", + "start":35,"end":44,"loc":{"start":{"line":1,"column":35},"end":{"line":1,"column":44},"identifierName":"stringify"}, + "name": "stringify" + } + }, + "arguments": [ + { + "type": "Identifier", + "start":45,"end":50,"loc":{"start":{"line":1,"column":45},"end":{"line":1,"column":50},"identifierName":"props"}, + "name": "props" + } + ] + } + ] + } + } + } + ], + "selfClosing": true + }, + "closingElement": null, + "children": [] + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/jsx/errors/attribute-sequence-expression/input.js b/packages/babel-parser/test/fixtures/jsx/errors/attribute-sequence-expression/input.js new file mode 100644 index 0000000000..90b46deab9 --- /dev/null +++ b/packages/babel-parser/test/fixtures/jsx/errors/attribute-sequence-expression/input.js @@ -0,0 +1 @@ +
\ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/jsx/errors/attribute-sequence-expression/options.json b/packages/babel-parser/test/fixtures/jsx/errors/attribute-sequence-expression/options.json new file mode 100644 index 0000000000..cbf6d15954 --- /dev/null +++ b/packages/babel-parser/test/fixtures/jsx/errors/attribute-sequence-expression/options.json @@ -0,0 +1,3 @@ +{ + "BABEL_8_BREAKING": true +} diff --git a/packages/babel-parser/test/fixtures/jsx/errors/attribute-sequence-expression/output.json b/packages/babel-parser/test/fixtures/jsx/errors/attribute-sequence-expression/output.json new file mode 100644 index 0000000000..982b611146 --- /dev/null +++ b/packages/babel-parser/test/fixtures/jsx/errors/attribute-sequence-expression/output.json @@ -0,0 +1,113 @@ +{ + "type": "File", + "start":0,"end":55,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":55}}, + "errors": [ + "SyntaxError: Sequence expressions cannot be directly nested inside JSX. Did you mean to wrap it in parentheses (...)? (1:30)" + ], + "program": { + "type": "Program", + "start":0,"end":55,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":55}}, + "sourceType": "script", + "interpreter": null, + "body": [ + { + "type": "ExpressionStatement", + "start":0,"end":55,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":55}}, + "expression": { + "type": "JSXElement", + "start":0,"end":55,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":55}}, + "openingElement": { + "type": "JSXOpeningElement", + "start":0,"end":55,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":55}}, + "name": { + "type": "JSXIdentifier", + "start":1,"end":4,"loc":{"start":{"line":1,"column":1},"end":{"line":1,"column":4}}, + "name": "div" + }, + "attributes": [ + { + "type": "JSXAttribute", + "start":5,"end":52,"loc":{"start":{"line":1,"column":5},"end":{"line":1,"column":52}}, + "name": { + "type": "JSXIdentifier", + "start":5,"end":8,"loc":{"start":{"line":1,"column":5},"end":{"line":1,"column":8}}, + "name": "key" + }, + "value": { + "type": "JSXExpressionContainer", + "start":9,"end":52,"loc":{"start":{"line":1,"column":9},"end":{"line":1,"column":52}}, + "expression": { + "type": "SequenceExpression", + "start":10,"end":51,"loc":{"start":{"line":1,"column":10},"end":{"line":1,"column":51}}, + "expressions": [ + { + "type": "CallExpression", + "start":10,"end":28,"loc":{"start":{"line":1,"column":10},"end":{"line":1,"column":28}}, + "callee": { + "type": "MemberExpression", + "start":10,"end":21,"loc":{"start":{"line":1,"column":10},"end":{"line":1,"column":21}}, + "object": { + "type": "Identifier", + "start":10,"end":17,"loc":{"start":{"line":1,"column":10},"end":{"line":1,"column":17},"identifierName":"console"}, + "name": "console" + }, + "computed": false, + "property": { + "type": "Identifier", + "start":18,"end":21,"loc":{"start":{"line":1,"column":18},"end":{"line":1,"column":21},"identifierName":"log"}, + "name": "log" + } + }, + "arguments": [ + { + "type": "StringLiteral", + "start":22,"end":27,"loc":{"start":{"line":1,"column":22},"end":{"line":1,"column":27}}, + "extra": { + "rawValue": "foo", + "raw": "'foo'" + }, + "value": "foo" + } + ] + }, + { + "type": "CallExpression", + "start":30,"end":51,"loc":{"start":{"line":1,"column":30},"end":{"line":1,"column":51}}, + "callee": { + "type": "MemberExpression", + "start":30,"end":44,"loc":{"start":{"line":1,"column":30},"end":{"line":1,"column":44}}, + "object": { + "type": "Identifier", + "start":30,"end":34,"loc":{"start":{"line":1,"column":30},"end":{"line":1,"column":34},"identifierName":"JSON"}, + "name": "JSON" + }, + "computed": false, + "property": { + "type": "Identifier", + "start":35,"end":44,"loc":{"start":{"line":1,"column":35},"end":{"line":1,"column":44},"identifierName":"stringify"}, + "name": "stringify" + } + }, + "arguments": [ + { + "type": "Identifier", + "start":45,"end":50,"loc":{"start":{"line":1,"column":45},"end":{"line":1,"column":50},"identifierName":"props"}, + "name": "props" + } + ] + } + ] + } + } + } + ], + "selfClosing": true + }, + "closingElement": null, + "children": [] + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/jsx/errors/sequence-expression-babel-7/input.js b/packages/babel-parser/test/fixtures/jsx/errors/sequence-expression-babel-7/input.js new file mode 100644 index 0000000000..17d05e6bdc --- /dev/null +++ b/packages/babel-parser/test/fixtures/jsx/errors/sequence-expression-babel-7/input.js @@ -0,0 +1 @@ +
{console.log('foo'), JSON.stringify(props)}
\ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/jsx/errors/sequence-expression-babel-7/options.json b/packages/babel-parser/test/fixtures/jsx/errors/sequence-expression-babel-7/options.json new file mode 100644 index 0000000000..29a3f0e841 --- /dev/null +++ b/packages/babel-parser/test/fixtures/jsx/errors/sequence-expression-babel-7/options.json @@ -0,0 +1,3 @@ +{ + "BABEL_8_BREAKING": false +} diff --git a/packages/babel-parser/test/fixtures/jsx/errors/sequence-expression-babel-7/output.json b/packages/babel-parser/test/fixtures/jsx/errors/sequence-expression-babel-7/output.json new file mode 100644 index 0000000000..bd27e4c1c0 --- /dev/null +++ b/packages/babel-parser/test/fixtures/jsx/errors/sequence-expression-babel-7/output.json @@ -0,0 +1,109 @@ +{ + "type": "File", + "start":0,"end":54,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":54}}, + "program": { + "type": "Program", + "start":0,"end":54,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":54}}, + "sourceType": "script", + "interpreter": null, + "body": [ + { + "type": "ExpressionStatement", + "start":0,"end":54,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":54}}, + "expression": { + "type": "JSXElement", + "start":0,"end":54,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":54}}, + "openingElement": { + "type": "JSXOpeningElement", + "start":0,"end":5,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":5}}, + "name": { + "type": "JSXIdentifier", + "start":1,"end":4,"loc":{"start":{"line":1,"column":1},"end":{"line":1,"column":4}}, + "name": "div" + }, + "attributes": [], + "selfClosing": false + }, + "closingElement": { + "type": "JSXClosingElement", + "start":48,"end":54,"loc":{"start":{"line":1,"column":48},"end":{"line":1,"column":54}}, + "name": { + "type": "JSXIdentifier", + "start":50,"end":53,"loc":{"start":{"line":1,"column":50},"end":{"line":1,"column":53}}, + "name": "div" + } + }, + "children": [ + { + "type": "JSXExpressionContainer", + "start":5,"end":48,"loc":{"start":{"line":1,"column":5},"end":{"line":1,"column":48}}, + "expression": { + "type": "SequenceExpression", + "start":6,"end":47,"loc":{"start":{"line":1,"column":6},"end":{"line":1,"column":47}}, + "expressions": [ + { + "type": "CallExpression", + "start":6,"end":24,"loc":{"start":{"line":1,"column":6},"end":{"line":1,"column":24}}, + "callee": { + "type": "MemberExpression", + "start":6,"end":17,"loc":{"start":{"line":1,"column":6},"end":{"line":1,"column":17}}, + "object": { + "type": "Identifier", + "start":6,"end":13,"loc":{"start":{"line":1,"column":6},"end":{"line":1,"column":13},"identifierName":"console"}, + "name": "console" + }, + "computed": false, + "property": { + "type": "Identifier", + "start":14,"end":17,"loc":{"start":{"line":1,"column":14},"end":{"line":1,"column":17},"identifierName":"log"}, + "name": "log" + } + }, + "arguments": [ + { + "type": "StringLiteral", + "start":18,"end":23,"loc":{"start":{"line":1,"column":18},"end":{"line":1,"column":23}}, + "extra": { + "rawValue": "foo", + "raw": "'foo'" + }, + "value": "foo" + } + ] + }, + { + "type": "CallExpression", + "start":26,"end":47,"loc":{"start":{"line":1,"column":26},"end":{"line":1,"column":47}}, + "callee": { + "type": "MemberExpression", + "start":26,"end":40,"loc":{"start":{"line":1,"column":26},"end":{"line":1,"column":40}}, + "object": { + "type": "Identifier", + "start":26,"end":30,"loc":{"start":{"line":1,"column":26},"end":{"line":1,"column":30},"identifierName":"JSON"}, + "name": "JSON" + }, + "computed": false, + "property": { + "type": "Identifier", + "start":31,"end":40,"loc":{"start":{"line":1,"column":31},"end":{"line":1,"column":40},"identifierName":"stringify"}, + "name": "stringify" + } + }, + "arguments": [ + { + "type": "Identifier", + "start":41,"end":46,"loc":{"start":{"line":1,"column":41},"end":{"line":1,"column":46},"identifierName":"props"}, + "name": "props" + } + ] + } + ] + } + } + ] + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/jsx/errors/sequence-expression-parenthesized/input.js b/packages/babel-parser/test/fixtures/jsx/errors/sequence-expression-parenthesized/input.js new file mode 100644 index 0000000000..abd2de1e0f --- /dev/null +++ b/packages/babel-parser/test/fixtures/jsx/errors/sequence-expression-parenthesized/input.js @@ -0,0 +1 @@ +
{(console.log('foo'), JSON.stringify(props))}
diff --git a/packages/babel-parser/test/fixtures/jsx/errors/sequence-expression-parenthesized/output.json b/packages/babel-parser/test/fixtures/jsx/errors/sequence-expression-parenthesized/output.json new file mode 100644 index 0000000000..1afdb0d06d --- /dev/null +++ b/packages/babel-parser/test/fixtures/jsx/errors/sequence-expression-parenthesized/output.json @@ -0,0 +1,113 @@ +{ + "type": "File", + "start":0,"end":56,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":56}}, + "program": { + "type": "Program", + "start":0,"end":56,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":56}}, + "sourceType": "script", + "interpreter": null, + "body": [ + { + "type": "ExpressionStatement", + "start":0,"end":56,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":56}}, + "expression": { + "type": "JSXElement", + "start":0,"end":56,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":56}}, + "openingElement": { + "type": "JSXOpeningElement", + "start":0,"end":5,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":5}}, + "name": { + "type": "JSXIdentifier", + "start":1,"end":4,"loc":{"start":{"line":1,"column":1},"end":{"line":1,"column":4}}, + "name": "div" + }, + "attributes": [], + "selfClosing": false + }, + "closingElement": { + "type": "JSXClosingElement", + "start":50,"end":56,"loc":{"start":{"line":1,"column":50},"end":{"line":1,"column":56}}, + "name": { + "type": "JSXIdentifier", + "start":52,"end":55,"loc":{"start":{"line":1,"column":52},"end":{"line":1,"column":55}}, + "name": "div" + } + }, + "children": [ + { + "type": "JSXExpressionContainer", + "start":5,"end":50,"loc":{"start":{"line":1,"column":5},"end":{"line":1,"column":50}}, + "expression": { + "type": "SequenceExpression", + "start":7,"end":48,"loc":{"start":{"line":1,"column":7},"end":{"line":1,"column":48}}, + "extra": { + "parenthesized": true, + "parenStart": 6 + }, + "expressions": [ + { + "type": "CallExpression", + "start":7,"end":25,"loc":{"start":{"line":1,"column":7},"end":{"line":1,"column":25}}, + "callee": { + "type": "MemberExpression", + "start":7,"end":18,"loc":{"start":{"line":1,"column":7},"end":{"line":1,"column":18}}, + "object": { + "type": "Identifier", + "start":7,"end":14,"loc":{"start":{"line":1,"column":7},"end":{"line":1,"column":14},"identifierName":"console"}, + "name": "console" + }, + "computed": false, + "property": { + "type": "Identifier", + "start":15,"end":18,"loc":{"start":{"line":1,"column":15},"end":{"line":1,"column":18},"identifierName":"log"}, + "name": "log" + } + }, + "arguments": [ + { + "type": "StringLiteral", + "start":19,"end":24,"loc":{"start":{"line":1,"column":19},"end":{"line":1,"column":24}}, + "extra": { + "rawValue": "foo", + "raw": "'foo'" + }, + "value": "foo" + } + ] + }, + { + "type": "CallExpression", + "start":27,"end":48,"loc":{"start":{"line":1,"column":27},"end":{"line":1,"column":48}}, + "callee": { + "type": "MemberExpression", + "start":27,"end":41,"loc":{"start":{"line":1,"column":27},"end":{"line":1,"column":41}}, + "object": { + "type": "Identifier", + "start":27,"end":31,"loc":{"start":{"line":1,"column":27},"end":{"line":1,"column":31},"identifierName":"JSON"}, + "name": "JSON" + }, + "computed": false, + "property": { + "type": "Identifier", + "start":32,"end":41,"loc":{"start":{"line":1,"column":32},"end":{"line":1,"column":41},"identifierName":"stringify"}, + "name": "stringify" + } + }, + "arguments": [ + { + "type": "Identifier", + "start":42,"end":47,"loc":{"start":{"line":1,"column":42},"end":{"line":1,"column":47},"identifierName":"props"}, + "name": "props" + } + ] + } + ] + } + } + ] + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/jsx/errors/sequence-expression/input.js b/packages/babel-parser/test/fixtures/jsx/errors/sequence-expression/input.js new file mode 100644 index 0000000000..17d05e6bdc --- /dev/null +++ b/packages/babel-parser/test/fixtures/jsx/errors/sequence-expression/input.js @@ -0,0 +1 @@ +
{console.log('foo'), JSON.stringify(props)}
\ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/jsx/errors/sequence-expression/options.json b/packages/babel-parser/test/fixtures/jsx/errors/sequence-expression/options.json new file mode 100644 index 0000000000..cbf6d15954 --- /dev/null +++ b/packages/babel-parser/test/fixtures/jsx/errors/sequence-expression/options.json @@ -0,0 +1,3 @@ +{ + "BABEL_8_BREAKING": true +} diff --git a/packages/babel-parser/test/fixtures/jsx/errors/sequence-expression/output.json b/packages/babel-parser/test/fixtures/jsx/errors/sequence-expression/output.json new file mode 100644 index 0000000000..6204622a6c --- /dev/null +++ b/packages/babel-parser/test/fixtures/jsx/errors/sequence-expression/output.json @@ -0,0 +1,112 @@ +{ + "type": "File", + "start":0,"end":54,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":54}}, + "errors": [ + "SyntaxError: Sequence expressions cannot be directly nested inside JSX. Did you mean to wrap it in parentheses (...)? (1:26)" + ], + "program": { + "type": "Program", + "start":0,"end":54,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":54}}, + "sourceType": "script", + "interpreter": null, + "body": [ + { + "type": "ExpressionStatement", + "start":0,"end":54,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":54}}, + "expression": { + "type": "JSXElement", + "start":0,"end":54,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":54}}, + "openingElement": { + "type": "JSXOpeningElement", + "start":0,"end":5,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":5}}, + "name": { + "type": "JSXIdentifier", + "start":1,"end":4,"loc":{"start":{"line":1,"column":1},"end":{"line":1,"column":4}}, + "name": "div" + }, + "attributes": [], + "selfClosing": false + }, + "closingElement": { + "type": "JSXClosingElement", + "start":48,"end":54,"loc":{"start":{"line":1,"column":48},"end":{"line":1,"column":54}}, + "name": { + "type": "JSXIdentifier", + "start":50,"end":53,"loc":{"start":{"line":1,"column":50},"end":{"line":1,"column":53}}, + "name": "div" + } + }, + "children": [ + { + "type": "JSXExpressionContainer", + "start":5,"end":48,"loc":{"start":{"line":1,"column":5},"end":{"line":1,"column":48}}, + "expression": { + "type": "SequenceExpression", + "start":6,"end":47,"loc":{"start":{"line":1,"column":6},"end":{"line":1,"column":47}}, + "expressions": [ + { + "type": "CallExpression", + "start":6,"end":24,"loc":{"start":{"line":1,"column":6},"end":{"line":1,"column":24}}, + "callee": { + "type": "MemberExpression", + "start":6,"end":17,"loc":{"start":{"line":1,"column":6},"end":{"line":1,"column":17}}, + "object": { + "type": "Identifier", + "start":6,"end":13,"loc":{"start":{"line":1,"column":6},"end":{"line":1,"column":13},"identifierName":"console"}, + "name": "console" + }, + "computed": false, + "property": { + "type": "Identifier", + "start":14,"end":17,"loc":{"start":{"line":1,"column":14},"end":{"line":1,"column":17},"identifierName":"log"}, + "name": "log" + } + }, + "arguments": [ + { + "type": "StringLiteral", + "start":18,"end":23,"loc":{"start":{"line":1,"column":18},"end":{"line":1,"column":23}}, + "extra": { + "rawValue": "foo", + "raw": "'foo'" + }, + "value": "foo" + } + ] + }, + { + "type": "CallExpression", + "start":26,"end":47,"loc":{"start":{"line":1,"column":26},"end":{"line":1,"column":47}}, + "callee": { + "type": "MemberExpression", + "start":26,"end":40,"loc":{"start":{"line":1,"column":26},"end":{"line":1,"column":40}}, + "object": { + "type": "Identifier", + "start":26,"end":30,"loc":{"start":{"line":1,"column":26},"end":{"line":1,"column":30},"identifierName":"JSON"}, + "name": "JSON" + }, + "computed": false, + "property": { + "type": "Identifier", + "start":31,"end":40,"loc":{"start":{"line":1,"column":31},"end":{"line":1,"column":40},"identifierName":"stringify"}, + "name": "stringify" + } + }, + "arguments": [ + { + "type": "Identifier", + "start":41,"end":46,"loc":{"start":{"line":1,"column":41},"end":{"line":1,"column":46},"identifierName":"props"}, + "name": "props" + } + ] + } + ] + } + } + ] + } + } + ], + "directives": [] + } +} \ No newline at end of file