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