diff options
Diffstat (limited to 'crates/ra_hir/src')
-rw-r--r-- | crates/ra_hir/src/from_source.rs | 2 | ||||
-rw-r--r-- | crates/ra_hir/src/lib.rs | 1 | ||||
-rw-r--r-- | crates/ra_hir/src/source_binder.rs | 68 |
3 files changed, 53 insertions, 18 deletions
diff --git a/crates/ra_hir/src/from_source.rs b/crates/ra_hir/src/from_source.rs index 6314be8d4..59722eba3 100644 --- a/crates/ra_hir/src/from_source.rs +++ b/crates/ra_hir/src/from_source.rs | |||
@@ -20,7 +20,7 @@ use crate::{ | |||
20 | MacroDef, Module, Static, Struct, StructField, Trait, TypeAlias, TypeParam, Union, | 20 | MacroDef, Module, Static, Struct, StructField, Trait, TypeAlias, TypeParam, Union, |
21 | }; | 21 | }; |
22 | 22 | ||
23 | pub trait FromSource: Sized { | 23 | pub(crate) trait FromSource: Sized { |
24 | type Ast; | 24 | type Ast; |
25 | fn from_source(db: &impl DefDatabase, src: InFile<Self::Ast>) -> Option<Self>; | 25 | fn from_source(db: &impl DefDatabase, src: InFile<Self::Ast>) -> Option<Self>; |
26 | } | 26 | } |
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs index a2350573c..11829f42a 100644 --- a/crates/ra_hir/src/lib.rs +++ b/crates/ra_hir/src/lib.rs | |||
@@ -45,7 +45,6 @@ pub use crate::{ | |||
45 | MacroDef, Module, ModuleDef, ScopeDef, Static, Struct, StructField, Trait, Type, TypeAlias, | 45 | MacroDef, Module, ModuleDef, ScopeDef, Static, Struct, StructField, Trait, Type, TypeAlias, |
46 | TypeParam, Union, VariantDef, | 46 | TypeParam, Union, VariantDef, |
47 | }, | 47 | }, |
48 | from_source::FromSource, | ||
49 | has_source::HasSource, | 48 | has_source::HasSource, |
50 | source_analyzer::{PathResolution, ScopeEntryWithSyntax, SourceAnalyzer}, | 49 | source_analyzer::{PathResolution, ScopeEntryWithSyntax, SourceAnalyzer}, |
51 | source_binder::SourceBinder, | 50 | source_binder::SourceBinder, |
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index 00541dbe1..66930e492 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs | |||
@@ -11,7 +11,7 @@ use hir_def::{ | |||
11 | ConstId, DefWithBodyId, EnumId, EnumVariantId, FunctionId, ImplId, ModuleId, StaticId, | 11 | ConstId, DefWithBodyId, EnumId, EnumVariantId, FunctionId, ImplId, ModuleId, StaticId, |
12 | StructFieldId, StructId, TraitId, TypeAliasId, UnionId, VariantId, | 12 | StructFieldId, StructId, TraitId, TypeAliasId, UnionId, VariantId, |
13 | }; | 13 | }; |
14 | use hir_expand::InFile; | 14 | use hir_expand::{AstId, InFile, MacroDefId, MacroDefKind}; |
15 | use ra_prof::profile; | 15 | use ra_prof::profile; |
16 | use ra_syntax::{ast, match_ast, AstNode, SyntaxNode, TextUnit}; | 16 | use ra_syntax::{ast, match_ast, AstNode, SyntaxNode, TextUnit}; |
17 | use rustc_hash::FxHashMap; | 17 | use rustc_hash::FxHashMap; |
@@ -62,18 +62,7 @@ impl<DB: HirDatabase> SourceBinder<'_, DB> { | |||
62 | } | 62 | } |
63 | 63 | ||
64 | fn to_id<T: ToId>(&mut self, src: InFile<T>) -> Option<T::ID> { | 64 | fn to_id<T: ToId>(&mut self, src: InFile<T>) -> Option<T::ID> { |
65 | let container = self.find_container(src.as_ref().map(|it| it.syntax()))?; | 65 | T::to_id(self, src) |
66 | let db = self.db; | ||
67 | let dyn_map = | ||
68 | &*self.child_by_source_cache.entry(container).or_insert_with(|| match container { | ||
69 | ChildContainer::DefWithBodyId(it) => it.child_by_source(db), | ||
70 | ChildContainer::ModuleId(it) => it.child_by_source(db), | ||
71 | ChildContainer::TraitId(it) => it.child_by_source(db), | ||
72 | ChildContainer::ImplId(it) => it.child_by_source(db), | ||
73 | ChildContainer::EnumId(it) => it.child_by_source(db), | ||
74 | ChildContainer::VariantId(it) => it.child_by_source(db), | ||
75 | }); | ||
76 | dyn_map[T::KEY].get(&src).copied() | ||
77 | } | 66 | } |
78 | 67 | ||
79 | fn find_container(&mut self, src: InFile<&SyntaxNode>) -> Option<ChildContainer> { | 68 | fn find_container(&mut self, src: InFile<&SyntaxNode>) -> Option<ChildContainer> { |
@@ -146,19 +135,46 @@ impl_froms! { | |||
146 | 135 | ||
147 | pub trait ToId: Sized + AstNode + 'static { | 136 | pub trait ToId: Sized + AstNode + 'static { |
148 | type ID: Sized + Copy + 'static; | 137 | type ID: Sized + Copy + 'static; |
138 | fn to_id<DB: HirDatabase>(sb: &mut SourceBinder<'_, DB>, src: InFile<Self>) | ||
139 | -> Option<Self::ID>; | ||
140 | } | ||
141 | |||
142 | pub trait ToIdByKey: Sized + AstNode + 'static { | ||
143 | type ID: Sized + Copy + 'static; | ||
149 | const KEY: Key<Self, Self::ID>; | 144 | const KEY: Key<Self, Self::ID>; |
150 | } | 145 | } |
151 | 146 | ||
152 | macro_rules! to_id_impls { | 147 | impl<T: ToIdByKey> ToId for T { |
148 | type ID = <T as ToIdByKey>::ID; | ||
149 | fn to_id<DB: HirDatabase>( | ||
150 | sb: &mut SourceBinder<'_, DB>, | ||
151 | src: InFile<Self>, | ||
152 | ) -> Option<Self::ID> { | ||
153 | let container = sb.find_container(src.as_ref().map(|it| it.syntax()))?; | ||
154 | let db = sb.db; | ||
155 | let dyn_map = | ||
156 | &*sb.child_by_source_cache.entry(container).or_insert_with(|| match container { | ||
157 | ChildContainer::DefWithBodyId(it) => it.child_by_source(db), | ||
158 | ChildContainer::ModuleId(it) => it.child_by_source(db), | ||
159 | ChildContainer::TraitId(it) => it.child_by_source(db), | ||
160 | ChildContainer::ImplId(it) => it.child_by_source(db), | ||
161 | ChildContainer::EnumId(it) => it.child_by_source(db), | ||
162 | ChildContainer::VariantId(it) => it.child_by_source(db), | ||
163 | }); | ||
164 | dyn_map[T::KEY].get(&src).copied() | ||
165 | } | ||
166 | } | ||
167 | |||
168 | macro_rules! to_id_key_impls { | ||
153 | ($(($id:ident, $ast:path, $key:path)),* ,) => {$( | 169 | ($(($id:ident, $ast:path, $key:path)),* ,) => {$( |
154 | impl ToId for $ast { | 170 | impl ToIdByKey for $ast { |
155 | type ID = $id; | 171 | type ID = $id; |
156 | const KEY: Key<Self, Self::ID> = $key; | 172 | const KEY: Key<Self, Self::ID> = $key; |
157 | } | 173 | } |
158 | )*} | 174 | )*} |
159 | } | 175 | } |
160 | 176 | ||
161 | to_id_impls![ | 177 | to_id_key_impls![ |
162 | (StructId, ast::StructDef, keys::STRUCT), | 178 | (StructId, ast::StructDef, keys::STRUCT), |
163 | (UnionId, ast::UnionDef, keys::UNION), | 179 | (UnionId, ast::UnionDef, keys::UNION), |
164 | (EnumId, ast::EnumDef, keys::ENUM), | 180 | (EnumId, ast::EnumDef, keys::ENUM), |
@@ -171,3 +187,23 @@ to_id_impls![ | |||
171 | (StructFieldId, ast::RecordFieldDef, keys::RECORD_FIELD), | 187 | (StructFieldId, ast::RecordFieldDef, keys::RECORD_FIELD), |
172 | (EnumVariantId, ast::EnumVariant, keys::ENUM_VARIANT), | 188 | (EnumVariantId, ast::EnumVariant, keys::ENUM_VARIANT), |
173 | ]; | 189 | ]; |
190 | |||
191 | // FIXME: use DynMap as well? | ||
192 | impl ToId for ast::MacroCall { | ||
193 | type ID = MacroDefId; | ||
194 | fn to_id<DB: HirDatabase>( | ||
195 | sb: &mut SourceBinder<'_, DB>, | ||
196 | src: InFile<Self>, | ||
197 | ) -> Option<Self::ID> { | ||
198 | let kind = MacroDefKind::Declarative; | ||
199 | |||
200 | let module_src = ModuleSource::from_child_node(sb.db, src.as_ref().map(|it| it.syntax())); | ||
201 | let module = crate::Module::from_definition(sb.db, InFile::new(src.file_id, module_src))?; | ||
202 | let krate = Some(module.krate().id); | ||
203 | |||
204 | let ast_id = | ||
205 | Some(AstId::new(src.file_id, sb.db.ast_id_map(src.file_id).ast_id(&src.value))); | ||
206 | |||
207 | Some(MacroDefId { krate, ast_id, kind }) | ||
208 | } | ||
209 | } | ||