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/db.rs10
-rw-r--r--crates/ra_hir/src/ids.rs2
-rw-r--r--crates/ra_hir/src/lib.rs2
-rw-r--r--crates/ra_hir/src/nameres/raw.rs24
-rw-r--r--crates/ra_hir/src/source_binder.rs4
-rw-r--r--crates/ra_hir/src/source_id.rs54
6 files changed, 42 insertions, 54 deletions
diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs
index a7bbaefb8..147005848 100644
--- a/crates/ra_hir/src/db.rs
+++ b/crates/ra_hir/src/db.rs
@@ -4,7 +4,7 @@ use ra_syntax::{SyntaxNode, TreeArc, SourceFile};
4use ra_db::{SourceDatabase, salsa}; 4use ra_db::{SourceDatabase, salsa};
5 5
6use crate::{ 6use crate::{
7 HirFileId, MacroDefId, SourceFileItems, SourceItemId, Crate, Module, HirInterner, 7 HirFileId, MacroDefId, AstIdMap, ErasedFileAstId, Crate, Module, HirInterner,
8 Function, FnSignature, ExprScopes, TypeAlias, 8 Function, FnSignature, ExprScopes, TypeAlias,
9 Struct, Enum, StructField, 9 Struct, Enum, StructField,
10 Const, ConstSignature, Static, 10 Const, ConstSignature, Static,
@@ -34,11 +34,11 @@ pub trait DefDatabase: SourceDatabase + AsRef<HirInterner> {
34 #[salsa::invoke(crate::traits::TraitData::trait_data_query)] 34 #[salsa::invoke(crate::traits::TraitData::trait_data_query)]
35 fn trait_data(&self, t: Trait) -> Arc<TraitData>; 35 fn trait_data(&self, t: Trait) -> Arc<TraitData>;
36 36
37 #[salsa::invoke(crate::source_id::SourceFileItems::file_items_query)] 37 #[salsa::invoke(crate::source_id::AstIdMap::ast_id_map_query)]
38 fn file_items(&self, file_id: HirFileId) -> Arc<SourceFileItems>; 38 fn ast_id_map(&self, file_id: HirFileId) -> Arc<AstIdMap>;
39 39
40 #[salsa::invoke(crate::source_id::SourceFileItems::file_item_query)] 40 #[salsa::invoke(crate::source_id::AstIdMap::file_item_query)]
41 fn file_item(&self, source_item_id: SourceItemId) -> TreeArc<SyntaxNode>; 41 fn ast_id_to_node(&self, file_id: HirFileId, ast_id: ErasedFileAstId) -> TreeArc<SyntaxNode>;
42 42
43 #[salsa::invoke(RawItems::raw_items_query)] 43 #[salsa::invoke(RawItems::raw_items_query)]
44 fn raw_items(&self, file_id: HirFileId) -> Arc<RawItems>; 44 fn raw_items(&self, file_id: HirFileId) -> Arc<RawItems>;
diff --git a/crates/ra_hir/src/ids.rs b/crates/ra_hir/src/ids.rs
index 81b3cfd22..d8a25e246 100644
--- a/crates/ra_hir/src/ids.rs
+++ b/crates/ra_hir/src/ids.rs
@@ -207,7 +207,7 @@ impl<'a, DB: DefDatabase> LocationCtx<&'a DB> {
207pub(crate) trait AstItemDef<N: AstNode>: ArenaId + Clone { 207pub(crate) trait AstItemDef<N: AstNode>: ArenaId + Clone {
208 fn interner(interner: &HirInterner) -> &LocationInterner<ItemLoc<N>, Self>; 208 fn interner(interner: &HirInterner) -> &LocationInterner<ItemLoc<N>, Self>;
209 fn from_ast(ctx: LocationCtx<&impl DefDatabase>, ast: &N) -> Self { 209 fn from_ast(ctx: LocationCtx<&impl DefDatabase>, ast: &N) -> Self {
210 let items = ctx.db.file_items(ctx.file_id); 210 let items = ctx.db.ast_id_map(ctx.file_id);
211 let item_id = items.ast_id(ast); 211 let item_id = items.ast_id(ast);
212 Self::from_ast_id(ctx, item_id) 212 Self::from_ast_id(ctx, item_id)
213 } 213 }
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs
index b1f388b06..7c603bbd3 100644
--- a/crates/ra_hir/src/lib.rs
+++ b/crates/ra_hir/src/lib.rs
@@ -54,7 +54,7 @@ use crate::{
54pub use self::{ 54pub use self::{
55 path::{Path, PathKind}, 55 path::{Path, PathKind},
56 name::Name, 56 name::Name,
57 source_id::{SourceFileItems, SourceItemId}, 57 source_id::{AstIdMap, ErasedFileAstId},
58 ids::{HirFileId, MacroDefId, MacroCallId, MacroCallLoc, HirInterner}, 58 ids::{HirFileId, MacroDefId, MacroCallId, MacroCallLoc, HirInterner},
59 nameres::{PerNs, Namespace}, 59 nameres::{PerNs, Namespace},
60 ty::{Ty, ApplicationTy, TypeCtor, Substs, display::HirDisplay}, 60 ty::{Ty, ApplicationTy, TypeCtor, Substs, display::HirDisplay},
diff --git a/crates/ra_hir/src/nameres/raw.rs b/crates/ra_hir/src/nameres/raw.rs
index 984478adc..0936229ac 100644
--- a/crates/ra_hir/src/nameres/raw.rs
+++ b/crates/ra_hir/src/nameres/raw.rs
@@ -12,7 +12,7 @@ use ra_syntax::{
12 12
13use crate::{ 13use crate::{
14 DefDatabase, Name, AsName, Path, HirFileId, ModuleSource, 14 DefDatabase, Name, AsName, Path, HirFileId, ModuleSource,
15 SourceFileItems, FileAstId, 15 AstIdMap, FileAstId,
16}; 16};
17 17
18/// `RawItems` is a set of top-level items in a file (except for impls). 18/// `RawItems` is a set of top-level items in a file (except for impls).
@@ -60,7 +60,7 @@ impl RawItems {
60 ) -> (Arc<RawItems>, Arc<ImportSourceMap>) { 60 ) -> (Arc<RawItems>, Arc<ImportSourceMap>) {
61 let mut collector = RawItemsCollector { 61 let mut collector = RawItemsCollector {
62 raw_items: RawItems::default(), 62 raw_items: RawItems::default(),
63 source_file_items: db.file_items(file_id.into()), 63 source_ast_id_map: db.ast_id_map(file_id.into()),
64 source_map: ImportSourceMap::default(), 64 source_map: ImportSourceMap::default(),
65 }; 65 };
66 let source_file = db.hir_parse(file_id); 66 let source_file = db.hir_parse(file_id);
@@ -167,7 +167,7 @@ pub(super) struct MacroData {
167 167
168struct RawItemsCollector { 168struct RawItemsCollector {
169 raw_items: RawItems, 169 raw_items: RawItems,
170 source_file_items: Arc<SourceFileItems>, 170 source_ast_id_map: Arc<AstIdMap>,
171 source_map: ImportSourceMap, 171 source_map: ImportSourceMap,
172} 172}
173 173
@@ -200,25 +200,25 @@ impl RawItemsCollector {
200 return; 200 return;
201 } 201 }
202 ast::ModuleItemKind::StructDef(it) => { 202 ast::ModuleItemKind::StructDef(it) => {
203 (DefKind::Struct(self.source_file_items.ast_id(it)), it.name()) 203 (DefKind::Struct(self.source_ast_id_map.ast_id(it)), it.name())
204 } 204 }
205 ast::ModuleItemKind::EnumDef(it) => { 205 ast::ModuleItemKind::EnumDef(it) => {
206 (DefKind::Enum(self.source_file_items.ast_id(it)), it.name()) 206 (DefKind::Enum(self.source_ast_id_map.ast_id(it)), it.name())
207 } 207 }
208 ast::ModuleItemKind::FnDef(it) => { 208 ast::ModuleItemKind::FnDef(it) => {
209 (DefKind::Function(self.source_file_items.ast_id(it)), it.name()) 209 (DefKind::Function(self.source_ast_id_map.ast_id(it)), it.name())
210 } 210 }
211 ast::ModuleItemKind::TraitDef(it) => { 211 ast::ModuleItemKind::TraitDef(it) => {
212 (DefKind::Trait(self.source_file_items.ast_id(it)), it.name()) 212 (DefKind::Trait(self.source_ast_id_map.ast_id(it)), it.name())
213 } 213 }
214 ast::ModuleItemKind::TypeAliasDef(it) => { 214 ast::ModuleItemKind::TypeAliasDef(it) => {
215 (DefKind::TypeAlias(self.source_file_items.ast_id(it)), it.name()) 215 (DefKind::TypeAlias(self.source_ast_id_map.ast_id(it)), it.name())
216 } 216 }
217 ast::ModuleItemKind::ConstDef(it) => { 217 ast::ModuleItemKind::ConstDef(it) => {
218 (DefKind::Const(self.source_file_items.ast_id(it)), it.name()) 218 (DefKind::Const(self.source_ast_id_map.ast_id(it)), it.name())
219 } 219 }
220 ast::ModuleItemKind::StaticDef(it) => { 220 ast::ModuleItemKind::StaticDef(it) => {
221 (DefKind::Static(self.source_file_items.ast_id(it)), it.name()) 221 (DefKind::Static(self.source_ast_id_map.ast_id(it)), it.name())
222 } 222 }
223 }; 223 };
224 if let Some(name) = name { 224 if let Some(name) = name {
@@ -233,7 +233,7 @@ impl RawItemsCollector {
233 Some(it) => it.as_name(), 233 Some(it) => it.as_name(),
234 None => return, 234 None => return,
235 }; 235 };
236 let ast_id = self.source_file_items.ast_id(module); 236 let ast_id = self.source_ast_id_map.ast_id(module);
237 if module.has_semi() { 237 if module.has_semi() {
238 let item = self.raw_items.modules.alloc(ModuleData::Declaration { name, ast_id }); 238 let item = self.raw_items.modules.alloc(ModuleData::Declaration { name, ast_id });
239 self.push_item(current_module, RawItem::Module(item)); 239 self.push_item(current_module, RawItem::Module(item));
@@ -297,7 +297,7 @@ impl RawItemsCollector {
297 }; 297 };
298 298
299 let name = m.name().map(|it| it.as_name()); 299 let name = m.name().map(|it| it.as_name());
300 let ast_id = self.source_file_items.ast_id(m); 300 let ast_id = self.source_ast_id_map.ast_id(m);
301 let export = m.has_atom_attr("macro_export"); 301 let export = m.has_atom_attr("macro_export");
302 let m = self.raw_items.macros.alloc(MacroData { ast_id, path, name, export }); 302 let m = self.raw_items.macros.alloc(MacroData { ast_id, path, name, export });
303 self.push_item(current_module, RawItem::Macro(m)); 303 self.push_item(current_module, RawItem::Macro(m));
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs
index f9d2d0247..9dae4c3d1 100644
--- a/crates/ra_hir/src/source_binder.rs
+++ b/crates/ra_hir/src/source_binder.rs
@@ -54,8 +54,8 @@ fn module_from_inline(
54) -> Option<Module> { 54) -> Option<Module> {
55 assert!(!module.has_semi()); 55 assert!(!module.has_semi());
56 let file_id = file_id.into(); 56 let file_id = file_id.into();
57 let file_items = db.file_items(file_id); 57 let ast_id_map = db.ast_id_map(file_id);
58 let item_id = file_items.ast_id(module).with_file_id(file_id); 58 let item_id = ast_id_map.ast_id(module).with_file_id(file_id);
59 module_from_source(db, file_id, Some(item_id)) 59 module_from_source(db, file_id, Some(item_id))
60} 60}
61 61
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}