mirror of
https://github.com/danbulant/oxc
synced 2026-05-24 12:21:58 +00:00
feat(prettier) Use minimum amount of escapes in strings (#1376)
```ts
[
"foo",
'bar',
"bar'",
'bar\'',
'bar"',
"bar\"",
"bar\"\"\"''",
"bar\"\"\"'''",
]
```
Becomes:
```ts
["foo", "bar", "bar'", "bar'", 'bar"', 'bar"', 'bar"""\'\'', "bar\"\"\"'''"];
```
This commit is contained in:
parent
7b85843981
commit
5f5926e0ba
2 changed files with 59 additions and 2 deletions
|
|
@ -21,6 +21,7 @@ mod function_parameters;
|
|||
mod module;
|
||||
mod object;
|
||||
mod statement;
|
||||
mod string;
|
||||
mod ternary;
|
||||
|
||||
use crate::{
|
||||
|
|
@ -720,8 +721,7 @@ impl<'a> Format<'a> for RegExpLiteral {
|
|||
|
||||
impl<'a> Format<'a> for StringLiteral {
|
||||
fn format(&self, p: &mut Prettier<'a>) -> Doc<'a> {
|
||||
let quote = if p.options.single_quote { "'" } else { "\"" };
|
||||
array!(p, ss!(quote), p.str(&self.value), ss!(quote))
|
||||
array!(p, p.str(&string::print_string(self.value.as_str(), p.options.single_quote)))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
57
crates/oxc_prettier/src/format/string.rs
Normal file
57
crates/oxc_prettier/src/format/string.rs
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
fn get_preferred_quote(raw: &str, prefer_single_quote: bool) -> char {
|
||||
let (preferred_quote_char, alternate_quote_char) =
|
||||
if prefer_single_quote { ('\'', '"') } else { ('"', '\'') };
|
||||
|
||||
let mut preferred_quote_count = 0;
|
||||
let mut alternate_quote_count = 0;
|
||||
|
||||
for character in raw.chars() {
|
||||
if character == preferred_quote_char {
|
||||
preferred_quote_count += 1;
|
||||
} else if character == alternate_quote_char {
|
||||
alternate_quote_count += 1;
|
||||
}
|
||||
}
|
||||
|
||||
if preferred_quote_count > alternate_quote_count {
|
||||
alternate_quote_char
|
||||
} else {
|
||||
preferred_quote_char
|
||||
}
|
||||
}
|
||||
|
||||
fn make_string(raw_text: &str, enclosing_quote: char) -> String {
|
||||
let other_quote = if enclosing_quote == '"' { '\'' } else { '"' };
|
||||
let mut result = String::new();
|
||||
result.push(enclosing_quote);
|
||||
|
||||
let mut chars = raw_text.chars().peekable();
|
||||
while let Some(c) = chars.next() {
|
||||
match c {
|
||||
'\\' => {
|
||||
if let Some(&next_char) = chars.peek() {
|
||||
if next_char != other_quote {
|
||||
result.push('\\');
|
||||
}
|
||||
result.push(next_char);
|
||||
chars.next();
|
||||
} else {
|
||||
result.push('\\');
|
||||
}
|
||||
}
|
||||
_ if c == enclosing_quote => {
|
||||
result.push('\\');
|
||||
result.push(c);
|
||||
}
|
||||
_ => result.push(c),
|
||||
}
|
||||
}
|
||||
|
||||
result.push(enclosing_quote);
|
||||
result
|
||||
}
|
||||
|
||||
pub(super) fn print_string(raw_text: &str, prefer_single_quote: bool) -> String {
|
||||
let enclosing_quote = get_preferred_quote(raw_text, prefer_single_quote);
|
||||
make_string(raw_text, enclosing_quote)
|
||||
}
|
||||
Loading…
Reference in a new issue