aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src')
-rw-r--r--crates/ra_hir/src/from_source.rs2
-rw-r--r--crates/ra_hir/src/lib.rs1
-rw-r--r--crates/ra_hir/src/source_binder.rs68
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
23pub trait FromSource: Sized { 23pub(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};
14use hir_expand::InFile; 14use hir_expand::{AstId, InFile, MacroDefId, MacroDefKind};
15use ra_prof::profile; 15use ra_prof::profile;
16use ra_syntax::{ast, match_ast, AstNode, SyntaxNode, TextUnit}; 16use ra_syntax::{ast, match_ast, AstNode, SyntaxNode, TextUnit};
17use rustc_hash::FxHashMap; 17use 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
147pub trait ToId: Sized + AstNode + 'static { 136pub 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
142pub 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
152macro_rules! to_id_impls { 147impl<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
168macro_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
161to_id_impls![ 177to_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?
192impl 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}