aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src')
-rw-r--r--crates/ra_hir/src/source_id.rs40
1 files changed, 14 insertions, 26 deletions
diff --git a/crates/ra_hir/src/source_id.rs b/crates/ra_hir/src/source_id.rs
index 2c855897a..04b7bb7b3 100644
--- a/crates/ra_hir/src/source_id.rs
+++ b/crates/ra_hir/src/source_id.rs
@@ -36,7 +36,9 @@ impl<N: AstNode> AstId<N> {
36 } 36 }
37 37
38 pub(crate) fn to_node(&self, db: &impl DefDatabase) -> TreeArc<N> { 38 pub(crate) fn to_node(&self, db: &impl DefDatabase) -> TreeArc<N> {
39 let syntax_node = db.file_item(self.file_ast_id.raw.with_file_id(self.file_id)); 39 let source_item_id =
40 SourceItemId { file_id: self.file_id(), item_id: self.file_ast_id.raw };
41 let syntax_node = db.file_item(source_item_id);
40 N::cast(&syntax_node).unwrap().to_owned() 42 N::cast(&syntax_node).unwrap().to_owned()
41 } 43 }
42} 44}
@@ -75,19 +77,13 @@ impl<N: AstNode> FileAstId<N> {
75/// Identifier of item within a specific file. This is stable over reparses, so 77/// Identifier of item within a specific file. This is stable over reparses, so
76/// it's OK to use it as a salsa key/value. 78/// it's OK to use it as a salsa key/value.
77#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] 79#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
78pub(crate) struct SourceFileItemId(RawId); 80struct SourceFileItemId(RawId);
79impl_arena_id!(SourceFileItemId); 81impl_arena_id!(SourceFileItemId);
80 82
81impl SourceFileItemId {
82 pub(crate) fn with_file_id(self, file_id: HirFileId) -> SourceItemId {
83 SourceItemId { file_id, item_id: self }
84 }
85}
86
87#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 83#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
88pub struct SourceItemId { 84pub struct SourceItemId {
89 pub(crate) file_id: HirFileId, 85 file_id: HirFileId,
90 pub(crate) item_id: SourceFileItemId, 86 item_id: SourceFileItemId,
91} 87}
92 88
93/// Maps items' `SyntaxNode`s to `SourceFileItemId`s and back. 89/// Maps items' `SyntaxNode`s to `SourceFileItemId`s and back.
@@ -111,15 +107,16 @@ impl SourceFileItems {
111 source_item_id: SourceItemId, 107 source_item_id: SourceItemId,
112 ) -> TreeArc<SyntaxNode> { 108 ) -> TreeArc<SyntaxNode> {
113 let source_file = db.hir_parse(source_item_id.file_id); 109 let source_file = db.hir_parse(source_item_id.file_id);
114 db.file_items(source_item_id.file_id)[source_item_id.item_id] 110 db.file_items(source_item_id.file_id).arena[source_item_id.item_id]
115 .to_node(&source_file) 111 .to_node(&source_file)
116 .to_owned() 112 .to_owned()
117 } 113 }
118 114
119 pub(crate) fn from_source_file( 115 pub(crate) fn ast_id<N: AstNode>(&self, item: &N) -> FileAstId<N> {
120 source_file: &SourceFile, 116 FileAstId { raw: self.id_of_unchecked(item.syntax()), _ty: PhantomData }
121 file_id: HirFileId, 117 }
122 ) -> SourceFileItems { 118
119 fn from_source_file(source_file: &SourceFile, file_id: HirFileId) -> SourceFileItems {
123 let mut res = SourceFileItems { file_id, arena: Arena::default() }; 120 let mut res = SourceFileItems { file_id, arena: Arena::default() };
124 // By walking the tree in bread-first order we make sure that parents 121 // By walking the tree in bread-first order we make sure that parents
125 // get lower ids then children. That is, adding a new child does not 122 // get lower ids then children. That is, adding a new child does not
@@ -138,7 +135,8 @@ impl SourceFileItems {
138 fn alloc(&mut self, item: &SyntaxNode) -> SourceFileItemId { 135 fn alloc(&mut self, item: &SyntaxNode) -> SourceFileItemId {
139 self.arena.alloc(SyntaxNodePtr::new(item)) 136 self.arena.alloc(SyntaxNodePtr::new(item))
140 } 137 }
141 pub(crate) fn id_of_unchecked(&self, item: &SyntaxNode) -> SourceFileItemId { 138
139 fn id_of_unchecked(&self, item: &SyntaxNode) -> SourceFileItemId {
142 let ptr = SyntaxNodePtr::new(item); 140 let ptr = SyntaxNodePtr::new(item);
143 if let Some((id, _)) = self.arena.iter().find(|(_id, i)| **i == ptr) { 141 if let Some((id, _)) = self.arena.iter().find(|(_id, i)| **i == ptr) {
144 return id; 142 return id;
@@ -149,16 +147,6 @@ impl SourceFileItems {
149 self.arena.iter().map(|(_id, i)| i).collect::<Vec<_>>(), 147 self.arena.iter().map(|(_id, i)| i).collect::<Vec<_>>(),
150 ); 148 );
151 } 149 }
152 pub(crate) fn ast_id<N: AstNode>(&self, item: &N) -> FileAstId<N> {
153 FileAstId { raw: self.id_of_unchecked(item.syntax()), _ty: PhantomData }
154 }
155}
156
157impl std::ops::Index<SourceFileItemId> for SourceFileItems {
158 type Output = SyntaxNodePtr;
159 fn index(&self, idx: SourceFileItemId) -> &SyntaxNodePtr {
160 &self.arena[idx]
161 }
162} 150}
163 151
164/// Walks the subtree in bfs order, calling `f` for each node. 152/// Walks the subtree in bfs order, calling `f` for each node.