diff options
Diffstat (limited to 'crates/ra_analysis/src/imp.rs')
-rw-r--r-- | crates/ra_analysis/src/imp.rs | 78 |
1 files changed, 36 insertions, 42 deletions
diff --git a/crates/ra_analysis/src/imp.rs b/crates/ra_analysis/src/imp.rs index 704648b59..f2482559f 100644 --- a/crates/ra_analysis/src/imp.rs +++ b/crates/ra_analysis/src/imp.rs | |||
@@ -27,7 +27,7 @@ use crate::{ | |||
27 | input::{FilesDatabase, SourceRoot, SourceRootId, WORKSPACE}, | 27 | input::{FilesDatabase, SourceRoot, SourceRootId, WORKSPACE}, |
28 | symbol_index::SymbolIndex, | 28 | symbol_index::SymbolIndex, |
29 | AnalysisChange, Cancelable, CrateGraph, CrateId, Diagnostic, FileId, FileResolver, | 29 | AnalysisChange, Cancelable, CrateGraph, CrateId, Diagnostic, FileId, FileResolver, |
30 | FileSystemEdit, Position, Query, SourceChange, SourceFileEdit, | 30 | FileSystemEdit, FilePosition, Query, SourceChange, SourceFileEdit, |
31 | }; | 31 | }; |
32 | 32 | ||
33 | #[derive(Clone, Debug)] | 33 | #[derive(Clone, Debug)] |
@@ -220,16 +220,13 @@ 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( | 223 | pub fn parent_module(&self, position: FilePosition) -> Cancelable<Vec<(FileId, FileSymbol)>> { |
224 | &self, | 224 | let module_tree = self.module_tree(position.file_id)?; |
225 | file_id: FileId, | 225 | let file = self.db.file_syntax(position.file_id); |
226 | offset: TextUnit, | 226 | let module_source = match find_node_at_offset::<ast::Module>(file.syntax(), position.offset) |
227 | ) -> Cancelable<Vec<(FileId, FileSymbol)>> { | 227 | { |
228 | let module_tree = self.module_tree(file_id)?; | 228 | Some(m) if !m.has_semi() => ModuleSource::new_inline(position.file_id, m), |
229 | let file = self.db.file_syntax(file_id); | 229 | _ => ModuleSource::File(position.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 | }; | 230 | }; |
234 | 231 | ||
235 | let res = module_tree | 232 | let res = module_tree |
@@ -269,18 +266,14 @@ impl AnalysisImpl { | |||
269 | pub fn crate_root(&self, crate_id: CrateId) -> FileId { | 266 | pub fn crate_root(&self, crate_id: CrateId) -> FileId { |
270 | self.db.crate_graph().crate_roots[&crate_id] | 267 | self.db.crate_graph().crate_roots[&crate_id] |
271 | } | 268 | } |
272 | pub fn completions( | 269 | pub fn completions(&self, position: FilePosition) -> Cancelable<Option<Vec<CompletionItem>>> { |
273 | &self, | ||
274 | file_id: FileId, | ||
275 | offset: TextUnit, | ||
276 | ) -> Cancelable<Option<Vec<CompletionItem>>> { | ||
277 | let mut res = Vec::new(); | 270 | let mut res = Vec::new(); |
278 | let mut has_completions = false; | 271 | let mut has_completions = false; |
279 | if let Some(scope_based) = scope_completion(&self.db, file_id, offset) { | 272 | if let Some(scope_based) = scope_completion(&self.db, position) { |
280 | res.extend(scope_based); | 273 | res.extend(scope_based); |
281 | has_completions = true; | 274 | has_completions = true; |
282 | } | 275 | } |
283 | if let Some(scope_based) = resolve_based_completion(&self.db, file_id, offset)? { | 276 | if let Some(scope_based) = resolve_based_completion(&self.db, position)? { |
284 | res.extend(scope_based); | 277 | res.extend(scope_based); |
285 | has_completions = true; | 278 | has_completions = true; |
286 | } | 279 | } |
@@ -289,18 +282,19 @@ impl AnalysisImpl { | |||
289 | } | 282 | } |
290 | pub fn approximately_resolve_symbol( | 283 | pub fn approximately_resolve_symbol( |
291 | &self, | 284 | &self, |
292 | file_id: FileId, | 285 | position: FilePosition, |
293 | offset: TextUnit, | ||
294 | ) -> Cancelable<Vec<(FileId, FileSymbol)>> { | 286 | ) -> Cancelable<Vec<(FileId, FileSymbol)>> { |
295 | let module_tree = self.module_tree(file_id)?; | 287 | let module_tree = self.module_tree(position.file_id)?; |
296 | let file = self.db.file_syntax(file_id); | 288 | let file = self.db.file_syntax(position.file_id); |
297 | let syntax = file.syntax(); | 289 | let syntax = file.syntax(); |
298 | if let Some(name_ref) = find_node_at_offset::<ast::NameRef>(syntax, offset) { | 290 | if let Some(name_ref) = find_node_at_offset::<ast::NameRef>(syntax, position.offset) { |
299 | // First try to resolve the symbol locally | 291 | // First try to resolve the symbol locally |
300 | return if let Some((name, range)) = resolve_local_name(&self.db, file_id, name_ref) { | 292 | return if let Some((name, range)) = |
293 | resolve_local_name(&self.db, position.file_id, name_ref) | ||
294 | { | ||
301 | let mut vec = vec![]; | 295 | let mut vec = vec![]; |
302 | vec.push(( | 296 | vec.push(( |
303 | file_id, | 297 | position.file_id, |
304 | FileSymbol { | 298 | FileSymbol { |
305 | name, | 299 | name, |
306 | node_range: range, | 300 | node_range: range, |
@@ -313,10 +307,10 @@ impl AnalysisImpl { | |||
313 | self.index_resolve(name_ref) | 307 | self.index_resolve(name_ref) |
314 | }; | 308 | }; |
315 | } | 309 | } |
316 | if let Some(name) = find_node_at_offset::<ast::Name>(syntax, offset) { | 310 | if let Some(name) = find_node_at_offset::<ast::Name>(syntax, position.offset) { |
317 | if let Some(module) = name.syntax().parent().and_then(ast::Module::cast) { | 311 | if let Some(module) = name.syntax().parent().and_then(ast::Module::cast) { |
318 | if module.has_semi() { | 312 | if module.has_semi() { |
319 | let file_ids = self.resolve_module(&*module_tree, file_id, module); | 313 | let file_ids = self.resolve_module(&*module_tree, position.file_id, module); |
320 | 314 | ||
321 | let res = file_ids | 315 | let res = file_ids |
322 | .into_iter() | 316 | .into_iter() |
@@ -341,16 +335,17 @@ impl AnalysisImpl { | |||
341 | Ok(vec![]) | 335 | Ok(vec![]) |
342 | } | 336 | } |
343 | 337 | ||
344 | pub fn find_all_refs(&self, file_id: FileId, offset: TextUnit) -> Vec<(FileId, TextRange)> { | 338 | pub fn find_all_refs(&self, position: FilePosition) -> Vec<(FileId, TextRange)> { |
345 | let file = self.db.file_syntax(file_id); | 339 | let file = self.db.file_syntax(position.file_id); |
346 | let syntax = file.syntax(); | 340 | let syntax = file.syntax(); |
347 | 341 | ||
348 | // Find the binding associated with the offset | 342 | // Find the binding associated with the offset |
349 | let maybe_binding = find_node_at_offset::<ast::BindPat>(syntax, offset).or_else(|| { | 343 | let maybe_binding = |
350 | let name_ref = find_node_at_offset::<ast::NameRef>(syntax, offset)?; | 344 | find_node_at_offset::<ast::BindPat>(syntax, position.offset).or_else(|| { |
351 | let resolved = resolve_local_name(&self.db, file_id, name_ref)?; | 345 | let name_ref = find_node_at_offset::<ast::NameRef>(syntax, position.offset)?; |
352 | find_node_at_offset::<ast::BindPat>(syntax, resolved.1.end()) | 346 | let resolved = resolve_local_name(&self.db, position.file_id, name_ref)?; |
353 | }); | 347 | find_node_at_offset::<ast::BindPat>(syntax, resolved.1.end()) |
348 | }); | ||
354 | 349 | ||
355 | let binding = match maybe_binding { | 350 | let binding = match maybe_binding { |
356 | None => return Vec::new(), | 351 | None => return Vec::new(), |
@@ -359,11 +354,11 @@ impl AnalysisImpl { | |||
359 | 354 | ||
360 | let decl = DeclarationDescriptor::new(binding); | 355 | let decl = DeclarationDescriptor::new(binding); |
361 | 356 | ||
362 | let mut ret = vec![(file_id, decl.range)]; | 357 | let mut ret = vec![(position.file_id, decl.range)]; |
363 | ret.extend( | 358 | ret.extend( |
364 | decl.find_all_refs() | 359 | decl.find_all_refs() |
365 | .into_iter() | 360 | .into_iter() |
366 | .map(|ref_desc| (file_id, ref_desc.range)), | 361 | .map(|ref_desc| (position.file_id, ref_desc.range)), |
367 | ); | 362 | ); |
368 | 363 | ||
369 | ret | 364 | ret |
@@ -457,14 +452,13 @@ impl AnalysisImpl { | |||
457 | 452 | ||
458 | pub fn resolve_callable( | 453 | pub fn resolve_callable( |
459 | &self, | 454 | &self, |
460 | file_id: FileId, | 455 | position: FilePosition, |
461 | offset: TextUnit, | ||
462 | ) -> Cancelable<Option<(FnDescriptor, Option<usize>)>> { | 456 | ) -> Cancelable<Option<(FnDescriptor, Option<usize>)>> { |
463 | let file = self.db.file_syntax(file_id); | 457 | let file = self.db.file_syntax(position.file_id); |
464 | let syntax = file.syntax(); | 458 | let syntax = file.syntax(); |
465 | 459 | ||
466 | // Find the calling expression and it's NameRef | 460 | // Find the calling expression and it's NameRef |
467 | let calling_node = match FnCallNode::with_node(syntax, offset) { | 461 | let calling_node = match FnCallNode::with_node(syntax, position.offset) { |
468 | Some(node) => node, | 462 | Some(node) => node, |
469 | None => return Ok(None), | 463 | None => return Ok(None), |
470 | }; | 464 | }; |
@@ -499,7 +493,7 @@ impl AnalysisImpl { | |||
499 | if let Some(ref arg_list) = calling_node.arg_list() { | 493 | if let Some(ref arg_list) = calling_node.arg_list() { |
500 | let start = arg_list.syntax().range().start(); | 494 | let start = arg_list.syntax().range().start(); |
501 | 495 | ||
502 | let range_search = TextRange::from_to(start, offset); | 496 | let range_search = TextRange::from_to(start, position.offset); |
503 | let mut commas: usize = arg_list | 497 | let mut commas: usize = arg_list |
504 | .syntax() | 498 | .syntax() |
505 | .text() | 499 | .text() |
@@ -568,7 +562,7 @@ impl SourceChange { | |||
568 | file_system_edits: vec![], | 562 | file_system_edits: vec![], |
569 | cursor_position: edit | 563 | cursor_position: edit |
570 | .cursor_position | 564 | .cursor_position |
571 | .map(|offset| Position { offset, file_id }), | 565 | .map(|offset| FilePosition { offset, file_id }), |
572 | } | 566 | } |
573 | } | 567 | } |
574 | } | 568 | } |