From 8aacbf0bff9955f1ff537d07df370d4146a986f8 Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Wed, 1 Apr 2020 14:15:18 -0700 Subject: [PATCH 1/3] Add failing test --- ...tStringOrTemplateLiteral_escapedBackslashes.ts | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 tests/cases/fourslash/refactorConvertStringOrTemplateLiteral_escapedBackslashes.ts diff --git a/tests/cases/fourslash/refactorConvertStringOrTemplateLiteral_escapedBackslashes.ts b/tests/cases/fourslash/refactorConvertStringOrTemplateLiteral_escapedBackslashes.ts new file mode 100644 index 0000000000000..6025107ff0321 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertStringOrTemplateLiteral_escapedBackslashes.ts @@ -0,0 +1,15 @@ +/// + +//// console.log(/*0*/"\\[[" + text + "](" + link + ")\\]"/*1*/) + +goTo.select("0", "1"); +edit.applyRefactor({ + refactorName: "Convert to template string", + actionName: "Convert to template string", + actionDescription: ts.Diagnostics.Convert_to_template_string.message, + // Four backslashes here + // = two backslashes in the expected file content + // = one backslash in the string data sent to console.log + // (which is the same as what the user started with) + newContent: 'console.log(`\\\\[[${text}](${link})\\\\]`)', +}); From f7e3445735687dd3210b5072bc08012a46ac1cf5 Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Wed, 1 Apr 2020 16:29:36 -0700 Subject: [PATCH 2/3] Remove extraneous string escape --- src/compiler/utilities.ts | 7 ++++--- src/services/refactors/convertStringOrTemplateLiteral.ts | 1 - 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 2c6f8b70a34b1..6be4956aef3b8 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -3441,7 +3441,7 @@ namespace ts { const doubleQuoteEscapedCharsRegExp = /[\\\"\u0000-\u001f\t\v\f\b\r\n\u2028\u2029\u0085]/g; const singleQuoteEscapedCharsRegExp = /[\\\'\u0000-\u001f\t\v\f\b\r\n\u2028\u2029\u0085]/g; // Template strings should be preserved as much as possible - const backtickQuoteEscapedCharsRegExp = /[\\\`]/g; + const backtickQuoteEscapedCharsRegExp = /[\\`]/g; const escapedCharsMap = createMapFromTemplate({ "\t": "\\t", "\v": "\\v", @@ -3465,8 +3465,9 @@ namespace ts { } function getReplacement(c: string, offset: number, input: string) { - if (c.charCodeAt(0) === CharacterCodes.nullCharacter) { - const lookAhead = input.charCodeAt(offset + c.length); + const charCode = c.charCodeAt(0); + if (charCode === CharacterCodes.nullCharacter) { + const lookAhead = input.charCodeAt(offset + 1); if (lookAhead >= CharacterCodes._0 && lookAhead <= CharacterCodes._9) { // If the null character is followed by digits, print as a hex escape to prevent the result from parsing as an octal (which is forbidden in strict mode) return "\\x00"; diff --git a/src/services/refactors/convertStringOrTemplateLiteral.ts b/src/services/refactors/convertStringOrTemplateLiteral.ts index 58a62a77d7e3c..bfa398109e59a 100644 --- a/src/services/refactors/convertStringOrTemplateLiteral.ts +++ b/src/services/refactors/convertStringOrTemplateLiteral.ts @@ -134,7 +134,6 @@ namespace ts.refactor.convertStringOrTemplateLiteral { index++; } - text = escapeString(text); return [index, text, indexes]; } From b9c86af8e6a6e27a0fceed06fdf2dbd1d402c97b Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Wed, 8 Apr 2020 16:09:33 -0800 Subject: [PATCH 3/3] Revert unnecessary change --- src/compiler/utilities.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 6be4956aef3b8..9b302a9e5222b 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -3465,9 +3465,8 @@ namespace ts { } function getReplacement(c: string, offset: number, input: string) { - const charCode = c.charCodeAt(0); - if (charCode === CharacterCodes.nullCharacter) { - const lookAhead = input.charCodeAt(offset + 1); + if (c.charCodeAt(0) === CharacterCodes.nullCharacter) { + const lookAhead = input.charCodeAt(offset + c.length); if (lookAhead >= CharacterCodes._0 && lookAhead <= CharacterCodes._9) { // If the null character is followed by digits, print as a hex escape to prevent the result from parsing as an octal (which is forbidden in strict mode) return "\\x00";