aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_assists/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_assists/src')
-rw-r--r--crates/ra_assists/src/assists/auto_import.rs39
1 files changed, 22 insertions, 17 deletions
diff --git a/crates/ra_assists/src/assists/auto_import.rs b/crates/ra_assists/src/assists/auto_import.rs
index 2629f00e6..2068256b0 100644
--- a/crates/ra_assists/src/assists/auto_import.rs
+++ b/crates/ra_assists/src/assists/auto_import.rs
@@ -1,7 +1,6 @@
1use hir::{db::HirDatabase, ModPath}; 1use hir::{db::HirDatabase, ModPath};
2use ra_syntax::{ 2use ra_syntax::{
3 ast::{self, AstNode}, 3 ast::{self, AstNode},
4 SyntaxKind::USE_ITEM,
5 SyntaxNode, 4 SyntaxNode,
6}; 5};
7 6
@@ -33,9 +32,11 @@ pub(crate) fn auto_import<F: ImportsLocator>(
33) -> Option<Assist> { 32) -> Option<Assist> {
34 let path_to_import: ast::Path = ctx.find_node_at_offset()?; 33 let path_to_import: ast::Path = ctx.find_node_at_offset()?;
35 let path_to_import_syntax = path_to_import.syntax(); 34 let path_to_import_syntax = path_to_import.syntax();
36 if path_to_import_syntax.ancestors().find(|ancestor| ancestor.kind() == USE_ITEM).is_some() { 35 if path_to_import_syntax.ancestors().find_map(ast::UseItem::cast).is_some() {
37 return None; 36 return None;
38 } 37 }
38 let name_to_import =
39 path_to_import_syntax.descendants().find_map(ast::NameRef::cast)?.syntax().to_string();
39 40
40 let module = path_to_import_syntax.ancestors().find_map(ast::Module::cast); 41 let module = path_to_import_syntax.ancestors().find_map(ast::Module::cast);
41 let position = match module.and_then(|it| it.item_list()) { 42 let position = match module.and_then(|it| it.item_list()) {
@@ -52,7 +53,7 @@ pub(crate) fn auto_import<F: ImportsLocator>(
52 } 53 }
53 54
54 let proposed_imports = imports_locator 55 let proposed_imports = imports_locator
55 .find_imports(&path_to_import_syntax.to_string()) 56 .find_imports(&name_to_import)
56 .into_iter() 57 .into_iter()
57 .filter_map(|module_def| module_with_name_to_import.find_use_path(ctx.db, module_def)) 58 .filter_map(|module_def| module_with_name_to_import.find_use_path(ctx.db, module_def))
58 .filter(|use_path| !use_path.segments.is_empty()) 59 .filter(|use_path| !use_path.segments.is_empty())
@@ -62,16 +63,12 @@ pub(crate) fn auto_import<F: ImportsLocator>(
62 return None; 63 return None;
63 } 64 }
64 65
65 ctx.add_assist_group( 66 ctx.add_assist_group(AssistId("auto_import"), format!("Import {}", name_to_import), || {
66 AssistId("auto_import"), 67 proposed_imports
67 format!("Import {}", path_to_import_syntax), 68 .into_iter()
68 || { 69 .map(|import| import_to_action(import, &position, &path_to_import_syntax))
69 proposed_imports 70 .collect()
70 .into_iter() 71 })
71 .map(|import| import_to_action(import, &position, &path_to_import_syntax))
72 .collect()
73 },
74 )
75} 72}
76 73
77fn import_to_action(import: ModPath, position: &SyntaxNode, anchor: &SyntaxNode) -> ActionBuilder { 74fn import_to_action(import: ModPath, position: &SyntaxNode, anchor: &SyntaxNode) -> ActionBuilder {
@@ -121,21 +118,29 @@ mod tests {
121 r" 118 r"
122 use PubMod::PubStruct1; 119 use PubMod::PubStruct1;
123 120
124 PubStruct2<|> 121 struct Test {
122 test: Pub<|>Struct2<u8>,
123 }
125 124
126 pub mod PubMod { 125 pub mod PubMod {
127 pub struct PubStruct1; 126 pub struct PubStruct1;
128 pub struct PubStruct2; 127 pub struct PubStruct2<T> {
128 _t: T,
129 }
129 } 130 }
130 ", 131 ",
131 r" 132 r"
132 use PubMod::{PubStruct2, PubStruct1}; 133 use PubMod::{PubStruct2, PubStruct1};
133 134
134 PubStruct2<|> 135 struct Test {
136 test: Pub<|>Struct2<u8>,
137 }
135 138
136 pub mod PubMod { 139 pub mod PubMod {
137 pub struct PubStruct1; 140 pub struct PubStruct1;
138 pub struct PubStruct2; 141 pub struct PubStruct2<T> {
142 _t: T,
143 }
139 } 144 }
140 ", 145 ",
141 ); 146 );