Skip to content

fix: rename and add import #19799

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions crates/hir/src/semantics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,9 @@ impl PathResolutionPerNs {
pub fn any(&self) -> Option<PathResolution> {
self.type_ns.or(self.value_ns).or(self.macro_ns)
}
pub fn to_small_vec(&self) -> SmallVec<[Option<PathResolution>; 3]> {
smallvec![self.type_ns, self.value_ns, self.macro_ns,]
}
}

#[derive(Debug)]
Expand Down
34 changes: 31 additions & 3 deletions crates/ide-db/src/rename.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ use crate::{
use base_db::AnchoredPathBuf;
use either::Either;
use hir::{EditionedFileId, FieldSource, FileRange, InFile, ModuleSource, Semantics};
use itertools::Itertools;
use span::{Edition, FileId, SyntaxContext};
use stdx::{TupleExt, never};
use syntax::{
Expand Down Expand Up @@ -316,7 +317,7 @@ fn rename_mod(
let ref_edits = usages.iter().map(|(file_id, references)| {
(
file_id.file_id(sema.db),
source_edit_from_references(references, def, new_name, file_id.edition(sema.db)),
source_edit_from_references(sema, references, def, new_name, file_id.edition(sema.db)),
)
});
source_change.extend(ref_edits);
Expand Down Expand Up @@ -363,7 +364,7 @@ fn rename_reference(
source_change.extend(usages.iter().map(|(file_id, references)| {
(
file_id.file_id(sema.db),
source_edit_from_references(references, def, new_name, file_id.edition(sema.db)),
source_edit_from_references(sema, references, def, new_name, file_id.edition(sema.db)),
)
}));

Expand All @@ -375,6 +376,7 @@ fn rename_reference(
}

pub fn source_edit_from_references(
sema: &Semantics<'_, RootDatabase>,
references: &[FileReference],
def: Definition,
new_name: &str,
Expand All @@ -395,7 +397,7 @@ pub fn source_edit_from_references(
// to make special rewrites like shorthand syntax and such, so just rename the node in
// the macro input
FileReferenceNode::NameRef(name_ref) if name_range == range => {
source_edit_from_name_ref(&mut edit, name_ref, &new_name, def)
source_edit_from_name_ref(&mut edit, sema, name_ref, &new_name, def)
}
FileReferenceNode::Name(name) if name_range == range => {
source_edit_from_name(&mut edit, name, &new_name)
Expand Down Expand Up @@ -438,6 +440,7 @@ fn source_edit_from_name(edit: &mut TextEditBuilder, name: &ast::Name, new_name:

fn source_edit_from_name_ref(
edit: &mut TextEditBuilder,
sema: &Semantics<'_, RootDatabase>,
name_ref: &ast::NameRef,
new_name: &str,
def: Definition,
Expand Down Expand Up @@ -525,6 +528,31 @@ fn source_edit_from_name_ref(
}
_ => (),
}
} else if let Some(res) = ast::UseTree::find_tail_use_tree_for_name_ref(name_ref)
.and_then(|u| u.path())
.and_then(|p| sema.resolve_path_per_ns(&p))
{
let res = res
.to_small_vec()
.into_iter()
.flatten()
.filter_map(|res| match res {
hir::PathResolution::Def(def) => Some(Definition::from(def)),
_ => None,
})
.unique()
.collect::<Vec<_>>();

let range = name_ref.syntax().text_range();
if res.iter().any(|res| res == &def) {
if res.len() == 1 {
edit.replace(range, new_name.to_owned());
} else {
edit.replace(range, format!("{{{}, {}}}", new_name, name_ref.text()));
}
}

return true;
Comment on lines +531 to +555
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When we rename import item, We check that the path is ambiguous or not. if It is ambiguous, we add old import name and new name.

}
false
}
Expand Down
19 changes: 18 additions & 1 deletion crates/ide-db/src/search.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1170,6 +1170,22 @@ impl<'a> FindUsages<'a> {
}
}

fn is_related_import(&self, name_ref: &ast::NameRef) -> bool {
ast::UseTree::find_tail_use_tree_for_name_ref(name_ref)
.and_then(|u| u.path())
.and_then(|path| self.sema.resolve_path_per_ns(&path))
.map(|res| {
res.to_small_vec()
.into_iter()
.filter_map(|res| match res {
Some(PathResolution::Def(def)) => Some(Definition::from(def)),
_ => None,
})
.any(|def| def == self.def)
})
== Some(true)
}

fn found_name_ref(
&self,
name_ref: &ast::NameRef,
Expand All @@ -1180,7 +1196,8 @@ impl<'a> FindUsages<'a> {
if self.def == def
// is our def a trait assoc item? then we want to find all assoc items from trait impls of our trait
|| matches!(self.assoc_item_container, Some(hir::AssocItemContainer::Trait(_)))
&& convert_to_def_in_trait(self.sema.db, def) == self.def =>
&& convert_to_def_in_trait(self.sema.db, def) == self.def
|| self.is_related_import(name_ref) =>
Comment on lines 1196 to +1200
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When I find some definition item, we use NameRefClass::classify but it only return single definition. So, I check use block have some definition.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this change give affect to this test

#[test]
fn attr() {
check(
r#"
//- proc_macros: identity
use proc_macros::identity;
#[proc_macros::$0identity]
fn func() {}
"#,
expect![[r#"
identity Attribute FileId(1) 1..107 32..40
FileId(0) 17..25 import
FileId(0) 43..51
"#]],

{
let FileRange { file_id, range } = self.sema.original_range(name_ref.syntax());
let reference = FileReference {
Expand Down
4 changes: 2 additions & 2 deletions crates/ide/src/references.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1762,7 +1762,6 @@ trait Trait {
)
}

// FIXME: import is classified as function
#[test]
fn attr() {
check(
Expand All @@ -1776,6 +1775,7 @@ fn func() {}
expect![[r#"
identity Attribute FileId(1) 1..107 32..40

FileId(0) 17..25 import
FileId(0) 43..51
"#]],
);
Expand All @@ -1793,7 +1793,6 @@ fn func$0() {}
);
}

// FIXME: import is classified as function
#[test]
fn proc_macro() {
check(
Expand All @@ -1806,6 +1805,7 @@ mirror$0! {}
expect![[r#"
mirror ProcMacro FileId(1) 1..77 22..28

FileId(0) 17..23 import
FileId(0) 26..32
"#]],
)
Expand Down
Loading