1 //! When *constructing* `hir`, we start at some parent syntax node and recursively
2 //! lower the children.
4 //! This modules allows one to go in the opposite direction: start with a syntax
5 //! node for a *child*, and get its hir.
12 item_scope::ItemScope,
14 src::{HasChildSource, HasSource},
15 AdtId, AssocItemId, DefWithBodyId, EnumId, EnumVariantId, FieldId, ImplId, Lookup, ModuleDefId,
16 ModuleId, TraitId, VariantId,
19 pub trait ChildBySource {
20 fn child_by_source(&self, db: &dyn DefDatabase) -> DynMap;
23 impl ChildBySource for TraitId {
24 fn child_by_source(&self, db: &dyn DefDatabase) -> DynMap {
25 let mut res = DynMap::default();
27 let data = db.trait_data(*self);
28 for (_name, item) in data.items.iter() {
30 AssocItemId::FunctionId(func) => {
31 let src = func.lookup(db).source(db);
32 res[keys::FUNCTION].insert(src, func)
34 AssocItemId::ConstId(konst) => {
35 let src = konst.lookup(db).source(db);
36 res[keys::CONST].insert(src, konst)
38 AssocItemId::TypeAliasId(ty) => {
39 let src = ty.lookup(db).source(db);
40 res[keys::TYPE_ALIAS].insert(src, ty)
49 impl ChildBySource for ImplId {
50 fn child_by_source(&self, db: &dyn DefDatabase) -> DynMap {
51 let mut res = DynMap::default();
53 let data = db.impl_data(*self);
54 for &item in data.items.iter() {
56 AssocItemId::FunctionId(func) => {
57 let src = func.lookup(db).source(db);
58 res[keys::FUNCTION].insert(src, func)
60 AssocItemId::ConstId(konst) => {
61 let src = konst.lookup(db).source(db);
62 res[keys::CONST].insert(src, konst)
64 AssocItemId::TypeAliasId(ty) => {
65 let src = ty.lookup(db).source(db);
66 res[keys::TYPE_ALIAS].insert(src, ty)
75 impl ChildBySource for ModuleId {
76 fn child_by_source(&self, db: &dyn DefDatabase) -> DynMap {
77 let crate_def_map = db.crate_def_map(self.krate);
78 let module_data = &crate_def_map[self.local_id];
79 module_data.scope.child_by_source(db)
83 impl ChildBySource for ItemScope {
84 fn child_by_source(&self, db: &dyn DefDatabase) -> DynMap {
85 let mut res = DynMap::default();
86 self.declarations().for_each(|item| add_module_def(db, &mut res, item));
87 self.impls().for_each(|imp| add_impl(db, &mut res, imp));
90 fn add_module_def(db: &dyn DefDatabase, map: &mut DynMap, item: ModuleDefId) {
92 ModuleDefId::FunctionId(func) => {
93 let src = func.lookup(db).source(db);
94 map[keys::FUNCTION].insert(src, func)
96 ModuleDefId::ConstId(konst) => {
97 let src = konst.lookup(db).source(db);
98 map[keys::CONST].insert(src, konst)
100 ModuleDefId::StaticId(statik) => {
101 let src = statik.lookup(db).source(db);
102 map[keys::STATIC].insert(src, statik)
104 ModuleDefId::TypeAliasId(ty) => {
105 let src = ty.lookup(db).source(db);
106 map[keys::TYPE_ALIAS].insert(src, ty)
108 ModuleDefId::TraitId(trait_) => {
109 let src = trait_.lookup(db).source(db);
110 map[keys::TRAIT].insert(src, trait_)
112 ModuleDefId::AdtId(adt) => match adt {
113 AdtId::StructId(strukt) => {
114 let src = strukt.lookup(db).source(db);
115 map[keys::STRUCT].insert(src, strukt)
117 AdtId::UnionId(union_) => {
118 let src = union_.lookup(db).source(db);
119 map[keys::UNION].insert(src, union_)
121 AdtId::EnumId(enum_) => {
122 let src = enum_.lookup(db).source(db);
123 map[keys::ENUM].insert(src, enum_)
129 fn add_impl(db: &dyn DefDatabase, map: &mut DynMap, imp: ImplId) {
130 let src = imp.lookup(db).source(db);
131 map[keys::IMPL].insert(src, imp)
136 impl ChildBySource for VariantId {
137 fn child_by_source(&self, db: &dyn DefDatabase) -> DynMap {
138 let mut res = DynMap::default();
140 let arena_map = self.child_source(db);
141 let arena_map = arena_map.as_ref();
142 for (local_id, source) in arena_map.value.iter() {
143 let id = FieldId { parent: *self, local_id };
145 Either::Left(source) => {
146 res[keys::TUPLE_FIELD].insert(arena_map.with_value(source.clone()), id)
148 Either::Right(source) => {
149 res[keys::RECORD_FIELD].insert(arena_map.with_value(source.clone()), id)
157 impl ChildBySource for EnumId {
158 fn child_by_source(&self, db: &dyn DefDatabase) -> DynMap {
159 let mut res = DynMap::default();
161 let arena_map = self.child_source(db);
162 let arena_map = arena_map.as_ref();
163 for (local_id, source) in arena_map.value.iter() {
164 let id = EnumVariantId { parent: *self, local_id };
165 res[keys::VARIANT].insert(arena_map.with_value(source.clone()), id)
172 impl ChildBySource for DefWithBodyId {
173 fn child_by_source(&self, db: &dyn DefDatabase) -> DynMap {
174 let body = db.body(*self);
175 body.item_scope.child_by_source(db)