diff --git a/packages/babel-parser/src/plugins/jsx/index.js b/packages/babel-parser/src/plugins/jsx/index.js index 923223b97601..e481e8ff5f58 100644 --- a/packages/babel-parser/src/plugins/jsx/index.js +++ b/packages/babel-parser/src/plugins/jsx/index.js @@ -123,6 +123,19 @@ export default (superClass: Class): Class => chunkStart = this.state.pos; break; + case charCodes.greaterThan: + case charCodes.rightCurlyBrace: + if (process.env.BABEL_8_BREAKING) { + const htmlEntity = + ch === charCodes.rightCurlyBrace ? "}" : ">"; + const char = this.input[this.state.pos]; + this.raise( + this.state.pos, + `Unexpected token \`${char}\`. Did you mean \`${htmlEntity}\` or \`{'${char}'}\`?`, + ); + } + /* falls through */ + default: if (isNewLine(ch)) { out += this.input.slice(chunkStart, this.state.pos); diff --git a/packages/babel-parser/test/fixtures/jsx/basic/13/input.js b/packages/babel-parser/test/fixtures/jsx/basic/13/input.js deleted file mode 100644 index f7525a0e00c1..000000000000 --- a/packages/babel-parser/test/fixtures/jsx/basic/13/input.js +++ /dev/null @@ -1 +0,0 @@ - right=monkeys /> gorillas /> \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/jsx/basic/13/output.json b/packages/babel-parser/test/fixtures/jsx/basic/13/output.json deleted file mode 100644 index 0f199c3576f8..000000000000 --- a/packages/babel-parser/test/fixtures/jsx/basic/13/output.json +++ /dev/null @@ -1,105 +0,0 @@ -{ - "type": "File", - "start":0,"end":57,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":57}}, - "program": { - "type": "Program", - "start":0,"end":57,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":57}}, - "sourceType": "script", - "interpreter": null, - "body": [ - { - "type": "ExpressionStatement", - "start":0,"end":57,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":57}}, - "expression": { - "type": "JSXElement", - "start":0,"end":57,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":57}}, - "openingElement": { - "type": "JSXOpeningElement", - "start":0,"end":57,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":57}}, - "name": { - "type": "JSXIdentifier", - "start":1,"end":10,"loc":{"start":{"line":1,"column":1},"end":{"line":1,"column":10}}, - "name": "LeftRight" - }, - "attributes": [ - { - "type": "JSXAttribute", - "start":11,"end":21,"loc":{"start":{"line":1,"column":11},"end":{"line":1,"column":21}}, - "name": { - "type": "JSXIdentifier", - "start":11,"end":15,"loc":{"start":{"line":1,"column":11},"end":{"line":1,"column":15}}, - "name": "left" - }, - "value": { - "type": "JSXElement", - "start":16,"end":21,"loc":{"start":{"line":1,"column":16},"end":{"line":1,"column":21}}, - "openingElement": { - "type": "JSXOpeningElement", - "start":16,"end":21,"loc":{"start":{"line":1,"column":16},"end":{"line":1,"column":21}}, - "name": { - "type": "JSXIdentifier", - "start":17,"end":18,"loc":{"start":{"line":1,"column":17},"end":{"line":1,"column":18}}, - "name": "a" - }, - "attributes": [], - "selfClosing": true - }, - "closingElement": null, - "children": [] - } - }, - { - "type": "JSXAttribute", - "start":22,"end":54,"loc":{"start":{"line":1,"column":22},"end":{"line":1,"column":54}}, - "name": { - "type": "JSXIdentifier", - "start":22,"end":27,"loc":{"start":{"line":1,"column":22},"end":{"line":1,"column":27}}, - "name": "right" - }, - "value": { - "type": "JSXElement", - "start":28,"end":54,"loc":{"start":{"line":1,"column":28},"end":{"line":1,"column":54}}, - "openingElement": { - "type": "JSXOpeningElement", - "start":28,"end":31,"loc":{"start":{"line":1,"column":28},"end":{"line":1,"column":31}}, - "name": { - "type": "JSXIdentifier", - "start":29,"end":30,"loc":{"start":{"line":1,"column":29},"end":{"line":1,"column":30}}, - "name": "b" - }, - "attributes": [], - "selfClosing": false - }, - "closingElement": { - "type": "JSXClosingElement", - "start":50,"end":54,"loc":{"start":{"line":1,"column":50},"end":{"line":1,"column":54}}, - "name": { - "type": "JSXIdentifier", - "start":52,"end":53,"loc":{"start":{"line":1,"column":52},"end":{"line":1,"column":53}}, - "name": "b" - } - }, - "children": [ - { - "type": "JSXText", - "start":31,"end":50,"loc":{"start":{"line":1,"column":31},"end":{"line":1,"column":50}}, - "extra": { - "rawValue": "monkeys /> gorillas", - "raw": "monkeys /> gorillas" - }, - "value": "monkeys /> gorillas" - } - ] - } - } - ], - "selfClosing": true - }, - "closingElement": null, - "children": [] - } - } - ], - "directives": [] - } -} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/jsx/basic/jsx-text-closing-angle-bracket-babel-7/input.js b/packages/babel-parser/test/fixtures/jsx/basic/jsx-text-closing-angle-bracket-babel-7/input.js new file mode 100644 index 000000000000..4397f584cbb1 --- /dev/null +++ b/packages/babel-parser/test/fixtures/jsx/basic/jsx-text-closing-angle-bracket-babel-7/input.js @@ -0,0 +1 @@ +
>
diff --git a/packages/babel-parser/test/fixtures/jsx/basic/jsx-text-closing-angle-bracket-babel-7/options.json b/packages/babel-parser/test/fixtures/jsx/basic/jsx-text-closing-angle-bracket-babel-7/options.json new file mode 100644 index 000000000000..29a3f0e84167 --- /dev/null +++ b/packages/babel-parser/test/fixtures/jsx/basic/jsx-text-closing-angle-bracket-babel-7/options.json @@ -0,0 +1,3 @@ +{ + "BABEL_8_BREAKING": false +} diff --git a/packages/babel-parser/test/fixtures/jsx/basic/jsx-text-closing-angle-bracket-babel-7/output.json b/packages/babel-parser/test/fixtures/jsx/basic/jsx-text-closing-angle-bracket-babel-7/output.json new file mode 100644 index 000000000000..a99452094e4f --- /dev/null +++ b/packages/babel-parser/test/fixtures/jsx/basic/jsx-text-closing-angle-bracket-babel-7/output.json @@ -0,0 +1,52 @@ +{ + "type": "File", + "start":0,"end":12,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":12}}, + "program": { + "type": "Program", + "start":0,"end":12,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":12}}, + "sourceType": "script", + "interpreter": null, + "body": [ + { + "type": "ExpressionStatement", + "start":0,"end":12,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":12}}, + "expression": { + "type": "JSXElement", + "start":0,"end":12,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":12}}, + "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":6,"end":12,"loc":{"start":{"line":1,"column":6},"end":{"line":1,"column":12}}, + "name": { + "type": "JSXIdentifier", + "start":8,"end":11,"loc":{"start":{"line":1,"column":8},"end":{"line":1,"column":11}}, + "name": "div" + } + }, + "children": [ + { + "type": "JSXText", + "start":5,"end":6,"loc":{"start":{"line":1,"column":5},"end":{"line":1,"column":6}}, + "extra": { + "rawValue": ">", + "raw": ">" + }, + "value": ">" + } + ] + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/jsx/basic/jsx-text-closing-angle-bracket-wrapped/input.js b/packages/babel-parser/test/fixtures/jsx/basic/jsx-text-closing-angle-bracket-wrapped/input.js new file mode 100644 index 000000000000..980ff2c3a0da --- /dev/null +++ b/packages/babel-parser/test/fixtures/jsx/basic/jsx-text-closing-angle-bracket-wrapped/input.js @@ -0,0 +1 @@ +
{'>'}
diff --git a/packages/babel-parser/test/fixtures/jsx/basic/jsx-text-closing-angle-bracket-wrapped/output.json b/packages/babel-parser/test/fixtures/jsx/basic/jsx-text-closing-angle-bracket-wrapped/output.json new file mode 100644 index 000000000000..f520b65326dc --- /dev/null +++ b/packages/babel-parser/test/fixtures/jsx/basic/jsx-text-closing-angle-bracket-wrapped/output.json @@ -0,0 +1,56 @@ +{ + "type": "File", + "start":0,"end":16,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":16}}, + "program": { + "type": "Program", + "start":0,"end":16,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":16}}, + "sourceType": "script", + "interpreter": null, + "body": [ + { + "type": "ExpressionStatement", + "start":0,"end":16,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":16}}, + "expression": { + "type": "JSXElement", + "start":0,"end":16,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":16}}, + "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":10,"end":16,"loc":{"start":{"line":1,"column":10},"end":{"line":1,"column":16}}, + "name": { + "type": "JSXIdentifier", + "start":12,"end":15,"loc":{"start":{"line":1,"column":12},"end":{"line":1,"column":15}}, + "name": "div" + } + }, + "children": [ + { + "type": "JSXExpressionContainer", + "start":5,"end":10,"loc":{"start":{"line":1,"column":5},"end":{"line":1,"column":10}}, + "expression": { + "type": "StringLiteral", + "start":6,"end":9,"loc":{"start":{"line":1,"column":6},"end":{"line":1,"column":9}}, + "extra": { + "rawValue": ">", + "raw": "'>'" + }, + "value": ">" + } + } + ] + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/jsx/basic/jsx-text-closing-curly-brace-babel-7/input.js b/packages/babel-parser/test/fixtures/jsx/basic/jsx-text-closing-curly-brace-babel-7/input.js new file mode 100644 index 000000000000..1f7fd22cc8bc --- /dev/null +++ b/packages/babel-parser/test/fixtures/jsx/basic/jsx-text-closing-curly-brace-babel-7/input.js @@ -0,0 +1 @@ +
}
diff --git a/packages/babel-parser/test/fixtures/jsx/basic/jsx-text-closing-curly-brace-babel-7/options.json b/packages/babel-parser/test/fixtures/jsx/basic/jsx-text-closing-curly-brace-babel-7/options.json new file mode 100644 index 000000000000..29a3f0e84167 --- /dev/null +++ b/packages/babel-parser/test/fixtures/jsx/basic/jsx-text-closing-curly-brace-babel-7/options.json @@ -0,0 +1,3 @@ +{ + "BABEL_8_BREAKING": false +} diff --git a/packages/babel-parser/test/fixtures/jsx/basic/jsx-text-closing-curly-brace-babel-7/output.json b/packages/babel-parser/test/fixtures/jsx/basic/jsx-text-closing-curly-brace-babel-7/output.json new file mode 100644 index 000000000000..77bfdae4cedb --- /dev/null +++ b/packages/babel-parser/test/fixtures/jsx/basic/jsx-text-closing-curly-brace-babel-7/output.json @@ -0,0 +1,52 @@ +{ + "type": "File", + "start":0,"end":12,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":12}}, + "program": { + "type": "Program", + "start":0,"end":12,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":12}}, + "sourceType": "script", + "interpreter": null, + "body": [ + { + "type": "ExpressionStatement", + "start":0,"end":12,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":12}}, + "expression": { + "type": "JSXElement", + "start":0,"end":12,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":12}}, + "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":6,"end":12,"loc":{"start":{"line":1,"column":6},"end":{"line":1,"column":12}}, + "name": { + "type": "JSXIdentifier", + "start":8,"end":11,"loc":{"start":{"line":1,"column":8},"end":{"line":1,"column":11}}, + "name": "div" + } + }, + "children": [ + { + "type": "JSXText", + "start":5,"end":6,"loc":{"start":{"line":1,"column":5},"end":{"line":1,"column":6}}, + "extra": { + "rawValue": "}", + "raw": "}" + }, + "value": "}" + } + ] + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/jsx/basic/jsx-text-closing-curly-brace-wrapped/input.js b/packages/babel-parser/test/fixtures/jsx/basic/jsx-text-closing-curly-brace-wrapped/input.js new file mode 100644 index 000000000000..95b1a66963ab --- /dev/null +++ b/packages/babel-parser/test/fixtures/jsx/basic/jsx-text-closing-curly-brace-wrapped/input.js @@ -0,0 +1 @@ +
{'}'}
diff --git a/packages/babel-parser/test/fixtures/jsx/basic/jsx-text-closing-curly-brace-wrapped/output.json b/packages/babel-parser/test/fixtures/jsx/basic/jsx-text-closing-curly-brace-wrapped/output.json new file mode 100644 index 000000000000..bd70191c7559 --- /dev/null +++ b/packages/babel-parser/test/fixtures/jsx/basic/jsx-text-closing-curly-brace-wrapped/output.json @@ -0,0 +1,56 @@ +{ + "type": "File", + "start":0,"end":16,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":16}}, + "program": { + "type": "Program", + "start":0,"end":16,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":16}}, + "sourceType": "script", + "interpreter": null, + "body": [ + { + "type": "ExpressionStatement", + "start":0,"end":16,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":16}}, + "expression": { + "type": "JSXElement", + "start":0,"end":16,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":16}}, + "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":10,"end":16,"loc":{"start":{"line":1,"column":10},"end":{"line":1,"column":16}}, + "name": { + "type": "JSXIdentifier", + "start":12,"end":15,"loc":{"start":{"line":1,"column":12},"end":{"line":1,"column":15}}, + "name": "div" + } + }, + "children": [ + { + "type": "JSXExpressionContainer", + "start":5,"end":10,"loc":{"start":{"line":1,"column":5},"end":{"line":1,"column":10}}, + "expression": { + "type": "StringLiteral", + "start":6,"end":9,"loc":{"start":{"line":1,"column":6},"end":{"line":1,"column":9}}, + "extra": { + "rawValue": "}", + "raw": "'}'" + }, + "value": "}" + } + } + ] + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/jsx/errors/jsx-text-closing-angle-bracket/input.js b/packages/babel-parser/test/fixtures/jsx/errors/jsx-text-closing-angle-bracket/input.js new file mode 100644 index 000000000000..4397f584cbb1 --- /dev/null +++ b/packages/babel-parser/test/fixtures/jsx/errors/jsx-text-closing-angle-bracket/input.js @@ -0,0 +1 @@ +
>
diff --git a/packages/babel-parser/test/fixtures/jsx/errors/jsx-text-closing-angle-bracket/options.json b/packages/babel-parser/test/fixtures/jsx/errors/jsx-text-closing-angle-bracket/options.json new file mode 100644 index 000000000000..cbf6d1595427 --- /dev/null +++ b/packages/babel-parser/test/fixtures/jsx/errors/jsx-text-closing-angle-bracket/options.json @@ -0,0 +1,3 @@ +{ + "BABEL_8_BREAKING": true +} diff --git a/packages/babel-parser/test/fixtures/jsx/errors/jsx-text-closing-angle-bracket/output.json b/packages/babel-parser/test/fixtures/jsx/errors/jsx-text-closing-angle-bracket/output.json new file mode 100644 index 000000000000..287894bfee60 --- /dev/null +++ b/packages/babel-parser/test/fixtures/jsx/errors/jsx-text-closing-angle-bracket/output.json @@ -0,0 +1,55 @@ +{ + "type": "File", + "start":0,"end":12,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":12}}, + "errors": [ + "SyntaxError: Unexpected token `>`. Did you mean `>` or `{'>'}`? (1:5)" + ], + "program": { + "type": "Program", + "start":0,"end":12,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":12}}, + "sourceType": "script", + "interpreter": null, + "body": [ + { + "type": "ExpressionStatement", + "start":0,"end":12,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":12}}, + "expression": { + "type": "JSXElement", + "start":0,"end":12,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":12}}, + "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":6,"end":12,"loc":{"start":{"line":1,"column":6},"end":{"line":1,"column":12}}, + "name": { + "type": "JSXIdentifier", + "start":8,"end":11,"loc":{"start":{"line":1,"column":8},"end":{"line":1,"column":11}}, + "name": "div" + } + }, + "children": [ + { + "type": "JSXText", + "start":5,"end":6,"loc":{"start":{"line":1,"column":5},"end":{"line":1,"column":6}}, + "extra": { + "rawValue": ">", + "raw": ">" + }, + "value": ">" + } + ] + } + } + ], + "directives": [] + } +} \ No newline at end of file diff --git a/packages/babel-parser/test/fixtures/jsx/errors/jsx-text-closing-curly-brace/input.js b/packages/babel-parser/test/fixtures/jsx/errors/jsx-text-closing-curly-brace/input.js new file mode 100644 index 000000000000..1f7fd22cc8bc --- /dev/null +++ b/packages/babel-parser/test/fixtures/jsx/errors/jsx-text-closing-curly-brace/input.js @@ -0,0 +1 @@ +
}
diff --git a/packages/babel-parser/test/fixtures/jsx/errors/jsx-text-closing-curly-brace/options.json b/packages/babel-parser/test/fixtures/jsx/errors/jsx-text-closing-curly-brace/options.json new file mode 100644 index 000000000000..cbf6d1595427 --- /dev/null +++ b/packages/babel-parser/test/fixtures/jsx/errors/jsx-text-closing-curly-brace/options.json @@ -0,0 +1,3 @@ +{ + "BABEL_8_BREAKING": true +} diff --git a/packages/babel-parser/test/fixtures/jsx/errors/jsx-text-closing-curly-brace/output.json b/packages/babel-parser/test/fixtures/jsx/errors/jsx-text-closing-curly-brace/output.json new file mode 100644 index 000000000000..88df9cb165df --- /dev/null +++ b/packages/babel-parser/test/fixtures/jsx/errors/jsx-text-closing-curly-brace/output.json @@ -0,0 +1,55 @@ +{ + "type": "File", + "start":0,"end":12,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":12}}, + "errors": [ + "SyntaxError: Unexpected token `}`. Did you mean `}` or `{'}'}`? (1:5)" + ], + "program": { + "type": "Program", + "start":0,"end":12,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":12}}, + "sourceType": "script", + "interpreter": null, + "body": [ + { + "type": "ExpressionStatement", + "start":0,"end":12,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":12}}, + "expression": { + "type": "JSXElement", + "start":0,"end":12,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":12}}, + "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":6,"end":12,"loc":{"start":{"line":1,"column":6},"end":{"line":1,"column":12}}, + "name": { + "type": "JSXIdentifier", + "start":8,"end":11,"loc":{"start":{"line":1,"column":8},"end":{"line":1,"column":11}}, + "name": "div" + } + }, + "children": [ + { + "type": "JSXText", + "start":5,"end":6,"loc":{"start":{"line":1,"column":5},"end":{"line":1,"column":6}}, + "extra": { + "rawValue": "}", + "raw": "}" + }, + "value": "}" + } + ] + } + } + ], + "directives": [] + } +} \ No newline at end of file