diff options
Diffstat (limited to 'crates/ide_db/src/helpers')
-rw-r--r-- | crates/ide_db/src/helpers/import_assets.rs | 47 |
1 files changed, 23 insertions, 24 deletions
diff --git a/crates/ide_db/src/helpers/import_assets.rs b/crates/ide_db/src/helpers/import_assets.rs index 9bdc93877..f2866af13 100644 --- a/crates/ide_db/src/helpers/import_assets.rs +++ b/crates/ide_db/src/helpers/import_assets.rs | |||
@@ -1,11 +1,11 @@ | |||
1 | //! Look up accessible paths for items. | 1 | //! Look up accessible paths for items. |
2 | use hir::{ | 2 | use hir::{ |
3 | AsAssocItem, AssocItem, AssocItemContainer, Crate, ItemInNs, MacroDef, ModPath, Module, | 3 | AsAssocItem, AssocItem, AssocItemContainer, Crate, ItemInNs, MacroDef, ModPath, Module, |
4 | ModuleDef, Name, PathResolution, PrefixKind, ScopeDef, Semantics, SemanticsScope, Type, | 4 | ModuleDef, Name, PathResolution, PrefixKind, ScopeDef, Semantics, Type, |
5 | }; | 5 | }; |
6 | use itertools::Itertools; | 6 | use itertools::Itertools; |
7 | use rustc_hash::FxHashSet; | 7 | use rustc_hash::FxHashSet; |
8 | use syntax::{ast, AstNode}; | 8 | use syntax::{ast, AstNode, SyntaxNode}; |
9 | 9 | ||
10 | use crate::{ | 10 | use crate::{ |
11 | items_locator::{self, AssocItemSearch, DEFAULT_QUERY_SEARCH_LIMIT}, | 11 | items_locator::{self, AssocItemSearch, DEFAULT_QUERY_SEARCH_LIMIT}, |
@@ -62,38 +62,37 @@ impl NameToImport { | |||
62 | } | 62 | } |
63 | 63 | ||
64 | #[derive(Debug)] | 64 | #[derive(Debug)] |
65 | pub struct ImportAssets<'a> { | 65 | pub struct ImportAssets { |
66 | import_candidate: ImportCandidate, | 66 | import_candidate: ImportCandidate, |
67 | candidate_node: SyntaxNode, | ||
67 | module_with_candidate: Module, | 68 | module_with_candidate: Module, |
68 | scope: SemanticsScope<'a>, | ||
69 | } | 69 | } |
70 | 70 | ||
71 | impl<'a> ImportAssets<'a> { | 71 | impl ImportAssets { |
72 | pub fn for_method_call( | 72 | pub fn for_method_call( |
73 | method_call: &ast::MethodCallExpr, | 73 | method_call: &ast::MethodCallExpr, |
74 | sema: &'a Semantics<RootDatabase>, | 74 | sema: &Semantics<RootDatabase>, |
75 | ) -> Option<Self> { | 75 | ) -> Option<Self> { |
76 | let scope = sema.scope(method_call.syntax()); | 76 | let candidate_node = method_call.syntax().clone(); |
77 | Some(Self { | 77 | Some(Self { |
78 | import_candidate: ImportCandidate::for_method_call(sema, method_call)?, | 78 | import_candidate: ImportCandidate::for_method_call(sema, method_call)?, |
79 | module_with_candidate: scope.module()?, | 79 | module_with_candidate: sema.scope(&candidate_node).module()?, |
80 | scope, | 80 | candidate_node, |
81 | }) | 81 | }) |
82 | } | 82 | } |
83 | 83 | ||
84 | pub fn for_exact_path( | 84 | pub fn for_exact_path( |
85 | fully_qualified_path: &ast::Path, | 85 | fully_qualified_path: &ast::Path, |
86 | sema: &'a Semantics<RootDatabase>, | 86 | sema: &Semantics<RootDatabase>, |
87 | ) -> Option<Self> { | 87 | ) -> Option<Self> { |
88 | let syntax_under_caret = fully_qualified_path.syntax(); | 88 | let candidate_node = fully_qualified_path.syntax().clone(); |
89 | if syntax_under_caret.ancestors().find_map(ast::Use::cast).is_some() { | 89 | if candidate_node.ancestors().find_map(ast::Use::cast).is_some() { |
90 | return None; | 90 | return None; |
91 | } | 91 | } |
92 | let scope = sema.scope(syntax_under_caret); | ||
93 | Some(Self { | 92 | Some(Self { |
94 | import_candidate: ImportCandidate::for_regular_path(sema, fully_qualified_path)?, | 93 | import_candidate: ImportCandidate::for_regular_path(sema, fully_qualified_path)?, |
95 | module_with_candidate: scope.module()?, | 94 | module_with_candidate: sema.scope(&candidate_node).module()?, |
96 | scope, | 95 | candidate_node, |
97 | }) | 96 | }) |
98 | } | 97 | } |
99 | 98 | ||
@@ -102,12 +101,12 @@ impl<'a> ImportAssets<'a> { | |||
102 | qualifier: Option<ast::Path>, | 101 | qualifier: Option<ast::Path>, |
103 | fuzzy_name: String, | 102 | fuzzy_name: String, |
104 | sema: &Semantics<RootDatabase>, | 103 | sema: &Semantics<RootDatabase>, |
105 | scope: SemanticsScope<'a>, | 104 | candidate_node: SyntaxNode, |
106 | ) -> Option<Self> { | 105 | ) -> Option<Self> { |
107 | Some(Self { | 106 | Some(Self { |
108 | import_candidate: ImportCandidate::for_fuzzy_path(qualifier, fuzzy_name, sema)?, | 107 | import_candidate: ImportCandidate::for_fuzzy_path(qualifier, fuzzy_name, sema)?, |
109 | module_with_candidate, | 108 | module_with_candidate, |
110 | scope, | 109 | candidate_node, |
111 | }) | 110 | }) |
112 | } | 111 | } |
113 | 112 | ||
@@ -115,7 +114,7 @@ impl<'a> ImportAssets<'a> { | |||
115 | module_with_method_call: Module, | 114 | module_with_method_call: Module, |
116 | receiver_ty: Type, | 115 | receiver_ty: Type, |
117 | fuzzy_method_name: String, | 116 | fuzzy_method_name: String, |
118 | scope: SemanticsScope<'a>, | 117 | candidate_node: SyntaxNode, |
119 | ) -> Option<Self> { | 118 | ) -> Option<Self> { |
120 | Some(Self { | 119 | Some(Self { |
121 | import_candidate: ImportCandidate::TraitMethod(TraitImportCandidate { | 120 | import_candidate: ImportCandidate::TraitMethod(TraitImportCandidate { |
@@ -123,7 +122,7 @@ impl<'a> ImportAssets<'a> { | |||
123 | name: NameToImport::Fuzzy(fuzzy_method_name), | 122 | name: NameToImport::Fuzzy(fuzzy_method_name), |
124 | }), | 123 | }), |
125 | module_with_candidate: module_with_method_call, | 124 | module_with_candidate: module_with_method_call, |
126 | scope, | 125 | candidate_node, |
127 | }) | 126 | }) |
128 | } | 127 | } |
129 | } | 128 | } |
@@ -156,7 +155,7 @@ impl LocatedImport { | |||
156 | } | 155 | } |
157 | } | 156 | } |
158 | 157 | ||
159 | impl<'a> ImportAssets<'a> { | 158 | impl ImportAssets { |
160 | pub fn import_candidate(&self) -> &ImportCandidate { | 159 | pub fn import_candidate(&self) -> &ImportCandidate { |
161 | &self.import_candidate | 160 | &self.import_candidate |
162 | } | 161 | } |
@@ -182,7 +181,7 @@ impl<'a> ImportAssets<'a> { | |||
182 | prefixed: Option<PrefixKind>, | 181 | prefixed: Option<PrefixKind>, |
183 | ) -> Vec<LocatedImport> { | 182 | ) -> Vec<LocatedImport> { |
184 | let items_with_candidate_name = match self.name_to_import() { | 183 | let items_with_candidate_name = match self.name_to_import() { |
185 | NameToImport::Exact(exact_name) => items_locator::with_for_exact_name( | 184 | NameToImport::Exact(exact_name) => items_locator::with_exact_name( |
186 | sema, | 185 | sema, |
187 | self.module_with_candidate.krate(), | 186 | self.module_with_candidate.krate(), |
188 | exact_name.clone(), | 187 | exact_name.clone(), |
@@ -209,7 +208,7 @@ impl<'a> ImportAssets<'a> { | |||
209 | } | 208 | } |
210 | }; | 209 | }; |
211 | 210 | ||
212 | let scope_definitions = self.scope_definitions(); | 211 | let scope_definitions = self.scope_definitions(sema); |
213 | self.applicable_defs(sema.db, prefixed, items_with_candidate_name) | 212 | self.applicable_defs(sema.db, prefixed, items_with_candidate_name) |
214 | .into_iter() | 213 | .into_iter() |
215 | .filter(|import| import.import_path.len() > 1) | 214 | .filter(|import| import.import_path.len() > 1) |
@@ -218,9 +217,9 @@ impl<'a> ImportAssets<'a> { | |||
218 | .collect() | 217 | .collect() |
219 | } | 218 | } |
220 | 219 | ||
221 | fn scope_definitions(&self) -> FxHashSet<ScopeDef> { | 220 | fn scope_definitions(&self, sema: &Semantics<RootDatabase>) -> FxHashSet<ScopeDef> { |
222 | let mut scope_definitions = FxHashSet::default(); | 221 | let mut scope_definitions = FxHashSet::default(); |
223 | self.scope.process_all_names(&mut |_, scope_def| { | 222 | sema.scope(&self.candidate_node).process_all_names(&mut |_, scope_def| { |
224 | scope_definitions.insert(scope_def); | 223 | scope_definitions.insert(scope_def); |
225 | }); | 224 | }); |
226 | scope_definitions | 225 | scope_definitions |