aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2020-01-16 15:44:25 +0000
committerAleksey Kladov <[email protected]>2020-01-16 15:44:25 +0000
commit16cfc8d50c9b5b4deb1065b9394e7663df7e9500 (patch)
treed597b2a35210480e3ed2c717151ef47fc4a380a3
parent7aa627fe582e8811e9e98b58c8a6da80054ba2e3 (diff)
Cache source for generics
-rw-r--r--crates/ra_hir/src/source_binder.rs21
1 files changed, 20 insertions, 1 deletions
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs
index 97e3aef34..00f48177b 100644
--- a/crates/ra_hir/src/source_binder.rs
+++ b/crates/ra_hir/src/source_binder.rs
@@ -48,6 +48,7 @@ impl<DB: HirDatabase> SourceBinder<'_, DB> {
48 ChildContainer::ModuleId(it) => it.resolver(self.db), 48 ChildContainer::ModuleId(it) => it.resolver(self.db),
49 ChildContainer::EnumId(it) => it.resolver(self.db), 49 ChildContainer::EnumId(it) => it.resolver(self.db),
50 ChildContainer::VariantId(it) => it.resolver(self.db), 50 ChildContainer::VariantId(it) => it.resolver(self.db),
51 ChildContainer::GenericDefId(it) => it.resolver(self.db),
51 }; 52 };
52 SourceAnalyzer::new_for_resolver(resolver, src) 53 SourceAnalyzer::new_for_resolver(resolver, src)
53 } 54 }
@@ -107,6 +108,19 @@ impl<DB: HirDatabase> SourceBinder<'_, DB> {
107 let c = crate::Module::from_definition(self.db, src.with_value(module_source))?; 108 let c = crate::Module::from_definition(self.db, src.with_value(module_source))?;
108 Some(c.id.into()) 109 Some(c.id.into())
109 } 110 }
111
112 fn child_by_source(&mut self, container: ChildContainer) -> &DynMap {
113 let db = self.db;
114 self.child_by_source_cache.entry(container).or_insert_with(|| match container {
115 ChildContainer::DefWithBodyId(it) => it.child_by_source(db),
116 ChildContainer::ModuleId(it) => it.child_by_source(db),
117 ChildContainer::TraitId(it) => it.child_by_source(db),
118 ChildContainer::ImplId(it) => it.child_by_source(db),
119 ChildContainer::EnumId(it) => it.child_by_source(db),
120 ChildContainer::VariantId(it) => it.child_by_source(db),
121 ChildContainer::GenericDefId(it) => it.child_by_source(db),
122 })
123 }
110} 124}
111 125
112pub trait ToId: Sized { 126pub trait ToId: Sized {
@@ -157,6 +171,9 @@ enum ChildContainer {
157 ImplId(ImplId), 171 ImplId(ImplId),
158 EnumId(EnumId), 172 EnumId(EnumId),
159 VariantId(VariantId), 173 VariantId(VariantId),
174 /// XXX: this might be the same def as, for example an `EnumId`. However,
175 /// here the children generic parameters, and not, eg enum variants.
176 GenericDefId(GenericDefId),
160} 177}
161impl_froms! { 178impl_froms! {
162 ChildContainer: 179 ChildContainer:
@@ -166,6 +183,7 @@ impl_froms! {
166 ImplId, 183 ImplId,
167 EnumId, 184 EnumId,
168 VariantId, 185 VariantId,
186 GenericDefId
169} 187}
170 188
171pub trait ToIdByKey: Sized + AstNode + 'static { 189pub trait ToIdByKey: Sized + AstNode + 'static {
@@ -189,6 +207,7 @@ impl<T: ToIdByKey> ToId for T {
189 ChildContainer::ImplId(it) => it.child_by_source(db), 207 ChildContainer::ImplId(it) => it.child_by_source(db),
190 ChildContainer::EnumId(it) => it.child_by_source(db), 208 ChildContainer::EnumId(it) => it.child_by_source(db),
191 ChildContainer::VariantId(it) => it.child_by_source(db), 209 ChildContainer::VariantId(it) => it.child_by_source(db),
210 ChildContainer::GenericDefId(it) => it.child_by_source(db),
192 }); 211 });
193 dyn_map[T::KEY].get(&src).copied() 212 dyn_map[T::KEY].get(&src).copied()
194 } 213 }
@@ -283,7 +302,7 @@ impl ToDef for ast::TypeParam {
283 }; 302 };
284 Some(res) 303 Some(res)
285 })?; 304 })?;
286 let &id = parent.child_by_source(sb.db)[keys::TYPE_PARAM].get(&src)?; 305 let &id = sb.child_by_source(parent.into())[keys::TYPE_PARAM].get(&src)?;
287 Some(TypeParam { id }) 306 Some(TypeParam { id })
288 } 307 }
289} 308}