diff options
Diffstat (limited to 'crates/ra_analysis/src')
-rw-r--r-- | crates/ra_analysis/src/descriptors/module/imp.rs | 77 | ||||
-rw-r--r-- | crates/ra_analysis/src/descriptors/module/mod.rs | 7 | ||||
-rw-r--r-- | crates/ra_analysis/src/syntax_ptr.rs | 4 |
3 files changed, 67 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 @@ | |||
1 | use std::sync::Arc; | 1 | use std::sync::Arc; |
2 | 2 | ||
3 | use ra_syntax::{ | 3 | use ra_syntax::{ |
4 | ast::{self, ModuleItemOwner, NameOwner}, | 4 | ast::{self, ModuleItemOwner, NameOwner, AstNode}, |
5 | SmolStr, | 5 | SmolStr, |
6 | }; | 6 | }; |
7 | use relative_path::RelativePathBuf; | 7 | use 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 | ||
17 | use super::{ | 18 | use 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)] |
23 | pub(crate) struct Submodule { | 24 | pub(crate) enum Submodule { |
24 | name: SmolStr, | 25 | Declaration(SmolStr), |
26 | Definition(SmolStr, SyntaxPtr), | ||
27 | } | ||
28 | |||
29 | impl 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 | ||
27 | pub(crate) fn submodules( | 38 | pub(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) => { |
diff --git a/crates/ra_analysis/src/syntax_ptr.rs b/crates/ra_analysis/src/syntax_ptr.rs index 4db1529c2..4afb1fc93 100644 --- a/crates/ra_analysis/src/syntax_ptr.rs +++ b/crates/ra_analysis/src/syntax_ptr.rs | |||
@@ -22,6 +22,10 @@ impl SyntaxPtr { | |||
22 | let local = LocalSyntaxPtr::new(node); | 22 | let local = LocalSyntaxPtr::new(node); |
23 | SyntaxPtr { file_id, local } | 23 | SyntaxPtr { file_id, local } |
24 | } | 24 | } |
25 | |||
26 | pub(crate) fn file_id(self) -> FileId { | ||
27 | self.file_id | ||
28 | } | ||
25 | } | 29 | } |
26 | 30 | ||
27 | /// A pionter to a syntax node inside a file. | 31 | /// A pionter to a syntax node inside a file. |