From ddb3ca0f484f43b045d19d764c4896e820100492 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Mon, 1 Dec 2014 17:27:11 -0800 Subject: [PATCH] Augment escapeString to fix downlevel template literal emit. --- src/compiler/core.ts | 31 ++++++++++++++----- .../reference/templateStringTermination2.js | 2 +- .../reference/templateStringTermination4.js | 2 +- .../reference/templateStringTermination5.js | 2 +- .../templateStringWhitespaceEscapes1.js | 7 +++++ .../templateStringWhitespaceEscapes1.types | 5 +++ .../templateStringWhitespaceEscapes1_ES6.js | 6 ++++ ...templateStringWhitespaceEscapes1_ES6.types | 4 +++ .../templateStringWhitespaceEscapes2.js | 9 ++++++ .../templateStringWhitespaceEscapes2.types | 6 ++++ .../templateStringWhitespaceEscapes2_ES6.js | 8 +++++ ...templateStringWhitespaceEscapes2_ES6.types | 5 +++ .../templateStringWhitespaceEscapes1.ts | 3 ++ .../templateStringWhitespaceEscapes1_ES6.ts | 3 ++ .../templateStringWhitespaceEscapes2.ts | 4 +++ .../templateStringWhitespaceEscapes2_ES6.ts | 4 +++ 16 files changed, 91 insertions(+), 10 deletions(-) create mode 100644 tests/baselines/reference/templateStringWhitespaceEscapes1.js create mode 100644 tests/baselines/reference/templateStringWhitespaceEscapes1.types create mode 100644 tests/baselines/reference/templateStringWhitespaceEscapes1_ES6.js create mode 100644 tests/baselines/reference/templateStringWhitespaceEscapes1_ES6.types create mode 100644 tests/baselines/reference/templateStringWhitespaceEscapes2.js create mode 100644 tests/baselines/reference/templateStringWhitespaceEscapes2.types create mode 100644 tests/baselines/reference/templateStringWhitespaceEscapes2_ES6.js create mode 100644 tests/baselines/reference/templateStringWhitespaceEscapes2_ES6.types create mode 100644 tests/cases/conformance/es6/templates/templateStringWhitespaceEscapes1.ts create mode 100644 tests/cases/conformance/es6/templates/templateStringWhitespaceEscapes1_ES6.ts create mode 100644 tests/cases/conformance/es6/templates/templateStringWhitespaceEscapes2.ts create mode 100644 tests/cases/conformance/es6/templates/templateStringWhitespaceEscapes2_ES6.ts diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 6bbf9a13d03..1d3ae6429fa 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -591,27 +591,44 @@ module ts { return path; } - var escapedCharsRegExp = /[\t\v\f\b\0\r\n\"\\\u2028\u2029\u0085]/g; + var backslashOrDoubleQuote = /[\"\\]/g; + var escapedCharsRegExp = /[\0-\19\t\v\f\b\0\r\n\u2028\u2029\u0085]/g; var escapedCharsMap: Map = { + "\0": "\\0", "\t": "\\t", "\v": "\\v", "\f": "\\f", "\b": "\\b", - "\0": "\\0", "\r": "\\r", "\n": "\\n", + "\\": "\\\\", "\"": "\\\"", "\u2028": "\\u2028", // lineSeparator "\u2029": "\\u2029", // paragraphSeparator "\u0085": "\\u0085" // nextLine }; - /** NOTE: This *does not* support the full escape characters, it only supports the subset that can be used in file names - * or string literals. If the information encoded in the map changes, this needs to be revisited. */ + /** + * Based heavily on the abstract 'Quote' operation from ECMA-262 (24.3.2.2), + * but augmented for a few select characters. + * Note that this doesn't actually wrap the input in double quotes. + */ export function escapeString(s: string): string { - return escapedCharsRegExp.test(s) ? s.replace(escapedCharsRegExp, c => { - return escapedCharsMap[c] || c; - }) : s; + // Prioritize '"' and '\' + s = backslashOrDoubleQuote.test(s) ? s.replace(backslashOrDoubleQuote, getReplacement) : s; + s = escapedCharsRegExp.test(s) ? s.replace(escapedCharsRegExp, getReplacement) : s; + + return s; + + function getReplacement(c: string) { + return escapedCharsMap[c] || unicodeEscape(c); + } + + function unicodeEscape(c: string): string { + var hexCharCode = c.charCodeAt(0).toString(16); + var paddedHexCode = ("0000" + hexCharCode).slice(-4); + return "\\u" + paddedHexCode; + } } export interface ObjectAllocator { diff --git a/tests/baselines/reference/templateStringTermination2.js b/tests/baselines/reference/templateStringTermination2.js index de7792482ee..37fd3ffd6f9 100644 --- a/tests/baselines/reference/templateStringTermination2.js +++ b/tests/baselines/reference/templateStringTermination2.js @@ -3,4 +3,4 @@ `\\` //// [templateStringTermination2.js] -"\"; +"\\"; diff --git a/tests/baselines/reference/templateStringTermination4.js b/tests/baselines/reference/templateStringTermination4.js index 7ef49703665..29bbe4e9316 100644 --- a/tests/baselines/reference/templateStringTermination4.js +++ b/tests/baselines/reference/templateStringTermination4.js @@ -3,4 +3,4 @@ `\\\\` //// [templateStringTermination4.js] -"\\"; +"\\\\"; diff --git a/tests/baselines/reference/templateStringTermination5.js b/tests/baselines/reference/templateStringTermination5.js index af7f1d6a0a6..769597f5209 100644 --- a/tests/baselines/reference/templateStringTermination5.js +++ b/tests/baselines/reference/templateStringTermination5.js @@ -3,4 +3,4 @@ `\\\\\\` //// [templateStringTermination5.js] -"\\\"; +"\\\\\\"; diff --git a/tests/baselines/reference/templateStringWhitespaceEscapes1.js b/tests/baselines/reference/templateStringWhitespaceEscapes1.js new file mode 100644 index 00000000000..1edd38c315b --- /dev/null +++ b/tests/baselines/reference/templateStringWhitespaceEscapes1.js @@ -0,0 +1,7 @@ +//// [templateStringWhitespaceEscapes1.ts] + + +`\t\n\v\f\r`; + +//// [templateStringWhitespaceEscapes1.js] +"\t\n\v\f\r"; diff --git a/tests/baselines/reference/templateStringWhitespaceEscapes1.types b/tests/baselines/reference/templateStringWhitespaceEscapes1.types new file mode 100644 index 00000000000..6c1598e0549 --- /dev/null +++ b/tests/baselines/reference/templateStringWhitespaceEscapes1.types @@ -0,0 +1,5 @@ +=== tests/cases/conformance/es6/templates/templateStringWhitespaceEscapes1.ts === + +No type information for this code. +No type information for this code.`\t\n\v\f\r`; +No type information for this code. \ No newline at end of file diff --git a/tests/baselines/reference/templateStringWhitespaceEscapes1_ES6.js b/tests/baselines/reference/templateStringWhitespaceEscapes1_ES6.js new file mode 100644 index 00000000000..55b93bd68a6 --- /dev/null +++ b/tests/baselines/reference/templateStringWhitespaceEscapes1_ES6.js @@ -0,0 +1,6 @@ +//// [templateStringWhitespaceEscapes1_ES6.ts] + +`\t\n\v\f\r`; + +//// [templateStringWhitespaceEscapes1_ES6.js] +`\t\n\v\f\r`; diff --git a/tests/baselines/reference/templateStringWhitespaceEscapes1_ES6.types b/tests/baselines/reference/templateStringWhitespaceEscapes1_ES6.types new file mode 100644 index 00000000000..53a6c6f9cf9 --- /dev/null +++ b/tests/baselines/reference/templateStringWhitespaceEscapes1_ES6.types @@ -0,0 +1,4 @@ +=== tests/cases/conformance/es6/templates/templateStringWhitespaceEscapes1_ES6.ts === + +No type information for this code.`\t\n\v\f\r`; +No type information for this code. \ No newline at end of file diff --git a/tests/baselines/reference/templateStringWhitespaceEscapes2.js b/tests/baselines/reference/templateStringWhitespaceEscapes2.js new file mode 100644 index 00000000000..144b1e78b8b --- /dev/null +++ b/tests/baselines/reference/templateStringWhitespaceEscapes2.js @@ -0,0 +1,9 @@ +//// [templateStringWhitespaceEscapes2.ts] + + +// , , , , , +`\u0009\u000B\u000C\u0020\u00A0\uFEFF`; + +//// [templateStringWhitespaceEscapes2.js] +// , , , , , +"\t\v\f  "; diff --git a/tests/baselines/reference/templateStringWhitespaceEscapes2.types b/tests/baselines/reference/templateStringWhitespaceEscapes2.types new file mode 100644 index 00000000000..7c7de875379 --- /dev/null +++ b/tests/baselines/reference/templateStringWhitespaceEscapes2.types @@ -0,0 +1,6 @@ +=== tests/cases/conformance/es6/templates/templateStringWhitespaceEscapes2.ts === + +No type information for this code. +No type information for this code.// , , , , , +No type information for this code.`\u0009\u000B\u000C\u0020\u00A0\uFEFF`; +No type information for this code. \ No newline at end of file diff --git a/tests/baselines/reference/templateStringWhitespaceEscapes2_ES6.js b/tests/baselines/reference/templateStringWhitespaceEscapes2_ES6.js new file mode 100644 index 00000000000..bf901c5e843 --- /dev/null +++ b/tests/baselines/reference/templateStringWhitespaceEscapes2_ES6.js @@ -0,0 +1,8 @@ +//// [templateStringWhitespaceEscapes2_ES6.ts] + +// , , , , , +`\u0009\u000B\u000C\u0020\u00A0\uFEFF`; + +//// [templateStringWhitespaceEscapes2_ES6.js] +// , , , , , +`\u0009\u000B\u000C\u0020\u00A0\uFEFF`; diff --git a/tests/baselines/reference/templateStringWhitespaceEscapes2_ES6.types b/tests/baselines/reference/templateStringWhitespaceEscapes2_ES6.types new file mode 100644 index 00000000000..834ce22cc32 --- /dev/null +++ b/tests/baselines/reference/templateStringWhitespaceEscapes2_ES6.types @@ -0,0 +1,5 @@ +=== tests/cases/conformance/es6/templates/templateStringWhitespaceEscapes2_ES6.ts === + +No type information for this code.// , , , , , +No type information for this code.`\u0009\u000B\u000C\u0020\u00A0\uFEFF`; +No type information for this code. \ No newline at end of file diff --git a/tests/cases/conformance/es6/templates/templateStringWhitespaceEscapes1.ts b/tests/cases/conformance/es6/templates/templateStringWhitespaceEscapes1.ts new file mode 100644 index 00000000000..3d1a5459a43 --- /dev/null +++ b/tests/cases/conformance/es6/templates/templateStringWhitespaceEscapes1.ts @@ -0,0 +1,3 @@ + + +`\t\n\v\f\r`; \ No newline at end of file diff --git a/tests/cases/conformance/es6/templates/templateStringWhitespaceEscapes1_ES6.ts b/tests/cases/conformance/es6/templates/templateStringWhitespaceEscapes1_ES6.ts new file mode 100644 index 00000000000..8a16e77e0b2 --- /dev/null +++ b/tests/cases/conformance/es6/templates/templateStringWhitespaceEscapes1_ES6.ts @@ -0,0 +1,3 @@ +//@target: es6 + +`\t\n\v\f\r`; \ No newline at end of file diff --git a/tests/cases/conformance/es6/templates/templateStringWhitespaceEscapes2.ts b/tests/cases/conformance/es6/templates/templateStringWhitespaceEscapes2.ts new file mode 100644 index 00000000000..6df666971ea --- /dev/null +++ b/tests/cases/conformance/es6/templates/templateStringWhitespaceEscapes2.ts @@ -0,0 +1,4 @@ + + +// , , , , , +`\u0009\u000B\u000C\u0020\u00A0\uFEFF`; \ No newline at end of file diff --git a/tests/cases/conformance/es6/templates/templateStringWhitespaceEscapes2_ES6.ts b/tests/cases/conformance/es6/templates/templateStringWhitespaceEscapes2_ES6.ts new file mode 100644 index 00000000000..5ebaf3fad5f --- /dev/null +++ b/tests/cases/conformance/es6/templates/templateStringWhitespaceEscapes2_ES6.ts @@ -0,0 +1,4 @@ +//@target: es6 + +// , , , , , +`\u0009\u000B\u000C\u0020\u00A0\uFEFF`; \ No newline at end of file