diff options
-rw-r--r-- | crates/ra_ide/src/call_info.rs | 76 | ||||
-rw-r--r-- | crates/ra_ide/src/display/function_signature.rs | 107 | ||||
-rw-r--r-- | crates/ra_ide/src/lib.rs | 9 |
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 | }; |
8 | use test_utils::mark; | 8 | use test_utils::mark; |
9 | 9 | ||
10 | use crate::{CallInfo, FilePosition, FunctionSignature}; | 10 | use crate::{FilePosition, FunctionSignature}; |
11 | |||
12 | /// Contains information about a call site. Specifically the | ||
13 | /// `FunctionSignature`and current parameter. | ||
14 | #[derive(Debug)] | ||
15 | pub 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. |
13 | pub(crate) fn call_info(db: &RootDatabase, position: FilePosition) -> Option<CallInfo> { | 21 | pub(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(¯o_call)?; | 73 | let macro_def = sema.resolve_macro_call(¯o_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 | ||
63 | impl FunctionSignature { | 63 | impl 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 | ||
61 | pub use crate::{ | 61 | pub 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)] | ||
137 | pub 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)] |
144 | pub struct AnalysisHost { | 137 | pub struct AnalysisHost { |