aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide/src/call_hierarchy.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_ide/src/call_hierarchy.rs')
-rw-r--r--crates/ra_ide/src/call_hierarchy.rs52
1 files changed, 22 insertions, 30 deletions
diff --git a/crates/ra_ide/src/call_hierarchy.rs b/crates/ra_ide/src/call_hierarchy.rs
index f984f40ad..b00b6d431 100644
--- a/crates/ra_ide/src/call_hierarchy.rs
+++ b/crates/ra_ide/src/call_hierarchy.rs
@@ -2,18 +2,13 @@
2 2
3use indexmap::IndexMap; 3use indexmap::IndexMap;
4 4
5use hir::db::AstDatabase; 5use hir::Semantics;
6use ra_ide_db::RootDatabase; 6use ra_ide_db::RootDatabase;
7use ra_syntax::{ 7use ra_syntax::{ast, match_ast, AstNode, TextRange};
8 ast::{self, DocCommentsOwner},
9 match_ast, AstNode, TextRange,
10};
11 8
12use crate::{ 9use crate::{
13 call_info::FnCallNode, 10 call_info::FnCallNode, display::ToNav, goto_definition, references, FilePosition,
14 display::{ShortLabel, ToNav}, 11 NavigationTarget, RangeInfo,
15 expand::descend_into_macros,
16 goto_definition, references, FilePosition, NavigationTarget, RangeInfo,
17}; 12};
18 13
19#[derive(Debug, Clone)] 14#[derive(Debug, Clone)]
@@ -43,6 +38,7 @@ pub(crate) fn call_hierarchy(
43} 38}
44 39
45pub(crate) fn incoming_calls(db: &RootDatabase, position: FilePosition) -> Option<Vec<CallItem>> { 40pub(crate) fn incoming_calls(db: &RootDatabase, position: FilePosition) -> Option<Vec<CallItem>> {
41 let sema = Semantics::new(db);
46 // 1. Find all refs 42 // 1. Find all refs
47 // 2. Loop through refs and determine unique fndef. This will become our `from: CallHierarchyItem,` in the reply. 43 // 2. Loop through refs and determine unique fndef. This will become our `from: CallHierarchyItem,` in the reply.
48 // 3. Add ranges relative to the start of the fndef. 44 // 3. Add ranges relative to the start of the fndef.
@@ -52,24 +48,21 @@ pub(crate) fn incoming_calls(db: &RootDatabase, position: FilePosition) -> Optio
52 48
53 for reference in refs.info.references() { 49 for reference in refs.info.references() {
54 let file_id = reference.file_range.file_id; 50 let file_id = reference.file_range.file_id;
55 let file = db.parse_or_expand(file_id.into())?; 51 let file = sema.parse(file_id);
52 let file = file.syntax();
56 let token = file.token_at_offset(reference.file_range.range.start()).next()?; 53 let token = file.token_at_offset(reference.file_range.range.start()).next()?;
57 let token = descend_into_macros(db, file_id, token); 54 let token = sema.descend_into_macros(token);
58 let syntax = token.value.parent(); 55 let syntax = token.parent();
59 56
60 // This target is the containing function 57 // This target is the containing function
61 if let Some(nav) = syntax.ancestors().find_map(|node| { 58 if let Some(nav) = syntax.ancestors().find_map(|node| {
62 match_ast! { 59 match_ast! {
63 match node { 60 match node {
64 ast::FnDef(it) => { 61 ast::FnDef(it) => {
65 Some(NavigationTarget::from_named( 62 let def = sema.to_def(&it)?;
66 db, 63 Some(def.to_nav(sema.db))
67 token.with_value(&it),
68 it.doc_comment_text(),
69 it.short_label(),
70 ))
71 }, 64 },
72 _ => { None }, 65 _ => None,
73 } 66 }
74 } 67 }
75 }) { 68 }) {
@@ -82,11 +75,13 @@ pub(crate) fn incoming_calls(db: &RootDatabase, position: FilePosition) -> Optio
82} 75}
83 76
84pub(crate) fn outgoing_calls(db: &RootDatabase, position: FilePosition) -> Option<Vec<CallItem>> { 77pub(crate) fn outgoing_calls(db: &RootDatabase, position: FilePosition) -> Option<Vec<CallItem>> {
78 let sema = Semantics::new(db);
85 let file_id = position.file_id; 79 let file_id = position.file_id;
86 let file = db.parse_or_expand(file_id.into())?; 80 let file = sema.parse(file_id);
81 let file = file.syntax();
87 let token = file.token_at_offset(position.offset).next()?; 82 let token = file.token_at_offset(position.offset).next()?;
88 let token = descend_into_macros(db, file_id, token); 83 let token = sema.descend_into_macros(token);
89 let syntax = token.value.parent(); 84 let syntax = token.parent();
90 85
91 let mut calls = CallLocations::default(); 86 let mut calls = CallLocations::default();
92 87
@@ -95,14 +90,11 @@ pub(crate) fn outgoing_calls(db: &RootDatabase, position: FilePosition) -> Optio
95 .filter_map(|node| FnCallNode::with_node_exact(&node)) 90 .filter_map(|node| FnCallNode::with_node_exact(&node))
96 .filter_map(|call_node| { 91 .filter_map(|call_node| {
97 let name_ref = call_node.name_ref()?; 92 let name_ref = call_node.name_ref()?;
98 let name_ref = token.with_value(name_ref.syntax());
99
100 let analyzer = hir::SourceAnalyzer::new(db, name_ref, None);
101 93
102 if let Some(func_target) = match &call_node { 94 if let Some(func_target) = match &call_node {
103 FnCallNode::CallExpr(expr) => { 95 FnCallNode::CallExpr(expr) => {
104 //FIXME: Type::as_callable is broken 96 //FIXME: Type::as_callable is broken
105 let callable_def = analyzer.type_of(db, &expr.expr()?)?.as_callable()?; 97 let callable_def = sema.type_of_expr(&expr.expr()?)?.as_callable()?;
106 match callable_def { 98 match callable_def {
107 hir::CallableDef::FunctionId(it) => { 99 hir::CallableDef::FunctionId(it) => {
108 let fn_def: hir::Function = it.into(); 100 let fn_def: hir::Function = it.into();
@@ -113,15 +105,15 @@ pub(crate) fn outgoing_calls(db: &RootDatabase, position: FilePosition) -> Optio
113 } 105 }
114 } 106 }
115 FnCallNode::MethodCallExpr(expr) => { 107 FnCallNode::MethodCallExpr(expr) => {
116 let function = analyzer.resolve_method_call(&expr)?; 108 let function = sema.resolve_method_call(&expr)?;
117 Some(function.to_nav(db)) 109 Some(function.to_nav(db))
118 } 110 }
119 FnCallNode::MacroCallExpr(expr) => { 111 FnCallNode::MacroCallExpr(macro_call) => {
120 let macro_def = analyzer.resolve_macro_call(db, name_ref.with_value(&expr))?; 112 let macro_def = sema.resolve_macro_call(&macro_call)?;
121 Some(macro_def.to_nav(db)) 113 Some(macro_def.to_nav(db))
122 } 114 }
123 } { 115 } {
124 Some((func_target, name_ref.value.text_range())) 116 Some((func_target, name_ref.syntax().text_range()))
125 } else { 117 } else {
126 None 118 None
127 } 119 }