diff options
Diffstat (limited to 'crates/ra_analysis/src/descriptors/module/mod.rs')
-rw-r--r-- | crates/ra_analysis/src/descriptors/module/mod.rs | 43 |
1 files changed, 15 insertions, 28 deletions
diff --git a/crates/ra_analysis/src/descriptors/module/mod.rs b/crates/ra_analysis/src/descriptors/module/mod.rs index d0560244a..a894025ed 100644 --- a/crates/ra_analysis/src/descriptors/module/mod.rs +++ b/crates/ra_analysis/src/descriptors/module/mod.rs | |||
@@ -15,6 +15,7 @@ use relative_path::RelativePathBuf; | |||
15 | use crate::{ | 15 | use crate::{ |
16 | db::SyntaxDatabase, syntax_ptr::SyntaxPtr, FileId, FilePosition, Cancelable, | 16 | db::SyntaxDatabase, syntax_ptr::SyntaxPtr, FileId, FilePosition, Cancelable, |
17 | descriptors::DescriptorDatabase, | 17 | descriptors::DescriptorDatabase, |
18 | input::SourceRootId | ||
18 | }; | 19 | }; |
19 | 20 | ||
20 | pub(crate) use self::scope::ModuleScope; | 21 | pub(crate) use self::scope::ModuleScope; |
@@ -24,6 +25,7 @@ pub(crate) use self::scope::ModuleScope; | |||
24 | #[derive(Debug, Clone)] | 25 | #[derive(Debug, Clone)] |
25 | pub(crate) struct ModuleDescriptor { | 26 | pub(crate) struct ModuleDescriptor { |
26 | tree: Arc<ModuleTree>, | 27 | tree: Arc<ModuleTree>, |
28 | source_root_id: SourceRootId, | ||
27 | module_id: ModuleId, | 29 | module_id: ModuleId, |
28 | } | 30 | } |
29 | 31 | ||
@@ -59,13 +61,14 @@ impl ModuleDescriptor { | |||
59 | file_id: FileId, | 61 | file_id: FileId, |
60 | module_source: ModuleSource, | 62 | module_source: ModuleSource, |
61 | ) -> Cancelable<Option<ModuleDescriptor>> { | 63 | ) -> Cancelable<Option<ModuleDescriptor>> { |
62 | let source_root = db.file_source_root(file_id); | 64 | let source_root_id = db.file_source_root(file_id); |
63 | let module_tree = db.module_tree(source_root)?; | 65 | let module_tree = db.module_tree(source_root_id)?; |
64 | 66 | ||
65 | let res = match module_tree.any_module_for_source(module_source) { | 67 | let res = match module_tree.any_module_for_source(module_source) { |
66 | None => None, | 68 | None => None, |
67 | Some(module_id) => Some(ModuleDescriptor { | 69 | Some(module_id) => Some(ModuleDescriptor { |
68 | tree: module_tree, | 70 | tree: module_tree, |
71 | source_root_id, | ||
69 | module_id, | 72 | module_id, |
70 | }), | 73 | }), |
71 | }; | 74 | }; |
@@ -92,8 +95,8 @@ impl ModuleDescriptor { | |||
92 | pub fn parent(&self) -> Option<ModuleDescriptor> { | 95 | pub fn parent(&self) -> Option<ModuleDescriptor> { |
93 | let parent_id = self.module_id.parent(&self.tree)?; | 96 | let parent_id = self.module_id.parent(&self.tree)?; |
94 | Some(ModuleDescriptor { | 97 | Some(ModuleDescriptor { |
95 | tree: Arc::clone(&self.tree), | ||
96 | module_id: parent_id, | 98 | module_id: parent_id, |
99 | ..self.clone() | ||
97 | }) | 100 | }) |
98 | } | 101 | } |
99 | 102 | ||
@@ -109,13 +112,20 @@ impl ModuleDescriptor { | |||
109 | let link = self.module_id.parent_link(&self.tree)?; | 112 | let link = self.module_id.parent_link(&self.tree)?; |
110 | Some(link.name(&self.tree)) | 113 | Some(link.name(&self.tree)) |
111 | } | 114 | } |
115 | |||
116 | /// Finds a child module with the specified name. | ||
112 | pub fn child(&self, name: &str) -> Option<ModuleDescriptor> { | 117 | pub fn child(&self, name: &str) -> Option<ModuleDescriptor> { |
113 | let child_id = self.module_id.child(&self.tree, name)?; | 118 | let child_id = self.module_id.child(&self.tree, name)?; |
114 | Some(ModuleDescriptor { | 119 | Some(ModuleDescriptor { |
115 | tree: Arc::clone(&self.tree), | ||
116 | module_id: child_id, | 120 | module_id: child_id, |
121 | ..self.clone() | ||
117 | }) | 122 | }) |
118 | } | 123 | } |
124 | |||
125 | /// Returns a `ModuleScope`: a set of items, visible in this module. | ||
126 | pub fn scope(&self, db: &impl DescriptorDatabase) -> Cancelable<Arc<ModuleScope>> { | ||
127 | db.module_scope(self.source_root_id, self.module_id) | ||
128 | } | ||
119 | } | 129 | } |
120 | 130 | ||
121 | /// Phisically, rust source is organized as a set of files, but logically it is | 131 | /// Phisically, rust source is organized as a set of files, but logically it is |
@@ -190,20 +200,7 @@ impl ModuleId { | |||
190 | let link = self.parent_link(tree)?; | 200 | let link = self.parent_link(tree)?; |
191 | Some(tree.link(link).owner) | 201 | Some(tree.link(link).owner) |
192 | } | 202 | } |
193 | pub(crate) fn root(self, tree: &ModuleTree) -> ModuleId { | 203 | fn child(self, tree: &ModuleTree, name: &str) -> Option<ModuleId> { |
194 | let mut curr = self; | ||
195 | let mut i = 0; | ||
196 | while let Some(next) = curr.parent(tree) { | ||
197 | curr = next; | ||
198 | i += 1; | ||
199 | // simplistic cycle detection | ||
200 | if i > 100 { | ||
201 | return self; | ||
202 | } | ||
203 | } | ||
204 | curr | ||
205 | } | ||
206 | pub(crate) fn child(self, tree: &ModuleTree, name: &str) -> Option<ModuleId> { | ||
207 | let link = tree | 204 | let link = tree |
208 | .module(self) | 205 | .module(self) |
209 | .children | 206 | .children |
@@ -260,16 +257,6 @@ struct ModuleData { | |||
260 | } | 257 | } |
261 | 258 | ||
262 | impl ModuleSource { | 259 | impl ModuleSource { |
263 | pub(crate) fn for_node(file_id: FileId, node: SyntaxNodeRef) -> ModuleSource { | ||
264 | for node in node.ancestors() { | ||
265 | if let Some(m) = ast::Module::cast(node) { | ||
266 | if !m.has_semi() { | ||
267 | return ModuleSource::new_inline(file_id, m); | ||
268 | } | ||
269 | } | ||
270 | } | ||
271 | ModuleSource::SourceFile(file_id) | ||
272 | } | ||
273 | pub(crate) fn new_inline(file_id: FileId, module: ast::Module) -> ModuleSource { | 260 | pub(crate) fn new_inline(file_id: FileId, module: ast::Module) -> ModuleSource { |
274 | assert!(!module.has_semi()); | 261 | assert!(!module.has_semi()); |
275 | let ptr = SyntaxPtr::new(file_id, module.syntax()); | 262 | let ptr = SyntaxPtr::new(file_id, module.syntax()); |