aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_hir/src/code_model_impl/module.rs18
-rw-r--r--crates/ra_hir/src/lib.rs2
-rw-r--r--crates/ra_hir/src/nameres.rs20
-rw-r--r--crates/ra_hir/src/nameres/collector.rs22
-rw-r--r--crates/ra_hir/src/nameres/raw.rs13
-rw-r--r--crates/ra_hir/src/source_binder.rs8
-rw-r--r--crates/ra_hir/src/source_id.rs50
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 @@
1use ra_db::FileId; 1use ra_db::FileId;
2use ra_syntax::{ast, TreeArc, AstNode}; 2use ra_syntax::{ast, TreeArc};
3 3
4use crate::{ 4use 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
11impl ModuleSource { 11impl 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;
48use crate::{ 48use 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
54pub use self::{ 54pub 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;
59use ra_arena::{Arena, RawId, impl_arena_id}; 59use ra_arena::{Arena, RawId, impl_arena_id};
60use ra_db::{FileId, Edition}; 60use ra_db::{FileId, Edition};
61use test_utils::tested_by; 61use test_utils::tested_by;
62use ra_syntax::ast;
62 63
63use crate::{ 64use 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
71pub(crate) use self::raw::{RawItems, ImportId, ImportSourceMap}; 73pub(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
430mod diagnostics { 432mod 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;
3use relative_path::RelativePathBuf; 3use relative_path::RelativePathBuf;
4use test_utils::tested_by; 4use test_utils::tested_by;
5use ra_db::FileId; 5use ra_db::FileId;
6use ra_syntax::ast;
6 7
7use crate::{ 8use 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
20pub(super) fn collect_defs(db: &impl DefDatabase, mut def_map: CrateDefMap) -> CrateDefMap { 22pub(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
13use crate::{ 13use 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)]
117pub(super) enum ModuleData { 117pub(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
15use crate::{ 15use 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(
75fn module_from_source( 75fn 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 @@
1use std::sync::Arc; 1use std::{marker::PhantomData, sync::Arc};
2 2
3use ra_arena::{Arena, RawId, impl_arena_id}; 3use ra_arena::{Arena, RawId, impl_arena_id};
4use ra_syntax::{SyntaxNodePtr, TreeArc, SyntaxNode, SourceFile, AstNode, ast}; 4use ra_syntax::{SyntaxNodePtr, TreeArc, SyntaxNode, SourceFile, AstNode, ast};
5 5
6use crate::{HirFileId, DefDatabase}; 6use crate::{HirFileId, DefDatabase};
7 7
8#[derive(Debug, PartialEq, Eq)]
9pub(crate) struct AstId<N: AstNode> {
10 file_id: HirFileId,
11 file_ast_id: FileAstId<N>,
12}
13
14impl<N: AstNode> Clone for AstId<N> {
15 fn clone(&self) -> AstId<N> {
16 *self
17 }
18}
19
20impl<N: AstNode> Copy for AstId<N> {}
21
22impl<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)]
34pub(crate) struct FileAstId<N: AstNode> {
35 raw: SourceFileItemId,
36 _ty: PhantomData<N>,
37}
38
39impl<N: AstNode> Clone for FileAstId<N> {
40 fn clone(&self) -> FileAstId<N> {
41 *self
42 }
43}
44
45impl<N: AstNode> Copy for FileAstId<N> {}
46
47impl<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
95impl std::ops::Index<SourceFileItemId> for SourceFileItems { 143impl std::ops::Index<SourceFileItemId> for SourceFileItems {