diff options
author | Jeremy A. Kolb <[email protected]> | 2018-10-15 22:44:23 +0100 |
---|---|---|
committer | Jeremy A. Kolb <[email protected]> | 2018-10-16 14:41:10 +0100 |
commit | 61f3a438d3a729a6be941bca1ff4c6a97a33f221 (patch) | |
tree | 6551967cc8c6e921b66071453ad7888a9121d326 /crates/ra_analysis/src/imp.rs | |
parent | 39cb6c6d3f78b193f5873c3492e530bbd24d5dd2 (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.rs | 207 |
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 @@ | |||
1 | use std::{ | 1 | use 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 | ||
11 | use relative_path::RelativePath; | 9 | use ra_editor::{self, find_node_at_offset, resolve_local_name, FileSymbol, LineIndex, LocalEdit}; |
12 | use rustc_hash::FxHashSet; | ||
13 | use ra_editor::{self, FileSymbol, LineIndex, find_node_at_offset, LocalEdit, resolve_local_name}; | ||
14 | use ra_syntax::{ | 10 | use 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 | }; |
16 | use relative_path::RelativePath; | ||
17 | use rustc_hash::FxHashSet; | ||
19 | 18 | ||
20 | use crate::{ | 19 | use 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)] |
28 | pub(crate) struct FileResolverImp { | 27 | pub(crate) struct FileResolverImp { |
29 | inner: Arc<FileResolver> | 28 | inner: Arc<FileResolver>, |
30 | } | 29 | } |
31 | 30 | ||
32 | impl PartialEq for FileResolverImp { | 31 | impl PartialEq for FileResolverImp { |
@@ -35,8 +34,7 @@ impl PartialEq for FileResolverImp { | |||
35 | } | 34 | } |
36 | } | 35 | } |
37 | 36 | ||
38 | impl Eq for FileResolverImp { | 37 | impl Eq for FileResolverImp {} |
39 | } | ||
40 | 38 | ||
41 | impl Hash for FileResolverImp { | 39 | impl 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)] |
79 | pub(crate) struct AnalysisHostImpl { | 83 | pub(crate) struct AnalysisHostImpl { |
80 | data: WorldData | 84 | data: WorldData, |
81 | } | 85 | } |
82 | 86 | ||
83 | impl AnalysisHostImpl { | 87 | impl 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 | ||
416 | impl CrateGraph { | 458 | impl 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 | ||
425 | enum FnCallNode<'a> { | 468 | enum 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 | ||
430 | impl<'a> FnCallNode<'a> { | 473 | impl<'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 | } |