bc7d84c3ce
* a rule * access * after * amount * annotations * assignment * assist * associated * attribute * borrowed * built-in type * clarification * command * const * constructor * corresponding * counterparts * curlies * dependencies * deterministic * diagnostic * duplicates * edge * edited * efficient * elsewhere * execution * expression * extensions * extracted * fill * github * helper * heuristic * incomplete * indent end * inlay * invocation * lifetime * looking * maybe * move * mutability * mutable * necessarily * necessary * negative * nonexistent * occurred * offsets * offsetted * overridden * parameters * params * params_and_where_preds_in_scope * paredit * parent * parentheses * prepended if * punctuation * receive * receiver * referring * repeated * representing * semantically * separately * shouldnot * siblings * similar * something's * statement * struct * structure * surprise * the * this * transparent * unimplemented * unnamed * unnecessary * unneeded * unreachable * unterminated * utilities * variant * variants * visibility * work around (v) * workaround Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com>
308 lines
5.1 KiB
Rust
308 lines
5.1 KiB
Rust
use syntax::{
|
|
ast,
|
|
ast::IsString,
|
|
AstToken,
|
|
SyntaxKind::{CHAR, STRING},
|
|
TextRange, TextSize,
|
|
};
|
|
|
|
use crate::{AssistContext, AssistId, AssistKind, Assists};
|
|
|
|
// Assist: replace_string_with_char
|
|
//
|
|
// Replace string literal with char literal.
|
|
//
|
|
// ```
|
|
// fn main() {
|
|
// find("{$0");
|
|
// }
|
|
// ```
|
|
// ->
|
|
// ```
|
|
// fn main() {
|
|
// find('{');
|
|
// }
|
|
// ```
|
|
pub(crate) fn replace_string_with_char(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
|
|
let token = ctx.find_token_syntax_at_offset(STRING).and_then(ast::String::cast)?;
|
|
let value = token.value()?;
|
|
let target = token.syntax().text_range();
|
|
|
|
if value.chars().take(2).count() != 1 {
|
|
return None;
|
|
}
|
|
let quote_offsets = token.quote_offsets()?;
|
|
|
|
acc.add(
|
|
AssistId("replace_string_with_char", AssistKind::RefactorRewrite),
|
|
"Replace string with char",
|
|
target,
|
|
|edit| {
|
|
let (left, right) = quote_offsets.quotes;
|
|
edit.replace(left, '\'');
|
|
edit.replace(right, '\'');
|
|
if value == "'" {
|
|
edit.insert(left.end(), '\\');
|
|
}
|
|
},
|
|
)
|
|
}
|
|
|
|
// Assist: replace_char_with_string
|
|
//
|
|
// Replace a char literal with a string literal.
|
|
//
|
|
// ```
|
|
// fn main() {
|
|
// find('{$0');
|
|
// }
|
|
// ```
|
|
// ->
|
|
// ```
|
|
// fn main() {
|
|
// find("{");
|
|
// }
|
|
// ```
|
|
pub(crate) fn replace_char_with_string(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
|
|
let token = ctx.find_token_syntax_at_offset(CHAR)?;
|
|
let target = token.text_range();
|
|
|
|
acc.add(
|
|
AssistId("replace_char_with_string", AssistKind::RefactorRewrite),
|
|
"Replace char with string",
|
|
target,
|
|
|edit| {
|
|
if token.text() == "'\"'" {
|
|
edit.replace(token.text_range(), r#""\"""#);
|
|
} else {
|
|
let len = TextSize::of('\'');
|
|
edit.replace(TextRange::at(target.start(), len), '"');
|
|
edit.replace(TextRange::at(target.end() - len, len), '"');
|
|
}
|
|
},
|
|
)
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use crate::tests::{check_assist, check_assist_not_applicable};
|
|
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn replace_string_with_char_assist() {
|
|
check_assist(
|
|
replace_string_with_char,
|
|
r#"
|
|
fn f() {
|
|
let s = "$0c";
|
|
}
|
|
"#,
|
|
r##"
|
|
fn f() {
|
|
let s = 'c';
|
|
}
|
|
"##,
|
|
)
|
|
}
|
|
|
|
#[test]
|
|
fn replace_string_with_char_assist_with_multi_byte_char() {
|
|
check_assist(
|
|
replace_string_with_char,
|
|
r#"
|
|
fn f() {
|
|
let s = "$0😀";
|
|
}
|
|
"#,
|
|
r##"
|
|
fn f() {
|
|
let s = '😀';
|
|
}
|
|
"##,
|
|
)
|
|
}
|
|
|
|
#[test]
|
|
fn replace_string_with_char_multiple_chars() {
|
|
check_assist_not_applicable(
|
|
replace_string_with_char,
|
|
r#"
|
|
fn f() {
|
|
let s = "$0test";
|
|
}
|
|
"#,
|
|
)
|
|
}
|
|
|
|
#[test]
|
|
fn replace_string_with_char_works_inside_macros() {
|
|
check_assist(
|
|
replace_string_with_char,
|
|
r#"
|
|
fn f() {
|
|
format!($0"x", 92)
|
|
}
|
|
"#,
|
|
r##"
|
|
fn f() {
|
|
format!('x', 92)
|
|
}
|
|
"##,
|
|
)
|
|
}
|
|
|
|
#[test]
|
|
fn replace_string_with_char_newline() {
|
|
check_assist(
|
|
replace_string_with_char,
|
|
r#"
|
|
fn f() {
|
|
find($0"\n");
|
|
}
|
|
"#,
|
|
r##"
|
|
fn f() {
|
|
find('\n');
|
|
}
|
|
"##,
|
|
)
|
|
}
|
|
|
|
#[test]
|
|
fn replace_string_with_char_unicode_escape() {
|
|
check_assist(
|
|
replace_string_with_char,
|
|
r#"
|
|
fn f() {
|
|
find($0"\u{7FFF}");
|
|
}
|
|
"#,
|
|
r##"
|
|
fn f() {
|
|
find('\u{7FFF}');
|
|
}
|
|
"##,
|
|
)
|
|
}
|
|
|
|
#[test]
|
|
fn replace_raw_string_with_char() {
|
|
check_assist(
|
|
replace_string_with_char,
|
|
r##"
|
|
fn f() {
|
|
$0r#"X"#
|
|
}
|
|
"##,
|
|
r##"
|
|
fn f() {
|
|
'X'
|
|
}
|
|
"##,
|
|
)
|
|
}
|
|
|
|
#[test]
|
|
fn replace_char_with_string_assist() {
|
|
check_assist(
|
|
replace_char_with_string,
|
|
r"
|
|
fn f() {
|
|
let s = '$0c';
|
|
}
|
|
",
|
|
r#"
|
|
fn f() {
|
|
let s = "c";
|
|
}
|
|
"#,
|
|
)
|
|
}
|
|
|
|
#[test]
|
|
fn replace_char_with_string_assist_with_multi_byte_char() {
|
|
check_assist(
|
|
replace_char_with_string,
|
|
r"
|
|
fn f() {
|
|
let s = '$0😀';
|
|
}
|
|
",
|
|
r#"
|
|
fn f() {
|
|
let s = "😀";
|
|
}
|
|
"#,
|
|
)
|
|
}
|
|
|
|
#[test]
|
|
fn replace_char_with_string_newline() {
|
|
check_assist(
|
|
replace_char_with_string,
|
|
r"
|
|
fn f() {
|
|
find($0'\n');
|
|
}
|
|
",
|
|
r#"
|
|
fn f() {
|
|
find("\n");
|
|
}
|
|
"#,
|
|
)
|
|
}
|
|
|
|
#[test]
|
|
fn replace_char_with_string_unicode_escape() {
|
|
check_assist(
|
|
replace_char_with_string,
|
|
r"
|
|
fn f() {
|
|
find($0'\u{7FFF}');
|
|
}
|
|
",
|
|
r#"
|
|
fn f() {
|
|
find("\u{7FFF}");
|
|
}
|
|
"#,
|
|
)
|
|
}
|
|
|
|
#[test]
|
|
fn replace_char_with_string_quote() {
|
|
check_assist(
|
|
replace_char_with_string,
|
|
r#"
|
|
fn f() {
|
|
find($0'"');
|
|
}
|
|
"#,
|
|
r#"
|
|
fn f() {
|
|
find("\"");
|
|
}
|
|
"#,
|
|
)
|
|
}
|
|
|
|
#[test]
|
|
fn replace_string_with_char_quote() {
|
|
check_assist(
|
|
replace_string_with_char,
|
|
r#"
|
|
fn f() {
|
|
find($0"'");
|
|
}
|
|
"#,
|
|
r#"
|
|
fn f() {
|
|
find('\'');
|
|
}
|
|
"#,
|
|
)
|
|
}
|
|
}
|