diff options
Diffstat (limited to 'crates/ra_hir/src')
-rw-r--r-- | crates/ra_hir/src/source_id.rs | 40 |
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)] |
78 | pub(crate) struct SourceFileItemId(RawId); | 80 | struct SourceFileItemId(RawId); |
79 | impl_arena_id!(SourceFileItemId); | 81 | impl_arena_id!(SourceFileItemId); |
80 | 82 | ||
81 | impl 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)] |
88 | pub struct SourceItemId { | 84 | pub 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 | |||
157 | impl 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. |