diff options
Diffstat (limited to 'crates/ide_assists/src/handlers/qualify_path.rs')
-rw-r--r-- | crates/ide_assists/src/handlers/qualify_path.rs | 63 |
1 files changed, 39 insertions, 24 deletions
diff --git a/crates/ide_assists/src/handlers/qualify_path.rs b/crates/ide_assists/src/handlers/qualify_path.rs index b0b0d31b4..272874ae3 100644 --- a/crates/ide_assists/src/handlers/qualify_path.rs +++ b/crates/ide_assists/src/handlers/qualify_path.rs | |||
@@ -1,14 +1,16 @@ | |||
1 | use std::iter; | 1 | use std::iter; |
2 | 2 | ||
3 | use hir::{AsAssocItem, AsName}; | 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, |
8 | ast::{make, ArgListOwner}, | 11 | ast::{make, ArgListOwner}, |
9 | AstNode, | 12 | AstNode, |
10 | }; | 13 | }; |
11 | use test_utils::mark; | ||
12 | 14 | ||
13 | use crate::{ | 15 | use crate::{ |
14 | assist_context::{AssistContext, Assists}, | 16 | assist_context::{AssistContext, Assists}, |
@@ -47,42 +49,42 @@ pub(crate) fn qualify_path(acc: &mut Assists, ctx: &AssistContext) -> Option<()> | |||
47 | let qualify_candidate = match candidate { | 49 | let qualify_candidate = match candidate { |
48 | ImportCandidate::Path(candidate) => { | 50 | ImportCandidate::Path(candidate) => { |
49 | if candidate.qualifier.is_some() { | 51 | if candidate.qualifier.is_some() { |
50 | mark::hit!(qualify_path_qualifier_start); | 52 | cov_mark::hit!(qualify_path_qualifier_start); |
51 | let path = ast::Path::cast(syntax_under_caret)?; | 53 | let path = ast::Path::cast(syntax_under_caret)?; |
52 | let (prev_segment, segment) = (path.qualifier()?.segment()?, path.segment()?); | 54 | let (prev_segment, segment) = (path.qualifier()?.segment()?, path.segment()?); |
53 | QualifyCandidate::QualifierStart(segment, prev_segment.generic_arg_list()) | 55 | QualifyCandidate::QualifierStart(segment, prev_segment.generic_arg_list()) |
54 | } else { | 56 | } else { |
55 | mark::hit!(qualify_path_unqualified_name); | 57 | cov_mark::hit!(qualify_path_unqualified_name); |
56 | let path = ast::Path::cast(syntax_under_caret)?; | 58 | let path = ast::Path::cast(syntax_under_caret)?; |
57 | let generics = path.segment()?.generic_arg_list(); | 59 | let generics = path.segment()?.generic_arg_list(); |
58 | QualifyCandidate::UnqualifiedName(generics) | 60 | QualifyCandidate::UnqualifiedName(generics) |
59 | } | 61 | } |
60 | } | 62 | } |
61 | ImportCandidate::TraitAssocItem(_) => { | 63 | ImportCandidate::TraitAssocItem(_) => { |
62 | mark::hit!(qualify_path_trait_assoc_item); | 64 | cov_mark::hit!(qualify_path_trait_assoc_item); |
63 | let path = ast::Path::cast(syntax_under_caret)?; | 65 | let path = ast::Path::cast(syntax_under_caret)?; |
64 | let (qualifier, segment) = (path.qualifier()?, path.segment()?); | 66 | let (qualifier, segment) = (path.qualifier()?, path.segment()?); |
65 | QualifyCandidate::TraitAssocItem(qualifier, segment) | 67 | QualifyCandidate::TraitAssocItem(qualifier, segment) |
66 | } | 68 | } |
67 | ImportCandidate::TraitMethod(_) => { | 69 | ImportCandidate::TraitMethod(_) => { |
68 | mark::hit!(qualify_path_trait_method); | 70 | cov_mark::hit!(qualify_path_trait_method); |
69 | let mcall_expr = ast::MethodCallExpr::cast(syntax_under_caret)?; | 71 | let mcall_expr = ast::MethodCallExpr::cast(syntax_under_caret)?; |
70 | QualifyCandidate::TraitMethod(ctx.sema.db, mcall_expr) | 72 | QualifyCandidate::TraitMethod(ctx.sema.db, mcall_expr) |
71 | } | 73 | } |
72 | }; | 74 | }; |
73 | 75 | ||
74 | let group_label = group_label(candidate); | 76 | let group_label = group_label(candidate); |
75 | for (import, item) in proposed_imports { | 77 | for import in proposed_imports { |
76 | acc.add_group( | 78 | acc.add_group( |
77 | &group_label, | 79 | &group_label, |
78 | AssistId("qualify_path", AssistKind::QuickFix), | 80 | AssistId("qualify_path", AssistKind::QuickFix), |
79 | label(candidate, &import), | 81 | label(ctx.db(), candidate, &import), |
80 | range, | 82 | range, |
81 | |builder| { | 83 | |builder| { |
82 | qualify_candidate.qualify( | 84 | qualify_candidate.qualify( |
83 | |replace_with: String| builder.replace(range, replace_with), | 85 | |replace_with: String| builder.replace(range, replace_with), |
84 | import, | 86 | &import.import_path, |
85 | item, | 87 | import.item_to_import, |
86 | ) | 88 | ) |
87 | }, | 89 | }, |
88 | ); | 90 | ); |
@@ -98,8 +100,13 @@ enum QualifyCandidate<'db> { | |||
98 | } | 100 | } |
99 | 101 | ||
100 | impl QualifyCandidate<'_> { | 102 | impl QualifyCandidate<'_> { |
101 | fn qualify(&self, mut replacer: impl FnMut(String), import: hir::ModPath, item: hir::ItemInNs) { | 103 | fn qualify( |
102 | 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); | ||
103 | match self { | 110 | match self { |
104 | QualifyCandidate::QualifierStart(segment, generics) => { | 111 | QualifyCandidate::QualifierStart(segment, generics) => { |
105 | 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); |
@@ -160,7 +167,9 @@ fn find_trait_method( | |||
160 | ) -> Option<hir::Function> { | 167 | ) -> Option<hir::Function> { |
161 | if let Some(hir::AssocItem::Function(method)) = | 168 | if let Some(hir::AssocItem::Function(method)) = |
162 | trait_.items(db).into_iter().find(|item: &hir::AssocItem| { | 169 | trait_.items(db).into_iter().find(|item: &hir::AssocItem| { |
163 | item.name(db).map(|name| name == trait_method_name.as_name()).unwrap_or(false) | 170 | item.name(db) |
171 | .map(|name| name.to_string() == trait_method_name.to_string()) | ||
172 | .unwrap_or(false) | ||
164 | }) | 173 | }) |
165 | { | 174 | { |
166 | Some(method) | 175 | Some(method) |
@@ -182,23 +191,29 @@ fn item_as_trait(db: &RootDatabase, item: hir::ItemInNs) -> Option<hir::Trait> { | |||
182 | fn group_label(candidate: &ImportCandidate) -> GroupLabel { | 191 | fn group_label(candidate: &ImportCandidate) -> GroupLabel { |
183 | let name = match candidate { | 192 | let name = match candidate { |
184 | ImportCandidate::Path(it) => &it.name, | 193 | ImportCandidate::Path(it) => &it.name, |
185 | ImportCandidate::TraitAssocItem(it) | ImportCandidate::TraitMethod(it) => &it.name, | 194 | ImportCandidate::TraitAssocItem(it) | ImportCandidate::TraitMethod(it) => { |
195 | &it.assoc_item_name | ||
196 | } | ||
186 | } | 197 | } |
187 | .text(); | 198 | .text(); |
188 | GroupLabel(format!("Qualify {}", name)) | 199 | GroupLabel(format!("Qualify {}", name)) |
189 | } | 200 | } |
190 | 201 | ||
191 | 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 | }; | ||
192 | match candidate { | 207 | match candidate { |
193 | ImportCandidate::Path(candidate) => { | 208 | ImportCandidate::Path(candidate) => { |
194 | if candidate.qualifier.is_some() { | 209 | if candidate.qualifier.is_some() { |
195 | format!("Qualify with `{}`", &import) | 210 | format!("Qualify with `{}`", display_path) |
196 | } else { | 211 | } else { |
197 | format!("Qualify as `{}`", &import) | 212 | format!("Qualify as `{}`", display_path) |
198 | } | 213 | } |
199 | } | 214 | } |
200 | ImportCandidate::TraitAssocItem(_) => format!("Qualify `{}`", &import), | 215 | ImportCandidate::TraitAssocItem(_) => format!("Qualify `{}`", display_path), |
201 | ImportCandidate::TraitMethod(_) => format!("Qualify with cast as `{}`", &import), | 216 | ImportCandidate::TraitMethod(_) => format!("Qualify with cast as `{}`", display_path), |
202 | } | 217 | } |
203 | } | 218 | } |
204 | 219 | ||
@@ -210,7 +225,7 @@ mod tests { | |||
210 | 225 | ||
211 | #[test] | 226 | #[test] |
212 | fn applicable_when_found_an_import_partial() { | 227 | fn applicable_when_found_an_import_partial() { |
213 | mark::check!(qualify_path_unqualified_name); | 228 | cov_mark::check!(qualify_path_unqualified_name); |
214 | check_assist( | 229 | check_assist( |
215 | qualify_path, | 230 | qualify_path, |
216 | r" | 231 | r" |
@@ -502,7 +517,7 @@ fn main() { | |||
502 | 517 | ||
503 | #[test] | 518 | #[test] |
504 | fn associated_struct_const() { | 519 | fn associated_struct_const() { |
505 | mark::check!(qualify_path_qualifier_start); | 520 | cov_mark::check!(qualify_path_qualifier_start); |
506 | check_assist( | 521 | check_assist( |
507 | qualify_path, | 522 | qualify_path, |
508 | r" | 523 | r" |
@@ -603,7 +618,7 @@ fn main() { | |||
603 | 618 | ||
604 | #[test] | 619 | #[test] |
605 | fn associated_trait_const() { | 620 | fn associated_trait_const() { |
606 | mark::check!(qualify_path_trait_assoc_item); | 621 | cov_mark::check!(qualify_path_trait_assoc_item); |
607 | check_assist( | 622 | check_assist( |
608 | qualify_path, | 623 | qualify_path, |
609 | r" | 624 | r" |
@@ -673,7 +688,7 @@ fn main() { | |||
673 | 688 | ||
674 | #[test] | 689 | #[test] |
675 | fn trait_method() { | 690 | fn trait_method() { |
676 | mark::check!(qualify_path_trait_method); | 691 | cov_mark::check!(qualify_path_trait_method); |
677 | check_assist( | 692 | check_assist( |
678 | qualify_path, | 693 | qualify_path, |
679 | r" | 694 | r" |