aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_analysis/src/imp.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_analysis/src/imp.rs')
-rw-r--r--crates/ra_analysis/src/imp.rs78
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}