diff --git a/src/doc-utils.js b/src/doc-utils.js index be075585..bbef8d99 100644 --- a/src/doc-utils.js +++ b/src/doc-utils.js @@ -33,6 +33,23 @@ function traverseDoc(doc, onEnter, onExit) { traverseDocRec(doc); } +function mapDoc(doc, func) { + doc = func(doc); + + if(doc.type === "concat") { + return Object.assign({}, doc, { parts: doc.parts.map(d => mapDoc(d, func)) }); + } else if (doc.type === "if-break") { + return Object.assign({}, doc, { + breakContents: doc.breakContents && mapDoc(doc.breakContents, func), + flatContents: doc.flatContents && mapDoc(doc.flatContents, func) + }); + } else if(doc.contents) { + return Object.assign({}, doc, { contents: mapDoc(doc.contents, func) }); + } else { + return doc; + } +} + function findInDoc(doc, fn, defaultValue) { var result = defaultValue; traverseDoc(doc, function(doc) { @@ -132,5 +149,6 @@ module.exports = { willBreak, isLineNext, traverseDoc, + mapDoc, propagateBreaks }; diff --git a/src/printer.js b/src/printer.js index c61ccf38..e46132c4 100644 --- a/src/printer.js +++ b/src/printer.js @@ -1365,6 +1365,19 @@ function genericPrintNoParens(path, options, print) { case "TemplateLiteral": var expressions = path.map(print, "expressions"); + function removeLines(doc) { + // Force this doc into flat mode by statically converting all + // lines into spaces (or soft lines into nothing). Hard lines + // should still output because there's too great of a chance + // of breaking existing assumptions otherwise. + return docUtils.mapDoc(doc, d => { + if (d.type === "line" && !d.hard) { + return d.soft ? "" : " "; + } + return d; + }); + } + parts.push("`"); path.each( @@ -1374,7 +1387,7 @@ function genericPrintNoParens(path, options, print) { parts.push(print(childPath)); if (i < expressions.length) { - parts.push("${", expressions[i], "}"); + parts.push("${", removeLines(expressions[i]), "}"); } }, "quasis" diff --git a/tests/strings/__snapshots__/jsfmt.spec.js.snap b/tests/strings/__snapshots__/jsfmt.spec.js.snap index f6743984..cf292b02 100644 --- a/tests/strings/__snapshots__/jsfmt.spec.js.snap +++ b/tests/strings/__snapshots__/jsfmt.spec.js.snap @@ -26,6 +26,16 @@ exports[`strings.js 1`] = ` '\\\\uD801\\\\uDC28', ]; + +foo(\`a long string \${ 1 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 } with expr\`); + +const x = \`a long string \${ 1 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + ( function() {return 3 })() + 3 + 2 + 3 + 2 + 3 } with expr\`; + +foo(\`a long string \${ 1 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + ( function() { + const x = 5; + + return x; + })() + 3 + 2 + 3 + 2 + 3 } with expr\`); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [ \\"abc\\", @@ -51,5 +61,17 @@ exports[`strings.js 1`] = ` \\"🐶\\", '\\\\uD801\\\\uDC28' ]; +foo( + \`a long string \${1 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3} with expr\` +); +const x = \`a long string \${1 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + (function() { + return 3; + })() + 3 + 2 + 3 + 2 + 3} with expr\`; +foo( + \`a long string \${1 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + (function() { + const x = 5; + return x; + })() + 3 + 2 + 3 + 2 + 3} with expr\` +); " `; diff --git a/tests/strings/strings.js b/tests/strings/strings.js index d31dceb2..8eea02e7 100644 --- a/tests/strings/strings.js +++ b/tests/strings/strings.js @@ -23,3 +23,13 @@ '\uD801\uDC28', ]; + +foo(`a long string ${ 1 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 } with expr`); + +const x = `a long string ${ 1 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + ( function() {return 3 })() + 3 + 2 + 3 + 2 + 3 } with expr`; + +foo(`a long string ${ 1 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + 3 + 2 + ( function() { + const x = 5; + + return x; + })() + 3 + 2 + 3 + 2 + 3 } with expr`);