Skip to content

Commit

Permalink
Auto merge of #15788 - Young-Flash:import_anonymously, r=lnicola
Browse files Browse the repository at this point in the history
feat: import trait with alias

![import_trait_with_alias](https://github.com/rust-lang/rust-analyzer/assets/71162630/81601160-fe55-46e3-ab8d-b2705e1aa696)

cc `@Veykril`

close #15684
  • Loading branch information
bors committed Oct 31, 2023
2 parents a2e2881 + 929544e commit 99e94d2
Show file tree
Hide file tree
Showing 2 changed files with 276 additions and 12 deletions.
260 changes: 250 additions & 10 deletions crates/ide-assists/src/handlers/auto_import.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use ide_db::{
helpers::mod_path_to_ast,
imports::{
import_assets::{ImportAssets, ImportCandidate, LocatedImport},
insert_use::{insert_use, ImportScope},
insert_use::{insert_use, insert_use_as_alias, ImportScope},
},
};
use syntax::{ast, AstNode, NodeOrToken, SyntaxElement};
Expand Down Expand Up @@ -129,10 +129,12 @@ pub(crate) fn auto_import(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<
for import in proposed_imports {
let import_path = import.import_path;

let (assist_id, import_name) =
(AssistId("auto_import", AssistKind::QuickFix), import_path.display(ctx.db()));
acc.add_group(
&group_label,
AssistId("auto_import", AssistKind::QuickFix),
format!("Import `{}`", import_path.display(ctx.db())),
assist_id,
format!("Import `{}`", import_name),
range,
|builder| {
let scope = match scope.clone() {
Expand All @@ -143,6 +145,38 @@ pub(crate) fn auto_import(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<
insert_use(&scope, mod_path_to_ast(&import_path), &ctx.config.insert_use);
},
);

match import_assets.import_candidate() {
ImportCandidate::TraitAssocItem(name) | ImportCandidate::TraitMethod(name) => {
let is_method =
matches!(import_assets.import_candidate(), ImportCandidate::TraitMethod(_));
let type_ = if is_method { "method" } else { "item" };
let group_label = GroupLabel(format!(
"Import a trait for {} {} by alias",
type_,
name.assoc_item_name.text()
));
acc.add_group(
&group_label,
assist_id,
format!("Import `{} as _`", import_name),
range,
|builder| {
let scope = match scope.clone() {
ImportScope::File(it) => ImportScope::File(builder.make_mut(it)),
ImportScope::Module(it) => ImportScope::Module(builder.make_mut(it)),
ImportScope::Block(it) => ImportScope::Block(builder.make_mut(it)),
};
insert_use_as_alias(
&scope,
mod_path_to_ast(&import_path),
&ctx.config.insert_use,
);
},
);
}
_ => {}
}
}
Some(())
}
Expand Down Expand Up @@ -253,7 +287,8 @@ mod tests {
};

use crate::tests::{
check_assist, check_assist_not_applicable, check_assist_target, TEST_CONFIG,
check_assist, check_assist_by_label, check_assist_not_applicable, check_assist_target,
TEST_CONFIG,
};

fn check_auto_import_order(before: &str, order: &[&str]) {
Expand Down Expand Up @@ -705,7 +740,7 @@ fn main() {

#[test]
fn associated_trait_function() {
check_assist(
check_assist_by_label(
auto_import,
r"
mod test_mod {
Expand Down Expand Up @@ -739,6 +774,44 @@ fn main() {
test_mod::TestStruct::test_function
}
",
"Import `test_mod::TestTrait`",
);

check_assist_by_label(
auto_import,
r"
mod test_mod {
pub trait TestTrait {
fn test_function();
}
pub struct TestStruct {}
impl TestTrait for TestStruct {
fn test_function() {}
}
}
fn main() {
test_mod::TestStruct::test_function$0
}
",
r"
use test_mod::TestTrait as _;
mod test_mod {
pub trait TestTrait {
fn test_function();
}
pub struct TestStruct {}
impl TestTrait for TestStruct {
fn test_function() {}
}
}
fn main() {
test_mod::TestStruct::test_function
}
",
"Import `test_mod::TestTrait as _`",
);
}

Expand Down Expand Up @@ -776,7 +849,44 @@ fn main() {

#[test]
fn associated_trait_const() {
check_assist(
check_assist_by_label(
auto_import,
r"
mod test_mod {
pub trait TestTrait {
const TEST_CONST: u8;
}
pub struct TestStruct {}
impl TestTrait for TestStruct {
const TEST_CONST: u8 = 42;
}
}
fn main() {
test_mod::TestStruct::TEST_CONST$0
}
",
r"
use test_mod::TestTrait as _;
mod test_mod {
pub trait TestTrait {
const TEST_CONST: u8;
}
pub struct TestStruct {}
impl TestTrait for TestStruct {
const TEST_CONST: u8 = 42;
}
}
fn main() {
test_mod::TestStruct::TEST_CONST
}
",
"Import `test_mod::TestTrait as _`",
);

check_assist_by_label(
auto_import,
r"
mod test_mod {
Expand Down Expand Up @@ -810,6 +920,7 @@ fn main() {
test_mod::TestStruct::TEST_CONST
}
",
"Import `test_mod::TestTrait`",
);
}

Expand Down Expand Up @@ -847,7 +958,46 @@ fn main() {

#[test]
fn trait_method() {
check_assist(
check_assist_by_label(
auto_import,
r"
mod test_mod {
pub trait TestTrait {
fn test_method(&self);
}
pub struct TestStruct {}
impl TestTrait for TestStruct {
fn test_method(&self) {}
}
}
fn main() {
let test_struct = test_mod::TestStruct {};
test_struct.test_meth$0od()
}
",
r"
use test_mod::TestTrait as _;
mod test_mod {
pub trait TestTrait {
fn test_method(&self);
}
pub struct TestStruct {}
impl TestTrait for TestStruct {
fn test_method(&self) {}
}
}
fn main() {
let test_struct = test_mod::TestStruct {};
test_struct.test_method()
}
",
"Import `test_mod::TestTrait as _`",
);

check_assist_by_label(
auto_import,
r"
mod test_mod {
Expand Down Expand Up @@ -883,12 +1033,43 @@ fn main() {
test_struct.test_method()
}
",
"Import `test_mod::TestTrait`",
);
}

#[test]
fn trait_method_cross_crate() {
check_assist(
check_assist_by_label(
auto_import,
r"
//- /main.rs crate:main deps:dep
fn main() {
let test_struct = dep::test_mod::TestStruct {};
test_struct.test_meth$0od()
}
//- /dep.rs crate:dep
pub mod test_mod {
pub trait TestTrait {
fn test_method(&self);
}
pub struct TestStruct {}
impl TestTrait for TestStruct {
fn test_method(&self) {}
}
}
",
r"
use dep::test_mod::TestTrait as _;
fn main() {
let test_struct = dep::test_mod::TestStruct {};
test_struct.test_method()
}
",
"Import `dep::test_mod::TestTrait as _`",
);

check_assist_by_label(
auto_import,
r"
//- /main.rs crate:main deps:dep
Expand All @@ -915,12 +1096,41 @@ fn main() {
test_struct.test_method()
}
",
"Import `dep::test_mod::TestTrait`",
);
}

#[test]
fn assoc_fn_cross_crate() {
check_assist(
check_assist_by_label(
auto_import,
r"
//- /main.rs crate:main deps:dep
fn main() {
dep::test_mod::TestStruct::test_func$0tion
}
//- /dep.rs crate:dep
pub mod test_mod {
pub trait TestTrait {
fn test_function();
}
pub struct TestStruct {}
impl TestTrait for TestStruct {
fn test_function() {}
}
}
",
r"
use dep::test_mod::TestTrait as _;
fn main() {
dep::test_mod::TestStruct::test_function
}
",
"Import `dep::test_mod::TestTrait as _`",
);

check_assist_by_label(
auto_import,
r"
//- /main.rs crate:main deps:dep
Expand All @@ -945,12 +1155,41 @@ fn main() {
dep::test_mod::TestStruct::test_function
}
",
"Import `dep::test_mod::TestTrait`",
);
}

#[test]
fn assoc_const_cross_crate() {
check_assist(
check_assist_by_label(
auto_import,
r"
//- /main.rs crate:main deps:dep
fn main() {
dep::test_mod::TestStruct::CONST$0
}
//- /dep.rs crate:dep
pub mod test_mod {
pub trait TestTrait {
const CONST: bool;
}
pub struct TestStruct {}
impl TestTrait for TestStruct {
const CONST: bool = true;
}
}
",
r"
use dep::test_mod::TestTrait as _;
fn main() {
dep::test_mod::TestStruct::CONST
}
",
"Import `dep::test_mod::TestTrait as _`",
);

check_assist_by_label(
auto_import,
r"
//- /main.rs crate:main deps:dep
Expand All @@ -975,6 +1214,7 @@ fn main() {
dep::test_mod::TestStruct::CONST
}
",
"Import `dep::test_mod::TestTrait`",
);
}

Expand Down
Loading

0 comments on commit 99e94d2

Please sign in to comment.