Skip to content

Commit 13bdfab

Browse files
committed
Fix replace_string_with_char escaped char quote
1 parent 9ef1417 commit 13bdfab

File tree

1 file changed

+145
-5
lines changed

1 file changed

+145
-5
lines changed

crates/ide-assists/src/handlers/replace_string_with_char.rs

+145-5
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use syntax::{
55
ast::IsString,
66
};
77

8-
use crate::{AssistContext, AssistId, Assists};
8+
use crate::{AssistContext, AssistId, Assists, utils::string_suffix};
99

1010
// Assist: replace_string_with_char
1111
//
@@ -38,9 +38,11 @@ pub(crate) fn replace_string_with_char(acc: &mut Assists, ctx: &AssistContext<'_
3838
target,
3939
|edit| {
4040
let (left, right) = quote_offsets.quotes;
41+
let suffix = TextSize::of(string_suffix(token.text()).unwrap_or_default());
42+
let right = TextRange::new(right.start(), right.end() - suffix);
4143
edit.replace(left, '\'');
4244
edit.replace(right, '\'');
43-
if value == "'" {
45+
if token.text_without_quotes() == "'" {
4446
edit.insert(left.end(), '\\');
4547
}
4648
},
@@ -71,12 +73,14 @@ pub(crate) fn replace_char_with_string(acc: &mut Assists, ctx: &AssistContext<'_
7173
"Replace char with string",
7274
target,
7375
|edit| {
74-
if token.text() == "'\"'" {
75-
edit.replace(token.text_range(), r#""\"""#);
76+
let suffix = string_suffix(token.text()).unwrap_or_default();
77+
if token.text().starts_with("'\"'") {
78+
edit.replace(token.text_range(), format!(r#""\""{suffix}"#));
7679
} else {
7780
let len = TextSize::of('\'');
81+
let suffix = TextSize::of(suffix);
7882
edit.replace(TextRange::at(target.start(), len), '"');
79-
edit.replace(TextRange::at(target.end() - len, len), '"');
83+
edit.replace(TextRange::at(target.end() - suffix - len, len), '"');
8084
}
8185
},
8286
)
@@ -105,6 +109,23 @@ fn f() {
105109
)
106110
}
107111

112+
#[test]
113+
fn replace_string_with_char_has_suffix() {
114+
check_assist(
115+
replace_string_with_char,
116+
r#"
117+
fn f() {
118+
let s = "$0c"i32;
119+
}
120+
"#,
121+
r##"
122+
fn f() {
123+
let s = 'c'i32;
124+
}
125+
"##,
126+
)
127+
}
128+
108129
#[test]
109130
fn replace_string_with_char_assist_with_multi_byte_char() {
110131
check_assist(
@@ -287,6 +308,40 @@ fn f() {
287308
)
288309
}
289310

311+
#[test]
312+
fn replace_char_with_string_quote_has_suffix() {
313+
check_assist(
314+
replace_char_with_string,
315+
r#"
316+
fn f() {
317+
find($0'"'i32);
318+
}
319+
"#,
320+
r#"
321+
fn f() {
322+
find("\""i32);
323+
}
324+
"#,
325+
)
326+
}
327+
328+
#[test]
329+
fn replace_char_with_string_escaped_quote_has_suffix() {
330+
check_assist(
331+
replace_char_with_string,
332+
r#"
333+
fn f() {
334+
find($0'\"'i32);
335+
}
336+
"#,
337+
r#"
338+
fn f() {
339+
find("\""i32);
340+
}
341+
"#,
342+
)
343+
}
344+
290345
#[test]
291346
fn replace_string_with_char_quote() {
292347
check_assist(
@@ -300,6 +355,91 @@ fn f() {
300355
fn f() {
301356
find('\'');
302357
}
358+
"#,
359+
)
360+
}
361+
362+
#[test]
363+
fn replace_string_with_escaped_char_quote() {
364+
check_assist(
365+
replace_string_with_char,
366+
r#"
367+
fn f() {
368+
find($0"\'");
369+
}
370+
"#,
371+
r#"
372+
fn f() {
373+
find('\'');
374+
}
375+
"#,
376+
)
377+
}
378+
379+
#[test]
380+
fn replace_string_with_char_quote_has_suffix() {
381+
check_assist(
382+
replace_string_with_char,
383+
r#"
384+
fn f() {
385+
find($0"'"i32);
386+
}
387+
"#,
388+
r#"
389+
fn f() {
390+
find('\''i32);
391+
}
392+
"#,
393+
)
394+
}
395+
396+
#[test]
397+
fn replace_string_with_escaped_char_quote_has_suffix() {
398+
check_assist(
399+
replace_string_with_char,
400+
r#"
401+
fn f() {
402+
find($0"\'"i32);
403+
}
404+
"#,
405+
r#"
406+
fn f() {
407+
find('\''i32);
408+
}
409+
"#,
410+
)
411+
}
412+
413+
#[test]
414+
fn replace_raw_string_with_char_quote() {
415+
check_assist(
416+
replace_string_with_char,
417+
r#"
418+
fn f() {
419+
find($0r"'");
420+
}
421+
"#,
422+
r#"
423+
fn f() {
424+
find('\'');
425+
}
426+
"#,
427+
)
428+
}
429+
430+
#[test]
431+
fn replace_string_with_code_escaped_char_quote() {
432+
check_assist(
433+
replace_string_with_char,
434+
r#"
435+
fn f() {
436+
find($0"\x27");
437+
}
438+
"#,
439+
r#"
440+
fn f() {
441+
find('\x27');
442+
}
303443
"#,
304444
)
305445
}

0 commit comments

Comments
 (0)