aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/source_id.rs
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2019-03-26 16:00:11 +0000
committerAleksey Kladov <[email protected]>2019-03-26 16:11:01 +0000
commite28db444dfdc797002bd3561940cde2659b831de (patch)
tree1be9aba5d9d7f7ebf684208f4de702a44c54bae8 /crates/ra_hir/src/source_id.rs
parentb17217b34afbdbdc6b1d8ec480fcf06ec4bd587e (diff)
rename
Diffstat (limited to 'crates/ra_hir/src/source_id.rs')
-rw-r--r--crates/ra_hir/src/source_id.rs54
1 files changed, 21 insertions, 33 deletions
diff --git a/crates/ra_hir/src/source_id.rs b/crates/ra_hir/src/source_id.rs
index fb71417af..0a8fb6d32 100644
--- a/crates/ra_hir/src/source_id.rs
+++ b/crates/ra_hir/src/source_id.rs
@@ -5,7 +5,9 @@ use ra_syntax::{SyntaxNodePtr, TreeArc, SyntaxNode, SourceFile, AstNode, ast};
5 5
6use crate::{HirFileId, DefDatabase}; 6use crate::{HirFileId, DefDatabase};
7 7
8/// `AstId` points to an AST node in any file 8/// `AstId` points to an AST node in any file.
9///
10/// It is stable across reparses, and can be used as salsa key/value.
9#[derive(Debug)] 11#[derive(Debug)]
10pub(crate) struct AstId<N: AstNode> { 12pub(crate) struct AstId<N: AstNode> {
11 file_id: HirFileId, 13 file_id: HirFileId,
@@ -37,9 +39,7 @@ impl<N: AstNode> AstId<N> {
37 } 39 }
38 40
39 pub(crate) fn to_node(&self, db: &impl DefDatabase) -> TreeArc<N> { 41 pub(crate) fn to_node(&self, db: &impl DefDatabase) -> TreeArc<N> {
40 let source_item_id = 42 let syntax_node = db.ast_id_to_node(self.file_id, self.file_ast_id.raw);
41 SourceItemId { file_id: self.file_id(), item_id: self.file_ast_id.raw };
42 let syntax_node = db.file_item(source_item_id);
43 N::cast(&syntax_node).unwrap().to_owned() 43 N::cast(&syntax_node).unwrap().to_owned()
44 } 44 }
45} 45}
@@ -47,7 +47,7 @@ impl<N: AstNode> AstId<N> {
47/// `AstId` points to an AST node in a specific file. 47/// `AstId` points to an AST node in a specific file.
48#[derive(Debug)] 48#[derive(Debug)]
49pub(crate) struct FileAstId<N: AstNode> { 49pub(crate) struct FileAstId<N: AstNode> {
50 raw: SourceFileItemId, 50 raw: ErasedFileAstId,
51 _ty: PhantomData<N>, 51 _ty: PhantomData<N>,
52} 52}
53 53
@@ -76,41 +76,29 @@ impl<N: AstNode> FileAstId<N> {
76 } 76 }
77} 77}
78 78
79/// Identifier of item within a specific file. This is stable over reparses, so
80/// it's OK to use it as a salsa key/value.
81#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] 79#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
82struct SourceFileItemId(RawId); 80pub struct ErasedFileAstId(RawId);
83impl_arena_id!(SourceFileItemId); 81impl_arena_id!(ErasedFileAstId);
84 82
85#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 83/// Maps items' `SyntaxNode`s to `ErasedFileAstId`s and back.
86pub struct SourceItemId {
87 file_id: HirFileId,
88 item_id: SourceFileItemId,
89}
90
91/// Maps items' `SyntaxNode`s to `SourceFileItemId`s and back.
92#[derive(Debug, PartialEq, Eq)] 84#[derive(Debug, PartialEq, Eq)]
93pub struct SourceFileItems { 85pub struct AstIdMap {
94 arena: Arena<SourceFileItemId, SyntaxNodePtr>, 86 arena: Arena<ErasedFileAstId, SyntaxNodePtr>,
95} 87}
96 88
97impl SourceFileItems { 89impl AstIdMap {
98 pub(crate) fn file_items_query( 90 pub(crate) fn ast_id_map_query(db: &impl DefDatabase, file_id: HirFileId) -> Arc<AstIdMap> {
99 db: &impl DefDatabase,
100 file_id: HirFileId,
101 ) -> Arc<SourceFileItems> {
102 let source_file = db.hir_parse(file_id); 91 let source_file = db.hir_parse(file_id);
103 Arc::new(SourceFileItems::from_source_file(&source_file)) 92 Arc::new(AstIdMap::from_source_file(&source_file))
104 } 93 }
105 94
106 pub(crate) fn file_item_query( 95 pub(crate) fn file_item_query(
107 db: &impl DefDatabase, 96 db: &impl DefDatabase,
108 source_item_id: SourceItemId, 97 file_id: HirFileId,
98 ast_id: ErasedFileAstId,
109 ) -> TreeArc<SyntaxNode> { 99 ) -> TreeArc<SyntaxNode> {
110 let source_file = db.hir_parse(source_item_id.file_id); 100 let source_file = db.hir_parse(file_id);
111 db.file_items(source_item_id.file_id).arena[source_item_id.item_id] 101 db.ast_id_map(file_id).arena[ast_id].to_node(&source_file).to_owned()
112 .to_node(&source_file)
113 .to_owned()
114 } 102 }
115 103
116 pub(crate) fn ast_id<N: AstNode>(&self, item: &N) -> FileAstId<N> { 104 pub(crate) fn ast_id<N: AstNode>(&self, item: &N) -> FileAstId<N> {
@@ -118,7 +106,7 @@ impl SourceFileItems {
118 let raw = match self.arena.iter().find(|(_id, i)| **i == ptr) { 106 let raw = match self.arena.iter().find(|(_id, i)| **i == ptr) {
119 Some((it, _)) => it, 107 Some((it, _)) => it,
120 None => panic!( 108 None => panic!(
121 "Can't find {:?} in SourceFileItems:\n{:?}", 109 "Can't find {:?} in AstIdMap:\n{:?}",
122 item.syntax(), 110 item.syntax(),
123 self.arena.iter().map(|(_id, i)| i).collect::<Vec<_>>(), 111 self.arena.iter().map(|(_id, i)| i).collect::<Vec<_>>(),
124 ), 112 ),
@@ -127,8 +115,8 @@ impl SourceFileItems {
127 FileAstId { raw, _ty: PhantomData } 115 FileAstId { raw, _ty: PhantomData }
128 } 116 }
129 117
130 fn from_source_file(source_file: &SourceFile) -> SourceFileItems { 118 fn from_source_file(source_file: &SourceFile) -> AstIdMap {
131 let mut res = SourceFileItems { arena: Arena::default() }; 119 let mut res = AstIdMap { arena: Arena::default() };
132 // By walking the tree in bread-first order we make sure that parents 120 // By walking the tree in bread-first order we make sure that parents
133 // get lower ids then children. That is, adding a new child does not 121 // get lower ids then children. That is, adding a new child does not
134 // change parent's id. This means that, say, adding a new function to a 122 // change parent's id. This means that, say, adding a new function to a
@@ -143,7 +131,7 @@ impl SourceFileItems {
143 res 131 res
144 } 132 }
145 133
146 fn alloc(&mut self, item: &SyntaxNode) -> SourceFileItemId { 134 fn alloc(&mut self, item: &SyntaxNode) -> ErasedFileAstId {
147 self.arena.alloc(SyntaxNodePtr::new(item)) 135 self.arena.alloc(SyntaxNodePtr::new(item))
148 } 136 }
149} 137}