diff options
author | Aleksey Kladov <[email protected]> | 2019-01-08 15:16:26 +0000 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2019-01-08 15:16:26 +0000 |
commit | e6a4383bb475b866b67df6bb83ecbdf823d73667 (patch) | |
tree | 6dbf7da77cd26e44597c40d1b5c802c552007ae8 /crates/ra_analysis/src/imp.rs | |
parent | 2f07976cb51f7be216678f410175ba4c09bc7e71 (diff) |
move call-info to a separate file
Diffstat (limited to 'crates/ra_analysis/src/imp.rs')
-rw-r--r-- | crates/ra_analysis/src/imp.rs | 114 |
1 files changed, 3 insertions, 111 deletions
diff --git a/crates/ra_analysis/src/imp.rs b/crates/ra_analysis/src/imp.rs index 98554dd4c..b3f75fdbe 100644 --- a/crates/ra_analysis/src/imp.rs +++ b/crates/ra_analysis/src/imp.rs | |||
@@ -3,13 +3,13 @@ use std::sync::Arc; | |||
3 | use salsa::Database; | 3 | use salsa::Database; |
4 | 4 | ||
5 | use hir::{ | 5 | use hir::{ |
6 | self, FnSignatureInfo, Problem, source_binder, | 6 | self, Problem, source_binder, |
7 | }; | 7 | }; |
8 | use ra_db::{FilesDatabase, SourceRoot, SourceRootId, SyntaxDatabase}; | 8 | use ra_db::{FilesDatabase, SourceRoot, SourceRootId, SyntaxDatabase}; |
9 | use ra_editor::{self, find_node_at_offset, assists, LocalEdit, Severity}; | 9 | use ra_editor::{self, find_node_at_offset, assists, LocalEdit, Severity}; |
10 | use ra_syntax::{ | 10 | use ra_syntax::{ |
11 | SyntaxNode, TextRange, TextUnit, AstNode, SourceFile, | 11 | TextRange, AstNode, SourceFile, |
12 | ast::{self, ArgListOwner, NameOwner}, | 12 | ast::{self, NameOwner}, |
13 | SyntaxKind::*, | 13 | SyntaxKind::*, |
14 | }; | 14 | }; |
15 | 15 | ||
@@ -262,75 +262,6 @@ impl db::RootDatabase { | |||
262 | .collect() | 262 | .collect() |
263 | } | 263 | } |
264 | 264 | ||
265 | pub(crate) fn resolve_callable( | ||
266 | &self, | ||
267 | position: FilePosition, | ||
268 | ) -> Cancelable<Option<(FnSignatureInfo, Option<usize>)>> { | ||
269 | let file = self.source_file(position.file_id); | ||
270 | let syntax = file.syntax(); | ||
271 | |||
272 | // Find the calling expression and it's NameRef | ||
273 | let calling_node = ctry!(FnCallNode::with_node(syntax, position.offset)); | ||
274 | let name_ref = ctry!(calling_node.name_ref()); | ||
275 | |||
276 | // Resolve the function's NameRef (NOTE: this isn't entirely accurate). | ||
277 | let file_symbols = self.index_resolve(name_ref)?; | ||
278 | for symbol in file_symbols { | ||
279 | if symbol.ptr.kind() == FN_DEF { | ||
280 | let fn_file = self.source_file(symbol.file_id); | ||
281 | let fn_def = symbol.ptr.resolve(&fn_file); | ||
282 | let fn_def = ast::FnDef::cast(&fn_def).unwrap(); | ||
283 | let descr = ctry!(source_binder::function_from_source( | ||
284 | self, | ||
285 | symbol.file_id, | ||
286 | fn_def | ||
287 | )?); | ||
288 | if let Some(descriptor) = descr.signature_info(self) { | ||
289 | // If we have a calling expression let's find which argument we are on | ||
290 | let mut current_parameter = None; | ||
291 | |||
292 | let num_params = descriptor.params.len(); | ||
293 | let has_self = fn_def.param_list().and_then(|l| l.self_param()).is_some(); | ||
294 | |||
295 | if num_params == 1 { | ||
296 | if !has_self { | ||
297 | current_parameter = Some(0); | ||
298 | } | ||
299 | } else if num_params > 1 { | ||
300 | // Count how many parameters into the call we are. | ||
301 | // TODO: This is best effort for now and should be fixed at some point. | ||
302 | // It may be better to see where we are in the arg_list and then check | ||
303 | // where offset is in that list (or beyond). | ||
304 | // Revisit this after we get documentation comments in. | ||
305 | if let Some(ref arg_list) = calling_node.arg_list() { | ||
306 | let start = arg_list.syntax().range().start(); | ||
307 | |||
308 | let range_search = TextRange::from_to(start, position.offset); | ||
309 | let mut commas: usize = arg_list | ||
310 | .syntax() | ||
311 | .text() | ||
312 | .slice(range_search) | ||
313 | .to_string() | ||
314 | .matches(',') | ||
315 | .count(); | ||
316 | |||
317 | // If we have a method call eat the first param since it's just self. | ||
318 | if has_self { | ||
319 | commas += 1; | ||
320 | } | ||
321 | |||
322 | current_parameter = Some(commas); | ||
323 | } | ||
324 | } | ||
325 | |||
326 | return Ok(Some((descriptor, current_parameter))); | ||
327 | } | ||
328 | } | ||
329 | } | ||
330 | |||
331 | Ok(None) | ||
332 | } | ||
333 | |||
334 | pub(crate) fn rename( | 265 | pub(crate) fn rename( |
335 | &self, | 266 | &self, |
336 | position: FilePosition, | 267 | position: FilePosition, |
@@ -375,42 +306,3 @@ impl SourceChange { | |||
375 | } | 306 | } |
376 | } | 307 | } |
377 | } | 308 | } |
378 | |||
379 | enum FnCallNode<'a> { | ||
380 | CallExpr(&'a ast::CallExpr), | ||
381 | MethodCallExpr(&'a ast::MethodCallExpr), | ||
382 | } | ||
383 | |||
384 | impl<'a> FnCallNode<'a> { | ||
385 | pub fn with_node(syntax: &'a SyntaxNode, offset: TextUnit) -> Option<FnCallNode<'a>> { | ||
386 | if let Some(expr) = find_node_at_offset::<ast::CallExpr>(syntax, offset) { | ||
387 | return Some(FnCallNode::CallExpr(expr)); | ||
388 | } | ||
389 | if let Some(expr) = find_node_at_offset::<ast::MethodCallExpr>(syntax, offset) { | ||
390 | return Some(FnCallNode::MethodCallExpr(expr)); | ||
391 | } | ||
392 | None | ||
393 | } | ||
394 | |||
395 | pub fn name_ref(&self) -> Option<&'a ast::NameRef> { | ||
396 | match *self { | ||
397 | FnCallNode::CallExpr(call_expr) => Some(match call_expr.expr()?.kind() { | ||
398 | ast::ExprKind::PathExpr(path_expr) => path_expr.path()?.segment()?.name_ref()?, | ||
399 | _ => return None, | ||
400 | }), | ||
401 | |||
402 | FnCallNode::MethodCallExpr(call_expr) => call_expr | ||
403 | .syntax() | ||
404 | .children() | ||
405 | .filter_map(ast::NameRef::cast) | ||
406 | .nth(0), | ||
407 | } | ||
408 | } | ||
409 | |||
410 | pub fn arg_list(&self) -> Option<&'a ast::ArgList> { | ||
411 | match *self { | ||
412 | FnCallNode::CallExpr(expr) => expr.arg_list(), | ||
413 | FnCallNode::MethodCallExpr(expr) => expr.arg_list(), | ||
414 | } | ||
415 | } | ||
416 | } | ||