Fix rename trying to edit the same range multiple times

This commit is contained in:
Lukas Wirth 2021-10-02 18:50:21 +02:00
parent 745fd9903c
commit 86e5406539
2 changed files with 55 additions and 7 deletions

View File

@ -1899,6 +1899,51 @@ fn func$0() {
fn function() {
function();
}
"#,
)
}
#[test]
fn in_macro_multi_mapping() {
check(
"a",
r#"
fn foo() {
macro_rules! match_ast2 {
($node:ident {
$( $res:expr, )*
}) => {{
$( if $node { $res } else )*
{ loop {} }
}};
}
let $0d = 3;
match_ast2! {
d {
d,
d,
}
};
}
"#,
r#"
fn foo() {
macro_rules! match_ast2 {
($node:ident {
$( $res:expr, )*
}) => {{
$( if $node { $res } else )*
{ loop {} }
}};
}
let a = 3;
match_ast2! {
a {
a,
a,
}
};
}
"#,
)
}

View File

@ -291,23 +291,26 @@ pub fn source_edit_from_references(
new_name: &str,
) -> TextEdit {
let mut edit = TextEdit::builder();
for reference in references {
let has_emitted_edit = match &reference.name {
// macros can cause multiple refs to occur for the same text range, so keep track of what we have edited so far
let mut edited_ranges = Vec::new();
for &FileReference { range, ref name, .. } in references {
let has_emitted_edit = match name {
// if the ranges differ then the node is inside a macro call, we can't really attempt
// to make special rewrites like shorthand syntax and such, so just rename the node in
// the macro input
ast::NameLike::NameRef(name_ref)
if name_ref.syntax().text_range() == reference.range =>
{
ast::NameLike::NameRef(name_ref) if name_ref.syntax().text_range() == range => {
source_edit_from_name_ref(&mut edit, name_ref, new_name, def)
}
ast::NameLike::Name(name) if name.syntax().text_range() == reference.range => {
ast::NameLike::Name(name) if name.syntax().text_range() == range => {
source_edit_from_name(&mut edit, name, new_name)
}
_ => false,
};
if !has_emitted_edit {
edit.replace(reference.range, new_name.to_string());
if !edited_ranges.contains(&range.start()) {
edit.replace(range, new_name.to_string());
edited_ranges.push(range.start());
}
}
}