diff --git a/changelog_unreleased/javascript/12088.md b/changelog_unreleased/javascript/12088.md new file mode 100644 index 000000000..2ebd84743 --- /dev/null +++ b/changelog_unreleased/javascript/12088.md @@ -0,0 +1,23 @@ +#### Inline `await` expressions in JSX (#12088 by @j-f1) + +`await` expressions in JSX are now inlined if their argument would be inlined. + + +```jsx +// Input +{await Promise.all( + someVeryLongExpression +)} + +// Prettier stable +{ + await Promise.all( + someVeryLongExpression + ) +} + +// Prettier main +{await Promise.all( + someVeryLongExpression +)} +``` diff --git a/src/language-js/print/jsx.js b/src/language-js/print/jsx.js index 42fcc570f..bd9dc2bad 100644 --- a/src/language-js/print/jsx.js +++ b/src/language-js/print/jsx.js @@ -502,24 +502,24 @@ function printJsxAttribute(path, options, print) { function printJsxExpressionContainer(path, options, print) { const node = path.getValue(); - const parent = path.getParentNode(0); - const shouldInline = - node.expression.type === "JSXEmptyExpression" || - (!hasComment(node.expression) && - (node.expression.type === "ArrayExpression" || - node.expression.type === "ObjectExpression" || - node.expression.type === "ArrowFunctionExpression" || - isCallExpression(node.expression) || - node.expression.type === "FunctionExpression" || - node.expression.type === "TemplateLiteral" || - node.expression.type === "TaggedTemplateExpression" || - node.expression.type === "DoExpression" || + const shouldInline = (node, parent) => + node.type === "JSXEmptyExpression" || + (!hasComment(node) && + (node.type === "ArrayExpression" || + node.type === "ObjectExpression" || + node.type === "ArrowFunctionExpression" || + (node.type === "AwaitExpression" && + shouldInline(node.argument, node)) || + isCallExpression(node) || + node.type === "FunctionExpression" || + node.type === "TemplateLiteral" || + node.type === "TaggedTemplateExpression" || + node.type === "DoExpression" || (isJsxNode(parent) && - (node.expression.type === "ConditionalExpression" || - isBinaryish(node.expression))))); + (node.type === "ConditionalExpression" || isBinaryish(node))))); - if (shouldInline) { + if (shouldInline(node.expression, path.getParentNode(0))) { return group(["{", print("expression"), lineSuffixBoundary, "}"]); } diff --git a/tests/format/jsx/jsx/__snapshots__/jsfmt.spec.js.snap b/tests/format/jsx/jsx/__snapshots__/jsfmt.spec.js.snap index acb3d774c..f8eacf98c 100644 --- a/tests/format/jsx/jsx/__snapshots__/jsfmt.spec.js.snap +++ b/tests/format/jsx/jsx/__snapshots__/jsfmt.spec.js.snap @@ -616,6 +616,334 @@ singleQuote: true ================================================================================ `; +exports[`await.js - {"singleQuote":false,"jsxSingleQuote":false} format 1`] = ` +====================================options===================================== +jsxSingleQuote: false +parsers: ["flow", "babel", "typescript"] +printWidth: 80 +singleQuote: false + | printWidth +=====================================input====================================== +async function testFunction() { + const short = <> + {await Promise.all( + hierarchyCriticism + )} + {await hierarchyCriticism.ic.me.oa.p} + {await hierarchyCriticism} + + {Promise.all( + hierarchyCriticism + )} + {hierarchyCriticism.ic.me.oa.p} + {hierarchyCriticism} + + + const long = <> + {await Promise.all( + hierarchyCriticismIncongruousCooperateMaterialEducationOriginalArticulateParameter + )} + {await hierarchyCriticism.IncongruousCooperate.MaterialEducation.OriginalArticulate.Parameter} + {await hierarchyCriticismIncongruousCooperateMaterialEducationOriginalArticulateParameter} + + {Promise.all( + hierarchyCriticismIncongruousCooperateMaterialEducationOriginalArticulateParameter + )} + {hierarchyCriticism.IncongruousCooperate.MaterialEducation.OriginalArticulate.Parameter} + {hierarchyCriticismIncongruousCooperateMaterialEducationOriginalArticulateParameter} + +} + +=====================================output===================================== +async function testFunction() { + const short = ( + <> + {await Promise.all(hierarchyCriticism)} + {await hierarchyCriticism.ic.me.oa.p} + {await hierarchyCriticism} + + {Promise.all(hierarchyCriticism)} + {hierarchyCriticism.ic.me.oa.p} + {hierarchyCriticism} + + ); + + const long = ( + <> + {await Promise.all( + hierarchyCriticismIncongruousCooperateMaterialEducationOriginalArticulateParameter + )} + { + await hierarchyCriticism.IncongruousCooperate.MaterialEducation + .OriginalArticulate.Parameter + } + { + await hierarchyCriticismIncongruousCooperateMaterialEducationOriginalArticulateParameter + } + + {Promise.all( + hierarchyCriticismIncongruousCooperateMaterialEducationOriginalArticulateParameter + )} + { + hierarchyCriticism.IncongruousCooperate.MaterialEducation + .OriginalArticulate.Parameter + } + { + hierarchyCriticismIncongruousCooperateMaterialEducationOriginalArticulateParameter + } + + ); +} + +================================================================================ +`; + +exports[`await.js - {"singleQuote":false,"jsxSingleQuote":true} format 1`] = ` +====================================options===================================== +jsxSingleQuote: true +parsers: ["flow", "babel", "typescript"] +printWidth: 80 +singleQuote: false + | printWidth +=====================================input====================================== +async function testFunction() { + const short = <> + {await Promise.all( + hierarchyCriticism + )} + {await hierarchyCriticism.ic.me.oa.p} + {await hierarchyCriticism} + + {Promise.all( + hierarchyCriticism + )} + {hierarchyCriticism.ic.me.oa.p} + {hierarchyCriticism} + + + const long = <> + {await Promise.all( + hierarchyCriticismIncongruousCooperateMaterialEducationOriginalArticulateParameter + )} + {await hierarchyCriticism.IncongruousCooperate.MaterialEducation.OriginalArticulate.Parameter} + {await hierarchyCriticismIncongruousCooperateMaterialEducationOriginalArticulateParameter} + + {Promise.all( + hierarchyCriticismIncongruousCooperateMaterialEducationOriginalArticulateParameter + )} + {hierarchyCriticism.IncongruousCooperate.MaterialEducation.OriginalArticulate.Parameter} + {hierarchyCriticismIncongruousCooperateMaterialEducationOriginalArticulateParameter} + +} + +=====================================output===================================== +async function testFunction() { + const short = ( + <> + {await Promise.all(hierarchyCriticism)} + {await hierarchyCriticism.ic.me.oa.p} + {await hierarchyCriticism} + + {Promise.all(hierarchyCriticism)} + {hierarchyCriticism.ic.me.oa.p} + {hierarchyCriticism} + + ); + + const long = ( + <> + {await Promise.all( + hierarchyCriticismIncongruousCooperateMaterialEducationOriginalArticulateParameter + )} + { + await hierarchyCriticism.IncongruousCooperate.MaterialEducation + .OriginalArticulate.Parameter + } + { + await hierarchyCriticismIncongruousCooperateMaterialEducationOriginalArticulateParameter + } + + {Promise.all( + hierarchyCriticismIncongruousCooperateMaterialEducationOriginalArticulateParameter + )} + { + hierarchyCriticism.IncongruousCooperate.MaterialEducation + .OriginalArticulate.Parameter + } + { + hierarchyCriticismIncongruousCooperateMaterialEducationOriginalArticulateParameter + } + + ); +} + +================================================================================ +`; + +exports[`await.js - {"singleQuote":true,"jsxSingleQuote":false} format 1`] = ` +====================================options===================================== +jsxSingleQuote: false +parsers: ["flow", "babel", "typescript"] +printWidth: 80 +singleQuote: true + | printWidth +=====================================input====================================== +async function testFunction() { + const short = <> + {await Promise.all( + hierarchyCriticism + )} + {await hierarchyCriticism.ic.me.oa.p} + {await hierarchyCriticism} + + {Promise.all( + hierarchyCriticism + )} + {hierarchyCriticism.ic.me.oa.p} + {hierarchyCriticism} + + + const long = <> + {await Promise.all( + hierarchyCriticismIncongruousCooperateMaterialEducationOriginalArticulateParameter + )} + {await hierarchyCriticism.IncongruousCooperate.MaterialEducation.OriginalArticulate.Parameter} + {await hierarchyCriticismIncongruousCooperateMaterialEducationOriginalArticulateParameter} + + {Promise.all( + hierarchyCriticismIncongruousCooperateMaterialEducationOriginalArticulateParameter + )} + {hierarchyCriticism.IncongruousCooperate.MaterialEducation.OriginalArticulate.Parameter} + {hierarchyCriticismIncongruousCooperateMaterialEducationOriginalArticulateParameter} + +} + +=====================================output===================================== +async function testFunction() { + const short = ( + <> + {await Promise.all(hierarchyCriticism)} + {await hierarchyCriticism.ic.me.oa.p} + {await hierarchyCriticism} + + {Promise.all(hierarchyCriticism)} + {hierarchyCriticism.ic.me.oa.p} + {hierarchyCriticism} + + ); + + const long = ( + <> + {await Promise.all( + hierarchyCriticismIncongruousCooperateMaterialEducationOriginalArticulateParameter + )} + { + await hierarchyCriticism.IncongruousCooperate.MaterialEducation + .OriginalArticulate.Parameter + } + { + await hierarchyCriticismIncongruousCooperateMaterialEducationOriginalArticulateParameter + } + + {Promise.all( + hierarchyCriticismIncongruousCooperateMaterialEducationOriginalArticulateParameter + )} + { + hierarchyCriticism.IncongruousCooperate.MaterialEducation + .OriginalArticulate.Parameter + } + { + hierarchyCriticismIncongruousCooperateMaterialEducationOriginalArticulateParameter + } + + ); +} + +================================================================================ +`; + +exports[`await.js - {"singleQuote":true,"jsxSingleQuote":true} format 1`] = ` +====================================options===================================== +jsxSingleQuote: true +parsers: ["flow", "babel", "typescript"] +printWidth: 80 +singleQuote: true + | printWidth +=====================================input====================================== +async function testFunction() { + const short = <> + {await Promise.all( + hierarchyCriticism + )} + {await hierarchyCriticism.ic.me.oa.p} + {await hierarchyCriticism} + + {Promise.all( + hierarchyCriticism + )} + {hierarchyCriticism.ic.me.oa.p} + {hierarchyCriticism} + + + const long = <> + {await Promise.all( + hierarchyCriticismIncongruousCooperateMaterialEducationOriginalArticulateParameter + )} + {await hierarchyCriticism.IncongruousCooperate.MaterialEducation.OriginalArticulate.Parameter} + {await hierarchyCriticismIncongruousCooperateMaterialEducationOriginalArticulateParameter} + + {Promise.all( + hierarchyCriticismIncongruousCooperateMaterialEducationOriginalArticulateParameter + )} + {hierarchyCriticism.IncongruousCooperate.MaterialEducation.OriginalArticulate.Parameter} + {hierarchyCriticismIncongruousCooperateMaterialEducationOriginalArticulateParameter} + +} + +=====================================output===================================== +async function testFunction() { + const short = ( + <> + {await Promise.all(hierarchyCriticism)} + {await hierarchyCriticism.ic.me.oa.p} + {await hierarchyCriticism} + + {Promise.all(hierarchyCriticism)} + {hierarchyCriticism.ic.me.oa.p} + {hierarchyCriticism} + + ); + + const long = ( + <> + {await Promise.all( + hierarchyCriticismIncongruousCooperateMaterialEducationOriginalArticulateParameter + )} + { + await hierarchyCriticism.IncongruousCooperate.MaterialEducation + .OriginalArticulate.Parameter + } + { + await hierarchyCriticismIncongruousCooperateMaterialEducationOriginalArticulateParameter + } + + {Promise.all( + hierarchyCriticismIncongruousCooperateMaterialEducationOriginalArticulateParameter + )} + { + hierarchyCriticism.IncongruousCooperate.MaterialEducation + .OriginalArticulate.Parameter + } + { + hierarchyCriticismIncongruousCooperateMaterialEducationOriginalArticulateParameter + } + + ); +} + +================================================================================ +`; + exports[`conditional-expression.js - {"singleQuote":false,"jsxSingleQuote":false} format 1`] = ` ====================================options===================================== jsxSingleQuote: false diff --git a/tests/format/jsx/jsx/await.js b/tests/format/jsx/jsx/await.js new file mode 100644 index 000000000..3eb1f3296 --- /dev/null +++ b/tests/format/jsx/jsx/await.js @@ -0,0 +1,29 @@ +async function testFunction() { + const short = <> + {await Promise.all( + hierarchyCriticism + )} + {await hierarchyCriticism.ic.me.oa.p} + {await hierarchyCriticism} + + {Promise.all( + hierarchyCriticism + )} + {hierarchyCriticism.ic.me.oa.p} + {hierarchyCriticism} + + + const long = <> + {await Promise.all( + hierarchyCriticismIncongruousCooperateMaterialEducationOriginalArticulateParameter + )} + {await hierarchyCriticism.IncongruousCooperate.MaterialEducation.OriginalArticulate.Parameter} + {await hierarchyCriticismIncongruousCooperateMaterialEducationOriginalArticulateParameter} + + {Promise.all( + hierarchyCriticismIncongruousCooperateMaterialEducationOriginalArticulateParameter + )} + {hierarchyCriticism.IncongruousCooperate.MaterialEducation.OriginalArticulate.Parameter} + {hierarchyCriticismIncongruousCooperateMaterialEducationOriginalArticulateParameter} + +}