aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_analysis
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2018-11-27 20:33:36 +0000
committerAleksey Kladov <[email protected]>2018-11-27 20:33:36 +0000
commitb7049ea543d5ea9a965dfa51d9da923739f2420d (patch)
tree4cfda71ca655fc13479413825b452419fdc0e281 /crates/ra_analysis
parent90bc832b22aefb2a382b3465793df7e528351aa1 (diff)
move query definitions
Diffstat (limited to 'crates/ra_analysis')
-rw-r--r--crates/ra_analysis/src/db.rs13
-rw-r--r--crates/ra_analysis/src/hir/db.rs85
-rw-r--r--crates/ra_analysis/src/hir/function/imp.rs21
-rw-r--r--crates/ra_analysis/src/hir/function/mod.rs4
-rw-r--r--crates/ra_analysis/src/hir/mod.rs1
-rw-r--r--crates/ra_analysis/src/hir/module/imp.rs35
-rw-r--r--crates/ra_analysis/src/hir/module/mod.rs10
-rw-r--r--crates/ra_analysis/src/hir/module/nameres.rs100
-rw-r--r--crates/ra_analysis/src/hir/query_definitions.rs158
-rw-r--r--crates/ra_analysis/src/loc2id.rs4
10 files changed, 232 insertions, 199 deletions
diff --git a/crates/ra_analysis/src/db.rs b/crates/ra_analysis/src/db.rs
index 08aa9053b..78bbfcf2d 100644
--- a/crates/ra_analysis/src/db.rs
+++ b/crates/ra_analysis/src/db.rs
@@ -10,7 +10,7 @@ use crate::{
10 hir, 10 hir,
11 symbol_index::SymbolIndex, 11 symbol_index::SymbolIndex,
12 syntax_ptr::SyntaxPtr, 12 syntax_ptr::SyntaxPtr,
13 loc2id::{IdMaps, IdDatabase}, 13 loc2id::{IdMaps},
14 Cancelable, Canceled, FileId, 14 Cancelable, Canceled, FileId,
15}; 15};
16 16
@@ -77,7 +77,14 @@ impl salsa::ParallelDatabase for RootDatabase {
77 } 77 }
78} 78}
79 79
80impl IdDatabase for RootDatabase { 80pub(crate) trait BaseDatabase: salsa::Database {
81 fn id_maps(&self) -> &IdMaps;
82 fn check_canceled(&self) -> Cancelable<()> {
83 check_canceled(self)
84 }
85}
86
87impl BaseDatabase for RootDatabase {
81 fn id_maps(&self) -> &IdMaps { 88 fn id_maps(&self) -> &IdMaps {
82 &self.id_maps 89 &self.id_maps
83 } 90 }
@@ -136,7 +143,7 @@ salsa::database_storage! {
136} 143}
137 144
138salsa::query_group! { 145salsa::query_group! {
139 pub(crate) trait SyntaxDatabase: crate::input::FilesDatabase { 146 pub(crate) trait SyntaxDatabase: crate::input::FilesDatabase + BaseDatabase {
140 fn file_syntax(file_id: FileId) -> SourceFileNode { 147 fn file_syntax(file_id: FileId) -> SourceFileNode {
141 type FileSyntaxQuery; 148 type FileSyntaxQuery;
142 } 149 }
diff --git a/crates/ra_analysis/src/hir/db.rs b/crates/ra_analysis/src/hir/db.rs
index 498a5c2dd..c6dbde79b 100644
--- a/crates/ra_analysis/src/hir/db.rs
+++ b/crates/ra_analysis/src/hir/db.rs
@@ -8,56 +8,59 @@ use ra_syntax::{
8use crate::{ 8use crate::{
9 FileId, 9 FileId,
10 db::SyntaxDatabase, 10 db::SyntaxDatabase,
11 hir::query_definitions,
11 hir::function::{FnId, FnScopes}, 12 hir::function::{FnId, FnScopes},
12 hir::module::{ 13 hir::module::{
13 ModuleId, ModuleTree, ModuleSource, 14 ModuleId, ModuleTree, ModuleSource,
14 nameres::{ItemMap, InputModuleItems, FileItems, FileItemId} 15 nameres::{ItemMap, InputModuleItems, FileItems, FileItemId}
15 }, 16 },
16 input::SourceRootId, 17 input::SourceRootId,
17 loc2id::{IdDatabase},
18 Cancelable, 18 Cancelable,
19}; 19};
20 20
21salsa::query_group! { 21salsa::query_group! {
22pub(crate) trait HirDatabase: SyntaxDatabase + IdDatabase { 22
23 fn fn_scopes(fn_id: FnId) -> Arc<FnScopes> { 23pub(crate) trait HirDatabase: SyntaxDatabase {
24 type FnScopesQuery; 24 fn fn_scopes(fn_id: FnId) -> Arc<FnScopes> {
25 use fn crate::hir::function::imp::fn_scopes; 25 type FnScopesQuery;
26 } 26 use fn query_definitions::fn_scopes;
27 27 }
28 fn file_items(file_id: FileId) -> Arc<FileItems> { 28 fn fn_syntax(fn_id: FnId) -> FnDefNode {
29 type FileItemsQuery; 29 type FnSyntaxQuery;
30 storage dependencies; 30 // Don't retain syntax trees in memory
31 use fn crate::hir::module::nameres::file_items; 31 storage dependencies;
32 } 32 use fn query_definitions::fn_syntax;
33 33 }
34 fn file_item(file_id: FileId, file_item_id: FileItemId) -> SyntaxNode { 34
35 type FileItemQuery; 35 fn file_items(file_id: FileId) -> Arc<FileItems> {
36 storage dependencies; 36 type FileItemsQuery;
37 use fn crate::hir::module::nameres::file_item; 37 storage dependencies;
38 } 38 use fn query_definitions::file_items;
39 39 }
40 fn input_module_items(source_root_id: SourceRootId, module_id: ModuleId) -> Cancelable<Arc<InputModuleItems>> { 40
41 type InputModuleItemsQuery; 41 fn file_item(file_id: FileId, file_item_id: FileItemId) -> SyntaxNode {
42 use fn crate::hir::module::nameres::input_module_items; 42 type FileItemQuery;
43 } 43 storage dependencies;
44 fn item_map(source_root_id: SourceRootId) -> Cancelable<Arc<ItemMap>> { 44 use fn query_definitions::file_item;
45 type ItemMapQuery; 45 }
46 use fn crate::hir::module::nameres::item_map; 46
47 } 47 fn submodules(source: ModuleSource) -> Cancelable<Arc<Vec<crate::hir::module::imp::Submodule>>> {
48 fn module_tree(source_root_id: SourceRootId) -> Cancelable<Arc<ModuleTree>> { 48 type SubmodulesQuery;
49 type ModuleTreeQuery; 49 use fn query_definitions::submodules;
50 use fn crate::hir::module::imp::module_tree; 50 }
51 } 51
52 fn fn_syntax(fn_id: FnId) -> FnDefNode { 52 fn input_module_items(source_root_id: SourceRootId, module_id: ModuleId) -> Cancelable<Arc<InputModuleItems>> {
53 type FnSyntaxQuery; 53 type InputModuleItemsQuery;
54 // Don't retain syntax trees in memory 54 use fn query_definitions::input_module_items;
55 storage dependencies; 55 }
56 use fn crate::hir::function::imp::fn_syntax; 56 fn item_map(source_root_id: SourceRootId) -> Cancelable<Arc<ItemMap>> {
57 } 57 type ItemMapQuery;
58 fn submodules(source: ModuleSource) -> Cancelable<Arc<Vec<crate::hir::module::imp::Submodule>>> { 58 use fn query_definitions::item_map;
59 type SubmodulesQuery;
60 use fn crate::hir::module::imp::submodules;
61 }
62 } 59 }
60 fn module_tree(source_root_id: SourceRootId) -> Cancelable<Arc<ModuleTree>> {
61 type ModuleTreeQuery;
62 use fn crate::hir::module::imp::module_tree;
63 }
64}
65
63} 66}
diff --git a/crates/ra_analysis/src/hir/function/imp.rs b/crates/ra_analysis/src/hir/function/imp.rs
deleted file mode 100644
index 5f5f68ac5..000000000
--- a/crates/ra_analysis/src/hir/function/imp.rs
+++ /dev/null
@@ -1,21 +0,0 @@
1use std::sync::Arc;
2
3use ra_syntax::ast::{AstNode, FnDef, FnDefNode};
4
5use crate::hir::{
6 function::{FnId, FnScopes},
7 HirDatabase,
8};
9
10/// Resolve `FnId` to the corresponding `SyntaxNode`
11pub(crate) fn fn_syntax(db: &impl HirDatabase, fn_id: FnId) -> FnDefNode {
12 let ptr = db.id_maps().fn_ptr(fn_id);
13 let syntax = db.resolve_syntax_ptr(ptr);
14 FnDef::cast(syntax.borrowed()).unwrap().owned()
15}
16
17pub(crate) fn fn_scopes(db: &impl HirDatabase, fn_id: FnId) -> Arc<FnScopes> {
18 let syntax = db.fn_syntax(fn_id);
19 let res = FnScopes::new(syntax.borrowed());
20 Arc::new(res)
21}
diff --git a/crates/ra_analysis/src/hir/function/mod.rs b/crates/ra_analysis/src/hir/function/mod.rs
index c8af6bc21..5de9806e3 100644
--- a/crates/ra_analysis/src/hir/function/mod.rs
+++ b/crates/ra_analysis/src/hir/function/mod.rs
@@ -1,4 +1,3 @@
1pub(super) mod imp;
2mod scope; 1mod scope;
3 2
4use std::{ 3use std::{
@@ -14,14 +13,13 @@ use ra_syntax::{
14use crate::{ 13use crate::{
15 hir::HirDatabase, 14 hir::HirDatabase,
16 syntax_ptr::SyntaxPtr, FileId, 15 syntax_ptr::SyntaxPtr, FileId,
17 loc2id::IdDatabase,
18}; 16};
19 17
20pub(crate) use self::scope::{resolve_local_name, FnScopes}; 18pub(crate) use self::scope::{resolve_local_name, FnScopes};
21pub(crate) use crate::loc2id::FnId; 19pub(crate) use crate::loc2id::FnId;
22 20
23impl FnId { 21impl FnId {
24 pub(crate) fn get(db: &impl IdDatabase, file_id: FileId, fn_def: ast::FnDef) -> FnId { 22 pub(crate) fn get(db: &impl HirDatabase, file_id: FileId, fn_def: ast::FnDef) -> FnId {
25 let ptr = SyntaxPtr::new(file_id, fn_def.syntax()); 23 let ptr = SyntaxPtr::new(file_id, fn_def.syntax());
26 db.id_maps().fn_id(ptr) 24 db.id_maps().fn_id(ptr)
27 } 25 }
diff --git a/crates/ra_analysis/src/hir/mod.rs b/crates/ra_analysis/src/hir/mod.rs
index 27ac71a26..dc52fa4ef 100644
--- a/crates/ra_analysis/src/hir/mod.rs
+++ b/crates/ra_analysis/src/hir/mod.rs
@@ -9,6 +9,7 @@ pub(crate) mod function;
9pub(crate) mod module; 9pub(crate) mod module;
10pub(crate) mod db; 10pub(crate) mod db;
11mod path; 11mod path;
12mod query_definitions;
12 13
13use ra_syntax::{ 14use ra_syntax::{
14 ast::{self, AstNode}, 15 ast::{self, AstNode},
diff --git a/crates/ra_analysis/src/hir/module/imp.rs b/crates/ra_analysis/src/hir/module/imp.rs
index f9853584e..3b1baff76 100644
--- a/crates/ra_analysis/src/hir/module/imp.rs
+++ b/crates/ra_analysis/src/hir/module/imp.rs
@@ -15,7 +15,7 @@ use crate::{
15}; 15};
16 16
17use super::{ 17use super::{
18 LinkData, LinkId, ModuleData, ModuleId, ModuleSource, ModuleSourceNode, 18 LinkData, LinkId, ModuleData, ModuleId, ModuleSource,
19 ModuleTree, Problem, 19 ModuleTree, Problem,
20}; 20};
21 21
@@ -34,39 +34,6 @@ impl Submodule {
34 } 34 }
35} 35}
36 36
37pub(crate) fn submodules(
38 db: &impl HirDatabase,
39 source: ModuleSource,
40) -> Cancelable<Arc<Vec<Submodule>>> {
41 db::check_canceled(db)?;
42 let file_id = source.file_id();
43 let submodules = match source.resolve(db) {
44 ModuleSourceNode::SourceFile(it) => collect_submodules(file_id, it.borrowed()),
45 ModuleSourceNode::Module(it) => it
46 .borrowed()
47 .item_list()
48 .map(|it| collect_submodules(file_id, it))
49 .unwrap_or_else(Vec::new),
50 };
51 return Ok(Arc::new(submodules));
52
53 fn collect_submodules<'a>(
54 file_id: FileId,
55 root: impl ast::ModuleItemOwner<'a>,
56 ) -> Vec<Submodule> {
57 modules(root)
58 .map(|(name, m)| {
59 if m.has_semi() {
60 Submodule::Declaration(name)
61 } else {
62 let src = ModuleSource::new_inline(file_id, m);
63 Submodule::Definition(name, src)
64 }
65 })
66 .collect()
67 }
68}
69
70pub(crate) fn modules<'a>( 37pub(crate) fn modules<'a>(
71 root: impl ast::ModuleItemOwner<'a>, 38 root: impl ast::ModuleItemOwner<'a>,
72) -> impl Iterator<Item = (SmolStr, ast::Module<'a>)> { 39) -> impl Iterator<Item = (SmolStr, ast::Module<'a>)> {
diff --git a/crates/ra_analysis/src/hir/module/mod.rs b/crates/ra_analysis/src/hir/module/mod.rs
index 55b6639be..4d5945b1a 100644
--- a/crates/ra_analysis/src/hir/module/mod.rs
+++ b/crates/ra_analysis/src/hir/module/mod.rs
@@ -196,7 +196,7 @@ pub(crate) struct ModuleTree {
196} 196}
197 197
198impl ModuleTree { 198impl ModuleTree {
199 fn modules<'a>(&'a self) -> impl Iterator<Item = ModuleId> + 'a { 199 pub(in crate::hir) fn modules<'a>(&'a self) -> impl Iterator<Item = ModuleId> + 'a {
200 self.mods.iter().map(|(id, _)| id) 200 self.mods.iter().map(|(id, _)| id)
201 } 201 }
202 202
@@ -224,7 +224,7 @@ pub(crate) enum ModuleSource {
224 224
225/// An owned syntax node for a module. Unlike `ModuleSource`, 225/// An owned syntax node for a module. Unlike `ModuleSource`,
226/// this holds onto the AST for the whole file. 226/// this holds onto the AST for the whole file.
227enum ModuleSourceNode { 227pub(crate) enum ModuleSourceNode {
228 SourceFile(ast::SourceFileNode), 228 SourceFile(ast::SourceFileNode),
229 Module(ast::ModuleNode), 229 Module(ast::ModuleNode),
230} 230}
@@ -244,7 +244,7 @@ pub enum Problem {
244} 244}
245 245
246impl ModuleId { 246impl ModuleId {
247 fn source(self, tree: &ModuleTree) -> ModuleSource { 247 pub(in crate::hir) fn source(self, tree: &ModuleTree) -> ModuleSource {
248 tree.mods[self].source 248 tree.mods[self].source
249 } 249 }
250 fn parent_link(self, tree: &ModuleTree) -> Option<LinkId> { 250 fn parent_link(self, tree: &ModuleTree) -> Option<LinkId> {
@@ -318,7 +318,7 @@ pub(crate) struct ModuleData {
318} 318}
319 319
320impl ModuleSource { 320impl ModuleSource {
321 fn new_inline(file_id: FileId, module: ast::Module) -> ModuleSource { 321 pub(crate) fn new_inline(file_id: FileId, module: ast::Module) -> ModuleSource {
322 assert!(!module.has_semi()); 322 assert!(!module.has_semi());
323 let ptr = SyntaxPtr::new(file_id, module.syntax()); 323 let ptr = SyntaxPtr::new(file_id, module.syntax());
324 ModuleSource::Module(ptr) 324 ModuleSource::Module(ptr)
@@ -338,7 +338,7 @@ impl ModuleSource {
338 } 338 }
339 } 339 }
340 340
341 fn resolve(self, db: &impl SyntaxDatabase) -> ModuleSourceNode { 341 pub(crate) fn resolve(self, db: &impl SyntaxDatabase) -> ModuleSourceNode {
342 match self { 342 match self {
343 ModuleSource::SourceFile(file_id) => { 343 ModuleSource::SourceFile(file_id) => {
344 let syntax = db.file_syntax(file_id); 344 let syntax = db.file_syntax(file_id);
diff --git a/crates/ra_analysis/src/hir/module/nameres.rs b/crates/ra_analysis/src/hir/module/nameres.rs
index eaf9f9373..db5d6d9c0 100644
--- a/crates/ra_analysis/src/hir/module/nameres.rs
+++ b/crates/ra_analysis/src/hir/module/nameres.rs
@@ -16,7 +16,6 @@
16//! structure itself is modified. 16//! structure itself is modified.
17use std::{ 17use std::{
18 sync::Arc, 18 sync::Arc,
19 time::Instant,
20 ops::Index, 19 ops::Index,
21}; 20};
22 21
@@ -25,7 +24,7 @@ use rustc_hash::FxHashMap;
25use ra_syntax::{ 24use ra_syntax::{
26 SyntaxNode, SyntaxNodeRef, TextRange, 25 SyntaxNode, SyntaxNodeRef, TextRange,
27 SmolStr, SyntaxKind::{self, *}, 26 SmolStr, SyntaxKind::{self, *},
28 ast::{self, ModuleItemOwner, AstNode} 27 ast::{self, AstNode}
29}; 28};
30 29
31use crate::{ 30use crate::{
@@ -34,7 +33,7 @@ use crate::{
34 hir::{ 33 hir::{
35 Path, PathKind, 34 Path, PathKind,
36 HirDatabase, 35 HirDatabase,
37 module::{ModuleId, ModuleTree, ModuleSourceNode}, 36 module::{ModuleId, ModuleTree},
38 }, 37 },
39 input::SourceRootId, 38 input::SourceRootId,
40 arena::{Arena, Id} 39 arena::{Arena, Id}
@@ -51,7 +50,7 @@ pub(crate) struct FileItems {
51} 50}
52 51
53impl FileItems { 52impl FileItems {
54 fn alloc(&mut self, item: SyntaxNode) -> FileItemId { 53 pub(crate) fn alloc(&mut self, item: SyntaxNode) -> FileItemId {
55 self.arena.alloc(item) 54 self.arena.alloc(item)
56 } 55 }
57 fn id_of(&self, item: SyntaxNodeRef) -> FileItemId { 56 fn id_of(&self, item: SyntaxNodeRef) -> FileItemId {
@@ -71,29 +70,6 @@ impl Index<FileItemId> for FileItems {
71 } 70 }
72} 71}
73 72
74pub(crate) fn file_items(db: &impl HirDatabase, file_id: FileId) -> Arc<FileItems> {
75 let source_file = db.file_syntax(file_id);
76 let source_file = source_file.borrowed();
77 let mut res = FileItems::default();
78 source_file
79 .syntax()
80 .descendants()
81 .filter_map(ast::ModuleItem::cast)
82 .map(|it| it.syntax().owned())
83 .for_each(|it| {
84 res.alloc(it);
85 });
86 Arc::new(res)
87}
88
89pub(crate) fn file_item(
90 db: &impl HirDatabase,
91 file_id: FileId,
92 file_item_id: FileItemId,
93) -> SyntaxNode {
94 db.file_items(file_id)[file_item_id].clone()
95}
96
97/// Item map is the result of the name resolution. Item map contains, for each 73/// Item map is the result of the name resolution. Item map contains, for each
98/// module, the set of visible items. 74/// module, the set of visible items.
99#[derive(Default, Debug, PartialEq, Eq)] 75#[derive(Default, Debug, PartialEq, Eq)]
@@ -167,58 +143,6 @@ enum ImportKind {
167 Named(NamedImport), 143 Named(NamedImport),
168} 144}
169 145
170pub(crate) fn input_module_items(
171 db: &impl HirDatabase,
172 source_root: SourceRootId,
173 module_id: ModuleId,
174) -> Cancelable<Arc<InputModuleItems>> {
175 let module_tree = db.module_tree(source_root)?;
176 let source = module_id.source(&module_tree);
177 let file_items = db.file_items(source.file_id());
178 let res = match source.resolve(db) {
179 ModuleSourceNode::SourceFile(it) => {
180 let items = it.borrowed().items();
181 InputModuleItems::new(&file_items, items)
182 }
183 ModuleSourceNode::Module(it) => {
184 let items = it
185 .borrowed()
186 .item_list()
187 .into_iter()
188 .flat_map(|it| it.items());
189 InputModuleItems::new(&file_items, items)
190 }
191 };
192 Ok(Arc::new(res))
193}
194
195pub(crate) fn item_map(
196 db: &impl HirDatabase,
197 source_root: SourceRootId,
198) -> Cancelable<Arc<ItemMap>> {
199 let start = Instant::now();
200 let module_tree = db.module_tree(source_root)?;
201 let input = module_tree
202 .modules()
203 .map(|id| {
204 let items = db.input_module_items(source_root, id)?;
205 Ok((id, items))
206 })
207 .collect::<Cancelable<FxHashMap<_, _>>>()?;
208 let mut resolver = Resolver {
209 db: db,
210 input: &input,
211 source_root,
212 module_tree,
213 result: ItemMap::default(),
214 };
215 resolver.resolve()?;
216 let res = resolver.result;
217 let elapsed = start.elapsed();
218 log::info!("item_map: {:?}", elapsed);
219 Ok(Arc::new(res))
220}
221
222/// Resolution is basically `DefId` atm, but it should account for stuff like 146/// Resolution is basically `DefId` atm, but it should account for stuff like
223/// multiple namespaces, ambiguity and errors. 147/// multiple namespaces, ambiguity and errors.
224#[derive(Debug, Clone, PartialEq, Eq)] 148#[derive(Debug, Clone, PartialEq, Eq)]
@@ -242,7 +166,7 @@ pub(crate) struct Resolution {
242// } 166// }
243 167
244impl InputModuleItems { 168impl InputModuleItems {
245 fn new<'a>( 169 pub(in crate::hir) fn new<'a>(
246 file_items: &FileItems, 170 file_items: &FileItems,
247 items: impl Iterator<Item = ast::ModuleItem<'a>>, 171 items: impl Iterator<Item = ast::ModuleItem<'a>>,
248 ) -> InputModuleItems { 172 ) -> InputModuleItems {
@@ -306,19 +230,19 @@ impl ModuleItem {
306 } 230 }
307} 231}
308 232
309struct Resolver<'a, DB> { 233pub(in crate::hir) struct Resolver<'a, DB> {
310 db: &'a DB, 234 pub db: &'a DB,
311 input: &'a FxHashMap<ModuleId, Arc<InputModuleItems>>, 235 pub input: &'a FxHashMap<ModuleId, Arc<InputModuleItems>>,
312 source_root: SourceRootId, 236 pub source_root: SourceRootId,
313 module_tree: Arc<ModuleTree>, 237 pub module_tree: Arc<ModuleTree>,
314 result: ItemMap, 238 pub result: ItemMap,
315} 239}
316 240
317impl<'a, DB> Resolver<'a, DB> 241impl<'a, DB> Resolver<'a, DB>
318where 242where
319 DB: HirDatabase, 243 DB: HirDatabase,
320{ 244{
321 fn resolve(&mut self) -> Cancelable<()> { 245 pub(in crate::hir) fn resolve(mut self) -> Cancelable<ItemMap> {
322 for (&module_id, items) in self.input.iter() { 246 for (&module_id, items) in self.input.iter() {
323 self.populate_module(module_id, items) 247 self.populate_module(module_id, items)
324 } 248 }
@@ -327,7 +251,7 @@ where
327 crate::db::check_canceled(self.db)?; 251 crate::db::check_canceled(self.db)?;
328 self.resolve_imports(module_id); 252 self.resolve_imports(module_id);
329 } 253 }
330 Ok(()) 254 Ok(self.result)
331 } 255 }
332 256
333 fn populate_module(&mut self, module_id: ModuleId, input: &InputModuleItems) { 257 fn populate_module(&mut self, module_id: ModuleId, input: &InputModuleItems) {
diff --git a/crates/ra_analysis/src/hir/query_definitions.rs b/crates/ra_analysis/src/hir/query_definitions.rs
new file mode 100644
index 000000000..8584a8d64
--- /dev/null
+++ b/crates/ra_analysis/src/hir/query_definitions.rs
@@ -0,0 +1,158 @@
1use std::{
2 sync::Arc,
3 time::Instant,
4};
5
6use rustc_hash::FxHashMap;
7use ra_syntax::{
8 AstNode, SyntaxNode, SmolStr,
9 ast::{self, FnDef, FnDefNode, NameOwner, ModuleItemOwner}
10};
11
12use crate::{
13 FileId, Cancelable,
14 hir::{
15 db::HirDatabase,
16 function::{FnId, FnScopes},
17 module::{
18 ModuleSource, ModuleSourceNode, ModuleId,
19 imp::Submodule,
20 nameres::{FileItems, FileItemId, InputModuleItems, ItemMap, Resolver},
21 },
22 },
23 input::SourceRootId,
24};
25
26/// Resolve `FnId` to the corresponding `SyntaxNode`
27pub(super) fn fn_syntax(db: &impl HirDatabase, fn_id: FnId) -> FnDefNode {
28 let ptr = db.id_maps().fn_ptr(fn_id);
29 let syntax = db.resolve_syntax_ptr(ptr);
30 FnDef::cast(syntax.borrowed()).unwrap().owned()
31}
32
33pub(super) fn fn_scopes(db: &impl HirDatabase, fn_id: FnId) -> Arc<FnScopes> {
34 let syntax = db.fn_syntax(fn_id);
35 let res = FnScopes::new(syntax.borrowed());
36 Arc::new(res)
37}
38
39pub(super) fn file_items(db: &impl HirDatabase, file_id: FileId) -> Arc<FileItems> {
40 let source_file = db.file_syntax(file_id);
41 let source_file = source_file.borrowed();
42 let mut res = FileItems::default();
43 source_file
44 .syntax()
45 .descendants()
46 .filter_map(ast::ModuleItem::cast)
47 .map(|it| it.syntax().owned())
48 .for_each(|it| {
49 res.alloc(it);
50 });
51 Arc::new(res)
52}
53
54pub(super) fn file_item(
55 db: &impl HirDatabase,
56 file_id: FileId,
57 file_item_id: FileItemId,
58) -> SyntaxNode {
59 db.file_items(file_id)[file_item_id].clone()
60}
61
62pub(crate) fn submodules(
63 db: &impl HirDatabase,
64 source: ModuleSource,
65) -> Cancelable<Arc<Vec<Submodule>>> {
66 db.check_canceled()?;
67 let file_id = source.file_id();
68 let submodules = match source.resolve(db) {
69 ModuleSourceNode::SourceFile(it) => collect_submodules(file_id, it.borrowed()),
70 ModuleSourceNode::Module(it) => it
71 .borrowed()
72 .item_list()
73 .map(|it| collect_submodules(file_id, it))
74 .unwrap_or_else(Vec::new),
75 };
76 return Ok(Arc::new(submodules));
77
78 fn collect_submodules<'a>(
79 file_id: FileId,
80 root: impl ast::ModuleItemOwner<'a>,
81 ) -> Vec<Submodule> {
82 modules(root)
83 .map(|(name, m)| {
84 if m.has_semi() {
85 Submodule::Declaration(name)
86 } else {
87 let src = ModuleSource::new_inline(file_id, m);
88 Submodule::Definition(name, src)
89 }
90 })
91 .collect()
92 }
93}
94
95pub(crate) fn modules<'a>(
96 root: impl ast::ModuleItemOwner<'a>,
97) -> impl Iterator<Item = (SmolStr, ast::Module<'a>)> {
98 root.items()
99 .filter_map(|item| match item {
100 ast::ModuleItem::Module(m) => Some(m),
101 _ => None,
102 })
103 .filter_map(|module| {
104 let name = module.name()?.text();
105 Some((name, module))
106 })
107}
108
109pub(super) fn input_module_items(
110 db: &impl HirDatabase,
111 source_root: SourceRootId,
112 module_id: ModuleId,
113) -> Cancelable<Arc<InputModuleItems>> {
114 let module_tree = db.module_tree(source_root)?;
115 let source = module_id.source(&module_tree);
116 let file_items = db.file_items(source.file_id());
117 let res = match source.resolve(db) {
118 ModuleSourceNode::SourceFile(it) => {
119 let items = it.borrowed().items();
120 InputModuleItems::new(&file_items, items)
121 }
122 ModuleSourceNode::Module(it) => {
123 let items = it
124 .borrowed()
125 .item_list()
126 .into_iter()
127 .flat_map(|it| it.items());
128 InputModuleItems::new(&file_items, items)
129 }
130 };
131 Ok(Arc::new(res))
132}
133
134pub(super) fn item_map(
135 db: &impl HirDatabase,
136 source_root: SourceRootId,
137) -> Cancelable<Arc<ItemMap>> {
138 let start = Instant::now();
139 let module_tree = db.module_tree(source_root)?;
140 let input = module_tree
141 .modules()
142 .map(|id| {
143 let items = db.input_module_items(source_root, id)?;
144 Ok((id, items))
145 })
146 .collect::<Cancelable<FxHashMap<_, _>>>()?;
147 let resolver = Resolver {
148 db: db,
149 input: &input,
150 source_root,
151 module_tree,
152 result: ItemMap::default(),
153 };
154 let res = resolver.resolve()?;
155 let elapsed = start.elapsed();
156 log::info!("item_map: {:?}", elapsed);
157 Ok(Arc::new(res))
158}
diff --git a/crates/ra_analysis/src/loc2id.rs b/crates/ra_analysis/src/loc2id.rs
index d42af4e0a..40da83665 100644
--- a/crates/ra_analysis/src/loc2id.rs
+++ b/crates/ra_analysis/src/loc2id.rs
@@ -109,10 +109,6 @@ pub(crate) enum DefLoc {
109 }, 109 },
110} 110}
111 111
112pub(crate) trait IdDatabase: salsa::Database {
113 fn id_maps(&self) -> &IdMaps;
114}
115
116#[derive(Debug, Default, Clone)] 112#[derive(Debug, Default, Clone)]
117pub(crate) struct IdMaps { 113pub(crate) struct IdMaps {
118 inner: Arc<IdMapsInner>, 114 inner: Arc<IdMapsInner>,