Skip to content

Commit 02c4f82

Browse files
committed
simple test for item map
1 parent 36aad85 commit 02c4f82

4 files changed

Lines changed: 118 additions & 17 deletions

File tree

crates/ra_analysis/src/db.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use crate::{
88
db,
99
descriptors::{
1010
DescriptorDatabase, FnScopesQuery, FnSyntaxQuery, ModuleScopeQuery, ModuleTreeQuery,
11-
SubmodulesQuery, ItemMapQuery,
11+
SubmodulesQuery, ItemMapQuery, InputModuleItemsQuery,
1212
},
1313
symbol_index::SymbolIndex,
1414
syntax_ptr::SyntaxPtr,
@@ -86,6 +86,7 @@ salsa::database_storage! {
8686
impl DescriptorDatabase {
8787
fn module_tree() for ModuleTreeQuery;
8888
fn fn_scopes() for FnScopesQuery;
89+
fn _input_module_items() for InputModuleItemsQuery;
8990
fn _item_map() for ItemMapQuery;
9091
fn _module_scope() for ModuleScopeQuery;
9192
fn _fn_syntax() for FnSyntaxQuery;

crates/ra_analysis/src/descriptors/mod.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use ra_syntax::{
1111
use crate::{
1212
db::SyntaxDatabase,
1313
descriptors::function::{resolve_local_name, FnId, FnScopes},
14-
descriptors::module::{ModuleId, ModuleScope, ModuleTree, ModuleSource, nameres::ItemMap},
14+
descriptors::module::{ModuleId, ModuleScope, ModuleTree, ModuleSource, nameres::{ItemMap, InputModuleItems}},
1515
input::SourceRootId,
1616
loc2id::IdDatabase,
1717
syntax_ptr::LocalSyntaxPtr,
@@ -25,6 +25,10 @@ salsa::query_group! {
2525
use fn function::imp::fn_scopes;
2626
}
2727

28+
fn _input_module_items(source_root_id: SourceRootId, module_id: ModuleId) -> Cancelable<Arc<InputModuleItems>> {
29+
type InputModuleItemsQuery;
30+
use fn module::nameres::input_module_items;
31+
}
2832
fn _item_map(source_root_id: SourceRootId) -> Cancelable<Arc<ItemMap>> {
2933
type ItemMapQuery;
3034
use fn module::nameres::item_map;

crates/ra_analysis/src/descriptors/module/mod.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,13 @@ pub(crate) struct ModuleTree {
149149
}
150150

151151
impl ModuleTree {
152+
fn modules<'a>(&'a self) -> impl Iterator<Item = ModuleId> + 'a {
153+
self.mods
154+
.iter()
155+
.enumerate()
156+
.map(|(idx, _)| ModuleId(idx as u32))
157+
}
158+
152159
fn modules_for_source(&self, source: ModuleSource) -> Vec<ModuleId> {
153160
self.mods
154161
.iter()

crates/ra_analysis/src/descriptors/module/nameres.rs

Lines changed: 104 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,17 @@ use rustc_hash::FxHashMap;
55

66
use ra_syntax::{
77
SmolStr, SyntaxKind::{self, *},
8-
ast::{self, NameOwner, AstNode}
8+
ast::{self, NameOwner, AstNode, ModuleItemOwner}
99
};
1010

1111
use crate::{
1212
Cancelable,
1313
loc2id::{DefId, DefLoc},
1414
descriptors::{
1515
DescriptorDatabase,
16-
module::{ModuleId, ModuleTree},
16+
module::{ModuleId, ModuleTree, ModuleSourceNode},
1717
},
18-
syntax_ptr::{LocalSyntaxPtr, SyntaxPtr},
18+
syntax_ptr::{LocalSyntaxPtr},
1919
input::SourceRootId,
2020
};
2121

@@ -25,37 +25,79 @@ use crate::{
2525
/// This stands in-between raw syntax and name resolution and alow us to avoid
2626
/// recomputing name res: if `InputModuleItems` are the same, we can avoid
2727
/// running name resolution.
28-
#[derive(Debug, Default)]
29-
struct InputModuleItems {
28+
#[derive(Debug, Default, PartialEq, Eq)]
29+
pub(crate) struct InputModuleItems {
3030
items: Vec<ModuleItem>,
3131
glob_imports: Vec<Path>,
3232
imports: Vec<Path>,
3333
}
3434

35-
#[derive(Debug, Clone)]
35+
#[derive(Debug, Clone, PartialEq, Eq)]
3636
struct Path {
3737
kind: PathKind,
3838
segments: Vec<(LocalSyntaxPtr, SmolStr)>,
3939
}
4040

41-
#[derive(Debug, Clone, Copy)]
41+
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
4242
enum PathKind {
4343
Abs,
4444
Self_,
4545
Super,
4646
Crate,
4747
}
4848

49+
pub(crate) fn input_module_items(
50+
db: &impl DescriptorDatabase,
51+
source_root: SourceRootId,
52+
module_id: ModuleId,
53+
) -> Cancelable<Arc<InputModuleItems>> {
54+
let module_tree = db._module_tree(source_root)?;
55+
let source = module_id.source(&module_tree);
56+
let res = match source.resolve(db) {
57+
ModuleSourceNode::SourceFile(it) => {
58+
let items = it.borrowed().items();
59+
InputModuleItems::new(items)
60+
}
61+
ModuleSourceNode::Module(it) => {
62+
let items = it
63+
.borrowed()
64+
.item_list()
65+
.into_iter()
66+
.flat_map(|it| it.items());
67+
InputModuleItems::new(items)
68+
}
69+
};
70+
Ok(Arc::new(res))
71+
}
72+
4973
pub(crate) fn item_map(
5074
db: &impl DescriptorDatabase,
5175
source_root: SourceRootId,
5276
) -> Cancelable<Arc<ItemMap>> {
53-
unimplemented!()
77+
let module_tree = db._module_tree(source_root)?;
78+
let input = module_tree
79+
.modules()
80+
.map(|id| {
81+
let items = db._input_module_items(source_root, id)?;
82+
Ok((id, items))
83+
})
84+
.collect::<Cancelable<FxHashMap<_, _>>>()?;
85+
86+
let mut resolver = Resolver {
87+
db: db,
88+
input: &input,
89+
source_root,
90+
module_tree,
91+
result: ItemMap::default(),
92+
};
93+
resolver.resolve()?;
94+
let res = resolver.result;
95+
Ok(Arc::new(res))
5496
}
5597

5698
/// Item map is the result of the name resolution. Item map contains, for each
5799
/// module, the set of visible items.
58-
#[derive(Debug, PartialEq, Eq)]
100+
#[derive(Default, Debug, PartialEq, Eq)]
59101
pub(crate) struct ItemMap {
60102
per_module: FxHashMap<ModuleId, ModuleItems>,
61103
}
@@ -86,15 +128,15 @@ struct PerNs<T> {
86128
values: Option<T>,
87129
}
88130

89-
#[derive(Debug)]
131+
#[derive(Debug, PartialEq, Eq)]
90132
struct ModuleItem {
91133
ptr: LocalSyntaxPtr,
92134
name: SmolStr,
93135
kind: SyntaxKind,
94136
vis: Vis,
95137
}
96138

97-
#[derive(Debug)]
139+
#[derive(Debug, PartialEq, Eq)]
98140
enum Vis {
99141
Priv,
100142
Other,
@@ -116,11 +158,13 @@ impl InputModuleItems {
116158
ast::ModuleItem::FnDef(it) => self.items.push(ModuleItem::new(it)?),
117159
ast::ModuleItem::TraitDef(it) => self.items.push(ModuleItem::new(it)?),
118160
ast::ModuleItem::TypeDef(it) => self.items.push(ModuleItem::new(it)?),
119-
ast::ModuleItem::ImplItem(it) => {
161+
ast::ModuleItem::ImplItem(_) => {
120162
// impls don't define items
121163
}
122164
ast::ModuleItem::UseItem(it) => self.add_use_item(it),
123-
ast::ModuleItem::ExternCrateItem(it) => (),
165+
ast::ModuleItem::ExternCrateItem(_) => {
166+
// TODO
167+
}
124168
ast::ModuleItem::ConstDef(it) => self.items.push(ModuleItem::new(it)?),
125169
ast::ModuleItem::StaticDef(it) => self.items.push(ModuleItem::new(it)?),
126170
ast::ModuleItem::Module(it) => self.items.push(ModuleItem::new(it)?),
@@ -227,7 +271,7 @@ impl ModuleItem {
227271

228272
struct Resolver<'a, DB> {
229273
db: &'a DB,
230-
input: &'a FxHashMap<ModuleId, InputModuleItems>,
274+
input: &'a FxHashMap<ModuleId, Arc<InputModuleItems>>,
231275
source_root: SourceRootId,
232276
module_tree: Arc<ModuleTree>,
233277
result: ItemMap,
@@ -237,14 +281,16 @@ impl<'a, DB> Resolver<'a, DB>
237281
where
238282
DB: DescriptorDatabase,
239283
{
240-
fn resolve(&mut self) {
284+
fn resolve(&mut self) -> Cancelable<()> {
241285
for (&module_id, items) in self.input.iter() {
242286
self.populate_module(module_id, items)
243287
}
244288

245289
for &module_id in self.input.keys() {
290+
crate::db::check_canceled(self.db)?;
246291
self.resolve_imports(module_id);
247292
}
293+
Ok(())
248294
}
249295

250296
fn populate_module(&mut self, module_id: ModuleId, input: &InputModuleItems) {
@@ -346,3 +392,46 @@ where
346392
f(module_items)
347393
}
348394
}
395+
396+
#[cfg(test)]
397+
mod tests {
398+
use crate::{
399+
mock_analysis::analysis_and_position,
400+
descriptors::{DescriptorDatabase, module::ModuleDescriptor},
401+
input::FilesDatabase,
402+
};
403+
use super::*;
404+
405+
fn item_map(fixture: &str) -> (Arc<ItemMap>, ModuleId) {
406+
let (analysis, pos) = analysis_and_position(fixture);
407+
let db = analysis.imp.db;
408+
let source_root = db.file_source_root(pos.file_id);
409+
let descr = ModuleDescriptor::guess_from_position(&*db, pos)
410+
.unwrap()
411+
.unwrap();
412+
let module_id = descr.module_id;
413+
(db._item_map(source_root).unwrap(), module_id)
414+
}
415+
416+
#[test]
417+
fn test_item_map() {
418+
let (item_map, module_id) = item_map(
419+
"
420+
//- /lib.rs
421+
mod foo;
422+
423+
use crate::foo::bar::Baz;
424+
<|>
425+
426+
//- /foo/mod.rs
427+
pub mod bar;
428+
429+
//- /foo/bar.rs
430+
pub struct Baz;
431+
",
432+
);
433+
let name = SmolStr::from("Baz");
434+
let resolution = &item_map.per_module[&module_id].items[&name];
435+
assert!(resolution.def_id.is_some());
436+
}
437+
}

0 commit comments

Comments
 (0)