diff options
Diffstat (limited to 'crates/ra_analysis')
-rw-r--r-- | crates/ra_analysis/src/db.rs | 13 | ||||
-rw-r--r-- | crates/ra_analysis/src/hir/db.rs | 85 | ||||
-rw-r--r-- | crates/ra_analysis/src/hir/function/imp.rs | 21 | ||||
-rw-r--r-- | crates/ra_analysis/src/hir/function/mod.rs | 4 | ||||
-rw-r--r-- | crates/ra_analysis/src/hir/mod.rs | 1 | ||||
-rw-r--r-- | crates/ra_analysis/src/hir/module/imp.rs | 35 | ||||
-rw-r--r-- | crates/ra_analysis/src/hir/module/mod.rs | 10 | ||||
-rw-r--r-- | crates/ra_analysis/src/hir/module/nameres.rs | 100 | ||||
-rw-r--r-- | crates/ra_analysis/src/hir/query_definitions.rs | 158 | ||||
-rw-r--r-- | crates/ra_analysis/src/loc2id.rs | 4 |
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 | ||
80 | impl IdDatabase for RootDatabase { | 80 | pub(crate) trait BaseDatabase: salsa::Database { |
81 | fn id_maps(&self) -> &IdMaps; | ||
82 | fn check_canceled(&self) -> Cancelable<()> { | ||
83 | check_canceled(self) | ||
84 | } | ||
85 | } | ||
86 | |||
87 | impl 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 | ||
138 | salsa::query_group! { | 145 | salsa::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::{ | |||
8 | use crate::{ | 8 | use 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 | ||
21 | salsa::query_group! { | 21 | salsa::query_group! { |
22 | pub(crate) trait HirDatabase: SyntaxDatabase + IdDatabase { | 22 | |
23 | fn fn_scopes(fn_id: FnId) -> Arc<FnScopes> { | 23 | pub(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 @@ | |||
1 | use std::sync::Arc; | ||
2 | |||
3 | use ra_syntax::ast::{AstNode, FnDef, FnDefNode}; | ||
4 | |||
5 | use crate::hir::{ | ||
6 | function::{FnId, FnScopes}, | ||
7 | HirDatabase, | ||
8 | }; | ||
9 | |||
10 | /// Resolve `FnId` to the corresponding `SyntaxNode` | ||
11 | pub(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 | |||
17 | pub(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 @@ | |||
1 | pub(super) mod imp; | ||
2 | mod scope; | 1 | mod scope; |
3 | 2 | ||
4 | use std::{ | 3 | use std::{ |
@@ -14,14 +13,13 @@ use ra_syntax::{ | |||
14 | use crate::{ | 13 | use crate::{ |
15 | hir::HirDatabase, | 14 | hir::HirDatabase, |
16 | syntax_ptr::SyntaxPtr, FileId, | 15 | syntax_ptr::SyntaxPtr, FileId, |
17 | loc2id::IdDatabase, | ||
18 | }; | 16 | }; |
19 | 17 | ||
20 | pub(crate) use self::scope::{resolve_local_name, FnScopes}; | 18 | pub(crate) use self::scope::{resolve_local_name, FnScopes}; |
21 | pub(crate) use crate::loc2id::FnId; | 19 | pub(crate) use crate::loc2id::FnId; |
22 | 20 | ||
23 | impl FnId { | 21 | impl 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; | |||
9 | pub(crate) mod module; | 9 | pub(crate) mod module; |
10 | pub(crate) mod db; | 10 | pub(crate) mod db; |
11 | mod path; | 11 | mod path; |
12 | mod query_definitions; | ||
12 | 13 | ||
13 | use ra_syntax::{ | 14 | use 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 | ||
17 | use super::{ | 17 | use 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 | ||
37 | pub(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 | |||
70 | pub(crate) fn modules<'a>( | 37 | pub(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 | ||
198 | impl ModuleTree { | 198 | impl 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. |
227 | enum ModuleSourceNode { | 227 | pub(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 | ||
246 | impl ModuleId { | 246 | impl 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 | ||
320 | impl ModuleSource { | 320 | impl 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. |
17 | use std::{ | 17 | use 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; | |||
25 | use ra_syntax::{ | 24 | use 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 | ||
31 | use crate::{ | 30 | use 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 | ||
53 | impl FileItems { | 52 | impl 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 | ||
74 | pub(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 | |||
89 | pub(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 | ||
170 | pub(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 | |||
195 | pub(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 | ||
244 | impl InputModuleItems { | 168 | impl 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 | ||
309 | struct Resolver<'a, DB> { | 233 | pub(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 | ||
317 | impl<'a, DB> Resolver<'a, DB> | 241 | impl<'a, DB> Resolver<'a, DB> |
318 | where | 242 | where |
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 @@ | |||
1 | use std::{ | ||
2 | sync::Arc, | ||
3 | time::Instant, | ||
4 | }; | ||
5 | |||
6 | use rustc_hash::FxHashMap; | ||
7 | use ra_syntax::{ | ||
8 | AstNode, SyntaxNode, SmolStr, | ||
9 | ast::{self, FnDef, FnDefNode, NameOwner, ModuleItemOwner} | ||
10 | }; | ||
11 | |||
12 | use 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` | ||
27 | pub(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 | |||
33 | pub(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 | |||
39 | pub(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 | |||
54 | pub(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 | |||
62 | pub(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 | |||
95 | pub(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 | |||
109 | pub(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 | |||
134 | pub(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 | ||
112 | pub(crate) trait IdDatabase: salsa::Database { | ||
113 | fn id_maps(&self) -> &IdMaps; | ||
114 | } | ||
115 | |||
116 | #[derive(Debug, Default, Clone)] | 112 | #[derive(Debug, Default, Clone)] |
117 | pub(crate) struct IdMaps { | 113 | pub(crate) struct IdMaps { |
118 | inner: Arc<IdMapsInner>, | 114 | inner: Arc<IdMapsInner>, |