diff options
Diffstat (limited to 'crates/ra_hir/src/impl_block.rs')
-rw-r--r-- | crates/ra_hir/src/impl_block.rs | 84 |
1 files changed, 30 insertions, 54 deletions
diff --git a/crates/ra_hir/src/impl_block.rs b/crates/ra_hir/src/impl_block.rs index 551d0d149..222e47349 100644 --- a/crates/ra_hir/src/impl_block.rs +++ b/crates/ra_hir/src/impl_block.rs | |||
@@ -3,14 +3,13 @@ use rustc_hash::FxHashMap; | |||
3 | 3 | ||
4 | use ra_arena::{Arena, RawId, impl_arena_id}; | 4 | use ra_arena::{Arena, RawId, impl_arena_id}; |
5 | use ra_syntax::ast::{self, AstNode}; | 5 | use ra_syntax::ast::{self, AstNode}; |
6 | use ra_db::{SourceRootId}; | ||
7 | 6 | ||
8 | use crate::{ | 7 | use crate::{ |
9 | DefId, DefLoc, DefKind, SourceItemId, SourceFileItems, | 8 | Const, Type, |
10 | Function, HirInterner, | 9 | Function, HirFileId, |
11 | db::HirDatabase, | 10 | db::HirDatabase, |
12 | type_ref::TypeRef, | 11 | type_ref::TypeRef, |
13 | module_tree::ModuleId, | 12 | ids::LocationCtx, |
14 | }; | 13 | }; |
15 | 14 | ||
16 | use crate::code_model_api::{Module, ModuleSource}; | 15 | use crate::code_model_api::{Module, ModuleSource}; |
@@ -24,9 +23,9 @@ pub struct ImplBlock { | |||
24 | impl ImplBlock { | 23 | impl ImplBlock { |
25 | pub(crate) fn containing( | 24 | pub(crate) fn containing( |
26 | module_impl_blocks: Arc<ModuleImplBlocks>, | 25 | module_impl_blocks: Arc<ModuleImplBlocks>, |
27 | def_id: DefId, | 26 | item: ImplItem, |
28 | ) -> Option<ImplBlock> { | 27 | ) -> Option<ImplBlock> { |
29 | let impl_id = *module_impl_blocks.impls_by_def.get(&def_id)?; | 28 | let impl_id = *module_impl_blocks.impls_by_def.get(&item)?; |
30 | Some(ImplBlock { | 29 | Some(ImplBlock { |
31 | module_impl_blocks, | 30 | module_impl_blocks, |
32 | impl_id, | 31 | impl_id, |
@@ -66,39 +65,25 @@ pub struct ImplData { | |||
66 | 65 | ||
67 | impl ImplData { | 66 | impl ImplData { |
68 | pub(crate) fn from_ast( | 67 | pub(crate) fn from_ast( |
69 | db: &impl AsRef<HirInterner>, | 68 | db: &impl HirDatabase, |
70 | file_items: &SourceFileItems, | 69 | file_id: HirFileId, |
71 | module: &Module, | 70 | module: Module, |
72 | node: &ast::ImplBlock, | 71 | node: &ast::ImplBlock, |
73 | ) -> Self { | 72 | ) -> Self { |
74 | let target_trait = node.target_trait().map(TypeRef::from_ast); | 73 | let target_trait = node.target_trait().map(TypeRef::from_ast); |
75 | let target_type = TypeRef::from_ast_opt(node.target_type()); | 74 | let target_type = TypeRef::from_ast_opt(node.target_type()); |
76 | let module_loc = module.def_id.loc(db); | 75 | let ctx = LocationCtx::new(db, module, file_id); |
77 | let items = if let Some(item_list) = node.item_list() { | 76 | let items = if let Some(item_list) = node.item_list() { |
78 | item_list | 77 | item_list |
79 | .impl_items() | 78 | .impl_items() |
80 | .map(|item_node| { | 79 | .map(|item_node| match item_node.kind() { |
81 | let kind = match item_node.kind() { | 80 | ast::ImplItemKind::FnDef(it) => { |
82 | ast::ImplItemKind::FnDef(..) => DefKind::Function, | 81 | ImplItem::Method(Function { id: ctx.to_def(it) }) |
83 | ast::ImplItemKind::ConstDef(..) => DefKind::Item, | ||
84 | ast::ImplItemKind::TypeDef(..) => DefKind::Item, | ||
85 | }; | ||
86 | let item_id = file_items.id_of_unchecked(item_node.syntax()); | ||
87 | let source_item_id = SourceItemId { | ||
88 | file_id: module_loc.source_item_id.file_id, | ||
89 | item_id: Some(item_id), | ||
90 | }; | ||
91 | let def_loc = DefLoc { | ||
92 | kind, | ||
93 | source_item_id, | ||
94 | ..module_loc | ||
95 | }; | ||
96 | let def_id = def_loc.id(db); | ||
97 | match item_node.kind() { | ||
98 | ast::ImplItemKind::FnDef(..) => ImplItem::Method(Function::new(def_id)), | ||
99 | ast::ImplItemKind::ConstDef(..) => ImplItem::Const(def_id), | ||
100 | ast::ImplItemKind::TypeDef(..) => ImplItem::Type(def_id), | ||
101 | } | 82 | } |
83 | ast::ImplItemKind::ConstDef(it) => { | ||
84 | ImplItem::Const(Const { id: ctx.to_def(it) }) | ||
85 | } | ||
86 | ast::ImplItemKind::TypeDef(it) => ImplItem::Type(Type { id: ctx.to_def(it) }), | ||
102 | }) | 87 | }) |
103 | .collect() | 88 | .collect() |
104 | } else { | 89 | } else { |
@@ -124,22 +109,19 @@ impl ImplData { | |||
124 | } | 109 | } |
125 | } | 110 | } |
126 | 111 | ||
127 | #[derive(Debug, Clone, PartialEq, Eq)] | 112 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
113 | //TODO: rename to ImplDef? | ||
128 | pub enum ImplItem { | 114 | pub enum ImplItem { |
129 | Method(Function), | 115 | Method(Function), |
130 | // these don't have their own types yet | 116 | Const(Const), |
131 | Const(DefId), | 117 | Type(Type), |
132 | Type(DefId), | ||
133 | // Existential | 118 | // Existential |
134 | } | 119 | } |
120 | impl_froms!(ImplItem: Const, Type); | ||
135 | 121 | ||
136 | impl ImplItem { | 122 | impl From<Function> for ImplItem { |
137 | pub fn def_id(&self) -> DefId { | 123 | fn from(func: Function) -> ImplItem { |
138 | match self { | 124 | ImplItem::Method(func) |
139 | ImplItem::Method(f) => f.def_id(), | ||
140 | ImplItem::Const(def_id) => *def_id, | ||
141 | ImplItem::Type(def_id) => *def_id, | ||
142 | } | ||
143 | } | 125 | } |
144 | } | 126 | } |
145 | 127 | ||
@@ -155,7 +137,7 @@ impl_arena_id!(ImplId); | |||
155 | #[derive(Debug, PartialEq, Eq)] | 137 | #[derive(Debug, PartialEq, Eq)] |
156 | pub struct ModuleImplBlocks { | 138 | pub struct ModuleImplBlocks { |
157 | pub(crate) impls: Arena<ImplId, ImplData>, | 139 | pub(crate) impls: Arena<ImplId, ImplData>, |
158 | impls_by_def: FxHashMap<DefId, ImplId>, | 140 | impls_by_def: FxHashMap<ImplItem, ImplId>, |
159 | } | 141 | } |
160 | 142 | ||
161 | impl ModuleImplBlocks { | 143 | impl ModuleImplBlocks { |
@@ -168,6 +150,7 @@ impl ModuleImplBlocks { | |||
168 | 150 | ||
169 | fn collect(&mut self, db: &impl HirDatabase, module: Module) { | 151 | fn collect(&mut self, db: &impl HirDatabase, module: Module) { |
170 | let (file_id, module_source) = module.definition_source(db); | 152 | let (file_id, module_source) = module.definition_source(db); |
153 | let file_id: HirFileId = file_id.into(); | ||
171 | let node = match &module_source { | 154 | let node = match &module_source { |
172 | ModuleSource::SourceFile(node) => node.syntax(), | 155 | ModuleSource::SourceFile(node) => node.syntax(), |
173 | ModuleSource::Module(node) => node | 156 | ModuleSource::Module(node) => node |
@@ -176,25 +159,18 @@ impl ModuleImplBlocks { | |||
176 | .syntax(), | 159 | .syntax(), |
177 | }; | 160 | }; |
178 | 161 | ||
179 | let source_file_items = db.file_items(file_id.into()); | ||
180 | |||
181 | for impl_block_ast in node.children().filter_map(ast::ImplBlock::cast) { | 162 | for impl_block_ast in node.children().filter_map(ast::ImplBlock::cast) { |
182 | let impl_block = ImplData::from_ast(db, &source_file_items, &module, impl_block_ast); | 163 | let impl_block = ImplData::from_ast(db, file_id, module, impl_block_ast); |
183 | let id = self.impls.alloc(impl_block); | 164 | let id = self.impls.alloc(impl_block); |
184 | for impl_item in &self.impls[id].items { | 165 | for &impl_item in &self.impls[id].items { |
185 | self.impls_by_def.insert(impl_item.def_id(), id); | 166 | self.impls_by_def.insert(impl_item, id); |
186 | } | 167 | } |
187 | } | 168 | } |
188 | } | 169 | } |
189 | } | 170 | } |
190 | 171 | ||
191 | pub(crate) fn impls_in_module( | 172 | pub(crate) fn impls_in_module(db: &impl HirDatabase, module: Module) -> Arc<ModuleImplBlocks> { |
192 | db: &impl HirDatabase, | ||
193 | source_root_id: SourceRootId, | ||
194 | module_id: ModuleId, | ||
195 | ) -> Arc<ModuleImplBlocks> { | ||
196 | let mut result = ModuleImplBlocks::new(); | 173 | let mut result = ModuleImplBlocks::new(); |
197 | let module = Module::from_module_id(db, source_root_id, module_id); | ||
198 | result.collect(db, module); | 174 | result.collect(db, module); |
199 | Arc::new(result) | 175 | Arc::new(result) |
200 | } | 176 | } |