]> git.lizzy.rs Git - rust.git/blob - src/tools/rust-analyzer/crates/hir-def/src/src.rs
Rollup merge of #102953 - WaffleLapkin:better_docs_for_decorate_param, r=RalfJung
[rust.git] / src / tools / rust-analyzer / crates / hir-def / src / src.rs
1 //! Utilities for mapping between hir IDs and the surface syntax.
2
3 use hir_expand::InFile;
4 use la_arena::ArenaMap;
5 use syntax::ast;
6
7 use crate::{
8     db::DefDatabase, item_tree::ItemTreeNode, AssocItemLoc, ItemLoc, Macro2Loc, MacroRulesLoc,
9     ProcMacroLoc,
10 };
11
12 pub trait HasSource {
13     type Value;
14     fn source(&self, db: &dyn DefDatabase) -> InFile<Self::Value>;
15 }
16
17 impl<N: ItemTreeNode> HasSource for AssocItemLoc<N> {
18     type Value = N::Source;
19
20     fn source(&self, db: &dyn DefDatabase) -> InFile<N::Source> {
21         let tree = self.id.item_tree(db);
22         let ast_id_map = db.ast_id_map(self.id.file_id());
23         let root = db.parse_or_expand(self.id.file_id()).unwrap();
24         let node = &tree[self.id.value];
25
26         InFile::new(self.id.file_id(), ast_id_map.get(node.ast_id()).to_node(&root))
27     }
28 }
29
30 impl<N: ItemTreeNode> HasSource for ItemLoc<N> {
31     type Value = N::Source;
32
33     fn source(&self, db: &dyn DefDatabase) -> InFile<N::Source> {
34         let tree = self.id.item_tree(db);
35         let ast_id_map = db.ast_id_map(self.id.file_id());
36         let root = db.parse_or_expand(self.id.file_id()).unwrap();
37         let node = &tree[self.id.value];
38
39         InFile::new(self.id.file_id(), ast_id_map.get(node.ast_id()).to_node(&root))
40     }
41 }
42
43 impl HasSource for Macro2Loc {
44     type Value = ast::MacroDef;
45
46     fn source(&self, db: &dyn DefDatabase) -> InFile<Self::Value> {
47         let tree = self.id.item_tree(db);
48         let ast_id_map = db.ast_id_map(self.id.file_id());
49         let root = db.parse_or_expand(self.id.file_id()).unwrap();
50         let node = &tree[self.id.value];
51
52         InFile::new(self.id.file_id(), ast_id_map.get(node.ast_id()).to_node(&root))
53     }
54 }
55
56 impl HasSource for MacroRulesLoc {
57     type Value = ast::MacroRules;
58
59     fn source(&self, db: &dyn DefDatabase) -> InFile<Self::Value> {
60         let tree = self.id.item_tree(db);
61         let ast_id_map = db.ast_id_map(self.id.file_id());
62         let root = db.parse_or_expand(self.id.file_id()).unwrap();
63         let node = &tree[self.id.value];
64
65         InFile::new(self.id.file_id(), ast_id_map.get(node.ast_id()).to_node(&root))
66     }
67 }
68
69 impl HasSource for ProcMacroLoc {
70     type Value = ast::Fn;
71
72     fn source(&self, db: &dyn DefDatabase) -> InFile<Self::Value> {
73         let tree = self.id.item_tree(db);
74         let ast_id_map = db.ast_id_map(self.id.file_id());
75         let root = db.parse_or_expand(self.id.file_id()).unwrap();
76         let node = &tree[self.id.value];
77
78         InFile::new(self.id.file_id(), ast_id_map.get(node.ast_id()).to_node(&root))
79     }
80 }
81
82 pub trait HasChildSource<ChildId> {
83     type Value;
84     fn child_source(&self, db: &dyn DefDatabase) -> InFile<ArenaMap<ChildId, Self::Value>>;
85 }