aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/source_binder.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/source_binder.rs')
-rw-r--r--crates/ra_hir/src/source_binder.rs84
1 files changed, 14 insertions, 70 deletions
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs
index 0b8a641f9..4353e25ac 100644
--- a/crates/ra_hir/src/source_binder.rs
+++ b/crates/ra_hir/src/source_binder.rs
@@ -6,7 +6,7 @@ use hir_def::{
6 dyn_map::DynMap, 6 dyn_map::DynMap,
7 keys::{self, Key}, 7 keys::{self, Key},
8 ConstId, DefWithBodyId, EnumId, EnumVariantId, FunctionId, GenericDefId, ImplId, ModuleId, 8 ConstId, DefWithBodyId, EnumId, EnumVariantId, FunctionId, GenericDefId, ImplId, ModuleId,
9 StaticId, StructFieldId, StructId, TraitId, TypeAliasId, UnionId, VariantId, 9 StaticId, StructFieldId, StructId, TraitId, TypeAliasId, TypeParamId, UnionId, VariantId,
10}; 10};
11use hir_expand::{name::AsName, AstId, InFile, MacroDefId, MacroDefKind}; 11use hir_expand::{name::AsName, AstId, InFile, MacroDefId, MacroDefKind};
12use ra_db::FileId; 12use ra_db::FileId;
@@ -17,9 +17,9 @@ use ra_syntax::{
17}; 17};
18use rustc_hash::FxHashMap; 18use rustc_hash::FxHashMap;
19 19
20use crate::{db::HirDatabase, Local, Module, TypeParam}; 20use crate::{db::HirDatabase, Module};
21 21
22pub struct SourceBinder { 22pub(crate) struct SourceBinder {
23 child_by_source_cache: FxHashMap<ChildContainer, DynMap>, 23 child_by_source_cache: FxHashMap<ChildContainer, DynMap>,
24} 24}
25 25
@@ -38,7 +38,11 @@ impl SourceBinder {
38 Some(Module { id: ModuleId { krate, local_id } }) 38 Some(Module { id: ModuleId { krate, local_id } })
39 } 39 }
40 40
41 fn to_id<T: ToId>(&mut self, db: &impl HirDatabase, src: InFile<T>) -> Option<T::ID> { 41 pub(crate) fn to_id<T: ToId>(
42 &mut self,
43 db: &impl HirDatabase,
44 src: InFile<T>,
45 ) -> Option<T::ID> {
42 T::to_id(db, self, src) 46 T::to_id(db, self, src)
43 } 47 }
44 48
@@ -118,42 +122,6 @@ pub(crate) trait ToId: Sized {
118 ) -> Option<Self::ID>; 122 ) -> Option<Self::ID>;
119} 123}
120 124
121pub trait ToDef: Sized + AstNode + 'static {
122 type Def;
123 fn to_def<DB: HirDatabase>(
124 db: &DB,
125 sb: &mut SourceBinder,
126 src: InFile<Self>,
127 ) -> Option<Self::Def>;
128}
129
130macro_rules! to_def_impls {
131 ($(($def:path, $ast:path)),* ,) => {$(
132 impl ToDef for $ast {
133 type Def = $def;
134 fn to_def<DB: HirDatabase>(db: &DB, sb: &mut SourceBinder, src: InFile<Self>)
135 -> Option<Self::Def>
136 { sb.to_id(db, src).map(Into::into) }
137 }
138 )*}
139}
140
141to_def_impls![
142 (crate::Module, ast::Module),
143 (crate::Struct, ast::StructDef),
144 (crate::Enum, ast::EnumDef),
145 (crate::Union, ast::UnionDef),
146 (crate::Trait, ast::TraitDef),
147 (crate::ImplBlock, ast::ImplBlock),
148 (crate::TypeAlias, ast::TypeAliasDef),
149 (crate::Const, ast::ConstDef),
150 (crate::Static, ast::StaticDef),
151 (crate::Function, ast::FnDef),
152 (crate::StructField, ast::RecordFieldDef),
153 (crate::EnumVariant, ast::EnumVariant),
154 (crate::MacroDef, ast::MacroCall), // this one is dubious, not all calls are macros
155];
156
157#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] 125#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
158pub(crate) enum ChildContainer { 126pub(crate) enum ChildContainer {
159 DefWithBodyId(DefWithBodyId), 127 DefWithBodyId(DefWithBodyId),
@@ -245,37 +213,14 @@ impl ToId for ast::MacroCall {
245 } 213 }
246} 214}
247 215
248impl ToDef for ast::BindPat { 216impl ToId for ast::TypeParam {
249 type Def = Local; 217 type ID = TypeParamId;
250 218
251 fn to_def<DB: HirDatabase>(db: &DB, sb: &mut SourceBinder, src: InFile<Self>) -> Option<Local> { 219 fn to_id<DB: HirDatabase>(
252 let file_id = src.file_id;
253 let parent: DefWithBodyId = src.value.syntax().ancestors().find_map(|it| {
254 let res = match_ast! {
255 match it {
256 ast::ConstDef(value) => { sb.to_id(db, InFile { value, file_id})?.into() },
257 ast::StaticDef(value) => { sb.to_id(db, InFile { value, file_id})?.into() },
258 ast::FnDef(value) => { sb.to_id(db, InFile { value, file_id})?.into() },
259 _ => return None,
260 }
261 };
262 Some(res)
263 })?;
264 let (_body, source_map) = db.body_with_source_map(parent);
265 let src = src.map(ast::Pat::from);
266 let pat_id = source_map.node_pat(src.as_ref())?;
267 Some(Local { parent: parent.into(), pat_id })
268 }
269}
270
271impl ToDef for ast::TypeParam {
272 type Def = TypeParam;
273
274 fn to_def<DB: HirDatabase>(
275 db: &DB, 220 db: &DB,
276 sb: &mut SourceBinder, 221 sb: &mut SourceBinder,
277 src: InFile<ast::TypeParam>, 222 src: InFile<Self>,
278 ) -> Option<TypeParam> { 223 ) -> Option<Self::ID> {
279 let file_id = src.file_id; 224 let file_id = src.file_id;
280 let parent: GenericDefId = src.value.syntax().ancestors().find_map(|it| { 225 let parent: GenericDefId = src.value.syntax().ancestors().find_map(|it| {
281 let res = match_ast! { 226 let res = match_ast! {
@@ -291,8 +236,7 @@ impl ToDef for ast::TypeParam {
291 }; 236 };
292 Some(res) 237 Some(res)
293 })?; 238 })?;
294 let &id = sb.child_by_source(db, parent.into())[keys::TYPE_PARAM].get(&src)?; 239 sb.child_by_source(db, parent.into())[keys::TYPE_PARAM].get(&src).copied()
295 Some(TypeParam { id })
296 } 240 }
297} 241}
298 242