mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-13 21:54:42 +00:00
Merge #3068
3068: Do not import anything if first segment of the qualified path resolves r=matklad a=SomeoneToIgnore Part of initial https://github.com/rust-analyzer/rust-analyzer/pull/3061, closing 2nd issue mentioned in the last comment there. Co-authored-by: Kirill Bulatov <mail4score@gmail.com>
This commit is contained in:
commit
1b9b13b4b4
1 changed files with 37 additions and 13 deletions
|
@ -27,31 +27,34 @@ use std::collections::BTreeSet;
|
||||||
// # pub mod std { pub mod collections { pub struct HashMap { } } }
|
// # pub mod std { pub mod collections { pub struct HashMap { } } }
|
||||||
// ```
|
// ```
|
||||||
pub(crate) fn auto_import(ctx: AssistCtx) -> Option<Assist> {
|
pub(crate) fn auto_import(ctx: AssistCtx) -> Option<Assist> {
|
||||||
let path_to_import: ast::Path = ctx.find_node_at_offset()?;
|
let path_under_caret: ast::Path = ctx.find_node_at_offset()?;
|
||||||
let path_to_import_syntax = path_to_import.syntax();
|
if path_under_caret.syntax().ancestors().find_map(ast::UseItem::cast).is_some() {
|
||||||
if path_to_import_syntax.ancestors().find_map(ast::UseItem::cast).is_some() {
|
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
let name_to_import =
|
|
||||||
path_to_import_syntax.descendants().find_map(ast::NameRef::cast)?.syntax().to_string();
|
|
||||||
|
|
||||||
let module = path_to_import_syntax.ancestors().find_map(ast::Module::cast);
|
let module = path_under_caret.syntax().ancestors().find_map(ast::Module::cast);
|
||||||
let position = match module.and_then(|it| it.item_list()) {
|
let position = match module.and_then(|it| it.item_list()) {
|
||||||
Some(item_list) => item_list.syntax().clone(),
|
Some(item_list) => item_list.syntax().clone(),
|
||||||
None => {
|
None => {
|
||||||
let current_file = path_to_import_syntax.ancestors().find_map(ast::SourceFile::cast)?;
|
let current_file =
|
||||||
|
path_under_caret.syntax().ancestors().find_map(ast::SourceFile::cast)?;
|
||||||
current_file.syntax().clone()
|
current_file.syntax().clone()
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let source_analyzer = ctx.source_analyzer(&position, None);
|
let source_analyzer = ctx.source_analyzer(&position, None);
|
||||||
let module_with_name_to_import = source_analyzer.module()?;
|
let module_with_name_to_import = source_analyzer.module()?;
|
||||||
if source_analyzer.resolve_path(ctx.db, &path_to_import).is_some() {
|
|
||||||
|
let name_ref_to_import =
|
||||||
|
path_under_caret.syntax().descendants().find_map(ast::NameRef::cast)?;
|
||||||
|
if source_analyzer
|
||||||
|
.resolve_path(ctx.db, &name_ref_to_import.syntax().ancestors().find_map(ast::Path::cast)?)
|
||||||
|
.is_some()
|
||||||
|
{
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut imports_locator = ImportsLocator::new(ctx.db);
|
let name_to_import = name_ref_to_import.syntax().to_string();
|
||||||
|
let proposed_imports = ImportsLocator::new(ctx.db)
|
||||||
let proposed_imports = imports_locator
|
|
||||||
.find_imports(&name_to_import)
|
.find_imports(&name_to_import)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter_map(|module_def| module_with_name_to_import.find_use_path(ctx.db, module_def))
|
.filter_map(|module_def| module_with_name_to_import.find_use_path(ctx.db, module_def))
|
||||||
|
@ -66,10 +69,10 @@ pub(crate) fn auto_import(ctx: AssistCtx) -> Option<Assist> {
|
||||||
let mut group = ctx.add_assist_group(format!("Import {}", name_to_import));
|
let mut group = ctx.add_assist_group(format!("Import {}", name_to_import));
|
||||||
for import in proposed_imports {
|
for import in proposed_imports {
|
||||||
group.add_assist(AssistId("auto_import"), format!("Import `{}`", &import), |edit| {
|
group.add_assist(AssistId("auto_import"), format!("Import `{}`", &import), |edit| {
|
||||||
edit.target(path_to_import_syntax.text_range());
|
edit.target(path_under_caret.syntax().text_range());
|
||||||
insert_use_statement(
|
insert_use_statement(
|
||||||
&position,
|
&position,
|
||||||
path_to_import_syntax,
|
path_under_caret.syntax(),
|
||||||
&import,
|
&import,
|
||||||
edit.text_edit_builder(),
|
edit.text_edit_builder(),
|
||||||
);
|
);
|
||||||
|
@ -266,4 +269,25 @@ mod tests {
|
||||||
"GroupLabel",
|
"GroupLabel",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn not_applicable_when_path_start_is_imported() {
|
||||||
|
check_assist_not_applicable(
|
||||||
|
auto_import,
|
||||||
|
r"
|
||||||
|
pub mod mod1 {
|
||||||
|
pub mod mod2 {
|
||||||
|
pub mod mod3 {
|
||||||
|
pub struct TestStruct;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
use mod1::mod2;
|
||||||
|
fn main() {
|
||||||
|
mod2::mod3::TestStruct<|>
|
||||||
|
}
|
||||||
|
",
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue