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/imp.rs77
-rw-r--r--crates/ra_analysis/src/descriptors/module/mod.rs7
2 files changed, 63 insertions, 21 deletions
diff --git a/crates/ra_analysis/src/descriptors/module/imp.rs b/crates/ra_analysis/src/descriptors/module/imp.rs
index d67ffa9de..257a323ed 100644
--- a/crates/ra_analysis/src/descriptors/module/imp.rs
+++ b/crates/ra_analysis/src/descriptors/module/imp.rs
@@ -1,7 +1,7 @@
1use std::sync::Arc; 1use std::sync::Arc;
2 2
3use ra_syntax::{ 3use ra_syntax::{
4 ast::{self, ModuleItemOwner, NameOwner}, 4 ast::{self, ModuleItemOwner, NameOwner, AstNode},
5 SmolStr, 5 SmolStr,
6}; 6};
7use relative_path::RelativePathBuf; 7use relative_path::RelativePathBuf;
@@ -12,6 +12,7 @@ use crate::{
12 descriptors::DescriptorDatabase, 12 descriptors::DescriptorDatabase,
13 input::{SourceRoot, SourceRootId}, 13 input::{SourceRoot, SourceRootId},
14 Cancelable, FileId, FileResolverImp, 14 Cancelable, FileId, FileResolverImp,
15 syntax_ptr::SyntaxPtr,
15}; 16};
16 17
17use super::{ 18use super::{
@@ -20,8 +21,18 @@ use super::{
20}; 21};
21 22
22#[derive(Clone, Hash, PartialEq, Eq, Debug)] 23#[derive(Clone, Hash, PartialEq, Eq, Debug)]
23pub(crate) struct Submodule { 24pub(crate) enum Submodule {
24 name: SmolStr, 25 Declaration(SmolStr),
26 Definition(SmolStr, SyntaxPtr),
27}
28
29impl Submodule {
30 fn name(&self) -> &SmolStr {
31 match self {
32 Submodule::Declaration(name) => name,
33 Submodule::Definition(name, _) => name,
34 }
35 }
25} 36}
26 37
27pub(crate) fn submodules( 38pub(crate) fn submodules(
@@ -29,20 +40,29 @@ pub(crate) fn submodules(
29 source: ModuleSource, 40 source: ModuleSource,
30) -> Cancelable<Arc<Vec<Submodule>>> { 41) -> Cancelable<Arc<Vec<Submodule>>> {
31 db::check_canceled(db)?; 42 db::check_canceled(db)?;
43 let file_id = source.file_id();
32 let submodules = match source.resolve(db) { 44 let submodules = match source.resolve(db) {
33 ModuleSourceNode::Root(it) => collect_submodules(it.ast()), 45 ModuleSourceNode::Root(it) => collect_submodules(file_id, it.ast()),
34 ModuleSourceNode::Inline(it) => it 46 ModuleSourceNode::Inline(it) => it
35 .ast() 47 .ast()
36 .item_list() 48 .item_list()
37 .map(collect_submodules) 49 .map(|it| collect_submodules(file_id, it))
38 .unwrap_or_else(Vec::new), 50 .unwrap_or_else(Vec::new),
39 }; 51 };
40 return Ok(Arc::new(submodules)); 52 return Ok(Arc::new(submodules));
41 53
42 fn collect_submodules<'a>(root: impl ast::ModuleItemOwner<'a>) -> Vec<Submodule> { 54 fn collect_submodules<'a>(
55 file_id: FileId,
56 root: impl ast::ModuleItemOwner<'a>,
57 ) -> Vec<Submodule> {
43 modules(root) 58 modules(root)
44 .filter(|(_, m)| m.has_semi()) 59 .map(|(name, m)| {
45 .map(|(name, _)| Submodule { name }) 60 if m.has_semi() {
61 Submodule::Declaration(name)
62 } else {
63 Submodule::Definition(name, SyntaxPtr::new(file_id, m.syntax()))
64 }
65 })
46 .collect() 66 .collect()
47 } 67 }
48} 68}
@@ -135,25 +155,40 @@ fn build_subtree(
135 children: Vec::new(), 155 children: Vec::new(),
136 }); 156 });
137 for sub in db.submodules(ModuleSource::File(file_id))?.iter() { 157 for sub in db.submodules(ModuleSource::File(file_id))?.iter() {
138 let name = sub.name.clone();
139 let (points_to, problem) = resolve_submodule(file_id, &name, &source_root.file_resolver);
140 let link = tree.push_link(LinkData { 158 let link = tree.push_link(LinkData {
141 name, 159 name: sub.name().clone(),
142 owner: id, 160 owner: id,
143 points_to: Vec::new(), 161 points_to: Vec::new(),
144 problem: None, 162 problem: None,
145 }); 163 });
146 164
147 let points_to = points_to 165 let (points_to, problem) = match sub {
148 .into_iter() 166 Submodule::Declaration(name) => {
149 .map(|file_id| match roots.remove(&file_id) { 167 let (points_to, problem) =
150 Some(module_id) => { 168 resolve_submodule(file_id, &name, &source_root.file_resolver);
151 tree.module_mut(module_id).parent = Some(link); 169 let points_to = points_to
152 Ok(module_id) 170 .into_iter()
153 } 171 .map(|file_id| match roots.remove(&file_id) {
154 None => build_subtree(db, source_root, tree, visited, roots, Some(link), file_id), 172 Some(module_id) => {
155 }) 173 tree.module_mut(module_id).parent = Some(link);
156 .collect::<Cancelable<Vec<_>>>()?; 174 Ok(module_id)
175 }
176 None => build_subtree(
177 db,
178 source_root,
179 tree,
180 visited,
181 roots,
182 Some(link),
183 file_id,
184 ),
185 })
186 .collect::<Cancelable<Vec<_>>>()?;
187 (points_to, problem)
188 }
189 Submodule::Definition(..) => continue,
190 };
191
157 tree.link_mut(link).points_to = points_to; 192 tree.link_mut(link).points_to = points_to;
158 tree.link_mut(link).problem = problem; 193 tree.link_mut(link).problem = problem;
159 } 194 }
diff --git a/crates/ra_analysis/src/descriptors/module/mod.rs b/crates/ra_analysis/src/descriptors/module/mod.rs
index 13bab0087..8464b0618 100644
--- a/crates/ra_analysis/src/descriptors/module/mod.rs
+++ b/crates/ra_analysis/src/descriptors/module/mod.rs
@@ -164,6 +164,13 @@ impl ModuleSource {
164 } 164 }
165 } 165 }
166 166
167 fn file_id(self) -> FileId {
168 match self {
169 ModuleSource::File(f) => f,
170 ModuleSource::Inline(ptr) => ptr.file_id(),
171 }
172 }
173
167 fn resolve(self, db: &impl SyntaxDatabase) -> ModuleSourceNode { 174 fn resolve(self, db: &impl SyntaxDatabase) -> ModuleSourceNode {
168 match self { 175 match self {
169 ModuleSource::File(file_id) => { 176 ModuleSource::File(file_id) => {