Don't remove uselsess \ in string literals (#16563)

This commit is contained in:
SUZUKI Sosuke authored and GitHub committed 2024-08-14 07:53:22 +09:00
1 parent 509a0cc10f
commit 44a35adfa8
8 files changed
+69 -48

No files matched your search

+23
View File
@@ -0,0 +1,23 @@
#### Don't remove useless `\` in string literals (#16563 by @sosukesuzuki)
Previously, Prettier would remove useless escape characters (`\`) from string literals. However, this behavior was inconsistent as it did not apply to template literals, which was reported in [issue #16542](https://github.com/prettier/prettier/issues/16542).
This issue is a feature request to extend this behavior to template literals as well.
After discussing this internally, the Prettier team concluded that removing useless escape characters, whether in string literals or template literals, is the responsibility of a linter, not a formatter.
This change disables the removal of useless escape characters in string literals across all languages supported by Prettier. To keep the previous behavior, we recommend using ESLint rules like [`no-useless-escape`](https://eslint.org/docs/latest/rules/no-useless-escape).
Escaping quotes within string literals (e.g. `"\"\'"`) works the same as before. This is explained on the [Rationale](https://prettier.io/docs/en/rationale.html#strings) page of the official documentation.
<!-- prettier-ignore -->
```jsx
// Input
const str = "\a";
// Prettier stable
const str = "a";
// Prettier main
const str = "\a";
```
+4 -6
View File
@@ -33,12 +33,10 @@ function printString(raw, options) {
return makeString(
rawContent,
enclosingQuote,
!(
options.parser === "css" ||
options.parser === "less" ||
options.parser === "scss" ||
options.__embeddedInHtml
),
// Until Prettier 3.3.3, this option was set to true for most parsers, with some exceptions like CSS.
// Since Prettier 3.3.4, it is set to false for all parsers.
// For more details, please see https://github.com/prettier/prettier/issues/16542#issuecomment-2282249280.
false,
);
}
@@ -17,7 +17,7 @@ const error: string = 123; // Should be an error, but can't lex this file
// @flow
// Example found at
// https://github.com/sebmarkbage/art/blob/51ffce8164a555d652843241c2fdda52e186cbbd/parsers/svg/text.js#L137
const evil_regex_as_a_string = "/[s�]*$/";
const evil_regex_as_a_string = "/[\\s�]*$/";
const error: string = 123; // Should be an error, but can't lex this file
@@ -496,7 +496,7 @@ Object.entries({
};
a = {
a: 1,
"\\a": 1,
b: 2,
};
@@ -714,8 +714,8 @@ Object.entries({
};
a = {
a: 1,
b: 2,
'\\a': 1,
'b': 2,
};
================================================================================
@@ -931,8 +931,8 @@ Object.entries({
};
a = {
a: 1,
b: 2,
"\\a": 1,
"b": 2,
};
================================================================================
@@ -1148,7 +1148,7 @@ Object.entries({
};
a = {
"a": 1,
"\\a": 1,
"b": 2,
};
@@ -236,21 +236,21 @@ singleQuote: true
// Unnecessary escapes.
("'");
('"');
('a');
('a');
('hola');
('hola');
('\\a');
('\\a');
('hol\\a');
('hol\\a');
('hol\\\\a (the a is not escaped)');
('hol\\\\a (the a is not escaped)');
('multiple a unnecessary a escapes');
('multiple a unnecessary a escapes');
('unnecessarily escaped character preceded by escaped backslash \\\\a');
('unnecessarily escaped character preceded by escaped backslash \\\\a');
('multiple \\a unnecessary \\a escapes');
('multiple \\a unnecessary \\a escapes');
('unnecessarily escaped character preceded by escaped backslash \\\\\\a');
('unnecessarily escaped character preceded by escaped backslash \\\\\\a');
('unescaped character preceded by two escaped backslashes \\\\\\\\a');
('unescaped character preceded by two escaped backslashes \\\\\\\\a');
('aa'); // consecutive unnecessarily escaped characters
('aa'); // consecutive unnecessarily escaped characters
('escaped \\u2030 ‰ (should not stay escaped)');
('\\a\\a'); // consecutive unnecessarily escaped characters
('\\a\\a'); // consecutive unnecessarily escaped characters
('escaped \\u2030 \\‰ (should not stay escaped)');
// Meaningful escapes
('octal escapes \\0 \\1 \\2 \\3 \\4 \\5 \\6 \\7');
@@ -448,21 +448,21 @@ printWidth: 80
// Unnecessary escapes.
("'");
('"');
("a");
("a");
("hola");
("hola");
("\\a");
("\\a");
("hol\\a");
("hol\\a");
("hol\\\\a (the a is not escaped)");
("hol\\\\a (the a is not escaped)");
("multiple a unnecessary a escapes");
("multiple a unnecessary a escapes");
("unnecessarily escaped character preceded by escaped backslash \\\\a");
("unnecessarily escaped character preceded by escaped backslash \\\\a");
("multiple \\a unnecessary \\a escapes");
("multiple \\a unnecessary \\a escapes");
("unnecessarily escaped character preceded by escaped backslash \\\\\\a");
("unnecessarily escaped character preceded by escaped backslash \\\\\\a");
("unescaped character preceded by two escaped backslashes \\\\\\\\a");
("unescaped character preceded by two escaped backslashes \\\\\\\\a");
("aa"); // consecutive unnecessarily escaped characters
("aa"); // consecutive unnecessarily escaped characters
("escaped \\u2030 ‰ (should not stay escaped)");
("\\a\\a"); // consecutive unnecessarily escaped characters
("\\a\\a"); // consecutive unnecessarily escaped characters
("escaped \\u2030 \\‰ (should not stay escaped)");
// Meaningful escapes
("octal escapes \\0 \\1 \\2 \\3 \\4 \\5 \\6 \\7");
@@ -154,10 +154,10 @@ trailingComma: "all"
=====================================output=====================================
// https://github.com/babel/babel/pull/11852
"8", "9";
"\\8", "\\9";
() => {
"use strict";
"8", "9";
"\\8", "\\9";
};
================================================================================
@@ -205,10 +205,10 @@ trailingComma: "es5"
=====================================output=====================================
// https://github.com/babel/babel/pull/11852
"8", "9";
"\\8", "\\9";
() => {
"use strict";
"8", "9";
"\\8", "\\9";
};
================================================================================
@@ -25,7 +25,7 @@ runFormatTest(
code: SINGLE_QUOTE + BACKSLASH + character + SINGLE_QUOTE,
output:
character === UNDERSCORE || character === SPACE
? DOUBLE_QUOTE + character + DOUBLE_QUOTE + LINE_FEED
? DOUBLE_QUOTE + BACKSLASH + character + DOUBLE_QUOTE + LINE_FEED
: DOUBLE_QUOTE + BACKSLASH + character + DOUBLE_QUOTE + LINE_FEED,
})),
...characters.map((character) => ({
@@ -1536,7 +1536,7 @@ trailingComma: "all"
"quote": "\\"",
"backslash": "\\\\",
"controls": "\\b\\f\\n\\r\\t",
"slash": "/ & /",
"slash": "/ & \\/",
"alpha": "abcdefghijklmnopqrstuvwyz",
"ALPHA": "ABCDEFGHIJKLMNOPQRSTUVWYZ",
"digit": "0123456789",
@@ -1560,7 +1560,7 @@ trailingComma: "all"
"compact": [1, 2, 3, 4, 5, 6, 7],
"jsontext": "{\\"object with 1 member\\":[\\"array with 1 element\\"]}",
"quotes": "&#34; \\u0022 %22 0x22 034 &#x22;",
"/\\\\\\"\\uCAFE\\uBABE\\uAB98\\uFCDE\\ubcda\\uef4A\\b\\f\\n\\r\\t\`1~!@#$%^&*()_+-=[]{}|;:',./<>?": "A key can be any string"
"\\/\\\\\\"\\uCAFE\\uBABE\\uAB98\\uFCDE\\ubcda\\uef4A\\b\\f\\n\\r\\t\`1~!@#$%^&*()_+-=[]{}|;:',./<>?": "A key can be any string"
},
0.5,
98.6,
@@ -1667,7 +1667,7 @@ trailingComma: "all"
quote: '"',
backslash: "\\\\",
controls: "\\b\\f\\n\\r\\t",
slash: "/ & /",
slash: "/ & \\/",
alpha: "abcdefghijklmnopqrstuvwyz",
ALPHA: "ABCDEFGHIJKLMNOPQRSTUVWYZ",
digit: "0123456789",
@@ -1691,7 +1691,7 @@ trailingComma: "all"
compact: [1, 2, 3, 4, 5, 6, 7],
jsontext: '{"object with 1 member":["array with 1 element"]}',
quotes: "&#34; \\u0022 %22 0x22 034 &#x22;",
"/\\\\\\"\\uCAFE\\uBABE\\uAB98\\uFCDE\\ubcda\\uef4A\\b\\f\\n\\r\\t\`1~!@#$%^&*()_+-=[]{}|;:',./<>?": "A key can be any string",
"\\/\\\\\\"\\uCAFE\\uBABE\\uAB98\\uFCDE\\ubcda\\uef4A\\b\\f\\n\\r\\t\`1~!@#$%^&*()_+-=[]{}|;:',./<>?": "A key can be any string",
},
0.5,
98.6,
@@ -1798,7 +1798,7 @@ trailingComma: "es5"
"quote": "\\"",
"backslash": "\\\\",
"controls": "\\b\\f\\n\\r\\t",
"slash": "/ & /",
"slash": "/ & \\/",
"alpha": "abcdefghijklmnopqrstuvwyz",
"ALPHA": "ABCDEFGHIJKLMNOPQRSTUVWYZ",
"digit": "0123456789",
@@ -1822,7 +1822,7 @@ trailingComma: "es5"
"compact": [1, 2, 3, 4, 5, 6, 7],
"jsontext": "{\\"object with 1 member\\":[\\"array with 1 element\\"]}",
"quotes": "&#34; \\u0022 %22 0x22 034 &#x22;",
"/\\\\\\"\\uCAFE\\uBABE\\uAB98\\uFCDE\\ubcda\\uef4A\\b\\f\\n\\r\\t\`1~!@#$%^&*()_+-=[]{}|;:',./<>?": "A key can be any string"
"\\/\\\\\\"\\uCAFE\\uBABE\\uAB98\\uFCDE\\ubcda\\uef4A\\b\\f\\n\\r\\t\`1~!@#$%^&*()_+-=[]{}|;:',./<>?": "A key can be any string"
},
0.5,
98.6,
@@ -1929,7 +1929,7 @@ trailingComma: "es5"
quote: '"',
backslash: "\\\\",
controls: "\\b\\f\\n\\r\\t",
slash: "/ & /",
slash: "/ & \\/",
alpha: "abcdefghijklmnopqrstuvwyz",
ALPHA: "ABCDEFGHIJKLMNOPQRSTUVWYZ",
digit: "0123456789",
@@ -1953,7 +1953,7 @@ trailingComma: "es5"
compact: [1, 2, 3, 4, 5, 6, 7],
jsontext: '{"object with 1 member":["array with 1 element"]}',
quotes: "&#34; \\u0022 %22 0x22 034 &#x22;",
"/\\\\\\"\\uCAFE\\uBABE\\uAB98\\uFCDE\\ubcda\\uef4A\\b\\f\\n\\r\\t\`1~!@#$%^&*()_+-=[]{}|;:',./<>?": "A key can be any string",
"\\/\\\\\\"\\uCAFE\\uBABE\\uAB98\\uFCDE\\ubcda\\uef4A\\b\\f\\n\\r\\t\`1~!@#$%^&*()_+-=[]{}|;:',./<>?": "A key can be any string",
},
0.5,
98.6,