diff options
-rw-r--r-- | crates/ra_analysis/src/descriptors/module/imp.rs | 8 | ||||
-rw-r--r-- | crates/ra_analysis/src/descriptors/module/mod.rs | 31 | ||||
-rw-r--r-- | crates/ra_analysis/src/imp.rs | 12 |
3 files changed, 40 insertions, 11 deletions
diff --git a/crates/ra_analysis/src/descriptors/module/imp.rs b/crates/ra_analysis/src/descriptors/module/imp.rs index 1c102f4e5..22dbe7184 100644 --- a/crates/ra_analysis/src/descriptors/module/imp.rs +++ b/crates/ra_analysis/src/descriptors/module/imp.rs | |||
@@ -14,7 +14,9 @@ use crate::{ | |||
14 | Cancelable, FileId, FileResolverImp, | 14 | Cancelable, FileId, FileResolverImp, |
15 | }; | 15 | }; |
16 | 16 | ||
17 | use super::{LinkData, LinkId, ModuleData, ModuleId, ModuleScope, ModuleTree, Problem}; | 17 | use super::{ |
18 | LinkData, LinkId, ModuleData, ModuleId, ModuleScope, ModuleSource, ModuleTree, Problem, | ||
19 | }; | ||
18 | 20 | ||
19 | pub(crate) fn submodules( | 21 | pub(crate) fn submodules( |
20 | db: &impl DescriptorDatabase, | 22 | db: &impl DescriptorDatabase, |
@@ -43,7 +45,7 @@ pub(crate) fn module_scope( | |||
43 | module_id: ModuleId, | 45 | module_id: ModuleId, |
44 | ) -> Cancelable<Arc<ModuleScope>> { | 46 | ) -> Cancelable<Arc<ModuleScope>> { |
45 | let tree = db.module_tree(source_root_id)?; | 47 | let tree = db.module_tree(source_root_id)?; |
46 | let file_id = module_id.file_id(&tree); | 48 | let ModuleSource::File(file_id) = module_id.source(&tree); |
47 | let syntax = db.file_syntax(file_id); | 49 | let syntax = db.file_syntax(file_id); |
48 | let res = ModuleScope::new(&syntax); | 50 | let res = ModuleScope::new(&syntax); |
49 | Ok(Arc::new(res)) | 51 | Ok(Arc::new(res)) |
@@ -106,7 +108,7 @@ fn build_subtree( | |||
106 | ) -> Cancelable<ModuleId> { | 108 | ) -> Cancelable<ModuleId> { |
107 | visited.insert(file_id); | 109 | visited.insert(file_id); |
108 | let id = tree.push_mod(ModuleData { | 110 | let id = tree.push_mod(ModuleData { |
109 | file_id, | 111 | source: ModuleSource::File(file_id), |
110 | parent, | 112 | parent, |
111 | children: Vec::new(), | 113 | children: Vec::new(), |
112 | }); | 114 | }); |
diff --git a/crates/ra_analysis/src/descriptors/module/mod.rs b/crates/ra_analysis/src/descriptors/module/mod.rs index 302e3e81c..cbccdb2e2 100644 --- a/crates/ra_analysis/src/descriptors/module/mod.rs +++ b/crates/ra_analysis/src/descriptors/module/mod.rs | |||
@@ -11,6 +11,13 @@ use crate::FileId; | |||
11 | 11 | ||
12 | pub(crate) use self::scope::ModuleScope; | 12 | pub(crate) use self::scope::ModuleScope; |
13 | 13 | ||
14 | /// Phisically, rust source is organized as a set of files, but logically it is | ||
15 | /// organized as a tree of modules. Usually, a single file corresponds to a | ||
16 | /// single module, but it is not nessary the case. | ||
17 | /// | ||
18 | /// Module encapsulate the logic of transitioning from the fuzzy world of files | ||
19 | /// (which can have multiple parents) to the precise world of modules (which | ||
20 | /// always have one parent). | ||
14 | #[derive(Debug, PartialEq, Eq, Hash)] | 21 | #[derive(Debug, PartialEq, Eq, Hash)] |
15 | pub(crate) struct ModuleTree { | 22 | pub(crate) struct ModuleTree { |
16 | mods: Vec<ModuleData>, | 23 | mods: Vec<ModuleData>, |
@@ -22,7 +29,7 @@ impl ModuleTree { | |||
22 | self.mods | 29 | self.mods |
23 | .iter() | 30 | .iter() |
24 | .enumerate() | 31 | .enumerate() |
25 | .filter(|(_idx, it)| it.file_id == file_id) | 32 | .filter(|(_idx, it)| it.source.is_file(file_id)) |
26 | .map(|(idx, _)| ModuleId(idx as u32)) | 33 | .map(|(idx, _)| ModuleId(idx as u32)) |
27 | .collect() | 34 | .collect() |
28 | } | 35 | } |
@@ -50,8 +57,8 @@ pub enum Problem { | |||
50 | } | 57 | } |
51 | 58 | ||
52 | impl ModuleId { | 59 | impl ModuleId { |
53 | pub(crate) fn file_id(self, tree: &ModuleTree) -> FileId { | 60 | pub(crate) fn source(self, tree: &ModuleTree) -> ModuleSource { |
54 | tree.module(self).file_id | 61 | tree.module(self).source |
55 | } | 62 | } |
56 | pub(crate) fn parent_link(self, tree: &ModuleTree) -> Option<LinkId> { | 63 | pub(crate) fn parent_link(self, tree: &ModuleTree) -> Option<LinkId> { |
57 | tree.module(self).parent | 64 | tree.module(self).parent |
@@ -110,11 +117,27 @@ impl LinkId { | |||
110 | 117 | ||
111 | #[derive(Debug, PartialEq, Eq, Hash)] | 118 | #[derive(Debug, PartialEq, Eq, Hash)] |
112 | struct ModuleData { | 119 | struct ModuleData { |
113 | file_id: FileId, | 120 | source: ModuleSource, |
114 | parent: Option<LinkId>, | 121 | parent: Option<LinkId>, |
115 | children: Vec<LinkId>, | 122 | children: Vec<LinkId>, |
116 | } | 123 | } |
117 | 124 | ||
125 | /// `ModuleSource` is the syntax tree element that produced this module: | ||
126 | /// either a file, or an inlinde module. | ||
127 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] | ||
128 | pub(crate) enum ModuleSource { | ||
129 | File(FileId), | ||
130 | // Inline(SyntaxPtr), | ||
131 | } | ||
132 | |||
133 | impl ModuleSource { | ||
134 | fn is_file(self, file_id: FileId) -> bool { | ||
135 | match self { | ||
136 | ModuleSource::File(f) => f == file_id, | ||
137 | } | ||
138 | } | ||
139 | } | ||
140 | |||
118 | #[derive(Hash, Debug, PartialEq, Eq)] | 141 | #[derive(Hash, Debug, PartialEq, Eq)] |
119 | struct LinkData { | 142 | struct LinkData { |
120 | owner: ModuleId, | 143 | owner: ModuleId, |
diff --git a/crates/ra_analysis/src/imp.rs b/crates/ra_analysis/src/imp.rs index 0744ea9c8..c1269025c 100644 --- a/crates/ra_analysis/src/imp.rs +++ b/crates/ra_analysis/src/imp.rs | |||
@@ -20,7 +20,7 @@ use crate::{ | |||
20 | db::{self, FileSyntaxQuery, SyntaxDatabase}, | 20 | db::{self, FileSyntaxQuery, SyntaxDatabase}, |
21 | descriptors::{ | 21 | descriptors::{ |
22 | function::{FnDescriptor, FnId}, | 22 | function::{FnDescriptor, FnId}, |
23 | module::{ModuleTree, Problem}, | 23 | module::{ModuleSource, ModuleTree, Problem}, |
24 | DeclarationDescriptor, DescriptorDatabase, | 24 | DeclarationDescriptor, DescriptorDatabase, |
25 | }, | 25 | }, |
26 | input::{FilesDatabase, SourceRoot, SourceRootId, WORKSPACE}, | 26 | input::{FilesDatabase, SourceRoot, SourceRootId, WORKSPACE}, |
@@ -222,7 +222,7 @@ impl AnalysisImpl { | |||
222 | .into_iter() | 222 | .into_iter() |
223 | .filter_map(|module_id| { | 223 | .filter_map(|module_id| { |
224 | let link = module_id.parent_link(&module_tree)?; | 224 | let link = module_id.parent_link(&module_tree)?; |
225 | let file_id = link.owner(&module_tree).file_id(&module_tree); | 225 | let ModuleSource::File(file_id) = link.owner(&module_tree).source(&module_tree); |
226 | let syntax = self.db.file_syntax(file_id); | 226 | let syntax = self.db.file_syntax(file_id); |
227 | let decl = link.bind_source(&module_tree, syntax.ast()); | 227 | let decl = link.bind_source(&module_tree, syntax.ast()); |
228 | 228 | ||
@@ -243,7 +243,9 @@ impl AnalysisImpl { | |||
243 | .modules_for_file(file_id) | 243 | .modules_for_file(file_id) |
244 | .into_iter() | 244 | .into_iter() |
245 | .map(|it| it.root(&module_tree)) | 245 | .map(|it| it.root(&module_tree)) |
246 | .map(|it| it.file_id(&module_tree)) | 246 | .map(|it| match it.source(&module_tree) { |
247 | ModuleSource::File(file_id) => file_id, | ||
248 | }) | ||
247 | .filter_map(|it| crate_graph.crate_id_for_crate_root(it)) | 249 | .filter_map(|it| crate_graph.crate_id_for_crate_root(it)) |
248 | .collect(); | 250 | .collect(); |
249 | 251 | ||
@@ -533,7 +535,9 @@ impl AnalysisImpl { | |||
533 | }; | 535 | }; |
534 | module_id | 536 | module_id |
535 | .child(module_tree, name.as_str()) | 537 | .child(module_tree, name.as_str()) |
536 | .map(|it| it.file_id(module_tree)) | 538 | .map(|it| match it.source(&module_tree) { |
539 | ModuleSource::File(file_id) => file_id, | ||
540 | }) | ||
537 | .into_iter() | 541 | .into_iter() |
538 | .collect() | 542 | .collect() |
539 | } | 543 | } |