aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/impl_block.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/impl_block.rs')
-rw-r--r--crates/ra_hir/src/impl_block.rs84
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
4use ra_arena::{Arena, RawId, impl_arena_id}; 4use ra_arena::{Arena, RawId, impl_arena_id};
5use ra_syntax::ast::{self, AstNode}; 5use ra_syntax::ast::{self, AstNode};
6use ra_db::{SourceRootId};
7 6
8use crate::{ 7use 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
16use crate::code_model_api::{Module, ModuleSource}; 15use crate::code_model_api::{Module, ModuleSource};
@@ -24,9 +23,9 @@ pub struct ImplBlock {
24impl ImplBlock { 23impl 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
67impl ImplData { 66impl 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?
128pub enum ImplItem { 114pub 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}
120impl_froms!(ImplItem: Const, Type);
135 121
136impl ImplItem { 122impl 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)]
156pub struct ModuleImplBlocks { 138pub 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
161impl ModuleImplBlocks { 143impl 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
191pub(crate) fn impls_in_module( 172pub(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}