aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir')
-rw-r--r--crates/ra_hir/src/code_model_api.rs16
-rw-r--r--crates/ra_hir/src/code_model_impl/module.rs13
-rw-r--r--crates/ra_hir/src/db.rs11
-rw-r--r--crates/ra_hir/src/impl_block.rs57
-rw-r--r--crates/ra_hir/src/source_binder.rs24
-rw-r--r--crates/ra_hir/src/ty/method_resolution.rs6
6 files changed, 114 insertions, 13 deletions
diff --git a/crates/ra_hir/src/code_model_api.rs b/crates/ra_hir/src/code_model_api.rs
index e4008058c..53e84429c 100644
--- a/crates/ra_hir/src/code_model_api.rs
+++ b/crates/ra_hir/src/code_model_api.rs
@@ -10,12 +10,13 @@ use crate::{
10 nameres::{ModuleScope, lower::ImportId}, 10 nameres::{ModuleScope, lower::ImportId},
11 db::HirDatabase, 11 db::HirDatabase,
12 expr::BodySyntaxMapping, 12 expr::BodySyntaxMapping,
13 ty::InferenceResult, 13 ty::{InferenceResult},
14 adt::{EnumVariantId, StructFieldId, VariantDef}, 14 adt::{EnumVariantId, StructFieldId, VariantDef},
15 generics::GenericParams, 15 generics::GenericParams,
16 docs::{Documentation, Docs, docs_from_ast}, 16 docs::{Documentation, Docs, docs_from_ast},
17 module_tree::ModuleId, 17 module_tree::ModuleId,
18 ids::{FunctionId, StructId, EnumId, AstItemDef, ConstId, StaticId, TraitId, TypeId}, 18 ids::{FunctionId, StructId, EnumId, AstItemDef, ConstId, StaticId, TraitId, TypeId},
19 impl_block::ImplId,
19}; 20};
20 21
21/// hir::Crate describes a single crate. It's the main interface with which 22/// hir::Crate describes a single crate. It's the main interface with which
@@ -126,6 +127,11 @@ impl Module {
126 self.import_source_impl(db, import) 127 self.import_source_impl(db, import)
127 } 128 }
128 129
130 /// Returns the syntax of the impl block in this module
131 pub fn impl_source(&self, db: &impl HirDatabase, impl_id: ImplId) -> TreeArc<ast::ImplBlock> {
132 self.impl_source_impl(db, impl_id)
133 }
134
129 /// Returns the crate this module is part of. 135 /// Returns the crate this module is part of.
130 pub fn krate(&self, db: &impl HirDatabase) -> Option<Crate> { 136 pub fn krate(&self, db: &impl HirDatabase) -> Option<Crate> {
131 self.krate_impl(db) 137 self.krate_impl(db)
@@ -272,6 +278,10 @@ impl Struct {
272 pub fn generic_params(&self, db: &impl HirDatabase) -> Arc<GenericParams> { 278 pub fn generic_params(&self, db: &impl HirDatabase) -> Arc<GenericParams> {
273 db.generic_params((*self).into()) 279 db.generic_params((*self).into())
274 } 280 }
281
282 pub fn ty(&self, db: &impl HirDatabase) -> Ty {
283 db.type_for_def((*self).into())
284 }
275} 285}
276 286
277impl Docs for Struct { 287impl Docs for Struct {
@@ -317,6 +327,10 @@ impl Enum {
317 pub fn generic_params(&self, db: &impl HirDatabase) -> Arc<GenericParams> { 327 pub fn generic_params(&self, db: &impl HirDatabase) -> Arc<GenericParams> {
318 db.generic_params((*self).into()) 328 db.generic_params((*self).into())
319 } 329 }
330
331 pub fn ty(&self, db: &impl HirDatabase) -> Ty {
332 db.type_for_def((*self).into())
333 }
320} 334}
321 335
322impl Docs for Enum { 336impl Docs for Enum {
diff --git a/crates/ra_hir/src/code_model_impl/module.rs b/crates/ra_hir/src/code_model_impl/module.rs
index 418d59c91..c6f85ac82 100644
--- a/crates/ra_hir/src/code_model_impl/module.rs
+++ b/crates/ra_hir/src/code_model_impl/module.rs
@@ -5,6 +5,7 @@ use crate::{
5 Module, ModuleSource, Problem, 5 Module, ModuleSource, Problem,
6 Crate, Name, 6 Crate, Name,
7 module_tree::ModuleId, 7 module_tree::ModuleId,
8 impl_block::ImplId,
8 nameres::{lower::ImportId}, 9 nameres::{lower::ImportId},
9 db::HirDatabase, 10 db::HirDatabase,
10}; 11};
@@ -51,11 +52,21 @@ impl Module {
51 db: &impl HirDatabase, 52 db: &impl HirDatabase,
52 import: ImportId, 53 import: ImportId,
53 ) -> TreeArc<ast::PathSegment> { 54 ) -> TreeArc<ast::PathSegment> {
54 let source_map = db.lower_module_source_map(self.clone()); 55 let source_map = db.lower_module_source_map(*self);
55 let (_, source) = self.definition_source(db); 56 let (_, source) = self.definition_source(db);
56 source_map.get(&source, import) 57 source_map.get(&source, import)
57 } 58 }
58 59
60 pub(crate) fn impl_source_impl(
61 &self,
62 db: &impl HirDatabase,
63 impl_id: ImplId,
64 ) -> TreeArc<ast::ImplBlock> {
65 let source_map = db.impls_in_module_source_map(*self);
66 let (_, source) = self.definition_source(db);
67 source_map.get(&source, impl_id)
68 }
69
59 pub(crate) fn krate_impl(&self, _db: &impl HirDatabase) -> Option<Crate> { 70 pub(crate) fn krate_impl(&self, _db: &impl HirDatabase) -> Option<Crate> {
60 Some(Crate::new(self.krate)) 71 Some(Crate::new(self.krate))
61 } 72 }
diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs
index 3f76b769d..70d9de212 100644
--- a/crates/ra_hir/src/db.rs
+++ b/crates/ra_hir/src/db.rs
@@ -14,7 +14,7 @@ use crate::{
14 nameres::{ItemMap, lower::{LoweredModule, ImportSourceMap}}, 14 nameres::{ItemMap, lower::{LoweredModule, ImportSourceMap}},
15 ty::{InferenceResult, Ty, method_resolution::CrateImplBlocks, TypableDef}, 15 ty::{InferenceResult, Ty, method_resolution::CrateImplBlocks, TypableDef},
16 adt::{StructData, EnumData}, 16 adt::{StructData, EnumData},
17 impl_block::ModuleImplBlocks, 17 impl_block::{ModuleImplBlocks, ImplSourceMap},
18 generics::{GenericParams, GenericDef}, 18 generics::{GenericParams, GenericDef},
19 ids::SourceFileItemId, 19 ids::SourceFileItemId,
20}; 20};
@@ -73,9 +73,18 @@ pub trait HirDatabase: SourceDatabase + AsRef<HirInterner> {
73 #[salsa::invoke(crate::module_tree::ModuleTree::module_tree_query)] 73 #[salsa::invoke(crate::module_tree::ModuleTree::module_tree_query)]
74 fn module_tree(&self, crate_id: CrateId) -> Arc<ModuleTree>; 74 fn module_tree(&self, crate_id: CrateId) -> Arc<ModuleTree>;
75 75
76 #[salsa::invoke(crate::impl_block::impls_in_module_with_source_map_query)]
77 fn impls_in_module_with_source_map(
78 &self,
79 module: Module,
80 ) -> (Arc<ModuleImplBlocks>, Arc<ImplSourceMap>);
81
76 #[salsa::invoke(crate::impl_block::impls_in_module)] 82 #[salsa::invoke(crate::impl_block::impls_in_module)]
77 fn impls_in_module(&self, module: Module) -> Arc<ModuleImplBlocks>; 83 fn impls_in_module(&self, module: Module) -> Arc<ModuleImplBlocks>;
78 84
85 #[salsa::invoke(crate::impl_block::impls_in_module_source_map_query)]
86 fn impls_in_module_source_map(&self, module: Module) -> Arc<ImplSourceMap>;
87
79 #[salsa::invoke(crate::ty::method_resolution::CrateImplBlocks::impls_in_crate_query)] 88 #[salsa::invoke(crate::ty::method_resolution::CrateImplBlocks::impls_in_crate_query)]
80 fn impls_in_crate(&self, krate: Crate) -> Arc<CrateImplBlocks>; 89 fn impls_in_crate(&self, krate: Crate) -> Arc<CrateImplBlocks>;
81 90
diff --git a/crates/ra_hir/src/impl_block.rs b/crates/ra_hir/src/impl_block.rs
index 222e47349..5fc26324a 100644
--- a/crates/ra_hir/src/impl_block.rs
+++ b/crates/ra_hir/src/impl_block.rs
@@ -1,8 +1,10 @@
1use std::sync::Arc; 1use std::sync::Arc;
2use rustc_hash::FxHashMap; 2use rustc_hash::FxHashMap;
3 3
4use ra_arena::{Arena, RawId, impl_arena_id}; 4use ra_arena::{Arena, RawId, impl_arena_id, map::ArenaMap};
5use ra_syntax::ast::{self, AstNode}; 5use ra_syntax::{
6 AstPtr, SourceFile, TreeArc,
7ast::{self, AstNode}};
6 8
7use crate::{ 9use crate::{
8 Const, Type, 10 Const, Type,
@@ -14,6 +16,26 @@ use crate::{
14 16
15use crate::code_model_api::{Module, ModuleSource}; 17use crate::code_model_api::{Module, ModuleSource};
16 18
19#[derive(Debug, Default, PartialEq, Eq)]
20pub struct ImplSourceMap {
21 map: ArenaMap<ImplId, AstPtr<ast::ImplBlock>>,
22}
23
24impl ImplSourceMap {
25 fn insert(&mut self, impl_id: ImplId, impl_block: &ast::ImplBlock) {
26 self.map.insert(impl_id, AstPtr::new(impl_block))
27 }
28
29 pub fn get(&self, source: &ModuleSource, impl_id: ImplId) -> TreeArc<ast::ImplBlock> {
30 let file = match source {
31 ModuleSource::SourceFile(file) => &*file,
32 ModuleSource::Module(m) => m.syntax().ancestors().find_map(SourceFile::cast).unwrap(),
33 };
34
35 self.map[impl_id].to_node(file).to_owned()
36 }
37}
38
17#[derive(Debug, Clone, PartialEq, Eq)] 39#[derive(Debug, Clone, PartialEq, Eq)]
18pub struct ImplBlock { 40pub struct ImplBlock {
19 module_impl_blocks: Arc<ModuleImplBlocks>, 41 module_impl_blocks: Arc<ModuleImplBlocks>,
@@ -39,6 +61,10 @@ impl ImplBlock {
39 } 61 }
40 } 62 }
41 63
64 pub fn id(&self) -> ImplId {
65 self.impl_id
66 }
67
42 fn impl_data(&self) -> &ImplData { 68 fn impl_data(&self) -> &ImplData {
43 &self.module_impl_blocks.impls[self.impl_id] 69 &self.module_impl_blocks.impls[self.impl_id]
44 } 70 }
@@ -148,7 +174,7 @@ impl ModuleImplBlocks {
148 } 174 }
149 } 175 }
150 176
151 fn collect(&mut self, db: &impl HirDatabase, module: Module) { 177 fn collect(&mut self, db: &impl HirDatabase, module: Module, source_map: &mut ImplSourceMap) {
152 let (file_id, module_source) = module.definition_source(db); 178 let (file_id, module_source) = module.definition_source(db);
153 let file_id: HirFileId = file_id.into(); 179 let file_id: HirFileId = file_id.into();
154 let node = match &module_source { 180 let node = match &module_source {
@@ -165,12 +191,31 @@ impl ModuleImplBlocks {
165 for &impl_item in &self.impls[id].items { 191 for &impl_item in &self.impls[id].items {
166 self.impls_by_def.insert(impl_item, id); 192 self.impls_by_def.insert(impl_item, id);
167 } 193 }
194
195 source_map.insert(id, impl_block_ast);
168 } 196 }
169 } 197 }
170} 198}
171 199
172pub(crate) fn impls_in_module(db: &impl HirDatabase, module: Module) -> Arc<ModuleImplBlocks> { 200pub(crate) fn impls_in_module_with_source_map_query(
201 db: &impl HirDatabase,
202 module: Module,
203) -> (Arc<ModuleImplBlocks>, Arc<ImplSourceMap>) {
204 let mut source_map = ImplSourceMap::default();
205
173 let mut result = ModuleImplBlocks::new(); 206 let mut result = ModuleImplBlocks::new();
174 result.collect(db, module); 207 result.collect(db, module, &mut source_map);
175 Arc::new(result) 208
209 (Arc::new(result), Arc::new(source_map))
210}
211
212pub(crate) fn impls_in_module(db: &impl HirDatabase, module: Module) -> Arc<ModuleImplBlocks> {
213 db.impls_in_module_with_source_map(module).0
214}
215
216pub(crate) fn impls_in_module_source_map_query(
217 db: &impl HirDatabase,
218 module: Module,
219) -> Arc<ImplSourceMap> {
220 db.impls_in_module_with_source_map(module).1
176} 221}
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs
index f523f0647..589efd023 100644
--- a/crates/ra_hir/src/source_binder.rs
+++ b/crates/ra_hir/src/source_binder.rs
@@ -13,7 +13,7 @@ use ra_syntax::{
13}; 13};
14 14
15use crate::{ 15use crate::{
16 HirDatabase, Function, ModuleDef, 16 HirDatabase, Function, ModuleDef, Struct, Enum,
17 AsName, Module, HirFileId, 17 AsName, Module, HirFileId,
18 ids::{LocationCtx, SourceFileItemId}, 18 ids::{LocationCtx, SourceFileItemId},
19}; 19};
@@ -128,6 +128,28 @@ pub fn function_from_child_node(
128 function_from_source(db, file_id, fn_def) 128 function_from_source(db, file_id, fn_def)
129} 129}
130 130
131pub fn struct_from_module(
132 db: &impl HirDatabase,
133 module: Module,
134 struct_def: &ast::StructDef,
135) -> Struct {
136 let (file_id, _) = module.definition_source(db);
137 let file_id = file_id.into();
138 let ctx = LocationCtx::new(db, module, file_id);
139 Struct {
140 id: ctx.to_def(struct_def),
141 }
142}
143
144pub fn enum_from_module(db: &impl HirDatabase, module: Module, enum_def: &ast::EnumDef) -> Enum {
145 let (file_id, _) = module.definition_source(db);
146 let file_id = file_id.into();
147 let ctx = LocationCtx::new(db, module, file_id);
148 Enum {
149 id: ctx.to_def(enum_def),
150 }
151}
152
131pub fn macro_symbols(db: &impl HirDatabase, file_id: FileId) -> Vec<(SmolStr, TextRange)> { 153pub fn macro_symbols(db: &impl HirDatabase, file_id: FileId) -> Vec<(SmolStr, TextRange)> {
132 let module = match module_from_file_id(db, file_id) { 154 let module = match module_from_file_id(db, file_id) {
133 Some(it) => it, 155 Some(it) => it,
diff --git a/crates/ra_hir/src/ty/method_resolution.rs b/crates/ra_hir/src/ty/method_resolution.rs
index 9a571c2aa..d70a24582 100644
--- a/crates/ra_hir/src/ty/method_resolution.rs
+++ b/crates/ra_hir/src/ty/method_resolution.rs
@@ -44,7 +44,7 @@ impl CrateImplBlocks {
44 &'a self, 44 &'a self,
45 db: &'a impl HirDatabase, 45 db: &'a impl HirDatabase,
46 ty: &Ty, 46 ty: &Ty,
47 ) -> impl Iterator<Item = ImplBlock> + 'a { 47 ) -> impl Iterator<Item = (Module, ImplBlock)> + 'a {
48 let fingerprint = TyFingerprint::for_impl(ty); 48 let fingerprint = TyFingerprint::for_impl(ty);
49 fingerprint 49 fingerprint
50 .and_then(|f| self.impls.get(&f)) 50 .and_then(|f| self.impls.get(&f))
@@ -56,7 +56,7 @@ impl CrateImplBlocks {
56 module_id: *module_id, 56 module_id: *module_id,
57 }; 57 };
58 let module_impl_blocks = db.impls_in_module(module); 58 let module_impl_blocks = db.impls_in_module(module);
59 ImplBlock::from_id(module_impl_blocks, *impl_id) 59 (module, ImplBlock::from_id(module_impl_blocks, *impl_id))
60 }) 60 })
61 } 61 }
62 62
@@ -152,7 +152,7 @@ impl Ty {
152 }; 152 };
153 let impls = db.impls_in_crate(krate); 153 let impls = db.impls_in_crate(krate);
154 154
155 for impl_block in impls.lookup_impl_blocks(db, &derefed_ty) { 155 for (_, impl_block) in impls.lookup_impl_blocks(db, &derefed_ty) {
156 for item in impl_block.items() { 156 for item in impl_block.items() {
157 match item { 157 match item {
158 ImplItem::Method(f) => { 158 ImplItem::Method(f) => {