aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_analysis/src/imp.rs
diff options
context:
space:
mode:
authorbors[bot] <bors[bot]@users.noreply.github.com>2018-10-23 18:57:10 +0100
committerbors[bot] <bors[bot]@users.noreply.github.com>2018-10-23 18:57:10 +0100
commitffbb60436305c9ef8c8944188e0373122051c53a (patch)
tree3240bdb3aa75eb278f13b7294f01591181189135 /crates/ra_analysis/src/imp.rs
parente49c628c0d7ab30a09e8d3ba3d7ac93ab967ff6d (diff)
parentdc477db757247d5184250bffe9dd0c38dd867778 (diff)
Merge #157
157: Introduce ModuleId r=matklad a=matklad Previously, module was synonym with a file, and so a module could have had several parents. This commit introduces a separate module concept, such that each module has only one parent, but a single file can correspond to different modules. Co-authored-by: Aleksey Kladov <[email protected]>
Diffstat (limited to 'crates/ra_analysis/src/imp.rs')
-rw-r--r--crates/ra_analysis/src/imp.rs145
1 files changed, 73 insertions, 72 deletions
diff --git a/crates/ra_analysis/src/imp.rs b/crates/ra_analysis/src/imp.rs
index 196627539..c15873328 100644
--- a/crates/ra_analysis/src/imp.rs
+++ b/crates/ra_analysis/src/imp.rs
@@ -1,5 +1,4 @@
1use std::{ 1use std::{
2 collections::VecDeque,
3 fmt, 2 fmt,
4 hash::{Hash, Hasher}, 3 hash::{Hash, Hasher},
5 iter, 4 iter,
@@ -17,7 +16,8 @@ use relative_path::RelativePath;
17use rustc_hash::FxHashSet; 16use rustc_hash::FxHashSet;
18 17
19use crate::{ 18use crate::{
20 descriptors::{FnDescriptor, ModuleTreeDescriptor, Problem}, 19 descriptors::module::{ModuleTree, Problem},
20 descriptors::{FnDescriptor},
21 roots::{ReadonlySourceRoot, SourceRoot, WritableSourceRoot}, 21 roots::{ReadonlySourceRoot, SourceRoot, WritableSourceRoot},
22 CrateGraph, CrateId, Diagnostic, FileId, FileResolver, FileSystemEdit, Position, 22 CrateGraph, CrateId, Diagnostic, FileId, FileResolver, FileSystemEdit, Position,
23 Query, SourceChange, SourceFileEdit, Cancelable, 23 Query, SourceChange, SourceFileEdit, Cancelable,
@@ -113,7 +113,7 @@ impl AnalysisHostImpl {
113 self.data_mut().crate_graph = graph; 113 self.data_mut().crate_graph = graph;
114 } 114 }
115 pub fn add_library(&mut self, root: ReadonlySourceRoot) { 115 pub fn add_library(&mut self, root: ReadonlySourceRoot) {
116 self.data_mut().libs.push(Arc::new(root)); 116 self.data_mut().libs.push(root);
117 } 117 }
118 fn data_mut(&mut self) -> &mut WorldData { 118 fn data_mut(&mut self) -> &mut WorldData {
119 &mut self.data 119 &mut self.data
@@ -135,7 +135,7 @@ impl AnalysisImpl {
135 if self.data.root.contains(file_id) { 135 if self.data.root.contains(file_id) {
136 return &self.data.root; 136 return &self.data.root;
137 } 137 }
138 &**self 138 self
139 .data 139 .data
140 .libs 140 .libs
141 .iter() 141 .iter()
@@ -162,19 +162,21 @@ impl AnalysisImpl {
162 pub fn parent_module(&self, file_id: FileId) -> Cancelable<Vec<(FileId, FileSymbol)>> { 162 pub fn parent_module(&self, file_id: FileId) -> Cancelable<Vec<(FileId, FileSymbol)>> {
163 let root = self.root(file_id); 163 let root = self.root(file_id);
164 let module_tree = root.module_tree()?; 164 let module_tree = root.module_tree()?;
165 let res = module_tree 165
166 .parent_modules(file_id) 166 let res = module_tree.modules_for_file(file_id)
167 .iter() 167 .into_iter()
168 .map(|link| { 168 .filter_map(|module_id| {
169 let file_id = link.owner(&module_tree); 169 let link = module_id.parent_link(&module_tree)?;
170 let file_id = link.owner(&module_tree).file_id(&module_tree);
170 let syntax = root.syntax(file_id); 171 let syntax = root.syntax(file_id);
171 let decl = link.bind_source(&module_tree, syntax.ast()); 172 let decl = link.bind_source(&module_tree, syntax.ast());
173
172 let sym = FileSymbol { 174 let sym = FileSymbol {
173 name: link.name(&module_tree), 175 name: decl.name().unwrap().text(),
174 node_range: decl.syntax().range(), 176 node_range: decl.syntax().range(),
175 kind: MODULE, 177 kind: MODULE,
176 }; 178 };
177 (file_id, sym) 179 Some((file_id, sym))
178 }) 180 })
179 .collect(); 181 .collect();
180 Ok(res) 182 Ok(res)
@@ -182,22 +184,13 @@ impl AnalysisImpl {
182 pub fn crate_for(&self, file_id: FileId) -> Cancelable<Vec<CrateId>> { 184 pub fn crate_for(&self, file_id: FileId) -> Cancelable<Vec<CrateId>> {
183 let module_tree = self.root(file_id).module_tree()?; 185 let module_tree = self.root(file_id).module_tree()?;
184 let crate_graph = &self.data.crate_graph; 186 let crate_graph = &self.data.crate_graph;
185 let mut res = Vec::new(); 187 let res = module_tree.modules_for_file(file_id)
186 let mut work = VecDeque::new(); 188 .into_iter()
187 work.push_back(file_id); 189 .map(|it| it.root(&module_tree))
188 let mut visited = FxHashSet::default(); 190 .map(|it| it.file_id(&module_tree))
189 while let Some(id) = work.pop_front() { 191 .filter_map(|it| crate_graph.crate_id_for_crate_root(it))
190 if let Some(crate_id) = crate_graph.crate_id_for_crate_root(id) { 192 .collect();
191 res.push(crate_id); 193
192 continue;
193 }
194 let parents = module_tree
195 .parent_modules(id)
196 .into_iter()
197 .map(|link| link.owner(&module_tree))
198 .filter(|&id| visited.insert(id));
199 work.extend(parents);
200 }
201 Ok(res) 194 Ok(res)
202 } 195 }
203 pub fn crate_root(&self, crate_id: CrateId) -> FileId { 196 pub fn crate_root(&self, crate_id: CrateId) -> FileId {
@@ -303,50 +296,51 @@ impl AnalysisImpl {
303 fix: None, 296 fix: None,
304 }) 297 })
305 .collect::<Vec<_>>(); 298 .collect::<Vec<_>>();
306 299 if let Some(m) = module_tree.any_module_for_file(file_id) {
307 for (name_node, problem) in module_tree.problems(file_id, syntax.ast()) { 300 for (name_node, problem) in m.problems(&module_tree, syntax.ast()) {
308 let diag = match problem { 301 let diag = match problem {
309 Problem::UnresolvedModule { candidate } => { 302 Problem::UnresolvedModule { candidate } => {
310 let create_file = FileSystemEdit::CreateFile { 303 let create_file = FileSystemEdit::CreateFile {
311 anchor: file_id, 304 anchor: file_id,
312 path: candidate.clone(), 305 path: candidate.clone(),
313 }; 306 };
314 let fix = SourceChange { 307 let fix = SourceChange {
315 label: "create module".to_string(), 308 label: "create module".to_string(),
316 source_file_edits: Vec::new(), 309 source_file_edits: Vec::new(),
317 file_system_edits: vec![create_file], 310 file_system_edits: vec![create_file],
318 cursor_position: None, 311 cursor_position: None,
319 }; 312 };
320 Diagnostic { 313 Diagnostic {
321 range: name_node.syntax().range(), 314 range: name_node.range(),
322 message: "unresolved module".to_string(), 315 message: "unresolved module".to_string(),
323 fix: Some(fix), 316 fix: Some(fix),
317 }
324 } 318 }
325 } 319 Problem::NotDirOwner { move_to, candidate } => {
326 Problem::NotDirOwner { move_to, candidate } => { 320 let move_file = FileSystemEdit::MoveFile {
327 let move_file = FileSystemEdit::MoveFile { 321 file: file_id,
328 file: file_id, 322 path: move_to.clone(),
329 path: move_to.clone(), 323 };
330 }; 324 let create_file = FileSystemEdit::CreateFile {
331 let create_file = FileSystemEdit::CreateFile { 325 anchor: file_id,
332 anchor: file_id, 326 path: move_to.join(candidate),
333 path: move_to.join(candidate), 327 };
334 }; 328 let fix = SourceChange {
335 let fix = SourceChange { 329 label: "move file and create module".to_string(),
336 label: "move file and create module".to_string(), 330 source_file_edits: Vec::new(),
337 source_file_edits: Vec::new(), 331 file_system_edits: vec![move_file, create_file],
338 file_system_edits: vec![move_file, create_file], 332 cursor_position: None,
339 cursor_position: None, 333 };
340 }; 334 Diagnostic {
341 Diagnostic { 335 range: name_node.range(),
342 range: name_node.syntax().range(), 336 message: "can't declare module at this location".to_string(),
343 message: "can't declare module at this location".to_string(), 337 fix: Some(fix),
344 fix: Some(fix), 338 }
345 } 339 }
346 } 340 };
347 }; 341 res.push(diag)
348 res.push(diag) 342 }
349 } 343 };
350 Ok(res) 344 Ok(res)
351 } 345 }
352 346
@@ -457,7 +451,7 @@ impl AnalysisImpl {
457 451
458 fn resolve_module( 452 fn resolve_module(
459 &self, 453 &self,
460 module_tree: &ModuleTreeDescriptor, 454 module_tree: &ModuleTree,
461 file_id: FileId, 455 file_id: FileId,
462 module: ast::Module, 456 module: ast::Module,
463 ) -> Vec<FileId> { 457 ) -> Vec<FileId> {
@@ -465,7 +459,14 @@ impl AnalysisImpl {
465 Some(name) => name.text(), 459 Some(name) => name.text(),
466 None => return Vec::new(), 460 None => return Vec::new(),
467 }; 461 };
468 module_tree.child_module_by_name(file_id, name.as_str()) 462 let module_id = match module_tree.any_module_for_file(file_id) {
463 Some(id) => id,
464 None => return Vec::new(),
465 };
466 module_id.child(module_tree, name.as_str())
467 .map(|it| it.file_id(module_tree))
468 .into_iter()
469 .collect()
469 } 470 }
470} 471}
471 472
@@ -473,7 +474,7 @@ impl AnalysisImpl {
473struct WorldData { 474struct WorldData {
474 crate_graph: CrateGraph, 475 crate_graph: CrateGraph,
475 root: WritableSourceRoot, 476 root: WritableSourceRoot,
476 libs: Vec<Arc<ReadonlySourceRoot>>, 477 libs: Vec<ReadonlySourceRoot>,
477} 478}
478 479
479impl SourceChange { 480impl SourceChange {