aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_ide/src/call_info.rs76
-rw-r--r--crates/ra_ide/src/display/function_signature.rs107
-rw-r--r--crates/ra_ide/src/lib.rs9
3 files changed, 76 insertions, 116 deletions
diff --git a/crates/ra_ide/src/call_info.rs b/crates/ra_ide/src/call_info.rs
index e1d6efb2a..0ef92ed4b 100644
--- a/crates/ra_ide/src/call_info.rs
+++ b/crates/ra_ide/src/call_info.rs
@@ -7,7 +7,15 @@ use ra_syntax::{
7}; 7};
8use test_utils::mark; 8use test_utils::mark;
9 9
10use crate::{CallInfo, FilePosition, FunctionSignature}; 10use crate::{FilePosition, FunctionSignature};
11
12/// Contains information about a call site. Specifically the
13/// `FunctionSignature`and current parameter.
14#[derive(Debug)]
15pub struct CallInfo {
16 pub signature: FunctionSignature,
17 pub active_parameter: Option<usize>,
18}
11 19
12/// Computes parameter information for the given call expression. 20/// Computes parameter information for the given call expression.
13pub(crate) fn call_info(db: &RootDatabase, position: FilePosition) -> Option<CallInfo> { 21pub(crate) fn call_info(db: &RootDatabase, position: FilePosition) -> Option<CallInfo> {
@@ -40,43 +48,40 @@ fn call_info_for_token(sema: &Semantics<RootDatabase>, token: SyntaxToken) -> Op
40 // Find the calling expression and it's NameRef 48 // Find the calling expression and it's NameRef
41 let calling_node = FnCallNode::with_node(&token.parent())?; 49 let calling_node = FnCallNode::with_node(&token.parent())?;
42 50
43 let (mut call_info, has_self) = match &calling_node { 51 let signature = match &calling_node {
44 FnCallNode::CallExpr(call) => { 52 FnCallNode::CallExpr(call) => {
45 //FIXME: Type::as_callable is broken 53 //FIXME: Type::as_callable is broken
46 let callable_def = sema.type_of_expr(&call.expr()?)?.as_callable()?; 54 let callable_def = sema.type_of_expr(&call.expr()?)?.as_callable()?;
47 match callable_def { 55 match callable_def {
48 hir::CallableDef::FunctionId(it) => { 56 hir::CallableDef::FunctionId(it) => {
49 let fn_def = it.into(); 57 let fn_def = it.into();
50 (CallInfo::with_fn(sema.db, fn_def), fn_def.has_self_param(sema.db)) 58 FunctionSignature::from_hir(sema.db, fn_def)
51 } 59 }
52 hir::CallableDef::StructId(it) => { 60 hir::CallableDef::StructId(it) => {
53 (CallInfo::with_struct(sema.db, it.into())?, false) 61 FunctionSignature::from_struct(sema.db, it.into())?
54 } 62 }
55 hir::CallableDef::EnumVariantId(it) => { 63 hir::CallableDef::EnumVariantId(it) => {
56 (CallInfo::with_enum_variant(sema.db, it.into())?, false) 64 FunctionSignature::from_enum_variant(sema.db, it.into())?
57 } 65 }
58 } 66 }
59 } 67 }
60 FnCallNode::MethodCallExpr(method_call) => { 68 FnCallNode::MethodCallExpr(method_call) => {
61 let function = sema.resolve_method_call(&method_call)?; 69 let function = sema.resolve_method_call(&method_call)?;
62 (CallInfo::with_fn(sema.db, function), function.has_self_param(sema.db)) 70 FunctionSignature::from_hir(sema.db, function)
63 } 71 }
64 FnCallNode::MacroCallExpr(macro_call) => { 72 FnCallNode::MacroCallExpr(macro_call) => {
65 let macro_def = sema.resolve_macro_call(&macro_call)?; 73 let macro_def = sema.resolve_macro_call(&macro_call)?;
66 (CallInfo::with_macro(sema.db, macro_def)?, false) 74 FunctionSignature::from_macro(sema.db, macro_def)?
67 } 75 }
68 }; 76 };
69 77
70 // If we have a calling expression let's find which argument we are on 78 // If we have a calling expression let's find which argument we are on
71 let num_params = call_info.parameters().len(); 79 let num_params = signature.parameters.len();
72 80
73 match num_params { 81 let active_parameter = match num_params {
74 0 => (), 82 0 => None,
75 1 => { 83 1 if signature.has_self_param => None,
76 if !has_self { 84 1 => Some(0),
77 call_info.active_parameter = Some(0);
78 }
79 }
80 _ => { 85 _ => {
81 if let Some(arg_list) = calling_node.arg_list() { 86 if let Some(arg_list) = calling_node.arg_list() {
82 // Number of arguments specified at the call site 87 // Number of arguments specified at the call site
@@ -99,16 +104,18 @@ fn call_info_for_token(sema: &Semantics<RootDatabase>, token: SyntaxToken) -> Op
99 ); 104 );
100 105
101 // If we are in a method account for `self` 106 // If we are in a method account for `self`
102 if has_self { 107 if signature.has_self_param {
103 param += 1; 108 param += 1;
104 } 109 }
105 110
106 call_info.active_parameter = Some(param); 111 Some(param)
112 } else {
113 None
107 } 114 }
108 } 115 }
109 } 116 };
110 117
111 Some(call_info) 118 Some(CallInfo { signature, active_parameter })
112} 119}
113 120
114#[derive(Debug)] 121#[derive(Debug)]
@@ -181,34 +188,6 @@ impl CallInfo {
181 let res = ActiveParameter { ty, name }; 188 let res = ActiveParameter { ty, name };
182 Some(res) 189 Some(res)
183 } 190 }
184
185 fn with_fn(db: &RootDatabase, function: hir::Function) -> Self {
186 let signature = FunctionSignature::from_hir(db, function);
187
188 CallInfo { signature, active_parameter: None }
189 }
190
191 fn with_struct(db: &RootDatabase, st: hir::Struct) -> Option<Self> {
192 let signature = FunctionSignature::from_struct(db, st)?;
193
194 Some(CallInfo { signature, active_parameter: None })
195 }
196
197 fn with_enum_variant(db: &RootDatabase, variant: hir::EnumVariant) -> Option<Self> {
198 let signature = FunctionSignature::from_enum_variant(db, variant)?;
199
200 Some(CallInfo { signature, active_parameter: None })
201 }
202
203 fn with_macro(db: &RootDatabase, macro_def: hir::MacroDef) -> Option<Self> {
204 let signature = FunctionSignature::from_macro(db, macro_def)?;
205
206 Some(CallInfo { signature, active_parameter: None })
207 }
208
209 fn parameters(&self) -> &[String] {
210 &self.signature.parameters
211 }
212} 191}
213 192
214#[cfg(test)] 193#[cfg(test)]
@@ -228,7 +207,8 @@ mod tests {
228 Some(docs) => format!("{}\n------\n", docs.as_str()), 207 Some(docs) => format!("{}\n------\n", docs.as_str()),
229 }; 208 };
230 let params = call_info 209 let params = call_info
231 .parameters() 210 .signature
211 .parameters
232 .iter() 212 .iter()
233 .enumerate() 213 .enumerate()
234 .map(|(i, param)| { 214 .map(|(i, param)| {
diff --git a/crates/ra_ide/src/display/function_signature.rs b/crates/ra_ide/src/display/function_signature.rs
index a98264fb3..1d39544d3 100644
--- a/crates/ra_ide/src/display/function_signature.rs
+++ b/crates/ra_ide/src/display/function_signature.rs
@@ -61,15 +61,11 @@ pub struct FunctionQualifier {
61} 61}
62 62
63impl FunctionSignature { 63impl FunctionSignature {
64 pub(crate) fn with_doc_opt(mut self, doc: Option<Documentation>) -> Self {
65 self.doc = doc;
66 self
67 }
68
69 pub(crate) fn from_hir(db: &RootDatabase, function: hir::Function) -> Self { 64 pub(crate) fn from_hir(db: &RootDatabase, function: hir::Function) -> Self {
70 let doc = function.docs(db);
71 let ast_node = function.source(db).value; 65 let ast_node = function.source(db).value;
72 FunctionSignature::from(&ast_node).with_doc_opt(doc) 66 let mut res = FunctionSignature::from(&ast_node);
67 res.doc = function.docs(db);
68 res
73 } 69 }
74 70
75 pub(crate) fn from_struct(db: &RootDatabase, st: hir::Struct) -> Option<Self> { 71 pub(crate) fn from_struct(db: &RootDatabase, st: hir::Struct) -> Option<Self> {
@@ -93,24 +89,21 @@ impl FunctionSignature {
93 params.push(raw_param); 89 params.push(raw_param);
94 } 90 }
95 91
96 Some( 92 Some(FunctionSignature {
97 FunctionSignature { 93 kind: CallableKind::StructConstructor,
98 kind: CallableKind::StructConstructor, 94 visibility: node.visibility().map(|n| n.syntax().text().to_string()),
99 visibility: node.visibility().map(|n| n.syntax().text().to_string()), 95 // Do we need `const`?
100 // Do we need `const`? 96 qualifier: Default::default(),
101 qualifier: Default::default(), 97 name: node.name().map(|n| n.text().to_string()),
102 name: node.name().map(|n| n.text().to_string()), 98 ret_type: node.name().map(|n| n.text().to_string()),
103 ret_type: node.name().map(|n| n.text().to_string()), 99 parameters: params,
104 parameters: params, 100 parameter_names: vec![],
105 parameter_names: vec![], 101 parameter_types,
106 parameter_types, 102 generic_parameters: generic_parameters(&node),
107 generic_parameters: generic_parameters(&node), 103 where_predicates: where_predicates(&node),
108 where_predicates: where_predicates(&node), 104 doc: st.docs(db),
109 doc: None, 105 has_self_param: false,
110 has_self_param: false, 106 })
111 }
112 .with_doc_opt(st.docs(db)),
113 )
114 } 107 }
115 108
116 pub(crate) fn from_enum_variant(db: &RootDatabase, variant: hir::EnumVariant) -> Option<Self> { 109 pub(crate) fn from_enum_variant(db: &RootDatabase, variant: hir::EnumVariant) -> Option<Self> {
@@ -140,24 +133,21 @@ impl FunctionSignature {
140 params.push(format!("{}: {}", name, ty.display(db))); 133 params.push(format!("{}: {}", name, ty.display(db)));
141 } 134 }
142 135
143 Some( 136 Some(FunctionSignature {
144 FunctionSignature { 137 kind: CallableKind::VariantConstructor,
145 kind: CallableKind::VariantConstructor, 138 visibility: None,
146 visibility: None, 139 // Do we need `const`?
147 // Do we need `const`? 140 qualifier: Default::default(),
148 qualifier: Default::default(), 141 name: Some(name),
149 name: Some(name), 142 ret_type: None,
150 ret_type: None, 143 parameters: params,
151 parameters: params, 144 parameter_names: vec![],
152 parameter_names: vec![], 145 parameter_types,
153 parameter_types, 146 generic_parameters: vec![],
154 generic_parameters: vec![], 147 where_predicates: vec![],
155 where_predicates: vec![], 148 doc: variant.docs(db),
156 doc: None, 149 has_self_param: false,
157 has_self_param: false, 150 })
158 }
159 .with_doc_opt(variant.docs(db)),
160 )
161 } 151 }
162 152
163 pub(crate) fn from_macro(db: &RootDatabase, macro_def: hir::MacroDef) -> Option<Self> { 153 pub(crate) fn from_macro(db: &RootDatabase, macro_def: hir::MacroDef) -> Option<Self> {
@@ -165,23 +155,20 @@ impl FunctionSignature {
165 155
166 let params = vec![]; 156 let params = vec![];
167 157
168 Some( 158 Some(FunctionSignature {
169 FunctionSignature { 159 kind: CallableKind::Macro,
170 kind: CallableKind::Macro, 160 visibility: None,
171 visibility: None, 161 qualifier: Default::default(),
172 qualifier: Default::default(), 162 name: node.name().map(|n| n.text().to_string()),
173 name: node.name().map(|n| n.text().to_string()), 163 ret_type: None,
174 ret_type: None, 164 parameters: params,
175 parameters: params, 165 parameter_names: vec![],
176 parameter_names: vec![], 166 parameter_types: vec![],
177 parameter_types: vec![], 167 generic_parameters: vec![],
178 generic_parameters: vec![], 168 where_predicates: vec![],
179 where_predicates: vec![], 169 doc: macro_def.docs(db),
180 doc: None, 170 has_self_param: false,
181 has_self_param: false, 171 })
182 }
183 .with_doc_opt(macro_def.docs(db)),
184 )
185 } 172 }
186} 173}
187 174
diff --git a/crates/ra_ide/src/lib.rs b/crates/ra_ide/src/lib.rs
index 6a4f5cb3d..5d1f64e19 100644
--- a/crates/ra_ide/src/lib.rs
+++ b/crates/ra_ide/src/lib.rs
@@ -60,6 +60,7 @@ use crate::display::ToNav;
60 60
61pub use crate::{ 61pub use crate::{
62 call_hierarchy::CallItem, 62 call_hierarchy::CallItem,
63 call_info::CallInfo,
63 completion::{ 64 completion::{
64 CompletionConfig, CompletionItem, CompletionItemKind, CompletionScore, InsertTextFormat, 65 CompletionConfig, CompletionItem, CompletionItemKind, CompletionScore, InsertTextFormat,
65 }, 66 },
@@ -131,14 +132,6 @@ impl<T> RangeInfo<T> {
131 } 132 }
132} 133}
133 134
134/// Contains information about a call site. Specifically the
135/// `FunctionSignature`and current parameter.
136#[derive(Debug)]
137pub struct CallInfo {
138 pub signature: FunctionSignature,
139 pub active_parameter: Option<usize>,
140}
141
142/// `AnalysisHost` stores the current state of the world. 135/// `AnalysisHost` stores the current state of the world.
143#[derive(Debug)] 136#[derive(Debug)]
144pub struct AnalysisHost { 137pub struct AnalysisHost {