aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/module/nameres.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/module/nameres.rs')
-rw-r--r--crates/ra_hir/src/module/nameres.rs134
1 files changed, 14 insertions, 120 deletions
diff --git a/crates/ra_hir/src/module/nameres.rs b/crates/ra_hir/src/module/nameres.rs
index 513a37646..837a8d5ae 100644
--- a/crates/ra_hir/src/module/nameres.rs
+++ b/crates/ra_hir/src/module/nameres.rs
@@ -38,20 +38,20 @@ use crate::{
38/// Item map is the result of the name resolution. Item map contains, for each 38/// Item map is the result of the name resolution. Item map contains, for each
39/// module, the set of visible items. 39/// module, the set of visible items.
40#[derive(Default, Debug, PartialEq, Eq)] 40#[derive(Default, Debug, PartialEq, Eq)]
41pub(crate) struct ItemMap { 41pub struct ItemMap {
42 pub(crate) per_module: FxHashMap<ModuleId, ModuleScope>, 42 pub per_module: FxHashMap<ModuleId, ModuleScope>,
43} 43}
44 44
45#[derive(Debug, Default, PartialEq, Eq, Clone)] 45#[derive(Debug, Default, PartialEq, Eq, Clone)]
46pub(crate) struct ModuleScope { 46pub struct ModuleScope {
47 items: FxHashMap<SmolStr, Resolution>, 47 pub items: FxHashMap<SmolStr, Resolution>,
48} 48}
49 49
50impl ModuleScope { 50impl ModuleScope {
51 pub(crate) fn entries<'a>(&'a self) -> impl Iterator<Item = (&'a SmolStr, &Resolution)> + 'a { 51 pub fn entries<'a>(&'a self) -> impl Iterator<Item = (&'a SmolStr, &Resolution)> + 'a {
52 self.items.iter() 52 self.items.iter()
53 } 53 }
54 pub(crate) fn get(&self, name: &SmolStr) -> Option<&Resolution> { 54 pub fn get(&self, name: &SmolStr) -> Option<&Resolution> {
55 self.items.get(name) 55 self.items.get(name)
56 } 56 }
57} 57}
@@ -63,7 +63,7 @@ impl ModuleScope {
63/// recomputing name res: if `InputModuleItems` are the same, we can avoid 63/// recomputing name res: if `InputModuleItems` are the same, we can avoid
64/// running name resolution. 64/// running name resolution.
65#[derive(Debug, Default, PartialEq, Eq)] 65#[derive(Debug, Default, PartialEq, Eq)]
66pub(crate) struct InputModuleItems { 66pub struct InputModuleItems {
67 items: Vec<ModuleItem>, 67 items: Vec<ModuleItem>,
68 imports: Vec<Import>, 68 imports: Vec<Import>,
69} 69}
@@ -89,13 +89,13 @@ struct Import {
89} 89}
90 90
91#[derive(Debug, Clone, Copy, PartialEq, Eq)] 91#[derive(Debug, Clone, Copy, PartialEq, Eq)]
92pub(crate) struct NamedImport { 92pub struct NamedImport {
93 file_item_id: SourceFileItemId, 93 pub file_item_id: SourceFileItemId,
94 relative_range: TextRange, 94 pub relative_range: TextRange,
95} 95}
96 96
97impl NamedImport { 97impl NamedImport {
98 pub(crate) fn range(&self, db: &impl HirDatabase, file_id: FileId) -> TextRange { 98 pub fn range(&self, db: &impl HirDatabase, file_id: FileId) -> TextRange {
99 let source_item_id = SourceItemId { 99 let source_item_id = SourceItemId {
100 file_id, 100 file_id,
101 item_id: self.file_item_id, 101 item_id: self.file_item_id,
@@ -115,11 +115,11 @@ enum ImportKind {
115/// Resolution is basically `DefId` atm, but it should account for stuff like 115/// Resolution is basically `DefId` atm, but it should account for stuff like
116/// multiple namespaces, ambiguity and errors. 116/// multiple namespaces, ambiguity and errors.
117#[derive(Debug, Clone, PartialEq, Eq)] 117#[derive(Debug, Clone, PartialEq, Eq)]
118pub(crate) struct Resolution { 118pub struct Resolution {
119 /// None for unresolved 119 /// None for unresolved
120 pub(crate) def_id: Option<DefId>, 120 pub def_id: Option<DefId>,
121 /// ident by whitch this is imported into local scope. 121 /// ident by whitch this is imported into local scope.
122 pub(crate) import: Option<NamedImport>, 122 pub import: Option<NamedImport>,
123} 123}
124 124
125// #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] 125// #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
@@ -336,109 +336,3 @@ where
336 f(module_items) 336 f(module_items)
337 } 337 }
338} 338}
339
340#[cfg(test)]
341mod tests {
342 use ra_db::FilesDatabase;
343 use crate::{
344 AnalysisChange,
345 mock_analysis::{MockAnalysis, analysis_and_position},
346 hir::{self, HirDatabase},
347};
348 use super::*;
349
350 fn item_map(fixture: &str) -> (Arc<ItemMap>, ModuleId) {
351 let (analysis, pos) = analysis_and_position(fixture);
352 let db = analysis.imp.db;
353 let source_root = db.file_source_root(pos.file_id);
354 let descr = hir::Module::guess_from_position(&*db, pos)
355 .unwrap()
356 .unwrap();
357 let module_id = descr.module_id;
358 (db.item_map(source_root).unwrap(), module_id)
359 }
360
361 #[test]
362 fn test_item_map() {
363 let (item_map, module_id) = item_map(
364 "
365 //- /lib.rs
366 mod foo;
367
368 use crate::foo::bar::Baz;
369 <|>
370
371 //- /foo/mod.rs
372 pub mod bar;
373
374 //- /foo/bar.rs
375 pub struct Baz;
376 ",
377 );
378 let name = SmolStr::from("Baz");
379 let resolution = &item_map.per_module[&module_id].items[&name];
380 assert!(resolution.def_id.is_some());
381 }
382
383 #[test]
384 fn typing_inside_a_function_should_not_invalidate_item_map() {
385 let mock_analysis = MockAnalysis::with_files(
386 "
387 //- /lib.rs
388 mod foo;
389
390 use crate::foo::bar::Baz;
391
392 fn foo() -> i32 {
393 1 + 1
394 }
395 //- /foo/mod.rs
396 pub mod bar;
397
398 //- /foo/bar.rs
399 pub struct Baz;
400 ",
401 );
402
403 let file_id = mock_analysis.id_of("/lib.rs");
404 let mut host = mock_analysis.analysis_host();
405
406 let source_root = host.analysis().imp.db.file_source_root(file_id);
407
408 {
409 let db = host.analysis().imp.db;
410 let events = db.log_executed(|| {
411 db.item_map(source_root).unwrap();
412 });
413 assert!(format!("{:?}", events).contains("item_map"))
414 }
415
416 let mut change = AnalysisChange::new();
417
418 change.change_file(
419 file_id,
420 "
421 mod foo;
422
423 use crate::foo::bar::Baz;
424
425 fn foo() -> i32 { 92 }
426 "
427 .to_string(),
428 );
429
430 host.apply_change(change);
431
432 {
433 let db = host.analysis().imp.db;
434 let events = db.log_executed(|| {
435 db.item_map(source_root).unwrap();
436 });
437 assert!(
438 !format!("{:?}", events).contains("_item_map"),
439 "{:#?}",
440 events
441 )
442 }
443 }
444}