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.rs38
1 files changed, 12 insertions, 26 deletions
diff --git a/crates/ra_hir/src/ids.rs b/crates/ra_hir/src/ids.rs
index 7dd4b540e..0e4dc6261 100644
--- a/crates/ra_hir/src/ids.rs
+++ b/crates/ra_hir/src/ids.rs
@@ -4,7 +4,7 @@ use std::{
4}; 4};
5 5
6use ra_db::{LocationIntener, FileId}; 6use ra_db::{LocationIntener, FileId};
7use ra_syntax::{TreeArc, SyntaxNode, SourceFile, AstNode, ast}; 7use ra_syntax::{TreeArc, SyntaxNode, SourceFile, AstNode, SyntaxNodePtr, ast};
8use ra_arena::{Arena, RawId, ArenaId, impl_arena_id}; 8use ra_arena::{Arena, RawId, ArenaId, impl_arena_id};
9 9
10use crate::{ 10use crate::{
@@ -203,7 +203,7 @@ pub(crate) trait AstItemDef<N: AstNode>: ArenaId + Clone {
203 let items = ctx.db.file_items(ctx.file_id); 203 let items = ctx.db.file_items(ctx.file_id);
204 let raw = SourceItemId { 204 let raw = SourceItemId {
205 file_id: ctx.file_id, 205 file_id: ctx.file_id,
206 item_id: Some(items.id_of(ctx.file_id, ast.syntax())), 206 item_id: items.id_of(ctx.file_id, ast.syntax()),
207 }; 207 };
208 let loc = ItemLoc { 208 let loc = ItemLoc {
209 module: ctx.module, 209 module: ctx.module,
@@ -301,15 +301,14 @@ impl_arena_id!(SourceFileItemId);
301#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 301#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
302pub struct SourceItemId { 302pub struct SourceItemId {
303 pub(crate) file_id: HirFileId, 303 pub(crate) file_id: HirFileId,
304 /// None for the whole file. 304 pub(crate) item_id: SourceFileItemId,
305 pub(crate) item_id: Option<SourceFileItemId>,
306} 305}
307 306
308/// Maps items' `SyntaxNode`s to `SourceFileItemId`s and back. 307/// Maps items' `SyntaxNode`s to `SourceFileItemId`s and back.
309#[derive(Debug, PartialEq, Eq)] 308#[derive(Debug, PartialEq, Eq)]
310pub struct SourceFileItems { 309pub struct SourceFileItems {
311 file_id: HirFileId, 310 file_id: HirFileId,
312 arena: Arena<SourceFileItemId, TreeArc<SyntaxNode>>, 311 arena: Arena<SourceFileItemId, SyntaxNodePtr>,
313} 312}
314 313
315impl SourceFileItems { 314impl SourceFileItems {
@@ -329,15 +328,15 @@ impl SourceFileItems {
329 // trait does not chage ids of top-level items, which helps caching. 328 // trait does not chage ids of top-level items, which helps caching.
330 bfs(source_file.syntax(), |it| { 329 bfs(source_file.syntax(), |it| {
331 if let Some(module_item) = ast::ModuleItem::cast(it) { 330 if let Some(module_item) = ast::ModuleItem::cast(it) {
332 self.alloc(module_item.syntax().to_owned()); 331 self.alloc(module_item.syntax());
333 } else if let Some(macro_call) = ast::MacroCall::cast(it) { 332 } else if let Some(macro_call) = ast::MacroCall::cast(it) {
334 self.alloc(macro_call.syntax().to_owned()); 333 self.alloc(macro_call.syntax());
335 } 334 }
336 }) 335 })
337 } 336 }
338 337
339 fn alloc(&mut self, item: TreeArc<SyntaxNode>) -> SourceFileItemId { 338 fn alloc(&mut self, item: &SyntaxNode) -> SourceFileItemId {
340 self.arena.alloc(item) 339 self.arena.alloc(SyntaxNodePtr::new(item))
341 } 340 }
342 pub(crate) fn id_of(&self, file_id: HirFileId, item: &SyntaxNode) -> SourceFileItemId { 341 pub(crate) fn id_of(&self, file_id: HirFileId, item: &SyntaxNode) -> SourceFileItemId {
343 assert_eq!( 342 assert_eq!(
@@ -348,17 +347,8 @@ impl SourceFileItems {
348 self.id_of_unchecked(item) 347 self.id_of_unchecked(item)
349 } 348 }
350 pub(crate) fn id_of_unchecked(&self, item: &SyntaxNode) -> SourceFileItemId { 349 pub(crate) fn id_of_unchecked(&self, item: &SyntaxNode) -> SourceFileItemId {
351 if let Some((id, _)) = self.arena.iter().find(|(_id, i)| *i == item) { 350 let ptr = SyntaxNodePtr::new(item);
352 return id; 351 if let Some((id, _)) = self.arena.iter().find(|(_id, i)| **i == ptr) {
353 }
354 // This should not happen. Let's try to give a sensible diagnostics.
355 if let Some((id, i)) = self.arena.iter().find(|(_id, i)| i.range() == item.range()) {
356 // FIXME(#288): whyyy are we getting here?
357 log::error!(
358 "unequal syntax nodes with the same range:\n{:?}\n{:?}",
359 item,
360 i
361 );
362 return id; 352 return id;
363 } 353 }
364 panic!( 354 panic!(
@@ -367,15 +357,11 @@ impl SourceFileItems {
367 self.arena.iter().map(|(_id, i)| i).collect::<Vec<_>>(), 357 self.arena.iter().map(|(_id, i)| i).collect::<Vec<_>>(),
368 ); 358 );
369 } 359 }
370 pub fn id_of_parse(&self) -> SourceFileItemId {
371 let (id, _syntax) = self.arena.iter().next().unwrap();
372 id
373 }
374} 360}
375 361
376impl std::ops::Index<SourceFileItemId> for SourceFileItems { 362impl std::ops::Index<SourceFileItemId> for SourceFileItems {
377 type Output = SyntaxNode; 363 type Output = SyntaxNodePtr;
378 fn index(&self, idx: SourceFileItemId) -> &SyntaxNode { 364 fn index(&self, idx: SourceFileItemId) -> &SyntaxNodePtr {
379 &self.arena[idx] 365 &self.arena[idx]
380 } 366 }
381} 367}