From 8c86963d47953045f2f33ee6620d305a6589641e Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 5 Dec 2019 23:34:12 +0100 Subject: DynMap This might, or might not help us to reduce boilerplate associated with plumbing values from analysis to the IDE layer --- crates/ra_hir_def/src/child_by_source.rs | 139 +++++++++++++++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 crates/ra_hir_def/src/child_by_source.rs (limited to 'crates/ra_hir_def/src/child_by_source.rs') diff --git a/crates/ra_hir_def/src/child_by_source.rs b/crates/ra_hir_def/src/child_by_source.rs new file mode 100644 index 000000000..a3574a9db --- /dev/null +++ b/crates/ra_hir_def/src/child_by_source.rs @@ -0,0 +1,139 @@ +//! When *constructing* `hir`, we start at some parent syntax node and recursively +//! lower the children. +//! +//! This modules allows one to go in the opposite direction: start with a syntax +//! node for a *child*, and get its hir. + +use either::Either; + +use crate::{ + db::DefDatabase, + dyn_map::DynMap, + keys, + src::{HasChildSource, HasSource}, + AssocItemId, EnumId, EnumVariantId, ImplId, Lookup, ModuleDefId, ModuleId, StructFieldId, + TraitId, VariantId, +}; + +pub trait ChildBySource { + fn child_by_source(&self, db: &impl DefDatabase) -> DynMap; +} + +impl ChildBySource for TraitId { + fn child_by_source(&self, db: &impl DefDatabase) -> DynMap { + let mut res = DynMap::default(); + + let data = db.trait_data(*self); + for (_name, item) in data.items.iter() { + match *item { + AssocItemId::FunctionId(func) => { + let src = func.lookup(db).source(db); + res[keys::FUNCTION].insert(src, func) + } + AssocItemId::ConstId(konst) => { + let src = konst.lookup(db).source(db); + res[keys::CONST].insert(src, konst) + } + AssocItemId::TypeAliasId(ty) => { + let src = ty.lookup(db).source(db); + res[keys::TYPE_ALIAS].insert(src, ty) + } + } + } + + res + } +} + +impl ChildBySource for ImplId { + fn child_by_source(&self, db: &impl DefDatabase) -> DynMap { + let mut res = DynMap::default(); + + let data = db.impl_data(*self); + for &item in data.items.iter() { + match item { + AssocItemId::FunctionId(func) => { + let src = func.lookup(db).source(db); + res[keys::FUNCTION].insert(src, func) + } + AssocItemId::ConstId(konst) => { + let src = konst.lookup(db).source(db); + res[keys::CONST].insert(src, konst) + } + AssocItemId::TypeAliasId(ty) => { + let src = ty.lookup(db).source(db); + res[keys::TYPE_ALIAS].insert(src, ty) + } + } + } + + res + } +} + +impl ChildBySource for ModuleId { + fn child_by_source(&self, db: &impl DefDatabase) -> DynMap { + let mut res = DynMap::default(); + + let crate_def_map = db.crate_def_map(self.krate); + for item in crate_def_map[self.local_id].scope.declarations() { + match item { + ModuleDefId::FunctionId(func) => { + let src = func.lookup(db).source(db); + res[keys::FUNCTION].insert(src, func) + } + ModuleDefId::ConstId(konst) => { + let src = konst.lookup(db).source(db); + res[keys::CONST].insert(src, konst) + } + ModuleDefId::StaticId(statik) => { + let src = statik.lookup(db).source(db); + res[keys::STATIC].insert(src, statik) + } + ModuleDefId::TypeAliasId(ty) => { + let src = ty.lookup(db).source(db); + res[keys::TYPE_ALIAS].insert(src, ty) + } + _ => (), + } + } + + res + } +} + +impl ChildBySource for VariantId { + fn child_by_source(&self, db: &impl DefDatabase) -> DynMap { + let mut res = DynMap::default(); + + let arena_map = self.child_source(db); + let arena_map = arena_map.as_ref(); + for (local_id, source) in arena_map.value.iter() { + let id = StructFieldId { parent: *self, local_id }; + match source { + Either::Left(source) => { + res[keys::TUPLE_FIELD].insert(arena_map.with_value(source.clone()), id) + } + Either::Right(source) => { + res[keys::RECORD_FIELD].insert(arena_map.with_value(source.clone()), id) + } + } + } + res + } +} + +impl ChildBySource for EnumId { + fn child_by_source(&self, db: &impl DefDatabase) -> DynMap { + let mut res = DynMap::default(); + + let arena_map = self.child_source(db); + let arena_map = arena_map.as_ref(); + for (local_id, source) in arena_map.value.iter() { + let id = EnumVariantId { parent: *self, local_id }; + res[keys::ENUM_VARIANT].insert(arena_map.with_value(source.clone()), id) + } + + res + } +} -- cgit v1.2.3 From 7b0644d81e52d00a7a6795b187f356213ff68225 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 12 Dec 2019 14:09:13 +0100 Subject: Switch to the new location for impls --- crates/ra_hir_def/src/child_by_source.rs | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'crates/ra_hir_def/src/child_by_source.rs') diff --git a/crates/ra_hir_def/src/child_by_source.rs b/crates/ra_hir_def/src/child_by_source.rs index a3574a9db..821549bd5 100644 --- a/crates/ra_hir_def/src/child_by_source.rs +++ b/crates/ra_hir_def/src/child_by_source.rs @@ -98,6 +98,11 @@ impl ChildBySource for ModuleId { } } + for &impl_ in crate_def_map[self.local_id].impls.iter() { + let src = impl_.lookup(db).source(db); + res[keys::IMPL].insert(src, impl_) + } + res } } -- cgit v1.2.3 From 82e9b245587046d2a1ed432225b19023adbe3245 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 12 Dec 2019 14:34:03 +0100 Subject: Move traits to the new loc --- crates/ra_hir_def/src/child_by_source.rs | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'crates/ra_hir_def/src/child_by_source.rs') diff --git a/crates/ra_hir_def/src/child_by_source.rs b/crates/ra_hir_def/src/child_by_source.rs index 821549bd5..88c2d3f24 100644 --- a/crates/ra_hir_def/src/child_by_source.rs +++ b/crates/ra_hir_def/src/child_by_source.rs @@ -94,6 +94,10 @@ impl ChildBySource for ModuleId { let src = ty.lookup(db).source(db); res[keys::TYPE_ALIAS].insert(src, ty) } + ModuleDefId::TraitId(trait_) => { + let src = trait_.lookup(db).source(db); + res[keys::TRAIT].insert(src, trait_) + } _ => (), } } -- cgit v1.2.3 From f135a8ea55c0a46c67713fb3b79b5f62ada430c1 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 12 Dec 2019 14:58:04 +0100 Subject: Move structs to new loc --- crates/ra_hir_def/src/child_by_source.rs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'crates/ra_hir_def/src/child_by_source.rs') diff --git a/crates/ra_hir_def/src/child_by_source.rs b/crates/ra_hir_def/src/child_by_source.rs index 88c2d3f24..eba361578 100644 --- a/crates/ra_hir_def/src/child_by_source.rs +++ b/crates/ra_hir_def/src/child_by_source.rs @@ -11,8 +11,8 @@ use crate::{ dyn_map::DynMap, keys, src::{HasChildSource, HasSource}, - AssocItemId, EnumId, EnumVariantId, ImplId, Lookup, ModuleDefId, ModuleId, StructFieldId, - TraitId, VariantId, + AdtId, AssocItemId, EnumId, EnumVariantId, ImplId, Lookup, ModuleDefId, ModuleId, + StructFieldId, TraitId, VariantId, }; pub trait ChildBySource { @@ -98,6 +98,14 @@ impl ChildBySource for ModuleId { let src = trait_.lookup(db).source(db); res[keys::TRAIT].insert(src, trait_) } + ModuleDefId::AdtId(adt) => match adt { + AdtId::StructId(strukt) => { + let src = strukt.lookup(db).source(db); + res[keys::STRUCT].insert(src, strukt) + } + AdtId::UnionId(_) => (), + AdtId::EnumId(_) => (), + }, _ => (), } } -- cgit v1.2.3 From 56710f119b7114efac237ac36ea21730b8bd5311 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 12 Dec 2019 15:11:57 +0100 Subject: Move enum&union to new loc --- crates/ra_hir_def/src/child_by_source.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'crates/ra_hir_def/src/child_by_source.rs') diff --git a/crates/ra_hir_def/src/child_by_source.rs b/crates/ra_hir_def/src/child_by_source.rs index eba361578..3c9379b15 100644 --- a/crates/ra_hir_def/src/child_by_source.rs +++ b/crates/ra_hir_def/src/child_by_source.rs @@ -103,8 +103,14 @@ impl ChildBySource for ModuleId { let src = strukt.lookup(db).source(db); res[keys::STRUCT].insert(src, strukt) } - AdtId::UnionId(_) => (), - AdtId::EnumId(_) => (), + AdtId::UnionId(union_) => { + let src = union_.lookup(db).source(db); + res[keys::UNION].insert(src, union_) + } + AdtId::EnumId(enum_) => { + let src = enum_.lookup(db).source(db); + res[keys::ENUM].insert(src, enum_) + } }, _ => (), } -- cgit v1.2.3 From 9ccad60acca0d359f1fd9046c99952d0c1adc763 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 19 Dec 2019 18:21:26 +0100 Subject: Implement ChildBySource for DefWithBody --- crates/ra_hir_def/src/child_by_source.rs | 97 ++++++++++++++++++-------------- 1 file changed, 55 insertions(+), 42 deletions(-) (limited to 'crates/ra_hir_def/src/child_by_source.rs') diff --git a/crates/ra_hir_def/src/child_by_source.rs b/crates/ra_hir_def/src/child_by_source.rs index 3c9379b15..f5a65ad40 100644 --- a/crates/ra_hir_def/src/child_by_source.rs +++ b/crates/ra_hir_def/src/child_by_source.rs @@ -11,8 +11,8 @@ use crate::{ dyn_map::DynMap, keys, src::{HasChildSource, HasSource}, - AdtId, AssocItemId, EnumId, EnumVariantId, ImplId, Lookup, ModuleDefId, ModuleId, - StructFieldId, TraitId, VariantId, + AdtId, AssocItemId, DefWithBodyId, EnumId, EnumVariantId, ImplId, Lookup, ModuleDefId, + ModuleId, StructFieldId, TraitId, VariantId, }; pub trait ChildBySource { @@ -76,47 +76,11 @@ impl ChildBySource for ModuleId { let mut res = DynMap::default(); let crate_def_map = db.crate_def_map(self.krate); - for item in crate_def_map[self.local_id].scope.declarations() { - match item { - ModuleDefId::FunctionId(func) => { - let src = func.lookup(db).source(db); - res[keys::FUNCTION].insert(src, func) - } - ModuleDefId::ConstId(konst) => { - let src = konst.lookup(db).source(db); - res[keys::CONST].insert(src, konst) - } - ModuleDefId::StaticId(statik) => { - let src = statik.lookup(db).source(db); - res[keys::STATIC].insert(src, statik) - } - ModuleDefId::TypeAliasId(ty) => { - let src = ty.lookup(db).source(db); - res[keys::TYPE_ALIAS].insert(src, ty) - } - ModuleDefId::TraitId(trait_) => { - let src = trait_.lookup(db).source(db); - res[keys::TRAIT].insert(src, trait_) - } - ModuleDefId::AdtId(adt) => match adt { - AdtId::StructId(strukt) => { - let src = strukt.lookup(db).source(db); - res[keys::STRUCT].insert(src, strukt) - } - AdtId::UnionId(union_) => { - let src = union_.lookup(db).source(db); - res[keys::UNION].insert(src, union_) - } - AdtId::EnumId(enum_) => { - let src = enum_.lookup(db).source(db); - res[keys::ENUM].insert(src, enum_) - } - }, - _ => (), - } - } + let module_data = &crate_def_map[self.local_id]; - for &impl_ in crate_def_map[self.local_id].impls.iter() { + module_data.scope.declarations().for_each(|item| add_module_def(db, &mut res, item)); + + for &impl_ in module_data.impls.iter() { let src = impl_.lookup(db).source(db); res[keys::IMPL].insert(src, impl_) } @@ -125,6 +89,46 @@ impl ChildBySource for ModuleId { } } +fn add_module_def(db: &impl DefDatabase, map: &mut DynMap, item: ModuleDefId) { + match item { + ModuleDefId::FunctionId(func) => { + let src = func.lookup(db).source(db); + map[keys::FUNCTION].insert(src, func) + } + ModuleDefId::ConstId(konst) => { + let src = konst.lookup(db).source(db); + map[keys::CONST].insert(src, konst) + } + ModuleDefId::StaticId(statik) => { + let src = statik.lookup(db).source(db); + map[keys::STATIC].insert(src, statik) + } + ModuleDefId::TypeAliasId(ty) => { + let src = ty.lookup(db).source(db); + map[keys::TYPE_ALIAS].insert(src, ty) + } + ModuleDefId::TraitId(trait_) => { + let src = trait_.lookup(db).source(db); + map[keys::TRAIT].insert(src, trait_) + } + ModuleDefId::AdtId(adt) => match adt { + AdtId::StructId(strukt) => { + let src = strukt.lookup(db).source(db); + map[keys::STRUCT].insert(src, strukt) + } + AdtId::UnionId(union_) => { + let src = union_.lookup(db).source(db); + map[keys::UNION].insert(src, union_) + } + AdtId::EnumId(enum_) => { + let src = enum_.lookup(db).source(db); + map[keys::ENUM].insert(src, enum_) + } + }, + _ => (), + } +} + impl ChildBySource for VariantId { fn child_by_source(&self, db: &impl DefDatabase) -> DynMap { let mut res = DynMap::default(); @@ -160,3 +164,12 @@ impl ChildBySource for EnumId { res } } + +impl ChildBySource for DefWithBodyId { + fn child_by_source(&self, db: &impl DefDatabase) -> DynMap { + let mut res = DynMap::default(); + let body = db.body(*self); + body.defs.iter().copied().for_each(|item| add_module_def(db, &mut res, item)); + res + } +} -- cgit v1.2.3 From 1b8ce5b37b597679796b3ebc57afd55af49449b0 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 20 Dec 2019 15:58:20 +0100 Subject: Move impls to ItemScope --- crates/ra_hir_def/src/child_by_source.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'crates/ra_hir_def/src/child_by_source.rs') diff --git a/crates/ra_hir_def/src/child_by_source.rs b/crates/ra_hir_def/src/child_by_source.rs index f5a65ad40..403ba8b57 100644 --- a/crates/ra_hir_def/src/child_by_source.rs +++ b/crates/ra_hir_def/src/child_by_source.rs @@ -80,7 +80,7 @@ impl ChildBySource for ModuleId { module_data.scope.declarations().for_each(|item| add_module_def(db, &mut res, item)); - for &impl_ in module_data.impls.iter() { + for &impl_ in module_data.scope.impls.iter() { let src = impl_.lookup(db).source(db); res[keys::IMPL].insert(src, impl_) } -- cgit v1.2.3 From af42cb5981a1f94116b1da8cfeedb6efdd5aeb01 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 20 Dec 2019 16:55:38 +0100 Subject: Privitize impls --- crates/ra_hir_def/src/child_by_source.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'crates/ra_hir_def/src/child_by_source.rs') diff --git a/crates/ra_hir_def/src/child_by_source.rs b/crates/ra_hir_def/src/child_by_source.rs index 403ba8b57..4488e8502 100644 --- a/crates/ra_hir_def/src/child_by_source.rs +++ b/crates/ra_hir_def/src/child_by_source.rs @@ -80,9 +80,9 @@ impl ChildBySource for ModuleId { module_data.scope.declarations().for_each(|item| add_module_def(db, &mut res, item)); - for &impl_ in module_data.scope.impls.iter() { - let src = impl_.lookup(db).source(db); - res[keys::IMPL].insert(src, impl_) + for imp in module_data.scope.impls() { + let src = imp.lookup(db).source(db); + res[keys::IMPL].insert(src, imp) } res -- cgit v1.2.3 From baee74618524ad75819163d701ff9e6fe9883e95 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sun, 22 Dec 2019 15:49:39 +0100 Subject: Share impl Scope between modules and blocks --- crates/ra_hir_def/src/child_by_source.rs | 100 ++++++++++++++++--------------- 1 file changed, 51 insertions(+), 49 deletions(-) (limited to 'crates/ra_hir_def/src/child_by_source.rs') diff --git a/crates/ra_hir_def/src/child_by_source.rs b/crates/ra_hir_def/src/child_by_source.rs index 4488e8502..8b6c773ee 100644 --- a/crates/ra_hir_def/src/child_by_source.rs +++ b/crates/ra_hir_def/src/child_by_source.rs @@ -9,6 +9,7 @@ use either::Either; use crate::{ db::DefDatabase, dyn_map::DynMap, + item_scope::ItemScope, keys, src::{HasChildSource, HasSource}, AdtId, AssocItemId, DefWithBodyId, EnumId, EnumVariantId, ImplId, Lookup, ModuleDefId, @@ -73,59 +74,62 @@ impl ChildBySource for ImplId { impl ChildBySource for ModuleId { fn child_by_source(&self, db: &impl DefDatabase) -> DynMap { - let mut res = DynMap::default(); - let crate_def_map = db.crate_def_map(self.krate); let module_data = &crate_def_map[self.local_id]; - - module_data.scope.declarations().for_each(|item| add_module_def(db, &mut res, item)); - - for imp in module_data.scope.impls() { - let src = imp.lookup(db).source(db); - res[keys::IMPL].insert(src, imp) - } - - res + module_data.scope.child_by_source(db) } } -fn add_module_def(db: &impl DefDatabase, map: &mut DynMap, item: ModuleDefId) { - match item { - ModuleDefId::FunctionId(func) => { - let src = func.lookup(db).source(db); - map[keys::FUNCTION].insert(src, func) - } - ModuleDefId::ConstId(konst) => { - let src = konst.lookup(db).source(db); - map[keys::CONST].insert(src, konst) - } - ModuleDefId::StaticId(statik) => { - let src = statik.lookup(db).source(db); - map[keys::STATIC].insert(src, statik) - } - ModuleDefId::TypeAliasId(ty) => { - let src = ty.lookup(db).source(db); - map[keys::TYPE_ALIAS].insert(src, ty) +impl ChildBySource for ItemScope { + fn child_by_source(&self, db: &impl DefDatabase) -> DynMap { + let mut res = DynMap::default(); + self.declarations().for_each(|item| add_module_def(db, &mut res, item)); + self.impls().for_each(|imp| add_impl(db, &mut res, imp)); + return res; + + fn add_module_def(db: &impl DefDatabase, map: &mut DynMap, item: ModuleDefId) { + match item { + ModuleDefId::FunctionId(func) => { + let src = func.lookup(db).source(db); + map[keys::FUNCTION].insert(src, func) + } + ModuleDefId::ConstId(konst) => { + let src = konst.lookup(db).source(db); + map[keys::CONST].insert(src, konst) + } + ModuleDefId::StaticId(statik) => { + let src = statik.lookup(db).source(db); + map[keys::STATIC].insert(src, statik) + } + ModuleDefId::TypeAliasId(ty) => { + let src = ty.lookup(db).source(db); + map[keys::TYPE_ALIAS].insert(src, ty) + } + ModuleDefId::TraitId(trait_) => { + let src = trait_.lookup(db).source(db); + map[keys::TRAIT].insert(src, trait_) + } + ModuleDefId::AdtId(adt) => match adt { + AdtId::StructId(strukt) => { + let src = strukt.lookup(db).source(db); + map[keys::STRUCT].insert(src, strukt) + } + AdtId::UnionId(union_) => { + let src = union_.lookup(db).source(db); + map[keys::UNION].insert(src, union_) + } + AdtId::EnumId(enum_) => { + let src = enum_.lookup(db).source(db); + map[keys::ENUM].insert(src, enum_) + } + }, + _ => (), + } } - ModuleDefId::TraitId(trait_) => { - let src = trait_.lookup(db).source(db); - map[keys::TRAIT].insert(src, trait_) + fn add_impl(db: &impl DefDatabase, map: &mut DynMap, imp: ImplId) { + let src = imp.lookup(db).source(db); + map[keys::IMPL].insert(src, imp) } - ModuleDefId::AdtId(adt) => match adt { - AdtId::StructId(strukt) => { - let src = strukt.lookup(db).source(db); - map[keys::STRUCT].insert(src, strukt) - } - AdtId::UnionId(union_) => { - let src = union_.lookup(db).source(db); - map[keys::UNION].insert(src, union_) - } - AdtId::EnumId(enum_) => { - let src = enum_.lookup(db).source(db); - map[keys::ENUM].insert(src, enum_) - } - }, - _ => (), } } @@ -167,9 +171,7 @@ impl ChildBySource for EnumId { impl ChildBySource for DefWithBodyId { fn child_by_source(&self, db: &impl DefDatabase) -> DynMap { - let mut res = DynMap::default(); let body = db.body(*self); - body.defs.iter().copied().for_each(|item| add_module_def(db, &mut res, item)); - res + body.item_scope.child_by_source(db) } } -- cgit v1.2.3