Revert "Print \x and \u escapes in strings and regexes lowercase (#522)" (#574)

This reverts commit 7148184d65.

There are four types of literals where escapes were normalized:

1. Strings ('\xAb' and "\xAb")
2. Regexes (/\xAb/)
3. Untagged template literals (`\xAb`)
4. Tagged template literals (tag`\xAb`)

However, changing the case of the escapes alters the runtime behavior of
in two of the above cases.

```js
/\xAb/.source === '\\xAb' // true
String.raw`\xAb` === '\\xAb' // true
```

So for regexes and tagged template literals the escapes must not be
changed. Instead of enforcing lowercase escapes in only 50% of the
different cases, it was decided not to bother with escapes at all.

Closes #562.
master
Simon Lydell 2017-02-02 18:54:10 +01:00 committed by Christopher Chedeau
parent b040be2206
commit 69b7bd3fa8
5 changed files with 4 additions and 161 deletions

View File

@ -726,7 +726,7 @@ function genericPrintNoParens(path, options, print) {
case "NullLiteral":
return "null"; // Babel 6 Literal split
case "RegExpLiteral":
return printRegex(n);
return n.extra.raw;
// Babel 6 Literal split
case "NumericLiteral":
return printNumber(n.extra.raw);
@ -736,7 +736,6 @@ function genericPrintNoParens(path, options, print) {
case "StringLiteral":
case "Literal":
if (typeof n.value === "number") return printNumber(n.raw);
if (n.regex) return printRegex(n.regex);
if (typeof n.value !== "string") return "" + n.value;
return nodeStr(n, options); // Babel 6
@ -1231,10 +1230,7 @@ function genericPrintNoParens(path, options, print) {
case "ClassExpression":
return concat(printClass(path, options, print));
case "TemplateElement":
return join(
literalline,
n.value.raw.split("\n").map(line => normalizeEscapes(line))
);
return join(literalline, n.value.raw.split("\n"));
case "TemplateLiteral":
var expressions = path.map(print, "expressions");
@ -2591,37 +2587,7 @@ function makeString(rawContent, enclosingQuote) {
return match;
});
return enclosingQuote + normalizeEscapes(newContent) + enclosingQuote;
}
function printRegex(regexData) {
const pattern = regexData.pattern;
const flags = regexData.flags;
const skipES2015 = !flags.includes("u");
return "/" + normalizeEscapes(pattern, skipES2015) + "/" + flags;
}
function normalizeEscapes(rawContent, skipES2015) {
// Matches \x escapes and \u escapes (including the ES2015 variant) and other
// escapes.
const regex = /(\\x[\da-f]{2}|\\u[\da-f]{4}|\\u\{[\da-f]+\})|(\\[\s\S])/gi;
return rawContent.replace(regex, (match, escape, otherEscape) => {
// Return other escapes as-is.
if (otherEscape) {
return otherEscape;
}
// Regexes without the /u flag do not support ES2015 unicode escapes, so
// return the match as-is.
if (skipES2015 && escape[2] === "{") {
return escape;
}
// Print all \x and \u escapes lowercase.
return escape.toLowerCase();
});
return enclosingQuote + newContent + enclosingQuote;
}
function printNumber(rawNumber) {

View File

@ -116,48 +116,3 @@ function test5(): string {
0.1e-10;
"
`;
exports[`test regex.js 1`] = `
"// Normalization of \\x and \\u escapes:
// Basic case.
/a\\xAaAb\\uB1cDE/gim;
// ES2015 unicode escapes.
/\\u{1Fa3}/u;
/\\u{00000000A0}/u;
// Leaves what looks like a ES2015 unicode escape alone if not using the /u flag.
/\\u{1Fa3}/;
// Leaves what looks like escapes but aren\'t alone.
/\\xA\\u00BG/;
// Leaves other escapes alone.
/\\B\\S/;
// Handles escaped backslashes.
/\\\\xAB\\\\\\xAB\\\\\\\\xAB\\B\\\\\\B\\uAbCd/;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Normalization of \\x and \\u escapes:
// Basic case.
/a\\xaaAb\\ub1cdE/gim;
// ES2015 unicode escapes.
/\\u{1fa3}/u;
/\\u{00000000a0}/u;
// Leaves what looks like a ES2015 unicode escape alone if not using the /u flag.
/\\u{1Fa3}/;
// Leaves what looks like escapes but aren\'t alone.
/\\xA\\u00BG/;
// Leaves other escapes alone.
/\\B\\S/;
// Handles escaped backslashes.
/\\\\xAB\\\\\\xab\\\\\\\\xAB\\B\\\\\\B\\uabcd/;
"
`;

View File

@ -1,20 +0,0 @@
// Normalization of \x and \u escapes:
// Basic case.
/a\xAaAb\uB1cDE/gim;
// ES2015 unicode escapes.
/\u{1Fa3}/u;
/\u{00000000A0}/u;
// Leaves what looks like a ES2015 unicode escape alone if not using the /u flag.
/\u{1Fa3}/;
// Leaves what looks like escapes but aren't alone.
/\xA\u00BG/;
// Leaves other escapes alone.
/\B\S/;
// Handles escaped backslashes.
/\\xAB\\\xAB\\\\xAB\B\\\B\uAbCd/;

View File

@ -24,29 +24,6 @@ exports[`test strings.js 1`] = `
\'\\uD801\\uDC28\',
];
// Normalization of \\x and \\u escapes:
// Basic case.
\"a\\xAaAb\\uB1cDE\";
\`a\\xAaAb\\uB1cDE\`;
// ES2015 unicode escapes.
\"\\u{1Fa3}\";
\`\\u{1Fa3}\`;
\"\\u{00000000A0}\";
\`\\u{00000000A0}\`;
// Leaves other escapes alone.
\"\\B\\S\";
\`\\B\\S\`;
// Handles escaped backslashes.
\"\\\\xAB\\\\\\xAB\\\\\\\\xAB\\B\\\\\\B\\u1234\";
\`\\\\xAB\\\\\\xAB\\\\\\\\xAB\\B\\\\\\B\\u1234\`;
// Mix of everything.
\"\\xF0\"\`a\\uaBcD\${\'\\xFdE\'}\\\\\\u{00AbCdE}\`;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[
\"abc\",
@ -65,18 +42,6 @@ exports[`test strings.js 1`] = `
\"\\0\",
\"🐶\",
\'\\uD801\\uDC28\'
]; // Normalization of \\x and \\u escapes: // Basic case.
\"a\\xaaAb\\ub1cdE\";
\`a\\xaaAb\\ub1cdE\`; // ES2015 unicode escapes.
\"\\u{1fa3}\";
\`\\u{1fa3}\`;
\"\\u{00000000a0}\";
\`\\u{00000000a0}\`; // Leaves other escapes alone.
\"\\B\\S\";
\`\\B\\S\`; // Handles escaped backslashes.
\"\\\\xAB\\\\\\xab\\\\\\\\xAB\\B\\\\\\B\\u1234\";
\`\\\\xAB\\\\\\xab\\\\\\\\xAB\\B\\\\\\B\\u1234\`; // Mix of everything.
\"\\xf0\"\`a\\uabcd\${\"\\xfdE\"}\\\\\\u{00abcde}\`;
];
"
`;

View File

@ -23,26 +23,3 @@
'\uD801\uDC28',
];
// Normalization of \x and \u escapes:
// Basic case.
"a\xAaAb\uB1cDE";
`a\xAaAb\uB1cDE`;
// ES2015 unicode escapes.
"\u{1Fa3}";
`\u{1Fa3}`;
"\u{00000000A0}";
`\u{00000000A0}`;
// Leaves other escapes alone.
"\B\S";
`\B\S`;
// Handles escaped backslashes.
"\\xAB\\\xAB\\\\xAB\B\\\B\u1234";
`\\xAB\\\xAB\\\\xAB\B\\\B\u1234`;
// Mix of everything.
"\xF0"`a\uaBcD${'\xFdE'}\\\u{00AbCdE}`;