diff options
Diffstat (limited to 'crates/ra_hir/src/ids.rs')
-rw-r--r-- | crates/ra_hir/src/ids.rs | 38 |
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 | ||
6 | use ra_db::{LocationIntener, FileId}; | 6 | use ra_db::{LocationIntener, FileId}; |
7 | use ra_syntax::{TreeArc, SyntaxNode, SourceFile, AstNode, ast}; | 7 | use ra_syntax::{TreeArc, SyntaxNode, SourceFile, AstNode, SyntaxNodePtr, ast}; |
8 | use ra_arena::{Arena, RawId, ArenaId, impl_arena_id}; | 8 | use ra_arena::{Arena, RawId, ArenaId, impl_arena_id}; |
9 | 9 | ||
10 | use crate::{ | 10 | use 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)] |
302 | pub struct SourceItemId { | 302 | pub 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)] |
310 | pub struct SourceFileItems { | 309 | pub 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 | ||
315 | impl SourceFileItems { | 314 | impl 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 | ||
376 | impl std::ops::Index<SourceFileItemId> for SourceFileItems { | 362 | impl 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 | } |