Skip to content

Commit c1751c8

Browse files
committed
Ignore double quoted single quote
1 parent e5e2202 commit c1751c8

File tree

1 file changed

+37
-9
lines changed

1 file changed

+37
-9
lines changed

src/translate/fragments/interpolable.rs

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -62,14 +62,15 @@ impl InterpolableFragment {
6262

6363
fn balance_single_quotes(&mut self) {
6464
let mut in_single_quotes = false;
65+
let mut in_double_quotes = false;
6566

6667
for s in &mut self.strings {
6768
// If previous chunk left us inside quotes, reopen at the start.
6869
if in_single_quotes {
6970
s.insert_str(0, "\"'");
7071
}
7172

72-
let unescaped = count_unescaped_single_quotes(s);
73+
let unescaped = count_single_quotes(s, &mut in_double_quotes);
7374

7475
// If this chunk has an odd number of unescaped quotes, it toggles the region.
7576
if unescaped % 2 == 1 {
@@ -103,15 +104,21 @@ impl InterpolableFragment {
103104
}
104105

105106
/// Count single quotes that are NOT escaped by an odd number of preceding backslashes.
106-
fn count_unescaped_single_quotes(s: &str) -> usize {
107+
fn count_single_quotes(s: &str, in_double_quotes: &mut bool) -> usize {
107108
let mut count = 0usize;
108109
let mut backslashes = 0usize;
109110

110111
for b in s.bytes() {
111112
match b {
112113
b'\\' => backslashes += 1,
113-
b'\'' => {
114+
b'"' => {
114115
if backslashes % 2 == 0 {
116+
*in_double_quotes = !*in_double_quotes;
117+
}
118+
backslashes = 0;
119+
}
120+
b'\'' => {
121+
if !*in_double_quotes && backslashes % 2 == 0 {
115122
count += 1;
116123
}
117124
backslashes = 0;
@@ -180,12 +187,33 @@ mod tests {
180187

181188
#[test]
182189
fn test_count_unescaped_single_quotes() {
183-
assert_eq!(count_unescaped_single_quotes(r#"foo"#), 0);
184-
assert_eq!(count_unescaped_single_quotes(r#"foo\'bar"#), 0);
185-
assert_eq!(count_unescaped_single_quotes(r#"foo'bar"#), 1);
190+
let mut in_dq;
191+
in_dq = false; assert_eq!(count_single_quotes(r#"foo"#, &mut in_dq), 0);
192+
in_dq = false; assert_eq!(count_single_quotes(r#"foo\'bar"#, &mut in_dq), 0);
193+
in_dq = false; assert_eq!(count_single_quotes(r#"foo'bar"#, &mut in_dq), 1);
186194
// even number of backslashes before quote -> not escaped
187-
assert_eq!(count_unescaped_single_quotes(r#"foo\\\\'bar"#), 1);
188-
assert_eq!(count_unescaped_single_quotes(r#"'\"'"#), 2);
189-
assert_eq!(count_unescaped_single_quotes(r#"'''"#), 3);
195+
in_dq = false; assert_eq!(count_single_quotes(r#"foo\\\\'bar"#, &mut in_dq), 1);
196+
in_dq = false; assert_eq!(count_single_quotes(r#"'"#, &mut in_dq), 1);
197+
in_dq = false; assert_eq!(count_single_quotes(r#"'\"'"#, &mut in_dq), 2);
198+
in_dq = false; assert_eq!(count_single_quotes(r#"'''"#, &mut in_dq), 3);
199+
in_dq = false; assert_eq!(count_single_quotes(r#""'""#, &mut in_dq), 0);
200+
201+
in_dq = false;
202+
assert_eq!(count_single_quotes(r#"'""#, &mut in_dq), 1);
203+
assert!(in_dq);
204+
assert_eq!(count_single_quotes(r#"'""#, &mut in_dq), 0);
205+
assert!(!in_dq);
206+
assert_eq!(count_single_quotes(r#"\"'\""#, &mut in_dq), 1);
207+
assert!(!in_dq);
208+
assert_eq!(count_single_quotes(r#"""#, &mut in_dq), 0);
209+
assert!(in_dq);
210+
assert_eq!(count_single_quotes(r#"'"#, &mut in_dq), 0);
211+
assert!(in_dq);
212+
assert_eq!(count_single_quotes(r#"\'"#, &mut in_dq), 0);
213+
assert!(in_dq);
214+
assert_eq!(count_single_quotes(r#"\""#, &mut in_dq), 0);
215+
assert!(in_dq);
216+
assert_eq!(count_single_quotes(r#"""#, &mut in_dq), 0);
217+
assert!(!in_dq);
190218
}
191219
}

0 commit comments

Comments
 (0)