From 2d88ccec2a03f990626a06a4be10c65255436d7e Mon Sep 17 00:00:00 2001 From: Andrew Porritt Date: Mon, 7 Oct 2019 16:00:52 +0100 Subject: [PATCH 1/2] Add mapDocInPlace to modify the doc without creating unnecessary copies --- src/doc/doc-utils.js | 16 ++++++++++++++++ src/language-js/embed.js | 11 ++++++----- src/main/core.js | 4 ++-- 3 files changed, 24 insertions(+), 7 deletions(-) diff --git a/src/doc/doc-utils.js b/src/doc/doc-utils.js index 656617a13a42..f27f4d762e5c 100644 --- a/src/doc/doc-utils.js +++ b/src/doc/doc-utils.js @@ -72,6 +72,21 @@ function mapDoc(doc, cb) { return cb(doc); } +function mapDocInPlace(doc, cb) { + if (doc.type === "concat" || doc.type === "fill") { + for (let partIndex = 0; partIndex < doc.parts.length; ++partIndex) { + doc.parts[partIndex] = mapDocInPlace(doc.parts[partIndex], cb); + } + } else if (doc.type === "if-break") { + doc.breakContents = + doc.breakContents && mapDocInPlace(doc.breakContents, cb); + doc.flatContents = doc.flatContents && mapDocInPlace(doc.flatContents, cb); + } else if (doc.contents) { + doc.contents = mapDocInPlace(doc.contents, cb); + } + return cb(doc); +} + function findInDoc(doc, fn, defaultValue) { let result = defaultValue; let hasStopped = false; @@ -212,6 +227,7 @@ module.exports = { traverseDoc, findInDoc, mapDoc, + mapDocInPlace, propagateBreaks, removeLines, stripTrailingHardline diff --git a/src/language-js/embed.js b/src/language-js/embed.js index eb3e1e9d3666..76c7318eb53a 100644 --- a/src/language-js/embed.js +++ b/src/language-js/embed.js @@ -13,7 +13,7 @@ const { group, dedentToRoot }, - utils: { mapDoc, stripTrailingHardline } + utils: { mapDoc, mapDocInPlace, stripTrailingHardline } } = require("../doc"); function embed(path, print, textToDoc, options) { @@ -110,7 +110,7 @@ function embed(path, print, textToDoc, options) { } if (doc) { - doc = escapeTemplateCharacters(doc, false); + doc = escapeTemplateCharacters(doc, false, true); if (!isFirst && startsWithBlankLine) { parts.push(""); } @@ -194,7 +194,7 @@ function embed(path, print, textToDoc, options) { function printMarkdown(text) { const doc = textToDoc(text, { parser: "markdown", __inJsTemplate: true }); - return stripTrailingHardline(escapeTemplateCharacters(doc, true)); + return stripTrailingHardline(escapeTemplateCharacters(doc, true, true)); } } @@ -207,8 +207,9 @@ function uncook(cookedValue) { return cookedValue.replace(/([\\`]|\$\{)/g, "\\$1"); } -function escapeTemplateCharacters(doc, raw) { - return mapDoc(doc, currentDoc => { +function escapeTemplateCharacters(doc, raw, mapInPlace) { + const mapFunc = mapInPlace ? mapDocInPlace : mapDocInPlace; + return mapFunc(doc, currentDoc => { if (!currentDoc.parts) { return currentDoc; } diff --git a/src/main/core.js b/src/main/core.js index 0f37afe6ae2b..4331dd43128d 100644 --- a/src/main/core.js +++ b/src/main/core.js @@ -14,7 +14,7 @@ const { const rangeUtil = require("./range-util"); const privateUtil = require("../common/util"); const { - utils: { mapDoc }, + utils: { mapDocInPlace }, printer: { printDocToString }, debug: { printDocToDebug } } = require("../doc"); @@ -89,7 +89,7 @@ function coreFormat(text, opts, addAlignmentSize) { const result = printDocToString( opts.endOfLine === "lf" ? doc - : mapDoc(doc, currentDoc => + : mapDocInPlace(doc, currentDoc => typeof currentDoc === "string" && currentDoc.indexOf("\n") !== -1 ? currentDoc.replace(/\n/g, eol) : currentDoc From cb8b831a216e146d0d28c96b5a24d34f17a789b0 Mon Sep 17 00:00:00 2001 From: Andrew Porritt Date: Mon, 7 Oct 2019 17:13:01 +0100 Subject: [PATCH 2/2] Remove extra parameter for escapeTemplateCharacters in favour of a comment --- src/language-js/embed.js | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/language-js/embed.js b/src/language-js/embed.js index 76c7318eb53a..b122613de3bf 100644 --- a/src/language-js/embed.js +++ b/src/language-js/embed.js @@ -110,7 +110,7 @@ function embed(path, print, textToDoc, options) { } if (doc) { - doc = escapeTemplateCharacters(doc, false, true); + doc = escapeTemplateCharacters(doc, false); if (!isFirst && startsWithBlankLine) { parts.push(""); } @@ -194,7 +194,7 @@ function embed(path, print, textToDoc, options) { function printMarkdown(text) { const doc = textToDoc(text, { parser: "markdown", __inJsTemplate: true }); - return stripTrailingHardline(escapeTemplateCharacters(doc, true, true)); + return stripTrailingHardline(escapeTemplateCharacters(doc, true)); } } @@ -207,9 +207,10 @@ function uncook(cookedValue) { return cookedValue.replace(/([\\`]|\$\{)/g, "\\$1"); } -function escapeTemplateCharacters(doc, raw, mapInPlace) { - const mapFunc = mapInPlace ? mapDocInPlace : mapDocInPlace; - return mapFunc(doc, currentDoc => { +// Note that this uses mapDocInPlace, and so modifies the +// original doc object. +function escapeTemplateCharacters(doc, raw) { + return mapDocInPlace(doc, currentDoc => { if (!currentDoc.parts) { return currentDoc; }