Skip to content

Commit 2bae169

Browse files
committed
convertStringOrTemplateLiteral.ts: Re-fix escapeStringForTemplate
Make it backslash-escape backticks too. While I was there, remove the use of this function for the text (which was the earlier confused version that used only `text`), and rename it as `escapeRawStringForTemplate` to clarify. Added a test to the preivious pile of tests. Fixes microsoft#45278.
1 parent 03dff41 commit 2bae169

File tree

2 files changed

+18
-7
lines changed

2 files changed

+18
-7
lines changed

src/services/refactors/convertStringOrTemplateLiteral.ts

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -147,14 +147,13 @@ namespace ts.refactor.convertStringOrTemplateLiteral {
147147
}
148148
};
149149

150-
function escapeStringForTemplate(s: string) {
150+
function escapeRawStringForTemplate(s: string) {
151151
// Escaping for $s in strings that are to be used in template strings
152-
// Naive implementation: replace \x by itself and otherwise $ by \$.
152+
// Naive implementation: replace \x by itself and otherwise $ and ` by \$ and \`.
153153
// But to complicate it a bit, this should work for raw strings too.
154-
// And another bit: escape the $ in the replacement for JS's .replace().
155-
return s.replace(/\\.|\$/g, m => m === "$" ? "\\\$" : m);
154+
return s.replace(/\\.|[$`]/g, m => m[0] === "\\" ? m : "\\" + m);
156155
// Finally, a less-backslash-happy version can work too, doing only ${ instead of all $s:
157-
// s.replace(/\\.|\${/g, m => m === "${" ? "\\\${" : m);
156+
// s.replace(/\\.|\${|`/g, m => m[0] === "\\" ? m : "\\" + m);
158157
// but `\$${foo}` is likely more clear than the more-confusing-but-still-working `$${foo}`.
159158
}
160159

@@ -170,8 +169,8 @@ namespace ts.refactor.convertStringOrTemplateLiteral {
170169
while (index < nodes.length) {
171170
const node = nodes[index];
172171
if (isStringLiteralLike(node)) { // includes isNoSubstitutionTemplateLiteral(node)
173-
text += escapeStringForTemplate(node.text);
174-
rawText += escapeStringForTemplate(getTextOfNode(node).slice(1, -1));
172+
text += node.text;
173+
rawText += escapeRawStringForTemplate(getTextOfNode(node).slice(1, -1));
175174
indexes.push(index);
176175
index++;
177176
}

tests/cases/fourslash/refactorConvertStringOrTemplateLiteral_escapeSequences.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,3 +94,15 @@ edit.applyRefactor({
9494
// newContent is: let s = `\u0041\u0061${text}\0\u0000`;
9595
newContent: 'let s = `\\u0041\\u0061${text}\\0\\u0000`;'
9696
});
97+
98+
// @Filename: /i.ts
99+
////let s = /*i1*/'$`' + text + "`\\"/*i2*/;
100+
101+
goTo.select("i1", "i2");
102+
edit.applyRefactor({
103+
refactorName: "Convert to template string",
104+
actionName: "Convert to template string",
105+
actionDescription: ts.Diagnostics.Convert_to_template_string.message,
106+
// newContent is: let s = `\$\`${text}\`\\`;
107+
newContent: 'let s = `\\$\\`${text}\\`\\\\`;'
108+
});

0 commit comments

Comments
 (0)