diff options
-rw-r--r-- | crates/ra_hir/src/code_model_impl/module.rs | 18 | ||||
-rw-r--r-- | crates/ra_hir/src/lib.rs | 2 | ||||
-rw-r--r-- | crates/ra_hir/src/nameres.rs | 20 | ||||
-rw-r--r-- | crates/ra_hir/src/nameres/collector.rs | 22 | ||||
-rw-r--r-- | crates/ra_hir/src/nameres/raw.rs | 13 | ||||
-rw-r--r-- | crates/ra_hir/src/source_binder.rs | 8 | ||||
-rw-r--r-- | crates/ra_hir/src/source_id.rs | 50 |
7 files changed, 88 insertions, 45 deletions
diff --git a/crates/ra_hir/src/code_model_impl/module.rs b/crates/ra_hir/src/code_model_impl/module.rs index 790e2b80f..0edb8ade5 100644 --- a/crates/ra_hir/src/code_model_impl/module.rs +++ b/crates/ra_hir/src/code_model_impl/module.rs | |||
@@ -1,18 +1,18 @@ | |||
1 | use ra_db::FileId; | 1 | use ra_db::FileId; |
2 | use ra_syntax::{ast, TreeArc, AstNode}; | 2 | use ra_syntax::{ast, TreeArc}; |
3 | 3 | ||
4 | use crate::{ | 4 | use crate::{ |
5 | Module, ModuleSource, Name, | 5 | Module, ModuleSource, Name, AstId, |
6 | nameres::{CrateModuleId, ImportId}, | 6 | nameres::{CrateModuleId, ImportId}, |
7 | HirDatabase, DefDatabase, | 7 | HirDatabase, DefDatabase, |
8 | HirFileId, SourceItemId, | 8 | HirFileId, |
9 | }; | 9 | }; |
10 | 10 | ||
11 | impl ModuleSource { | 11 | impl ModuleSource { |
12 | pub(crate) fn new( | 12 | pub(crate) fn new( |
13 | db: &impl DefDatabase, | 13 | db: &impl DefDatabase, |
14 | file_id: Option<FileId>, | 14 | file_id: Option<FileId>, |
15 | decl_id: Option<SourceItemId>, | 15 | decl_id: Option<AstId<ast::Module>>, |
16 | ) -> ModuleSource { | 16 | ) -> ModuleSource { |
17 | match (file_id, decl_id) { | 17 | match (file_id, decl_id) { |
18 | (Some(file_id), _) => { | 18 | (Some(file_id), _) => { |
@@ -20,8 +20,7 @@ impl ModuleSource { | |||
20 | ModuleSource::SourceFile(source_file) | 20 | ModuleSource::SourceFile(source_file) |
21 | } | 21 | } |
22 | (None, Some(item_id)) => { | 22 | (None, Some(item_id)) => { |
23 | let module = db.file_item(item_id); | 23 | let module = item_id.to_node(db); |
24 | let module = ast::Module::cast(&*module).unwrap(); | ||
25 | assert!(module.item_list().is_some(), "expected inline module"); | 24 | assert!(module.item_list().is_some(), "expected inline module"); |
26 | ModuleSource::Module(module.to_owned()) | 25 | ModuleSource::Module(module.to_owned()) |
27 | } | 26 | } |
@@ -55,7 +54,7 @@ impl Module { | |||
55 | let decl_id = def_map[self.module_id].declaration; | 54 | let decl_id = def_map[self.module_id].declaration; |
56 | let file_id = def_map[self.module_id].definition; | 55 | let file_id = def_map[self.module_id].definition; |
57 | let module_source = ModuleSource::new(db, file_id, decl_id); | 56 | let module_source = ModuleSource::new(db, file_id, decl_id); |
58 | let file_id = file_id.map(HirFileId::from).unwrap_or_else(|| decl_id.unwrap().file_id); | 57 | let file_id = file_id.map(HirFileId::from).unwrap_or_else(|| decl_id.unwrap().file_id()); |
59 | (file_id, module_source) | 58 | (file_id, module_source) |
60 | } | 59 | } |
61 | 60 | ||
@@ -65,9 +64,8 @@ impl Module { | |||
65 | ) -> Option<(HirFileId, TreeArc<ast::Module>)> { | 64 | ) -> Option<(HirFileId, TreeArc<ast::Module>)> { |
66 | let def_map = db.crate_def_map(self.krate); | 65 | let def_map = db.crate_def_map(self.krate); |
67 | let decl = def_map[self.module_id].declaration?; | 66 | let decl = def_map[self.module_id].declaration?; |
68 | let syntax_node = db.file_item(decl); | 67 | let ast = decl.to_node(db); |
69 | let ast = ast::Module::cast(&syntax_node).unwrap().to_owned(); | 68 | Some((decl.file_id(), ast)) |
70 | Some((decl.file_id, ast)) | ||
71 | } | 69 | } |
72 | 70 | ||
73 | pub(crate) fn import_source_impl( | 71 | pub(crate) fn import_source_impl( |
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs index ac2585de0..3fc08c55c 100644 --- a/crates/ra_hir/src/lib.rs +++ b/crates/ra_hir/src/lib.rs | |||
@@ -48,7 +48,7 @@ mod marks; | |||
48 | use crate::{ | 48 | use crate::{ |
49 | db::{HirDatabase, DefDatabase}, | 49 | db::{HirDatabase, DefDatabase}, |
50 | name::{AsName, KnownName}, | 50 | name::{AsName, KnownName}, |
51 | source_id::SourceFileItemId, | 51 | source_id::{SourceFileItemId, FileAstId, AstId}, |
52 | }; | 52 | }; |
53 | 53 | ||
54 | pub use self::{ | 54 | pub use self::{ |
diff --git a/crates/ra_hir/src/nameres.rs b/crates/ra_hir/src/nameres.rs index e962bbd31..67b9d6986 100644 --- a/crates/ra_hir/src/nameres.rs +++ b/crates/ra_hir/src/nameres.rs | |||
@@ -59,13 +59,15 @@ use rustc_hash::FxHashMap; | |||
59 | use ra_arena::{Arena, RawId, impl_arena_id}; | 59 | use ra_arena::{Arena, RawId, impl_arena_id}; |
60 | use ra_db::{FileId, Edition}; | 60 | use ra_db::{FileId, Edition}; |
61 | use test_utils::tested_by; | 61 | use test_utils::tested_by; |
62 | use ra_syntax::ast; | ||
62 | 63 | ||
63 | use crate::{ | 64 | use crate::{ |
64 | ModuleDef, Name, Crate, Module, SourceItemId, | 65 | ModuleDef, Name, Crate, Module, |
65 | DefDatabase, Path, PathKind, HirFileId, Trait, | 66 | DefDatabase, Path, PathKind, HirFileId, Trait, |
66 | ids::MacroDefId, | 67 | ids::MacroDefId, |
67 | diagnostics::DiagnosticSink, | 68 | diagnostics::DiagnosticSink, |
68 | nameres::diagnostics::DefDiagnostic, | 69 | nameres::diagnostics::DefDiagnostic, |
70 | AstId, | ||
69 | }; | 71 | }; |
70 | 72 | ||
71 | pub(crate) use self::raw::{RawItems, ImportId, ImportSourceMap}; | 73 | pub(crate) use self::raw::{RawItems, ImportId, ImportSourceMap}; |
@@ -106,7 +108,7 @@ pub(crate) struct ModuleData { | |||
106 | pub(crate) children: FxHashMap<Name, CrateModuleId>, | 108 | pub(crate) children: FxHashMap<Name, CrateModuleId>, |
107 | pub(crate) scope: ModuleScope, | 109 | pub(crate) scope: ModuleScope, |
108 | /// None for root | 110 | /// None for root |
109 | pub(crate) declaration: Option<SourceItemId>, | 111 | pub(crate) declaration: Option<AstId<ast::Module>>, |
110 | /// None for inline modules. | 112 | /// None for inline modules. |
111 | /// | 113 | /// |
112 | /// Note that non-inline modules, by definition, live inside non-macro file. | 114 | /// Note that non-inline modules, by definition, live inside non-macro file. |
@@ -225,7 +227,7 @@ impl CrateDefMap { | |||
225 | pub(crate) fn find_module_by_source( | 227 | pub(crate) fn find_module_by_source( |
226 | &self, | 228 | &self, |
227 | file_id: HirFileId, | 229 | file_id: HirFileId, |
228 | decl_id: Option<SourceItemId>, | 230 | decl_id: Option<AstId<ast::Module>>, |
229 | ) -> Option<CrateModuleId> { | 231 | ) -> Option<CrateModuleId> { |
230 | let (module_id, _module_data) = self.modules.iter().find(|(_module_id, module_data)| { | 232 | let (module_id, _module_data) = self.modules.iter().find(|(_module_id, module_data)| { |
231 | if decl_id.is_some() { | 233 | if decl_id.is_some() { |
@@ -429,10 +431,10 @@ impl CrateDefMap { | |||
429 | 431 | ||
430 | mod diagnostics { | 432 | mod diagnostics { |
431 | use relative_path::RelativePathBuf; | 433 | use relative_path::RelativePathBuf; |
432 | use ra_syntax::{AstPtr, AstNode, ast}; | 434 | use ra_syntax::{AstPtr, ast}; |
433 | 435 | ||
434 | use crate::{ | 436 | use crate::{ |
435 | SourceItemId, DefDatabase, | 437 | AstId, DefDatabase, |
436 | nameres::CrateModuleId, | 438 | nameres::CrateModuleId, |
437 | diagnostics::{DiagnosticSink, UnresolvedModule}, | 439 | diagnostics::{DiagnosticSink, UnresolvedModule}, |
438 | }; | 440 | }; |
@@ -441,7 +443,7 @@ mod diagnostics { | |||
441 | pub(super) enum DefDiagnostic { | 443 | pub(super) enum DefDiagnostic { |
442 | UnresolvedModule { | 444 | UnresolvedModule { |
443 | module: CrateModuleId, | 445 | module: CrateModuleId, |
444 | declaration: SourceItemId, | 446 | declaration: AstId<ast::Module>, |
445 | candidate: RelativePathBuf, | 447 | candidate: RelativePathBuf, |
446 | }, | 448 | }, |
447 | } | 449 | } |
@@ -458,10 +460,9 @@ mod diagnostics { | |||
458 | if *module != target_module { | 460 | if *module != target_module { |
459 | return; | 461 | return; |
460 | } | 462 | } |
461 | let syntax = db.file_item(*declaration); | 463 | let decl = declaration.to_node(db); |
462 | let decl = ast::Module::cast(&syntax).unwrap(); | ||
463 | sink.push(UnresolvedModule { | 464 | sink.push(UnresolvedModule { |
464 | file: declaration.file_id, | 465 | file: declaration.file_id(), |
465 | decl: AstPtr::new(&decl), | 466 | decl: AstPtr::new(&decl), |
466 | candidate: candidate.clone(), | 467 | candidate: candidate.clone(), |
467 | }) | 468 | }) |
@@ -469,5 +470,4 @@ mod diagnostics { | |||
469 | } | 470 | } |
470 | } | 471 | } |
471 | } | 472 | } |
472 | |||
473 | } | 473 | } |
diff --git a/crates/ra_hir/src/nameres/collector.rs b/crates/ra_hir/src/nameres/collector.rs index 4fb298155..e6fd8632a 100644 --- a/crates/ra_hir/src/nameres/collector.rs +++ b/crates/ra_hir/src/nameres/collector.rs | |||
@@ -3,6 +3,7 @@ use rustc_hash::FxHashMap; | |||
3 | use relative_path::RelativePathBuf; | 3 | use relative_path::RelativePathBuf; |
4 | use test_utils::tested_by; | 4 | use test_utils::tested_by; |
5 | use ra_db::FileId; | 5 | use ra_db::FileId; |
6 | use ra_syntax::ast; | ||
6 | 7 | ||
7 | use crate::{ | 8 | use crate::{ |
8 | Function, Module, Struct, Enum, Const, Static, Trait, TypeAlias, | 9 | Function, Module, Struct, Enum, Const, Static, Trait, TypeAlias, |
@@ -15,6 +16,7 @@ use crate::{ | |||
15 | raw, | 16 | raw, |
16 | }, | 17 | }, |
17 | ids::{AstItemDef, LocationCtx, MacroCallLoc, MacroCallId, MacroDefId}, | 18 | ids::{AstItemDef, LocationCtx, MacroCallLoc, MacroCallId, MacroDefId}, |
19 | AstId, | ||
18 | }; | 20 | }; |
19 | 21 | ||
20 | pub(super) fn collect_defs(db: &impl DefDatabase, mut def_map: CrateDefMap) -> CrateDefMap { | 22 | pub(super) fn collect_defs(db: &impl DefDatabase, mut def_map: CrateDefMap) -> CrateDefMap { |
@@ -364,12 +366,9 @@ where | |||
364 | fn collect_module(&mut self, module: &raw::ModuleData) { | 366 | fn collect_module(&mut self, module: &raw::ModuleData) { |
365 | match module { | 367 | match module { |
366 | // inline module, just recurse | 368 | // inline module, just recurse |
367 | raw::ModuleData::Definition { name, items, source_item_id } => { | 369 | raw::ModuleData::Definition { name, items, ast_id } => { |
368 | let module_id = self.push_child_module( | 370 | let module_id = |
369 | name.clone(), | 371 | self.push_child_module(name.clone(), ast_id.with_file_id(self.file_id), None); |
370 | source_item_id.with_file_id(self.file_id), | ||
371 | None, | ||
372 | ); | ||
373 | ModCollector { | 372 | ModCollector { |
374 | def_collector: &mut *self.def_collector, | 373 | def_collector: &mut *self.def_collector, |
375 | module_id, | 374 | module_id, |
@@ -379,13 +378,12 @@ where | |||
379 | .collect(&*items); | 378 | .collect(&*items); |
380 | } | 379 | } |
381 | // out of line module, resovle, parse and recurse | 380 | // out of line module, resovle, parse and recurse |
382 | raw::ModuleData::Declaration { name, source_item_id } => { | 381 | raw::ModuleData::Declaration { name, ast_id } => { |
383 | let source_item_id = source_item_id.with_file_id(self.file_id); | 382 | let ast_id = ast_id.with_file_id(self.file_id); |
384 | let is_root = self.def_collector.def_map.modules[self.module_id].parent.is_none(); | 383 | let is_root = self.def_collector.def_map.modules[self.module_id].parent.is_none(); |
385 | match resolve_submodule(self.def_collector.db, self.file_id, name, is_root) { | 384 | match resolve_submodule(self.def_collector.db, self.file_id, name, is_root) { |
386 | Ok(file_id) => { | 385 | Ok(file_id) => { |
387 | let module_id = | 386 | let module_id = self.push_child_module(name.clone(), ast_id, Some(file_id)); |
388 | self.push_child_module(name.clone(), source_item_id, Some(file_id)); | ||
389 | let raw_items = self.def_collector.db.raw_items(file_id.into()); | 387 | let raw_items = self.def_collector.db.raw_items(file_id.into()); |
390 | ModCollector { | 388 | ModCollector { |
391 | def_collector: &mut *self.def_collector, | 389 | def_collector: &mut *self.def_collector, |
@@ -398,7 +396,7 @@ where | |||
398 | Err(candidate) => self.def_collector.def_map.diagnostics.push( | 396 | Err(candidate) => self.def_collector.def_map.diagnostics.push( |
399 | DefDiagnostic::UnresolvedModule { | 397 | DefDiagnostic::UnresolvedModule { |
400 | module: self.module_id, | 398 | module: self.module_id, |
401 | declaration: source_item_id, | 399 | declaration: ast_id, |
402 | candidate, | 400 | candidate, |
403 | }, | 401 | }, |
404 | ), | 402 | ), |
@@ -410,7 +408,7 @@ where | |||
410 | fn push_child_module( | 408 | fn push_child_module( |
411 | &mut self, | 409 | &mut self, |
412 | name: Name, | 410 | name: Name, |
413 | declaration: SourceItemId, | 411 | declaration: AstId<ast::Module>, |
414 | definition: Option<FileId>, | 412 | definition: Option<FileId>, |
415 | ) -> CrateModuleId { | 413 | ) -> CrateModuleId { |
416 | let modules = &mut self.def_collector.def_map.modules; | 414 | let modules = &mut self.def_collector.def_map.modules; |
diff --git a/crates/ra_hir/src/nameres/raw.rs b/crates/ra_hir/src/nameres/raw.rs index f32004601..09acd5a98 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 | ||
13 | use crate::{ | 13 | use crate::{ |
14 | DefDatabase, Name, AsName, Path, HirFileId, ModuleSource, | 14 | DefDatabase, Name, AsName, Path, HirFileId, ModuleSource, |
15 | SourceFileItemId, SourceFileItems, | 15 | SourceFileItemId, SourceFileItems, 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). |
@@ -115,8 +115,8 @@ impl_arena_id!(Module); | |||
115 | 115 | ||
116 | #[derive(Debug, PartialEq, Eq)] | 116 | #[derive(Debug, PartialEq, Eq)] |
117 | pub(super) enum ModuleData { | 117 | pub(super) enum ModuleData { |
118 | Declaration { name: Name, source_item_id: SourceFileItemId }, | 118 | Declaration { name: Name, ast_id: FileAstId<ast::Module> }, |
119 | Definition { name: Name, source_item_id: SourceFileItemId, items: Vec<RawItem> }, | 119 | Definition { name: Name, ast_id: FileAstId<ast::Module>, items: Vec<RawItem> }, |
120 | } | 120 | } |
121 | 121 | ||
122 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 122 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
@@ -221,10 +221,9 @@ impl RawItemsCollector { | |||
221 | Some(it) => it.as_name(), | 221 | Some(it) => it.as_name(), |
222 | None => return, | 222 | None => return, |
223 | }; | 223 | }; |
224 | let source_item_id = self.source_file_items.id_of_unchecked(module.syntax()); | 224 | let ast_id = self.source_file_items.ast_id(module); |
225 | if module.has_semi() { | 225 | if module.has_semi() { |
226 | let item = | 226 | let item = self.raw_items.modules.alloc(ModuleData::Declaration { name, ast_id }); |
227 | self.raw_items.modules.alloc(ModuleData::Declaration { name, source_item_id }); | ||
228 | self.push_item(current_module, RawItem::Module(item)); | 227 | self.push_item(current_module, RawItem::Module(item)); |
229 | return; | 228 | return; |
230 | } | 229 | } |
@@ -232,7 +231,7 @@ impl RawItemsCollector { | |||
232 | if let Some(item_list) = module.item_list() { | 231 | if let Some(item_list) = module.item_list() { |
233 | let item = self.raw_items.modules.alloc(ModuleData::Definition { | 232 | let item = self.raw_items.modules.alloc(ModuleData::Definition { |
234 | name, | 233 | name, |
235 | source_item_id, | 234 | ast_id, |
236 | items: Vec::new(), | 235 | items: Vec::new(), |
237 | }); | 236 | }); |
238 | self.process_module(Some(item), item_list); | 237 | self.process_module(Some(item), item_list); |
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index db9e3a22e..f9d2d0247 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs | |||
@@ -13,10 +13,10 @@ use ra_syntax::{ | |||
13 | }; | 13 | }; |
14 | 14 | ||
15 | use crate::{ | 15 | use crate::{ |
16 | HirDatabase, Function, Struct, Enum, SourceItemId, | 16 | HirDatabase, Function, Struct, Enum, |
17 | AsName, Module, HirFileId, Crate, Trait, Resolver, | 17 | AsName, Module, HirFileId, Crate, Trait, Resolver, |
18 | ids::LocationCtx, | 18 | ids::LocationCtx, |
19 | expr | 19 | expr, AstId |
20 | }; | 20 | }; |
21 | 21 | ||
22 | /// Locates the module by `FileId`. Picks topmost module in the file. | 22 | /// Locates the module by `FileId`. Picks topmost module in the file. |
@@ -55,7 +55,7 @@ fn module_from_inline( | |||
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 file_items = db.file_items(file_id); |
58 | let item_id = file_items.id_of(file_id, module.syntax()).with_file_id(file_id); | 58 | let item_id = file_items.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 | ||
@@ -75,7 +75,7 @@ pub fn module_from_child_node( | |||
75 | fn module_from_source( | 75 | fn module_from_source( |
76 | db: &impl HirDatabase, | 76 | db: &impl HirDatabase, |
77 | file_id: HirFileId, | 77 | file_id: HirFileId, |
78 | decl_id: Option<SourceItemId>, | 78 | decl_id: Option<AstId<ast::Module>>, |
79 | ) -> Option<Module> { | 79 | ) -> Option<Module> { |
80 | let source_root_id = db.file_source_root(file_id.as_original_file()); | 80 | let source_root_id = db.file_source_root(file_id.as_original_file()); |
81 | db.source_root_crates(source_root_id).iter().map(|&crate_id| Crate { crate_id }).find_map( | 81 | db.source_root_crates(source_root_id).iter().map(|&crate_id| Crate { crate_id }).find_map( |
diff --git a/crates/ra_hir/src/source_id.rs b/crates/ra_hir/src/source_id.rs index 62707ba6a..881cc590e 100644 --- a/crates/ra_hir/src/source_id.rs +++ b/crates/ra_hir/src/source_id.rs | |||
@@ -1,10 +1,55 @@ | |||
1 | use std::sync::Arc; | 1 | use std::{marker::PhantomData, sync::Arc}; |
2 | 2 | ||
3 | use ra_arena::{Arena, RawId, impl_arena_id}; | 3 | use ra_arena::{Arena, RawId, impl_arena_id}; |
4 | use ra_syntax::{SyntaxNodePtr, TreeArc, SyntaxNode, SourceFile, AstNode, ast}; | 4 | use ra_syntax::{SyntaxNodePtr, TreeArc, SyntaxNode, SourceFile, AstNode, ast}; |
5 | 5 | ||
6 | use crate::{HirFileId, DefDatabase}; | 6 | use crate::{HirFileId, DefDatabase}; |
7 | 7 | ||
8 | #[derive(Debug, PartialEq, Eq)] | ||
9 | pub(crate) struct AstId<N: AstNode> { | ||
10 | file_id: HirFileId, | ||
11 | file_ast_id: FileAstId<N>, | ||
12 | } | ||
13 | |||
14 | impl<N: AstNode> Clone for AstId<N> { | ||
15 | fn clone(&self) -> AstId<N> { | ||
16 | *self | ||
17 | } | ||
18 | } | ||
19 | |||
20 | impl<N: AstNode> Copy for AstId<N> {} | ||
21 | |||
22 | impl<N: AstNode> AstId<N> { | ||
23 | pub(crate) fn file_id(&self) -> HirFileId { | ||
24 | self.file_id | ||
25 | } | ||
26 | |||
27 | pub(crate) fn to_node(&self, db: &impl DefDatabase) -> TreeArc<N> { | ||
28 | let syntax_node = db.file_item(self.file_ast_id.raw.with_file_id(self.file_id)); | ||
29 | N::cast(&syntax_node).unwrap().to_owned() | ||
30 | } | ||
31 | } | ||
32 | |||
33 | #[derive(Debug, PartialEq, Eq)] | ||
34 | pub(crate) struct FileAstId<N: AstNode> { | ||
35 | raw: SourceFileItemId, | ||
36 | _ty: PhantomData<N>, | ||
37 | } | ||
38 | |||
39 | impl<N: AstNode> Clone for FileAstId<N> { | ||
40 | fn clone(&self) -> FileAstId<N> { | ||
41 | *self | ||
42 | } | ||
43 | } | ||
44 | |||
45 | impl<N: AstNode> Copy for FileAstId<N> {} | ||
46 | |||
47 | impl<N: AstNode> FileAstId<N> { | ||
48 | pub(crate) fn with_file_id(self, file_id: HirFileId) -> AstId<N> { | ||
49 | AstId { file_id, file_ast_id: self } | ||
50 | } | ||
51 | } | ||
52 | |||
8 | /// Identifier of item within a specific file. This is stable over reparses, so | 53 | /// Identifier of item within a specific file. This is stable over reparses, so |
9 | /// it's OK to use it as a salsa key/value. | 54 | /// it's OK to use it as a salsa key/value. |
10 | #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] | 55 | #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] |
@@ -90,6 +135,9 @@ impl SourceFileItems { | |||
90 | self.arena.iter().map(|(_id, i)| i).collect::<Vec<_>>(), | 135 | self.arena.iter().map(|(_id, i)| i).collect::<Vec<_>>(), |
91 | ); | 136 | ); |
92 | } | 137 | } |
138 | pub(crate) fn ast_id<N: AstNode>(&self, item: &N) -> FileAstId<N> { | ||
139 | FileAstId { raw: self.id_of_unchecked(item.syntax()), _ty: PhantomData } | ||
140 | } | ||
93 | } | 141 | } |
94 | 142 | ||
95 | impl std::ops::Index<SourceFileItemId> for SourceFileItems { | 143 | impl std::ops::Index<SourceFileItemId> for SourceFileItems { |