1 //! Utilities for mapping between hir IDs and the surface syntax.
2 
3 use hir_expand::InFile;
4 use la_arena::ArenaMap;
5 
6 use crate::{db::DefDatabase, item_tree::ItemTreeNode, AssocItemLoc, ItemLoc};
7 
8 pub trait HasSource {
9     type Value;
source(&self, db: &dyn DefDatabase) -> InFile<Self::Value>10     fn source(&self, db: &dyn DefDatabase) -> InFile<Self::Value>;
11 }
12 
13 impl<N: ItemTreeNode> HasSource for AssocItemLoc<N> {
14     type Value = N::Source;
15 
source(&self, db: &dyn DefDatabase) -> InFile<N::Source>16     fn source(&self, db: &dyn DefDatabase) -> InFile<N::Source> {
17         let tree = self.id.item_tree(db);
18         let ast_id_map = db.ast_id_map(self.id.file_id());
19         let root = db.parse_or_expand(self.id.file_id()).unwrap();
20         let node = &tree[self.id.value];
21 
22         InFile::new(self.id.file_id(), ast_id_map.get(node.ast_id()).to_node(&root))
23     }
24 }
25 
26 impl<N: ItemTreeNode> HasSource for ItemLoc<N> {
27     type Value = N::Source;
28 
source(&self, db: &dyn DefDatabase) -> InFile<N::Source>29     fn source(&self, db: &dyn DefDatabase) -> InFile<N::Source> {
30         let tree = self.id.item_tree(db);
31         let ast_id_map = db.ast_id_map(self.id.file_id());
32         let root = db.parse_or_expand(self.id.file_id()).unwrap();
33         let node = &tree[self.id.value];
34 
35         InFile::new(self.id.file_id(), ast_id_map.get(node.ast_id()).to_node(&root))
36     }
37 }
38 
39 pub trait HasChildSource<ChildId> {
40     type Value;
child_source(&self, db: &dyn DefDatabase) -> InFile<ArenaMap<ChildId, Self::Value>>41     fn child_source(&self, db: &dyn DefDatabase) -> InFile<ArenaMap<ChildId, Self::Value>>;
42 }
43