aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_analysis/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_analysis/src')
-rw-r--r--crates/ra_analysis/src/descriptors/module/imp.rs49
-rw-r--r--crates/ra_analysis/src/descriptors/module/mod.rs12
-rw-r--r--crates/ra_analysis/src/imp.rs27
-rw-r--r--crates/ra_analysis/src/lib.rs8
4 files changed, 64 insertions, 32 deletions
diff --git a/crates/ra_analysis/src/descriptors/module/imp.rs b/crates/ra_analysis/src/descriptors/module/imp.rs
index 257a323ed..b3b1f1f21 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, AstNode}, 4 ast::{self, ModuleItemOwner, NameOwner},
5 SmolStr, 5 SmolStr,
6}; 6};
7use relative_path::RelativePathBuf; 7use relative_path::RelativePathBuf;
@@ -12,7 +12,6 @@ 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,
16}; 15};
17 16
18use super::{ 17use super::{
@@ -23,7 +22,7 @@ use super::{
23#[derive(Clone, Hash, PartialEq, Eq, Debug)] 22#[derive(Clone, Hash, PartialEq, Eq, Debug)]
24pub(crate) enum Submodule { 23pub(crate) enum Submodule {
25 Declaration(SmolStr), 24 Declaration(SmolStr),
26 Definition(SmolStr, SyntaxPtr), 25 Definition(SmolStr, ModuleSource),
27} 26}
28 27
29impl Submodule { 28impl Submodule {
@@ -60,7 +59,8 @@ pub(crate) fn submodules(
60 if m.has_semi() { 59 if m.has_semi() {
61 Submodule::Declaration(name) 60 Submodule::Declaration(name)
62 } else { 61 } else {
63 Submodule::Definition(name, SyntaxPtr::new(file_id, m.syntax())) 62 let src = ModuleSource::new_inline(file_id, m);
63 Submodule::Definition(name, src)
64 } 64 }
65 }) 65 })
66 .collect() 66 .collect()
@@ -121,7 +121,8 @@ fn create_module_tree<'a>(
121 121
122 let source_root = db.source_root(source_root); 122 let source_root = db.source_root(source_root);
123 for &file_id in source_root.files.iter() { 123 for &file_id in source_root.files.iter() {
124 if visited.contains(&file_id) { 124 let source = ModuleSource::File(file_id);
125 if visited.contains(&source) {
125 continue; // TODO: use explicit crate_roots here 126 continue; // TODO: use explicit crate_roots here
126 } 127 }
127 assert!(!roots.contains_key(&file_id)); 128 assert!(!roots.contains_key(&file_id));
@@ -132,7 +133,7 @@ fn create_module_tree<'a>(
132 &mut visited, 133 &mut visited,
133 &mut roots, 134 &mut roots,
134 None, 135 None,
135 file_id, 136 source,
136 )?; 137 )?;
137 roots.insert(file_id, module_id); 138 roots.insert(file_id, module_id);
138 } 139 }
@@ -143,18 +144,18 @@ fn build_subtree(
143 db: &impl DescriptorDatabase, 144 db: &impl DescriptorDatabase,
144 source_root: &SourceRoot, 145 source_root: &SourceRoot,
145 tree: &mut ModuleTree, 146 tree: &mut ModuleTree,
146 visited: &mut FxHashSet<FileId>, 147 visited: &mut FxHashSet<ModuleSource>,
147 roots: &mut FxHashMap<FileId, ModuleId>, 148 roots: &mut FxHashMap<FileId, ModuleId>,
148 parent: Option<LinkId>, 149 parent: Option<LinkId>,
149 file_id: FileId, 150 source: ModuleSource,
150) -> Cancelable<ModuleId> { 151) -> Cancelable<ModuleId> {
151 visited.insert(file_id); 152 visited.insert(source);
152 let id = tree.push_mod(ModuleData { 153 let id = tree.push_mod(ModuleData {
153 source: ModuleSource::File(file_id), 154 source,
154 parent, 155 parent,
155 children: Vec::new(), 156 children: Vec::new(),
156 }); 157 });
157 for sub in db.submodules(ModuleSource::File(file_id))?.iter() { 158 for sub in db.submodules(source)?.iter() {
158 let link = tree.push_link(LinkData { 159 let link = tree.push_link(LinkData {
159 name: sub.name().clone(), 160 name: sub.name().clone(),
160 owner: id, 161 owner: id,
@@ -165,7 +166,7 @@ fn build_subtree(
165 let (points_to, problem) = match sub { 166 let (points_to, problem) = match sub {
166 Submodule::Declaration(name) => { 167 Submodule::Declaration(name) => {
167 let (points_to, problem) = 168 let (points_to, problem) =
168 resolve_submodule(file_id, &name, &source_root.file_resolver); 169 resolve_submodule(source, &name, &source_root.file_resolver);
169 let points_to = points_to 170 let points_to = points_to
170 .into_iter() 171 .into_iter()
171 .map(|file_id| match roots.remove(&file_id) { 172 .map(|file_id| match roots.remove(&file_id) {
@@ -180,13 +181,24 @@ fn build_subtree(
180 visited, 181 visited,
181 roots, 182 roots,
182 Some(link), 183 Some(link),
183 file_id, 184 ModuleSource::File(file_id),
184 ), 185 ),
185 }) 186 })
186 .collect::<Cancelable<Vec<_>>>()?; 187 .collect::<Cancelable<Vec<_>>>()?;
187 (points_to, problem) 188 (points_to, problem)
188 } 189 }
189 Submodule::Definition(..) => continue, 190 Submodule::Definition(_name, submodule_source) => {
191 let points_to = build_subtree(
192 db,
193 source_root,
194 tree,
195 visited,
196 roots,
197 Some(link),
198 *submodule_source,
199 )?;
200 (vec![points_to], None)
201 }
190 }; 202 };
191 203
192 tree.link_mut(link).points_to = points_to; 204 tree.link_mut(link).points_to = points_to;
@@ -196,10 +208,17 @@ fn build_subtree(
196} 208}
197 209
198fn resolve_submodule( 210fn resolve_submodule(
199 file_id: FileId, 211 source: ModuleSource,
200 name: &SmolStr, 212 name: &SmolStr,
201 file_resolver: &FileResolverImp, 213 file_resolver: &FileResolverImp,
202) -> (Vec<FileId>, Option<Problem>) { 214) -> (Vec<FileId>, Option<Problem>) {
215 let file_id = match source {
216 ModuleSource::File(it) => it,
217 ModuleSource::Inline(..) => {
218 // TODO
219 return (Vec::new(), None);
220 }
221 };
203 let mod_name = file_resolver.file_stem(file_id); 222 let mod_name = file_resolver.file_stem(file_id);
204 let is_dir_owner = mod_name == "mod" || mod_name == "lib" || mod_name == "main"; 223 let is_dir_owner = mod_name == "mod" || mod_name == "lib" || mod_name == "main";
205 224
diff --git a/crates/ra_analysis/src/descriptors/module/mod.rs b/crates/ra_analysis/src/descriptors/module/mod.rs
index 8464b0618..3d799ba05 100644
--- a/crates/ra_analysis/src/descriptors/module/mod.rs
+++ b/crates/ra_analysis/src/descriptors/module/mod.rs
@@ -142,9 +142,7 @@ impl LinkId {
142 .1; 142 .1;
143 ast.into() 143 ast.into()
144 } 144 }
145 ModuleSourceNode::Inline(..) => { 145 ModuleSourceNode::Inline(it) => it,
146 unimplemented!("https://github.com/rust-analyzer/rust-analyzer/issues/181")
147 }
148 } 146 }
149 } 147 }
150} 148}
@@ -157,6 +155,12 @@ struct ModuleData {
157} 155}
158 156
159impl ModuleSource { 157impl ModuleSource {
158 pub(crate) fn new_inline(file_id: FileId, module: ast::Module) -> ModuleSource {
159 assert!(!module.has_semi());
160 let ptr = SyntaxPtr::new(file_id, module.syntax());
161 ModuleSource::Inline(ptr)
162 }
163
160 pub(crate) fn as_file(self) -> Option<FileId> { 164 pub(crate) fn as_file(self) -> Option<FileId> {
161 match self { 165 match self {
162 ModuleSource::File(f) => Some(f), 166 ModuleSource::File(f) => Some(f),
@@ -164,7 +168,7 @@ impl ModuleSource {
164 } 168 }
165 } 169 }
166 170
167 fn file_id(self) -> FileId { 171 pub(crate) fn file_id(self) -> FileId {
168 match self { 172 match self {
169 ModuleSource::File(f) => f, 173 ModuleSource::File(f) => f,
170 ModuleSource::Inline(ptr) => ptr.file_id(), 174 ModuleSource::Inline(ptr) => ptr.file_id(),
diff --git a/crates/ra_analysis/src/imp.rs b/crates/ra_analysis/src/imp.rs
index 823ac9bdd..704648b59 100644
--- a/crates/ra_analysis/src/imp.rs
+++ b/crates/ra_analysis/src/imp.rs
@@ -220,27 +220,32 @@ impl AnalysisImpl {
220 let source_root = self.db.file_source_root(file_id); 220 let source_root = self.db.file_source_root(file_id);
221 self.db.module_tree(source_root) 221 self.db.module_tree(source_root)
222 } 222 }
223 pub fn parent_module(&self, file_id: FileId) -> Cancelable<Vec<(FileId, FileSymbol)>> { 223 pub fn parent_module(
224 &self,
225 file_id: FileId,
226 offset: TextUnit,
227 ) -> Cancelable<Vec<(FileId, FileSymbol)>> {
224 let module_tree = self.module_tree(file_id)?; 228 let module_tree = self.module_tree(file_id)?;
229 let file = self.db.file_syntax(file_id);
230 let module_source = match find_node_at_offset::<ast::Module>(file.syntax(), offset) {
231 Some(m) if !m.has_semi() => ModuleSource::new_inline(file_id, m),
232 _ => ModuleSource::File(file_id),
233 };
225 234
226 let res = module_tree 235 let res = module_tree
227 .modules_for_source(ModuleSource::File(file_id)) 236 .modules_for_source(module_source)
228 .into_iter() 237 .into_iter()
229 .filter_map(|module_id| { 238 .filter_map(|module_id| {
230 let link = module_id.parent_link(&module_tree)?; 239 let link = module_id.parent_link(&module_tree)?;
231 let file_id = match link.owner(&module_tree).source(&module_tree) { 240 let file_id = link.owner(&module_tree).source(&module_tree).file_id();
232 ModuleSource::File(file_id) => file_id,
233 ModuleSource::Inline(..) => {
234 //TODO: https://github.com/rust-analyzer/rust-analyzer/issues/181
235 return None;
236 }
237 };
238 let decl = link.bind_source(&module_tree, &*self.db); 241 let decl = link.bind_source(&module_tree, &*self.db);
239 let decl = decl.ast(); 242 let decl = decl.ast();
240 243
244 let decl_name = decl.name().unwrap();
245
241 let sym = FileSymbol { 246 let sym = FileSymbol {
242 name: decl.name().unwrap().text(), 247 name: decl_name.text(),
243 node_range: decl.syntax().range(), 248 node_range: decl_name.syntax().range(),
244 kind: MODULE, 249 kind: MODULE,
245 }; 250 };
246 Some((file_id, sym)) 251 Some((file_id, sym))
diff --git a/crates/ra_analysis/src/lib.rs b/crates/ra_analysis/src/lib.rs
index 4e4c65f08..fee382151 100644
--- a/crates/ra_analysis/src/lib.rs
+++ b/crates/ra_analysis/src/lib.rs
@@ -263,8 +263,12 @@ impl Analysis {
263 ) -> Cancelable<Vec<(FileId, TextRange)>> { 263 ) -> Cancelable<Vec<(FileId, TextRange)>> {
264 Ok(self.imp.find_all_refs(file_id, offset)) 264 Ok(self.imp.find_all_refs(file_id, offset))
265 } 265 }
266 pub fn parent_module(&self, file_id: FileId) -> Cancelable<Vec<(FileId, FileSymbol)>> { 266 pub fn parent_module(
267 self.imp.parent_module(file_id) 267 &self,
268 file_id: FileId,
269 offset: TextUnit,
270 ) -> Cancelable<Vec<(FileId, FileSymbol)>> {
271 self.imp.parent_module(file_id, offset)
268 } 272 }
269 pub fn crate_for(&self, file_id: FileId) -> Cancelable<Vec<CrateId>> { 273 pub fn crate_for(&self, file_id: FileId) -> Cancelable<Vec<CrateId>> {
270 self.imp.crate_for(file_id) 274 self.imp.crate_for(file_id)