diff options
Diffstat (limited to 'crates/ide_assists')
-rw-r--r-- | crates/ide_assists/src/handlers/auto_import.rs | 52 | ||||
-rw-r--r-- | crates/ide_assists/src/handlers/qualify_path.rs | 40 | ||||
-rw-r--r-- | crates/ide_assists/src/handlers/replace_derive_with_manual_impl.rs | 33 |
3 files changed, 54 insertions, 71 deletions
diff --git a/crates/ide_assists/src/handlers/auto_import.rs b/crates/ide_assists/src/handlers/auto_import.rs index 1422224ac..7caee8df0 100644 --- a/crates/ide_assists/src/handlers/auto_import.rs +++ b/crates/ide_assists/src/handlers/auto_import.rs | |||
@@ -1,7 +1,7 @@ | |||
1 | use ide_db::helpers::{ | 1 | use ide_db::helpers::{ |
2 | import_assets::{ImportAssets, ImportCandidate}, | 2 | import_assets::{ImportAssets, ImportCandidate}, |
3 | insert_use::{insert_use, ImportScope}, | 3 | insert_use::{insert_use, ImportScope}, |
4 | mod_path_to_ast, | 4 | item_name, mod_path_to_ast, |
5 | }; | 5 | }; |
6 | use syntax::{ast, AstNode, SyntaxNode}; | 6 | use syntax::{ast, AstNode, SyntaxNode}; |
7 | 7 | ||
@@ -92,14 +92,19 @@ pub(crate) fn auto_import(acc: &mut Assists, ctx: &AssistContext) -> Option<()> | |||
92 | let range = ctx.sema.original_range(&syntax_under_caret).range; | 92 | let range = ctx.sema.original_range(&syntax_under_caret).range; |
93 | let group = import_group_message(import_assets.import_candidate()); | 93 | let group = import_group_message(import_assets.import_candidate()); |
94 | let scope = ImportScope::find_insert_use_container(&syntax_under_caret, &ctx.sema)?; | 94 | let scope = ImportScope::find_insert_use_container(&syntax_under_caret, &ctx.sema)?; |
95 | for (import, _) in proposed_imports { | 95 | for import in proposed_imports { |
96 | let name = match item_name(ctx.db(), import.original_item) { | ||
97 | Some(name) => name, | ||
98 | None => continue, | ||
99 | }; | ||
96 | acc.add_group( | 100 | acc.add_group( |
97 | &group, | 101 | &group, |
98 | AssistId("auto_import", AssistKind::QuickFix), | 102 | AssistId("auto_import", AssistKind::QuickFix), |
99 | format!("Import `{}`", &import), | 103 | format!("Import `{}`", name), |
100 | range, | 104 | range, |
101 | |builder| { | 105 | |builder| { |
102 | let rewriter = insert_use(&scope, mod_path_to_ast(&import), ctx.config.insert_use); | 106 | let rewriter = |
107 | insert_use(&scope, mod_path_to_ast(&import.import_path), ctx.config.insert_use); | ||
103 | builder.rewrite(rewriter); | 108 | builder.rewrite(rewriter); |
104 | }, | 109 | }, |
105 | ); | 110 | ); |
@@ -125,10 +130,10 @@ fn import_group_message(import_candidate: &ImportCandidate) -> GroupLabel { | |||
125 | let name = match import_candidate { | 130 | let name = match import_candidate { |
126 | ImportCandidate::Path(candidate) => format!("Import {}", candidate.name.text()), | 131 | ImportCandidate::Path(candidate) => format!("Import {}", candidate.name.text()), |
127 | ImportCandidate::TraitAssocItem(candidate) => { | 132 | ImportCandidate::TraitAssocItem(candidate) => { |
128 | format!("Import a trait for item {}", candidate.name.text()) | 133 | format!("Import a trait for item {}", candidate.assoc_item_name.text()) |
129 | } | 134 | } |
130 | ImportCandidate::TraitMethod(candidate) => { | 135 | ImportCandidate::TraitMethod(candidate) => { |
131 | format!("Import a trait for method {}", candidate.name.text()) | 136 | format!("Import a trait for method {}", candidate.assoc_item_name.text()) |
132 | } | 137 | } |
133 | }; | 138 | }; |
134 | GroupLabel(name) | 139 | GroupLabel(name) |
@@ -221,41 +226,6 @@ mod tests { | |||
221 | } | 226 | } |
222 | 227 | ||
223 | #[test] | 228 | #[test] |
224 | fn auto_imports_are_merged() { | ||
225 | check_assist( | ||
226 | auto_import, | ||
227 | r" | ||
228 | use PubMod::PubStruct1; | ||
229 | |||
230 | struct Test { | ||
231 | test: Pub$0Struct2<u8>, | ||
232 | } | ||
233 | |||
234 | pub mod PubMod { | ||
235 | pub struct PubStruct1; | ||
236 | pub struct PubStruct2<T> { | ||
237 | _t: T, | ||
238 | } | ||
239 | } | ||
240 | ", | ||
241 | r" | ||
242 | use PubMod::{PubStruct1, PubStruct2}; | ||
243 | |||
244 | struct Test { | ||
245 | test: PubStruct2<u8>, | ||
246 | } | ||
247 | |||
248 | pub mod PubMod { | ||
249 | pub struct PubStruct1; | ||
250 | pub struct PubStruct2<T> { | ||
251 | _t: T, | ||
252 | } | ||
253 | } | ||
254 | ", | ||
255 | ); | ||
256 | } | ||
257 | |||
258 | #[test] | ||
259 | fn applicable_when_found_multiple_imports() { | 229 | fn applicable_when_found_multiple_imports() { |
260 | check_assist( | 230 | check_assist( |
261 | auto_import, | 231 | auto_import, |
diff --git a/crates/ide_assists/src/handlers/qualify_path.rs b/crates/ide_assists/src/handlers/qualify_path.rs index d3e34e540..272874ae3 100644 --- a/crates/ide_assists/src/handlers/qualify_path.rs +++ b/crates/ide_assists/src/handlers/qualify_path.rs | |||
@@ -1,7 +1,10 @@ | |||
1 | use std::iter; | 1 | use std::iter; |
2 | 2 | ||
3 | use hir::AsAssocItem; | 3 | use hir::AsAssocItem; |
4 | use ide_db::helpers::{import_assets::ImportCandidate, mod_path_to_ast}; | 4 | use ide_db::helpers::{ |
5 | import_assets::{ImportCandidate, LocatedImport}, | ||
6 | item_name, mod_path_to_ast, | ||
7 | }; | ||
5 | use ide_db::RootDatabase; | 8 | use ide_db::RootDatabase; |
6 | use syntax::{ | 9 | use syntax::{ |
7 | ast, | 10 | ast, |
@@ -71,17 +74,17 @@ pub(crate) fn qualify_path(acc: &mut Assists, ctx: &AssistContext) -> Option<()> | |||
71 | }; | 74 | }; |
72 | 75 | ||
73 | let group_label = group_label(candidate); | 76 | let group_label = group_label(candidate); |
74 | for (import, item) in proposed_imports { | 77 | for import in proposed_imports { |
75 | acc.add_group( | 78 | acc.add_group( |
76 | &group_label, | 79 | &group_label, |
77 | AssistId("qualify_path", AssistKind::QuickFix), | 80 | AssistId("qualify_path", AssistKind::QuickFix), |
78 | label(candidate, &import), | 81 | label(ctx.db(), candidate, &import), |
79 | range, | 82 | range, |
80 | |builder| { | 83 | |builder| { |
81 | qualify_candidate.qualify( | 84 | qualify_candidate.qualify( |
82 | |replace_with: String| builder.replace(range, replace_with), | 85 | |replace_with: String| builder.replace(range, replace_with), |
83 | import, | 86 | &import.import_path, |
84 | item, | 87 | import.item_to_import, |
85 | ) | 88 | ) |
86 | }, | 89 | }, |
87 | ); | 90 | ); |
@@ -97,8 +100,13 @@ enum QualifyCandidate<'db> { | |||
97 | } | 100 | } |
98 | 101 | ||
99 | impl QualifyCandidate<'_> { | 102 | impl QualifyCandidate<'_> { |
100 | fn qualify(&self, mut replacer: impl FnMut(String), import: hir::ModPath, item: hir::ItemInNs) { | 103 | fn qualify( |
101 | let import = mod_path_to_ast(&import); | 104 | &self, |
105 | mut replacer: impl FnMut(String), | ||
106 | import: &hir::ModPath, | ||
107 | item: hir::ItemInNs, | ||
108 | ) { | ||
109 | let import = mod_path_to_ast(import); | ||
102 | match self { | 110 | match self { |
103 | QualifyCandidate::QualifierStart(segment, generics) => { | 111 | QualifyCandidate::QualifierStart(segment, generics) => { |
104 | let generics = generics.as_ref().map_or_else(String::new, ToString::to_string); | 112 | let generics = generics.as_ref().map_or_else(String::new, ToString::to_string); |
@@ -183,23 +191,29 @@ fn item_as_trait(db: &RootDatabase, item: hir::ItemInNs) -> Option<hir::Trait> { | |||
183 | fn group_label(candidate: &ImportCandidate) -> GroupLabel { | 191 | fn group_label(candidate: &ImportCandidate) -> GroupLabel { |
184 | let name = match candidate { | 192 | let name = match candidate { |
185 | ImportCandidate::Path(it) => &it.name, | 193 | ImportCandidate::Path(it) => &it.name, |
186 | ImportCandidate::TraitAssocItem(it) | ImportCandidate::TraitMethod(it) => &it.name, | 194 | ImportCandidate::TraitAssocItem(it) | ImportCandidate::TraitMethod(it) => { |
195 | &it.assoc_item_name | ||
196 | } | ||
187 | } | 197 | } |
188 | .text(); | 198 | .text(); |
189 | GroupLabel(format!("Qualify {}", name)) | 199 | GroupLabel(format!("Qualify {}", name)) |
190 | } | 200 | } |
191 | 201 | ||
192 | fn label(candidate: &ImportCandidate, import: &hir::ModPath) -> String { | 202 | fn label(db: &RootDatabase, candidate: &ImportCandidate, import: &LocatedImport) -> String { |
203 | let display_path = match item_name(db, import.original_item) { | ||
204 | Some(display_path) => display_path.to_string(), | ||
205 | None => "{unknown}".to_string(), | ||
206 | }; | ||
193 | match candidate { | 207 | match candidate { |
194 | ImportCandidate::Path(candidate) => { | 208 | ImportCandidate::Path(candidate) => { |
195 | if candidate.qualifier.is_some() { | 209 | if candidate.qualifier.is_some() { |
196 | format!("Qualify with `{}`", &import) | 210 | format!("Qualify with `{}`", display_path) |
197 | } else { | 211 | } else { |
198 | format!("Qualify as `{}`", &import) | 212 | format!("Qualify as `{}`", display_path) |
199 | } | 213 | } |
200 | } | 214 | } |
201 | ImportCandidate::TraitAssocItem(_) => format!("Qualify `{}`", &import), | 215 | ImportCandidate::TraitAssocItem(_) => format!("Qualify `{}`", display_path), |
202 | ImportCandidate::TraitMethod(_) => format!("Qualify with cast as `{}`", &import), | 216 | ImportCandidate::TraitMethod(_) => format!("Qualify with cast as `{}`", display_path), |
203 | } | 217 | } |
204 | } | 218 | } |
205 | 219 | ||
diff --git a/crates/ide_assists/src/handlers/replace_derive_with_manual_impl.rs b/crates/ide_assists/src/handlers/replace_derive_with_manual_impl.rs index c69bc5cac..88fe2fe90 100644 --- a/crates/ide_assists/src/handlers/replace_derive_with_manual_impl.rs +++ b/crates/ide_assists/src/handlers/replace_derive_with_manual_impl.rs | |||
@@ -1,5 +1,6 @@ | |||
1 | use hir::ModuleDef; | ||
1 | use ide_db::helpers::mod_path_to_ast; | 2 | use ide_db::helpers::mod_path_to_ast; |
2 | use ide_db::imports_locator; | 3 | use ide_db::items_locator; |
3 | use itertools::Itertools; | 4 | use itertools::Itertools; |
4 | use syntax::{ | 5 | use syntax::{ |
5 | ast::{self, make, AstNode, NameOwner}, | 6 | ast::{self, make, AstNode, NameOwner}, |
@@ -64,22 +65,20 @@ pub(crate) fn replace_derive_with_manual_impl( | |||
64 | let current_module = ctx.sema.scope(annotated_name.syntax()).module()?; | 65 | let current_module = ctx.sema.scope(annotated_name.syntax()).module()?; |
65 | let current_crate = current_module.krate(); | 66 | let current_crate = current_module.krate(); |
66 | 67 | ||
67 | let found_traits = imports_locator::find_exact_imports( | 68 | let found_traits = |
68 | &ctx.sema, | 69 | items_locator::with_exact_name(&ctx.sema, current_crate, trait_token.text().to_string()) |
69 | current_crate, | 70 | .into_iter() |
70 | trait_token.text().to_string(), | 71 | .filter_map(|item| match ModuleDef::from(item.as_module_def_id()?) { |
71 | ) | 72 | ModuleDef::Trait(trait_) => Some(trait_), |
72 | .filter_map(|candidate: either::Either<hir::ModuleDef, hir::MacroDef>| match candidate { | 73 | _ => None, |
73 | either::Either::Left(hir::ModuleDef::Trait(trait_)) => Some(trait_), | 74 | }) |
74 | _ => None, | 75 | .flat_map(|trait_| { |
75 | }) | 76 | current_module |
76 | .flat_map(|trait_| { | 77 | .find_use_path(ctx.sema.db, hir::ModuleDef::Trait(trait_)) |
77 | current_module | 78 | .as_ref() |
78 | .find_use_path(ctx.sema.db, hir::ModuleDef::Trait(trait_)) | 79 | .map(mod_path_to_ast) |
79 | .as_ref() | 80 | .zip(Some(trait_)) |
80 | .map(mod_path_to_ast) | 81 | }); |
81 | .zip(Some(trait_)) | ||
82 | }); | ||
83 | 82 | ||
84 | let mut no_traits_found = true; | 83 | let mut no_traits_found = true; |
85 | for (trait_path, trait_) in found_traits.inspect(|_| no_traits_found = false) { | 84 | for (trait_path, trait_) in found_traits.inspect(|_| no_traits_found = false) { |