diff options
Diffstat (limited to 'crates/ra_hir/src/source_id.rs')
-rw-r--r-- | crates/ra_hir/src/source_id.rs | 33 |
1 files changed, 16 insertions, 17 deletions
diff --git a/crates/ra_hir/src/source_id.rs b/crates/ra_hir/src/source_id.rs index 04b7bb7b3..fb71417af 100644 --- a/crates/ra_hir/src/source_id.rs +++ b/crates/ra_hir/src/source_id.rs | |||
@@ -5,6 +5,7 @@ use ra_syntax::{SyntaxNodePtr, TreeArc, SyntaxNode, SourceFile, AstNode, ast}; | |||
5 | 5 | ||
6 | use crate::{HirFileId, DefDatabase}; | 6 | use crate::{HirFileId, DefDatabase}; |
7 | 7 | ||
8 | /// `AstId` points to an AST node in any file | ||
8 | #[derive(Debug)] | 9 | #[derive(Debug)] |
9 | pub(crate) struct AstId<N: AstNode> { | 10 | pub(crate) struct AstId<N: AstNode> { |
10 | file_id: HirFileId, | 11 | file_id: HirFileId, |
@@ -43,6 +44,7 @@ impl<N: AstNode> AstId<N> { | |||
43 | } | 44 | } |
44 | } | 45 | } |
45 | 46 | ||
47 | /// `AstId` points to an AST node in a specific file. | ||
46 | #[derive(Debug)] | 48 | #[derive(Debug)] |
47 | pub(crate) struct FileAstId<N: AstNode> { | 49 | pub(crate) struct FileAstId<N: AstNode> { |
48 | raw: SourceFileItemId, | 50 | raw: SourceFileItemId, |
@@ -89,7 +91,6 @@ pub struct SourceItemId { | |||
89 | /// Maps items' `SyntaxNode`s to `SourceFileItemId`s and back. | 91 | /// Maps items' `SyntaxNode`s to `SourceFileItemId`s and back. |
90 | #[derive(Debug, PartialEq, Eq)] | 92 | #[derive(Debug, PartialEq, Eq)] |
91 | pub struct SourceFileItems { | 93 | pub struct SourceFileItems { |
92 | file_id: HirFileId, | ||
93 | arena: Arena<SourceFileItemId, SyntaxNodePtr>, | 94 | arena: Arena<SourceFileItemId, SyntaxNodePtr>, |
94 | } | 95 | } |
95 | 96 | ||
@@ -99,7 +100,7 @@ impl SourceFileItems { | |||
99 | file_id: HirFileId, | 100 | file_id: HirFileId, |
100 | ) -> Arc<SourceFileItems> { | 101 | ) -> Arc<SourceFileItems> { |
101 | let source_file = db.hir_parse(file_id); | 102 | let source_file = db.hir_parse(file_id); |
102 | Arc::new(SourceFileItems::from_source_file(&source_file, file_id)) | 103 | Arc::new(SourceFileItems::from_source_file(&source_file)) |
103 | } | 104 | } |
104 | 105 | ||
105 | pub(crate) fn file_item_query( | 106 | pub(crate) fn file_item_query( |
@@ -113,11 +114,21 @@ impl SourceFileItems { | |||
113 | } | 114 | } |
114 | 115 | ||
115 | pub(crate) fn ast_id<N: AstNode>(&self, item: &N) -> FileAstId<N> { | 116 | pub(crate) fn ast_id<N: AstNode>(&self, item: &N) -> FileAstId<N> { |
116 | FileAstId { raw: self.id_of_unchecked(item.syntax()), _ty: PhantomData } | 117 | let ptr = SyntaxNodePtr::new(item.syntax()); |
118 | let raw = match self.arena.iter().find(|(_id, i)| **i == ptr) { | ||
119 | Some((it, _)) => it, | ||
120 | None => panic!( | ||
121 | "Can't find {:?} in SourceFileItems:\n{:?}", | ||
122 | item.syntax(), | ||
123 | self.arena.iter().map(|(_id, i)| i).collect::<Vec<_>>(), | ||
124 | ), | ||
125 | }; | ||
126 | |||
127 | FileAstId { raw, _ty: PhantomData } | ||
117 | } | 128 | } |
118 | 129 | ||
119 | fn from_source_file(source_file: &SourceFile, file_id: HirFileId) -> SourceFileItems { | 130 | fn from_source_file(source_file: &SourceFile) -> SourceFileItems { |
120 | let mut res = SourceFileItems { file_id, arena: Arena::default() }; | 131 | let mut res = SourceFileItems { arena: Arena::default() }; |
121 | // By walking the tree in bread-first order we make sure that parents | 132 | // By walking the tree in bread-first order we make sure that parents |
122 | // get lower ids then children. That is, adding a new child does not | 133 | // get lower ids then children. That is, adding a new child does not |
123 | // change parent's id. This means that, say, adding a new function to a | 134 | // change parent's id. This means that, say, adding a new function to a |
@@ -135,18 +146,6 @@ impl SourceFileItems { | |||
135 | fn alloc(&mut self, item: &SyntaxNode) -> SourceFileItemId { | 146 | fn alloc(&mut self, item: &SyntaxNode) -> SourceFileItemId { |
136 | self.arena.alloc(SyntaxNodePtr::new(item)) | 147 | self.arena.alloc(SyntaxNodePtr::new(item)) |
137 | } | 148 | } |
138 | |||
139 | fn id_of_unchecked(&self, item: &SyntaxNode) -> SourceFileItemId { | ||
140 | let ptr = SyntaxNodePtr::new(item); | ||
141 | if let Some((id, _)) = self.arena.iter().find(|(_id, i)| **i == ptr) { | ||
142 | return id; | ||
143 | } | ||
144 | panic!( | ||
145 | "Can't find {:?} in SourceFileItems:\n{:?}", | ||
146 | item, | ||
147 | self.arena.iter().map(|(_id, i)| i).collect::<Vec<_>>(), | ||
148 | ); | ||
149 | } | ||
150 | } | 149 | } |
151 | 150 | ||
152 | /// Walks the subtree in bfs order, calling `f` for each node. | 151 | /// Walks the subtree in bfs order, calling `f` for each node. |