aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_analysis/src/imp.rs
diff options
context:
space:
mode:
authorJeremy A. Kolb <[email protected]>2018-10-15 22:44:23 +0100
committerJeremy A. Kolb <[email protected]>2018-10-16 14:41:10 +0100
commit61f3a438d3a729a6be941bca1ff4c6a97a33f221 (patch)
tree6551967cc8c6e921b66071453ad7888a9121d326 /crates/ra_analysis/src/imp.rs
parent39cb6c6d3f78b193f5873c3492e530bbd24d5dd2 (diff)
Cargo Format
Run `cargo fmt` and ignore generated files
Diffstat (limited to 'crates/ra_analysis/src/imp.rs')
-rw-r--r--crates/ra_analysis/src/imp.rs207
1 files changed, 123 insertions, 84 deletions
diff --git a/crates/ra_analysis/src/imp.rs b/crates/ra_analysis/src/imp.rs
index 5efcaeca0..f1403cb5d 100644
--- a/crates/ra_analysis/src/imp.rs
+++ b/crates/ra_analysis/src/imp.rs
@@ -1,32 +1,31 @@
1use std::{ 1use std::{
2 sync::{
3 Arc,
4 },
5 hash::{Hash, Hasher},
6 fmt,
7 collections::VecDeque, 2 collections::VecDeque,
3 fmt,
4 hash::{Hash, Hasher},
8 iter, 5 iter,
6 sync::Arc,
9}; 7};
10 8
11use relative_path::RelativePath; 9use ra_editor::{self, find_node_at_offset, resolve_local_name, FileSymbol, LineIndex, LocalEdit};
12use rustc_hash::FxHashSet;
13use ra_editor::{self, FileSymbol, LineIndex, find_node_at_offset, LocalEdit, resolve_local_name};
14use ra_syntax::{ 10use ra_syntax::{
15 TextUnit, TextRange, SmolStr, File, AstNode, SyntaxNodeRef, 11 ast::{self, ArgListOwner, Expr, NameOwner},
12 AstNode, File, SmolStr,
16 SyntaxKind::*, 13 SyntaxKind::*,
17 ast::{self, NameOwner, ArgListOwner, Expr}, 14 SyntaxNodeRef, TextRange, TextUnit,
18}; 15};
16use relative_path::RelativePath;
17use rustc_hash::FxHashSet;
19 18
20use crate::{ 19use crate::{
21 FileId, FileResolver, Query, Diagnostic, SourceChange, SourceFileEdit, Position, FileSystemEdit,
22 JobToken, CrateGraph, CrateId,
23 roots::{SourceRoot, ReadonlySourceRoot, WritableSourceRoot},
24 descriptors::{FnDescriptor, ModuleTreeDescriptor, Problem}, 20 descriptors::{FnDescriptor, ModuleTreeDescriptor, Problem},
21 roots::{ReadonlySourceRoot, SourceRoot, WritableSourceRoot},
22 CrateGraph, CrateId, Diagnostic, FileId, FileResolver, FileSystemEdit, JobToken, Position,
23 Query, SourceChange, SourceFileEdit,
25}; 24};
26 25
27#[derive(Clone, Debug)] 26#[derive(Clone, Debug)]
28pub(crate) struct FileResolverImp { 27pub(crate) struct FileResolverImp {
29 inner: Arc<FileResolver> 28 inner: Arc<FileResolver>,
30} 29}
31 30
32impl PartialEq for FileResolverImp { 31impl PartialEq for FileResolverImp {
@@ -35,8 +34,7 @@ impl PartialEq for FileResolverImp {
35 } 34 }
36} 35}
37 36
38impl Eq for FileResolverImp { 37impl Eq for FileResolverImp {}
39}
40 38
41impl Hash for FileResolverImp { 39impl Hash for FileResolverImp {
42 fn hash<H: Hasher>(&self, hasher: &mut H) { 40 fn hash<H: Hasher>(&self, hasher: &mut H) {
@@ -67,17 +65,23 @@ impl Default for FileResolverImp {
67 fn file_stem(&self, _file_: FileId) -> String { 65 fn file_stem(&self, _file_: FileId) -> String {
68 panic!("file resolver not set") 66 panic!("file resolver not set")
69 } 67 }
70 fn resolve(&self, _file_id: FileId, _path: &::relative_path::RelativePath) -> Option<FileId> { 68 fn resolve(
69 &self,
70 _file_id: FileId,
71 _path: &::relative_path::RelativePath,
72 ) -> Option<FileId> {
71 panic!("file resolver not set") 73 panic!("file resolver not set")
72 } 74 }
73 } 75 }
74 FileResolverImp { inner: Arc::new(DummyResolver) } 76 FileResolverImp {
77 inner: Arc::new(DummyResolver),
78 }
75 } 79 }
76} 80}
77 81
78#[derive(Debug)] 82#[derive(Debug)]
79pub(crate) struct AnalysisHostImpl { 83pub(crate) struct AnalysisHostImpl {
80 data: WorldData 84 data: WorldData,
81} 85}
82 86
83impl AnalysisHostImpl { 87impl AnalysisHostImpl {
@@ -91,13 +95,13 @@ impl AnalysisHostImpl {
91 data: self.data.clone(), 95 data: self.data.clone(),
92 } 96 }
93 } 97 }
94 pub fn change_files(&mut self, changes: &mut dyn Iterator<Item=(FileId, Option<String>)>) { 98 pub fn change_files(&mut self, changes: &mut dyn Iterator<Item = (FileId, Option<String>)>) {
95 self.data_mut() 99 self.data_mut().root.apply_changes(changes, None);
96 .root.apply_changes(changes, None);
97 } 100 }
98 pub fn set_file_resolver(&mut self, resolver: FileResolverImp) { 101 pub fn set_file_resolver(&mut self, resolver: FileResolverImp) {
99 self.data_mut() 102 self.data_mut()
100 .root.apply_changes(&mut iter::empty(), Some(resolver)); 103 .root
104 .apply_changes(&mut iter::empty(), Some(resolver));
101 } 105 }
102 pub fn set_crate_graph(&mut self, graph: CrateGraph) { 106 pub fn set_crate_graph(&mut self, graph: CrateGraph) {
103 let mut visited = FxHashSet::default(); 107 let mut visited = FxHashSet::default();
@@ -131,7 +135,12 @@ impl AnalysisImpl {
131 if self.data.root.contains(file_id) { 135 if self.data.root.contains(file_id) {
132 return &self.data.root; 136 return &self.data.root;
133 } 137 }
134 &**self.data.libs.iter().find(|it| it.contains(file_id)).unwrap() 138 &**self
139 .data
140 .libs
141 .iter()
142 .find(|it| it.contains(file_id))
143 .unwrap()
135 } 144 }
136 pub fn file_syntax(&self, file_id: FileId) -> File { 145 pub fn file_syntax(&self, file_id: FileId) -> File {
137 self.root(file_id).syntax(file_id) 146 self.root(file_id).syntax(file_id)
@@ -142,18 +151,17 @@ impl AnalysisImpl {
142 pub fn world_symbols(&self, query: Query, token: &JobToken) -> Vec<(FileId, FileSymbol)> { 151 pub fn world_symbols(&self, query: Query, token: &JobToken) -> Vec<(FileId, FileSymbol)> {
143 let mut buf = Vec::new(); 152 let mut buf = Vec::new();
144 if query.libs { 153 if query.libs {
145 self.data.libs.iter() 154 self.data.libs.iter().for_each(|it| it.symbols(&mut buf));
146 .for_each(|it| it.symbols(&mut buf));
147 } else { 155 } else {
148 self.data.root.symbols(&mut buf); 156 self.data.root.symbols(&mut buf);
149 } 157 }
150 query.search(&buf, token) 158 query.search(&buf, token)
151
152 } 159 }
153 pub fn parent_module(&self, file_id: FileId) -> Vec<(FileId, FileSymbol)> { 160 pub fn parent_module(&self, file_id: FileId) -> Vec<(FileId, FileSymbol)> {
154 let root = self.root(file_id); 161 let root = self.root(file_id);
155 let module_tree = root.module_tree(); 162 let module_tree = root.module_tree();
156 module_tree.parent_modules(file_id) 163 module_tree
164 .parent_modules(file_id)
157 .iter() 165 .iter()
158 .map(|link| { 166 .map(|link| {
159 let file_id = link.owner(&module_tree); 167 let file_id = link.owner(&module_tree);
@@ -203,15 +211,17 @@ impl AnalysisImpl {
203 let file = root.syntax(file_id); 211 let file = root.syntax(file_id);
204 let syntax = file.syntax(); 212 let syntax = file.syntax();
205 if let Some(name_ref) = find_node_at_offset::<ast::NameRef>(syntax, offset) { 213 if let Some(name_ref) = find_node_at_offset::<ast::NameRef>(syntax, offset) {
206
207 // First try to resolve the symbol locally 214 // First try to resolve the symbol locally
208 if let Some((name, range)) = resolve_local_name(&file, offset, name_ref) { 215 if let Some((name, range)) = resolve_local_name(&file, offset, name_ref) {
209 let mut vec = vec![]; 216 let mut vec = vec![];
210 vec.push((file_id, FileSymbol { 217 vec.push((
211 name, 218 file_id,
212 node_range: range, 219 FileSymbol {
213 kind : NAME 220 name,
214 })); 221 node_range: range,
222 kind: NAME,
223 },
224 ));
215 225
216 return vec; 226 return vec;
217 } else { 227 } else {
@@ -224,17 +234,21 @@ impl AnalysisImpl {
224 if module.has_semi() { 234 if module.has_semi() {
225 let file_ids = self.resolve_module(&*module_tree, file_id, module); 235 let file_ids = self.resolve_module(&*module_tree, file_id, module);
226 236
227 let res = file_ids.into_iter().map(|id| { 237 let res = file_ids
228 let name = module.name() 238 .into_iter()
229 .map(|n| n.text()) 239 .map(|id| {
230 .unwrap_or_else(|| SmolStr::new("")); 240 let name = module
231 let symbol = FileSymbol { 241 .name()
232 name, 242 .map(|n| n.text())
233 node_range: TextRange::offset_len(0.into(), 0.into()), 243 .unwrap_or_else(|| SmolStr::new(""));
234 kind: MODULE, 244 let symbol = FileSymbol {
235 }; 245 name,
236 (id, symbol) 246 node_range: TextRange::offset_len(0.into(), 0.into()),
237 }).collect(); 247 kind: MODULE,
248 };
249 (id, symbol)
250 })
251 .collect();
238 252
239 return res; 253 return res;
240 } 254 }
@@ -245,12 +259,16 @@ impl AnalysisImpl {
245 259
246 pub fn diagnostics(&self, file_id: FileId) -> Vec<Diagnostic> { 260 pub fn diagnostics(&self, file_id: FileId) -> Vec<Diagnostic> {
247 let root = self.root(file_id); 261 let root = self.root(file_id);
248 let module_tree = root.module_tree(); 262 let module_tree = root.module_tree();
249 let syntax = root.syntax(file_id); 263 let syntax = root.syntax(file_id);
250 264
251 let mut res = ra_editor::diagnostics(&syntax) 265 let mut res = ra_editor::diagnostics(&syntax)
252 .into_iter() 266 .into_iter()
253 .map(|d| Diagnostic { range: d.range, message: d.msg, fix: None }) 267 .map(|d| Diagnostic {
268 range: d.range,
269 message: d.msg,
270 fix: None,
271 })
254 .collect::<Vec<_>>(); 272 .collect::<Vec<_>>();
255 273
256 for (name_node, problem) in module_tree.problems(file_id, syntax.ast()) { 274 for (name_node, problem) in module_tree.problems(file_id, syntax.ast()) {
@@ -273,8 +291,14 @@ impl AnalysisImpl {
273 } 291 }
274 } 292 }
275 Problem::NotDirOwner { move_to, candidate } => { 293 Problem::NotDirOwner { move_to, candidate } => {
276 let move_file = FileSystemEdit::MoveFile { file: file_id, path: move_to.clone() }; 294 let move_file = FileSystemEdit::MoveFile {
277 let create_file = FileSystemEdit::CreateFile { anchor: file_id, path: move_to.join(candidate) }; 295 file: file_id,
296 path: move_to.clone(),
297 };
298 let create_file = FileSystemEdit::CreateFile {
299 anchor: file_id,
300 path: move_to.join(candidate),
301 };
278 let fix = SourceChange { 302 let fix = SourceChange {
279 label: "move file and create module".to_string(), 303 label: "move file and create module".to_string(),
280 source_file_edits: Vec::new(), 304 source_file_edits: Vec::new(),
@@ -297,23 +321,34 @@ impl AnalysisImpl {
297 let file = self.file_syntax(file_id); 321 let file = self.file_syntax(file_id);
298 let offset = range.start(); 322 let offset = range.start();
299 let actions = vec![ 323 let actions = vec![
300 ("flip comma", ra_editor::flip_comma(&file, offset).map(|f| f())), 324 (
301 ("add `#[derive]`", ra_editor::add_derive(&file, offset).map(|f| f())), 325 "flip comma",
326 ra_editor::flip_comma(&file, offset).map(|f| f()),
327 ),
328 (
329 "add `#[derive]`",
330 ra_editor::add_derive(&file, offset).map(|f| f()),
331 ),
302 ("add impl", ra_editor::add_impl(&file, offset).map(|f| f())), 332 ("add impl", ra_editor::add_impl(&file, offset).map(|f| f())),
303 ("introduce variable", ra_editor::introduce_variable(&file, range).map(|f| f())), 333 (
334 "introduce variable",
335 ra_editor::introduce_variable(&file, range).map(|f| f()),
336 ),
304 ]; 337 ];
305 actions.into_iter() 338 actions
339 .into_iter()
306 .filter_map(|(name, local_edit)| { 340 .filter_map(|(name, local_edit)| {
307 Some(SourceChange::from_local_edit( 341 Some(SourceChange::from_local_edit(file_id, name, local_edit?))
308 file_id, name, local_edit?,
309 ))
310 }) 342 })
311 .collect() 343 .collect()
312 } 344 }
313 345
314 pub fn resolve_callable(&self, file_id: FileId, offset: TextUnit, token: &JobToken) 346 pub fn resolve_callable(
315 -> Option<(FnDescriptor, Option<usize>)> { 347 &self,
316 348 file_id: FileId,
349 offset: TextUnit,
350 token: &JobToken,
351 ) -> Option<(FnDescriptor, Option<usize>)> {
317 let root = self.root(file_id); 352 let root = self.root(file_id);
318 let file = root.syntax(file_id); 353 let file = root.syntax(file_id);
319 let syntax = file.syntax(); 354 let syntax = file.syntax();
@@ -332,9 +367,7 @@ impl AnalysisImpl {
332 let mut current_parameter = None; 367 let mut current_parameter = None;
333 368
334 let num_params = descriptor.params.len(); 369 let num_params = descriptor.params.len();
335 let has_self = fn_def.param_list() 370 let has_self = fn_def.param_list().and_then(|l| l.self_param()).is_some();
336 .and_then(|l| l.self_param())
337 .is_some();
338 371
339 if num_params == 1 { 372 if num_params == 1 {
340 if !has_self { 373 if !has_self {
@@ -350,8 +383,11 @@ impl AnalysisImpl {
350 let start = arg_list.syntax().range().start(); 383 let start = arg_list.syntax().range().start();
351 384
352 let range_search = TextRange::from_to(start, offset); 385 let range_search = TextRange::from_to(start, offset);
353 let mut commas: usize = arg_list.syntax().text() 386 let mut commas: usize = arg_list
354 .slice(range_search).to_string() 387 .syntax()
388 .text()
389 .slice(range_search)
390 .to_string()
355 .matches(",") 391 .matches(",")
356 .count(); 392 .count();
357 393
@@ -381,7 +417,12 @@ impl AnalysisImpl {
381 self.world_symbols(query, token) 417 self.world_symbols(query, token)
382 } 418 }
383 419
384 fn resolve_module(&self, module_tree: &ModuleTreeDescriptor, file_id: FileId, module: ast::Module) -> Vec<FileId> { 420 fn resolve_module(
421 &self,
422 module_tree: &ModuleTreeDescriptor,
423 file_id: FileId,
424 module: ast::Module,
425 ) -> Vec<FileId> {
385 let name = match module.name() { 426 let name = match module.name() {
386 Some(name) => name.text(), 427 Some(name) => name.text(),
387 None => return Vec::new(), 428 None => return Vec::new(),
@@ -407,15 +448,17 @@ impl SourceChange {
407 label: label.to_string(), 448 label: label.to_string(),
408 source_file_edits: vec![file_edit], 449 source_file_edits: vec![file_edit],
409 file_system_edits: vec![], 450 file_system_edits: vec![],
410 cursor_position: edit.cursor_position 451 cursor_position: edit
411 .map(|offset| Position { offset, file_id }) 452 .cursor_position
453 .map(|offset| Position { offset, file_id }),
412 } 454 }
413 } 455 }
414} 456}
415 457
416impl CrateGraph { 458impl CrateGraph {
417 fn crate_id_for_crate_root(&self, file_id: FileId) -> Option<CrateId> { 459 fn crate_id_for_crate_root(&self, file_id: FileId) -> Option<CrateId> {
418 let (&crate_id, _) = self.crate_roots 460 let (&crate_id, _) = self
461 .crate_roots
419 .iter() 462 .iter()
420 .find(|(_crate_id, &root_id)| root_id == file_id)?; 463 .find(|(_crate_id, &root_id)| root_id == file_id)?;
421 Some(crate_id) 464 Some(crate_id)
@@ -424,7 +467,7 @@ impl CrateGraph {
424 467
425enum FnCallNode<'a> { 468enum FnCallNode<'a> {
426 CallExpr(ast::CallExpr<'a>), 469 CallExpr(ast::CallExpr<'a>),
427 MethodCallExpr(ast::MethodCallExpr<'a>) 470 MethodCallExpr(ast::MethodCallExpr<'a>),
428} 471}
429 472
430impl<'a> FnCallNode<'a> { 473impl<'a> FnCallNode<'a> {
@@ -440,27 +483,23 @@ impl<'a> FnCallNode<'a> {
440 483
441 pub fn name_ref(&self) -> Option<ast::NameRef> { 484 pub fn name_ref(&self) -> Option<ast::NameRef> {
442 match *self { 485 match *self {
443 FnCallNode::CallExpr(call_expr) => { 486 FnCallNode::CallExpr(call_expr) => Some(match call_expr.expr()? {
444 Some(match call_expr.expr()? { 487 Expr::PathExpr(path_expr) => path_expr.path()?.segment()?.name_ref()?,
445 Expr::PathExpr(path_expr) => { 488 _ => return None,
446 path_expr.path()?.segment()?.name_ref()? 489 }),
447 }, 490
448 _ => return None 491 FnCallNode::MethodCallExpr(call_expr) => call_expr
449 }) 492 .syntax()
450 }, 493 .children()
451 494 .filter_map(ast::NameRef::cast)
452 FnCallNode::MethodCallExpr(call_expr) => { 495 .nth(0),
453 call_expr.syntax().children()
454 .filter_map(ast::NameRef::cast)
455 .nth(0)
456 }
457 } 496 }
458 } 497 }
459 498
460 pub fn arg_list(&self) -> Option<ast::ArgList> { 499 pub fn arg_list(&self) -> Option<ast::ArgList> {
461 match *self { 500 match *self {
462 FnCallNode::CallExpr(expr) => expr.arg_list(), 501 FnCallNode::CallExpr(expr) => expr.arg_list(),
463 FnCallNode::MethodCallExpr(expr) => expr.arg_list() 502 FnCallNode::MethodCallExpr(expr) => expr.arg_list(),
464 } 503 }
465 } 504 }
466} 505}