diff options
Diffstat (limited to 'crates/ra_hir/src/impl_block.rs')
-rw-r--r-- | crates/ra_hir/src/impl_block.rs | 69 |
1 files changed, 49 insertions, 20 deletions
diff --git a/crates/ra_hir/src/impl_block.rs b/crates/ra_hir/src/impl_block.rs index 36d72b103..738c58fbe 100644 --- a/crates/ra_hir/src/impl_block.rs +++ b/crates/ra_hir/src/impl_block.rs | |||
@@ -7,11 +7,13 @@ use ra_syntax::{ | |||
7 | ast::{self, AstNode}}; | 7 | ast::{self, AstNode}}; |
8 | 8 | ||
9 | use crate::{ | 9 | use crate::{ |
10 | Const, Type, | 10 | Const, Type, Function, HirFileId, |
11 | Function, HirFileId, | 11 | HirDatabase, PersistentHirDatabase, |
12 | PersistentHirDatabase, | 12 | ModuleDef, Trait, Resolution, |
13 | type_ref::TypeRef, | 13 | type_ref::TypeRef, |
14 | ids::LocationCtx, | 14 | ids::LocationCtx, |
15 | resolve::Resolver, | ||
16 | ty::Ty, | ||
15 | }; | 17 | }; |
16 | 18 | ||
17 | use crate::code_model_api::{Module, ModuleSource}; | 19 | use crate::code_model_api::{Module, ModuleSource}; |
@@ -69,7 +71,11 @@ impl ImplBlock { | |||
69 | &self.module_impl_blocks.impls[self.impl_id] | 71 | &self.module_impl_blocks.impls[self.impl_id] |
70 | } | 72 | } |
71 | 73 | ||
72 | pub fn target_trait(&self) -> Option<&TypeRef> { | 74 | pub fn module(&self) -> Module { |
75 | self.module_impl_blocks.module.clone() | ||
76 | } | ||
77 | |||
78 | pub fn target_trait_ref(&self) -> Option<&TypeRef> { | ||
73 | self.impl_data().target_trait() | 79 | self.impl_data().target_trait() |
74 | } | 80 | } |
75 | 81 | ||
@@ -77,9 +83,32 @@ impl ImplBlock { | |||
77 | self.impl_data().target_type() | 83 | self.impl_data().target_type() |
78 | } | 84 | } |
79 | 85 | ||
86 | pub fn target_ty(&self, db: &impl HirDatabase) -> Ty { | ||
87 | Ty::from_hir(db, &self.resolver(db), self.target_type()) | ||
88 | } | ||
89 | |||
90 | pub fn target_trait(&self, db: &impl HirDatabase) -> Option<Trait> { | ||
91 | if let Some(TypeRef::Path(path)) = self.target_trait_ref() { | ||
92 | let resolver = self.resolver(db); | ||
93 | if let Some(Resolution::Def(ModuleDef::Trait(tr))) = | ||
94 | resolver.resolve_path(db, path).take_types() | ||
95 | { | ||
96 | return Some(tr); | ||
97 | } | ||
98 | } | ||
99 | None | ||
100 | } | ||
101 | |||
80 | pub fn items(&self) -> &[ImplItem] { | 102 | pub fn items(&self) -> &[ImplItem] { |
81 | self.impl_data().items() | 103 | self.impl_data().items() |
82 | } | 104 | } |
105 | |||
106 | pub fn resolver(&self, db: &impl HirDatabase) -> Resolver { | ||
107 | let r = self.module().resolver(db); | ||
108 | // TODO: add generics | ||
109 | let r = r.push_impl_block_scope(self.clone()); | ||
110 | r | ||
111 | } | ||
83 | } | 112 | } |
84 | 113 | ||
85 | #[derive(Debug, Clone, PartialEq, Eq)] | 114 | #[derive(Debug, Clone, PartialEq, Eq)] |
@@ -162,25 +191,24 @@ impl_arena_id!(ImplId); | |||
162 | /// we don't need to do the second step again. | 191 | /// we don't need to do the second step again. |
163 | #[derive(Debug, PartialEq, Eq)] | 192 | #[derive(Debug, PartialEq, Eq)] |
164 | pub struct ModuleImplBlocks { | 193 | pub struct ModuleImplBlocks { |
194 | module: Module, | ||
165 | pub(crate) impls: Arena<ImplId, ImplData>, | 195 | pub(crate) impls: Arena<ImplId, ImplData>, |
166 | impls_by_def: FxHashMap<ImplItem, ImplId>, | 196 | impls_by_def: FxHashMap<ImplItem, ImplId>, |
167 | } | 197 | } |
168 | 198 | ||
169 | impl ModuleImplBlocks { | 199 | impl ModuleImplBlocks { |
170 | fn new() -> Self { | ||
171 | ModuleImplBlocks { | ||
172 | impls: Arena::default(), | ||
173 | impls_by_def: FxHashMap::default(), | ||
174 | } | ||
175 | } | ||
176 | |||
177 | fn collect( | 200 | fn collect( |
178 | &mut self, | ||
179 | db: &impl PersistentHirDatabase, | 201 | db: &impl PersistentHirDatabase, |
180 | module: Module, | 202 | module: Module, |
181 | source_map: &mut ImplSourceMap, | 203 | source_map: &mut ImplSourceMap, |
182 | ) { | 204 | ) -> Self { |
183 | let (file_id, module_source) = module.definition_source(db); | 205 | let mut m = ModuleImplBlocks { |
206 | module, | ||
207 | impls: Arena::default(), | ||
208 | impls_by_def: FxHashMap::default(), | ||
209 | }; | ||
210 | |||
211 | let (file_id, module_source) = m.module.definition_source(db); | ||
184 | let file_id: HirFileId = file_id.into(); | 212 | let file_id: HirFileId = file_id.into(); |
185 | let node = match &module_source { | 213 | let node = match &module_source { |
186 | ModuleSource::SourceFile(node) => node.syntax(), | 214 | ModuleSource::SourceFile(node) => node.syntax(), |
@@ -191,14 +219,16 @@ impl ModuleImplBlocks { | |||
191 | }; | 219 | }; |
192 | 220 | ||
193 | for impl_block_ast in node.children().filter_map(ast::ImplBlock::cast) { | 221 | for impl_block_ast in node.children().filter_map(ast::ImplBlock::cast) { |
194 | let impl_block = ImplData::from_ast(db, file_id, module, impl_block_ast); | 222 | let impl_block = ImplData::from_ast(db, file_id, m.module, impl_block_ast); |
195 | let id = self.impls.alloc(impl_block); | 223 | let id = m.impls.alloc(impl_block); |
196 | for &impl_item in &self.impls[id].items { | 224 | for &impl_item in &m.impls[id].items { |
197 | self.impls_by_def.insert(impl_item, id); | 225 | m.impls_by_def.insert(impl_item, id); |
198 | } | 226 | } |
199 | 227 | ||
200 | source_map.insert(id, impl_block_ast); | 228 | source_map.insert(id, impl_block_ast); |
201 | } | 229 | } |
230 | |||
231 | m | ||
202 | } | 232 | } |
203 | } | 233 | } |
204 | 234 | ||
@@ -208,8 +238,7 @@ pub(crate) fn impls_in_module_with_source_map_query( | |||
208 | ) -> (Arc<ModuleImplBlocks>, Arc<ImplSourceMap>) { | 238 | ) -> (Arc<ModuleImplBlocks>, Arc<ImplSourceMap>) { |
209 | let mut source_map = ImplSourceMap::default(); | 239 | let mut source_map = ImplSourceMap::default(); |
210 | 240 | ||
211 | let mut result = ModuleImplBlocks::new(); | 241 | let result = ModuleImplBlocks::collect(db, module, &mut source_map); |
212 | result.collect(db, module, &mut source_map); | ||
213 | 242 | ||
214 | (Arc::new(result), Arc::new(source_map)) | 243 | (Arc::new(result), Arc::new(source_map)) |
215 | } | 244 | } |