aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/ids.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/ids.rs')
-rw-r--r--crates/ra_hir/src/ids.rs27
1 files changed, 18 insertions, 9 deletions
diff --git a/crates/ra_hir/src/ids.rs b/crates/ra_hir/src/ids.rs
index 5b00330c6..e805ddcba 100644
--- a/crates/ra_hir/src/ids.rs
+++ b/crates/ra_hir/src/ids.rs
@@ -200,8 +200,14 @@ pub(crate) trait AstItemDef<N: AstNode>: ArenaId + Clone {
200 fn interner(interner: &HirInterner) -> &LocationIntener<ItemLoc<N>, Self>; 200 fn interner(interner: &HirInterner) -> &LocationIntener<ItemLoc<N>, Self>;
201 fn from_ast(ctx: LocationCtx<&impl PersistentHirDatabase>, ast: &N) -> Self { 201 fn from_ast(ctx: LocationCtx<&impl PersistentHirDatabase>, ast: &N) -> Self {
202 let items = ctx.db.file_items(ctx.file_id); 202 let items = ctx.db.file_items(ctx.file_id);
203 let raw = 203 let item_id = items.id_of(ctx.file_id, ast.syntax());
204 SourceItemId { file_id: ctx.file_id, item_id: items.id_of(ctx.file_id, ast.syntax()) }; 204 Self::from_source_item_id_unchecked(ctx, item_id)
205 }
206 fn from_source_item_id_unchecked(
207 ctx: LocationCtx<&impl PersistentHirDatabase>,
208 item_id: SourceFileItemId,
209 ) -> Self {
210 let raw = SourceItemId { file_id: ctx.file_id, item_id };
205 let loc = ItemLoc { module: ctx.module, raw, _ty: PhantomData }; 211 let loc = ItemLoc { module: ctx.module, raw, _ty: PhantomData };
206 212
207 Self::interner(ctx.db.as_ref()).loc2id(&loc) 213 Self::interner(ctx.db.as_ref()).loc2id(&loc)
@@ -309,9 +315,7 @@ impl SourceFileItems {
309 file_id: HirFileId, 315 file_id: HirFileId,
310 ) -> Arc<SourceFileItems> { 316 ) -> Arc<SourceFileItems> {
311 let source_file = db.hir_parse(file_id); 317 let source_file = db.hir_parse(file_id);
312 let mut res = SourceFileItems { file_id, arena: Arena::default() }; 318 Arc::new(SourceFileItems::from_source_file(&source_file, file_id))
313 res.init(&source_file);
314 Arc::new(res)
315 } 319 }
316 320
317 pub(crate) fn file_item_query( 321 pub(crate) fn file_item_query(
@@ -324,18 +328,23 @@ impl SourceFileItems {
324 .to_owned() 328 .to_owned()
325 } 329 }
326 330
327 fn init(&mut self, source_file: &SourceFile) { 331 pub(crate) fn from_source_file(
332 source_file: &SourceFile,
333 file_id: HirFileId,
334 ) -> SourceFileItems {
335 let mut res = SourceFileItems { file_id, arena: Arena::default() };
328 // By walking the tree in bread-first order we make sure that parents 336 // By walking the tree in bread-first order we make sure that parents
329 // get lower ids then children. That is, adding a new child does not 337 // get lower ids then children. That is, adding a new child does not
330 // change parent's id. This means that, say, adding a new function to a 338 // change parent's id. This means that, say, adding a new function to a
331 // trait does not change ids of top-level items, which helps caching. 339 // trait does not change ids of top-level items, which helps caching.
332 bfs(source_file.syntax(), |it| { 340 bfs(source_file.syntax(), |it| {
333 if let Some(module_item) = ast::ModuleItem::cast(it) { 341 if let Some(module_item) = ast::ModuleItem::cast(it) {
334 self.alloc(module_item.syntax()); 342 res.alloc(module_item.syntax());
335 } else if let Some(macro_call) = ast::MacroCall::cast(it) { 343 } else if let Some(macro_call) = ast::MacroCall::cast(it) {
336 self.alloc(macro_call.syntax()); 344 res.alloc(macro_call.syntax());
337 } 345 }
338 }) 346 });
347 res
339 } 348 }
340 349
341 fn alloc(&mut self, item: &SyntaxNode) -> SourceFileItemId { 350 fn alloc(&mut self, item: &SyntaxNode) -> SourceFileItemId {