aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_analysis/src/descriptors/module
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_analysis/src/descriptors/module')
-rw-r--r--crates/ra_analysis/src/descriptors/module/mod.rs37
1 files changed, 35 insertions, 2 deletions
diff --git a/crates/ra_analysis/src/descriptors/module/mod.rs b/crates/ra_analysis/src/descriptors/module/mod.rs
index 8a75e11be..16faea94e 100644
--- a/crates/ra_analysis/src/descriptors/module/mod.rs
+++ b/crates/ra_analysis/src/descriptors/module/mod.rs
@@ -6,6 +6,7 @@ use std::sync::Arc;
6use ra_editor::find_node_at_offset; 6use ra_editor::find_node_at_offset;
7 7
8use ra_syntax::{ 8use ra_syntax::{
9 algo::generate,
9 ast::{self, AstNode, NameOwner}, 10 ast::{self, AstNode, NameOwner},
10 SmolStr, SyntaxNode, SyntaxNodeRef, 11 SmolStr, SyntaxNode, SyntaxNodeRef,
11}; 12};
@@ -27,6 +28,16 @@ pub(crate) struct ModuleDescriptor {
27} 28}
28 29
29impl ModuleDescriptor { 30impl ModuleDescriptor {
31 /// Lookup `ModuleDescriptor` by `FileId`. Note that this is inherently
32 /// lossy transformation: in general, a single source might correspond to
33 /// several modules.
34 pub fn guess_from_file_id(
35 db: &impl DescriptorDatabase,
36 file_id: FileId,
37 ) -> Cancelable<Option<ModuleDescriptor>> {
38 ModuleDescriptor::guess_from_source(db, file_id, ModuleSource::SourceFile(file_id))
39 }
40
30 /// Lookup `ModuleDescriptor` by position in the source code. Note that this 41 /// Lookup `ModuleDescriptor` by position in the source code. Note that this
31 /// is inherently lossy transformation: in general, a single source might 42 /// is inherently lossy transformation: in general, a single source might
32 /// correspond to several modules. 43 /// correspond to several modules.
@@ -34,14 +45,23 @@ impl ModuleDescriptor {
34 db: &impl DescriptorDatabase, 45 db: &impl DescriptorDatabase,
35 position: FilePosition, 46 position: FilePosition,
36 ) -> Cancelable<Option<ModuleDescriptor>> { 47 ) -> Cancelable<Option<ModuleDescriptor>> {
37 let source_root = db.file_source_root(position.file_id);
38 let module_tree = db.module_tree(source_root)?;
39 let file = db.file_syntax(position.file_id); 48 let file = db.file_syntax(position.file_id);
40 let module_source = match find_node_at_offset::<ast::Module>(file.syntax(), position.offset) 49 let module_source = match find_node_at_offset::<ast::Module>(file.syntax(), position.offset)
41 { 50 {
42 Some(m) if !m.has_semi() => ModuleSource::new_inline(position.file_id, m), 51 Some(m) if !m.has_semi() => ModuleSource::new_inline(position.file_id, m),
43 _ => ModuleSource::SourceFile(position.file_id), 52 _ => ModuleSource::SourceFile(position.file_id),
44 }; 53 };
54 ModuleDescriptor::guess_from_source(db, position.file_id, module_source)
55 }
56
57 fn guess_from_source(
58 db: &impl DescriptorDatabase,
59 file_id: FileId,
60 module_source: ModuleSource,
61 ) -> Cancelable<Option<ModuleDescriptor>> {
62 let source_root = db.file_source_root(file_id);
63 let module_tree = db.module_tree(source_root)?;
64
45 let res = match module_tree.any_module_for_source(module_source) { 65 let res = match module_tree.any_module_for_source(module_source) {
46 None => None, 66 None => None,
47 Some(module_id) => Some(ModuleDescriptor { 67 Some(module_id) => Some(ModuleDescriptor {
@@ -64,6 +84,11 @@ impl ModuleDescriptor {
64 Some((file_id, src)) 84 Some((file_id, src))
65 } 85 }
66 86
87 pub fn source(&self) -> ModuleSource {
88 self.module_id.source(&self.tree)
89 }
90
91 /// Parent module. Returns `None` if this is a root module.
67 pub fn parent(&self) -> Option<ModuleDescriptor> { 92 pub fn parent(&self) -> Option<ModuleDescriptor> {
68 let parent_id = self.module_id.parent(&self.tree)?; 93 let parent_id = self.module_id.parent(&self.tree)?;
69 Some(ModuleDescriptor { 94 Some(ModuleDescriptor {
@@ -71,6 +96,14 @@ impl ModuleDescriptor {
71 module_id: parent_id, 96 module_id: parent_id,
72 }) 97 })
73 } 98 }
99
100 /// The root of the tree this module is part of
101 pub fn crate_root(&self) -> ModuleDescriptor {
102 generate(Some(self.clone()), |it| it.parent())
103 .last()
104 .unwrap()
105 }
106
74 /// `name` is `None` for the crate's root module 107 /// `name` is `None` for the crate's root module
75 pub fn name(&self) -> Option<SmolStr> { 108 pub fn name(&self) -> Option<SmolStr> {
76 let link = self.module_id.parent_link(&self.tree)?; 109 let link = self.module_id.parent_link(&self.tree)?;