Do not prepend / append with a semicolon the only JSX element in a program (#3330)
* Do not prepend / append with a semicolon the only JSX element in a program Fixes #3196 * Limit single JSX element without semicolon to Markdown only * Fix testsmaster
parent
f514d1e93f
commit
172d34e43d
|
@ -12,6 +12,7 @@ const concat = docBuilders.concat;
|
|||
function printSubtree(subtreeParser, path, print, options) {
|
||||
const next = Object.assign({}, { transformDoc: doc => doc }, subtreeParser);
|
||||
next.options = Object.assign({}, options, next.options, {
|
||||
parentParser: options.parser,
|
||||
originalText: next.text
|
||||
});
|
||||
if (next.options.parser === "json") {
|
||||
|
|
|
@ -292,7 +292,11 @@ function genericPrintNoParens(path, options, print, args) {
|
|||
if (n.directive) {
|
||||
return concat([nodeStr(n.expression, options, true), semi]);
|
||||
}
|
||||
return concat([path.call(print, "expression"), semi]); // Babel extension.
|
||||
// Do not append semicolon after the only JSX element in a program
|
||||
return concat([
|
||||
path.call(print, "expression"),
|
||||
isTheOnlyJSXElementInMarkdown(options, path) ? "" : semi
|
||||
]); // Babel extension.
|
||||
case "ParenthesizedExpression":
|
||||
return concat(["(", path.call(print, "expression"), ")"]);
|
||||
case "AssignmentExpression":
|
||||
|
@ -2864,7 +2868,13 @@ function printStatementSequence(path, options, print) {
|
|||
const parts = [];
|
||||
|
||||
// in no-semi mode, prepend statement with semicolon if it might break ASI
|
||||
if (!options.semi && !isClass && stmtNeedsASIProtection(stmtPath)) {
|
||||
// don't prepend the only JSX element in a program with semicolon
|
||||
if (
|
||||
!options.semi &&
|
||||
!isClass &&
|
||||
!isTheOnlyJSXElementInMarkdown(options, stmtPath) &&
|
||||
stmtNeedsASIProtection(stmtPath)
|
||||
) {
|
||||
if (stmt.comments && stmt.comments.some(comment => comment.leading)) {
|
||||
// Note: stmtNeedsASIProtection requires stmtPath to already be printed
|
||||
// as it reads needsParens which is mutated on the instance
|
||||
|
@ -5047,4 +5057,20 @@ function printAstToDoc(ast, options, addAlignmentSize) {
|
|||
return doc;
|
||||
}
|
||||
|
||||
function isTheOnlyJSXElementInMarkdown(options, path) {
|
||||
if (options.parentParser !== "markdown") {
|
||||
return false;
|
||||
}
|
||||
|
||||
const node = path.getNode();
|
||||
|
||||
if (!node.expression || node.expression.type !== "JSXElement") {
|
||||
return false;
|
||||
}
|
||||
|
||||
const parent = path.getParentNode();
|
||||
|
||||
return parent.type === "Program" && parent.body.length == 1;
|
||||
}
|
||||
|
||||
module.exports = { printAstToDoc };
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`semi.md 1`] = `
|
||||
\`\`\`jsx
|
||||
<div>foo</div>
|
||||
\`\`\`
|
||||
|
||||
\`\`\`jsx
|
||||
const a = 1;
|
||||
<div>foo</div>;
|
||||
\`\`\`
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
\`\`\`jsx
|
||||
<div>foo</div>
|
||||
\`\`\`
|
||||
|
||||
\`\`\`jsx
|
||||
const a = 1;
|
||||
<div>foo</div>;
|
||||
\`\`\`
|
||||
|
||||
`;
|
||||
|
||||
exports[`semi.md 2`] = `
|
||||
\`\`\`jsx
|
||||
<div>foo</div>
|
||||
\`\`\`
|
||||
|
||||
\`\`\`jsx
|
||||
const a = 1;
|
||||
<div>foo</div>;
|
||||
\`\`\`
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
\`\`\`jsx
|
||||
<div>foo</div>
|
||||
\`\`\`
|
||||
|
||||
\`\`\`jsx
|
||||
const a = 1
|
||||
;<div>foo</div>
|
||||
\`\`\`
|
||||
|
||||
`;
|
|
@ -0,0 +1,2 @@
|
|||
run_spec(__dirname, { semi: true, parser: "markdown" });
|
||||
run_spec(__dirname, { semi: false, parser: "markdown" });
|
|
@ -0,0 +1,8 @@
|
|||
```jsx
|
||||
<div>foo</div>
|
||||
```
|
||||
|
||||
```jsx
|
||||
const a = 1;
|
||||
<div>foo</div>;
|
||||
```
|
Loading…
Reference in New Issue