diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2020-07-16 21:18:28 +0100 |
---|---|---|
committer | GitHub <[email protected]> | 2020-07-16 21:18:28 +0100 |
commit | 81c82733899691fec7ed046525a5c583d3c7d5be (patch) | |
tree | 74f7814de8380f97c645afbfe3dad7d924785fcb /crates/ra_ide/src/inlay_hints.rs | |
parent | 4759a39f06be1ec1469101a8aac39039b8743806 (diff) | |
parent | 3823c2dc1995ec261e36435662b8802c714e23d4 (diff) |
Merge #5415
5415: Remove FunctionSignature r=matklad a=matklad
bors r+
🤖
Co-authored-by: Aleksey Kladov <[email protected]>
Diffstat (limited to 'crates/ra_ide/src/inlay_hints.rs')
-rw-r--r-- | crates/ra_ide/src/inlay_hints.rs | 76 |
1 files changed, 31 insertions, 45 deletions
diff --git a/crates/ra_ide/src/inlay_hints.rs b/crates/ra_ide/src/inlay_hints.rs index ae5695f61..cec3b04e8 100644 --- a/crates/ra_ide/src/inlay_hints.rs +++ b/crates/ra_ide/src/inlay_hints.rs | |||
@@ -1,4 +1,4 @@ | |||
1 | use hir::{Adt, HirDisplay, Semantics, Type}; | 1 | use hir::{Adt, Callable, HirDisplay, Semantics, Type}; |
2 | use ra_ide_db::RootDatabase; | 2 | use ra_ide_db::RootDatabase; |
3 | use ra_prof::profile; | 3 | use ra_prof::profile; |
4 | use ra_syntax::{ | 4 | use ra_syntax::{ |
@@ -7,7 +7,9 @@ use ra_syntax::{ | |||
7 | }; | 7 | }; |
8 | use stdx::to_lower_snake_case; | 8 | use stdx::to_lower_snake_case; |
9 | 9 | ||
10 | use crate::{display::function_signature::FunctionSignature, FileId}; | 10 | use crate::FileId; |
11 | use ast::NameOwner; | ||
12 | use either::Either; | ||
11 | 13 | ||
12 | #[derive(Clone, Debug, PartialEq, Eq)] | 14 | #[derive(Clone, Debug, PartialEq, Eq)] |
13 | pub struct InlayHintsConfig { | 15 | pub struct InlayHintsConfig { |
@@ -150,23 +152,26 @@ fn get_param_name_hints( | |||
150 | _ => return None, | 152 | _ => return None, |
151 | }; | 153 | }; |
152 | 154 | ||
153 | let fn_signature = get_fn_signature(sema, &expr)?; | 155 | let callable = get_callable(sema, &expr)?; |
154 | let n_params_to_skip = | 156 | let hints = callable |
155 | if fn_signature.has_self_param && matches!(&expr, ast::Expr::MethodCallExpr(_)) { | 157 | .params(sema.db) |
156 | 1 | 158 | .into_iter() |
157 | } else { | ||
158 | 0 | ||
159 | }; | ||
160 | let hints = fn_signature | ||
161 | .parameter_names | ||
162 | .iter() | ||
163 | .skip(n_params_to_skip) | ||
164 | .zip(args) | 159 | .zip(args) |
165 | .filter(|(param, arg)| should_show_param_name_hint(sema, &fn_signature, param, &arg)) | 160 | .filter_map(|((param, _ty), arg)| match param? { |
161 | Either::Left(self_param) => Some((self_param.to_string(), arg)), | ||
162 | Either::Right(pat) => { | ||
163 | let param_name = match pat { | ||
164 | ast::Pat::BindPat(it) => it.name()?.to_string(), | ||
165 | it => it.to_string(), | ||
166 | }; | ||
167 | Some((param_name, arg)) | ||
168 | } | ||
169 | }) | ||
170 | .filter(|(param_name, arg)| should_show_param_name_hint(sema, &callable, ¶m_name, &arg)) | ||
166 | .map(|(param_name, arg)| InlayHint { | 171 | .map(|(param_name, arg)| InlayHint { |
167 | range: arg.syntax().text_range(), | 172 | range: arg.syntax().text_range(), |
168 | kind: InlayKind::ParameterHint, | 173 | kind: InlayKind::ParameterHint, |
169 | label: param_name.into(), | 174 | label: param_name.to_string().into(), |
170 | }); | 175 | }); |
171 | 176 | ||
172 | acc.extend(hints); | 177 | acc.extend(hints); |
@@ -250,28 +255,26 @@ fn should_not_display_type_hint(db: &RootDatabase, bind_pat: &ast::BindPat, pat_ | |||
250 | 255 | ||
251 | fn should_show_param_name_hint( | 256 | fn should_show_param_name_hint( |
252 | sema: &Semantics<RootDatabase>, | 257 | sema: &Semantics<RootDatabase>, |
253 | fn_signature: &FunctionSignature, | 258 | callable: &Callable, |
254 | param_name: &str, | 259 | param_name: &str, |
255 | argument: &ast::Expr, | 260 | argument: &ast::Expr, |
256 | ) -> bool { | 261 | ) -> bool { |
257 | let param_name = param_name.trim_start_matches('_'); | 262 | let param_name = param_name.trim_start_matches('_'); |
263 | let fn_name = match callable.kind() { | ||
264 | hir::CallableKind::Function(it) => Some(it.name(sema.db).to_string()), | ||
265 | hir::CallableKind::TupleStruct(_) | hir::CallableKind::TupleEnumVariant(_) => None, | ||
266 | }; | ||
258 | if param_name.is_empty() | 267 | if param_name.is_empty() |
259 | || Some(param_name) == fn_signature.name.as_ref().map(|s| s.trim_start_matches('_')) | 268 | || Some(param_name) == fn_name.as_ref().map(|s| s.trim_start_matches('_')) |
260 | || is_argument_similar_to_param_name(sema, argument, param_name) | 269 | || is_argument_similar_to_param_name(sema, argument, param_name) |
261 | || param_name.starts_with("ra_fixture") | 270 | || param_name.starts_with("ra_fixture") |
262 | { | 271 | { |
263 | return false; | 272 | return false; |
264 | } | 273 | } |
265 | 274 | ||
266 | let parameters_len = if fn_signature.has_self_param { | ||
267 | fn_signature.parameters.len() - 1 | ||
268 | } else { | ||
269 | fn_signature.parameters.len() | ||
270 | }; | ||
271 | |||
272 | // avoid displaying hints for common functions like map, filter, etc. | 275 | // avoid displaying hints for common functions like map, filter, etc. |
273 | // or other obvious words used in std | 276 | // or other obvious words used in std |
274 | !(parameters_len == 1 && is_obvious_param(param_name)) | 277 | !(callable.n_params() == 1 && is_obvious_param(param_name)) |
275 | } | 278 | } |
276 | 279 | ||
277 | fn is_argument_similar_to_param_name( | 280 | fn is_argument_similar_to_param_name( |
@@ -318,27 +321,10 @@ fn is_obvious_param(param_name: &str) -> bool { | |||
318 | param_name.len() == 1 || is_obvious_param_name | 321 | param_name.len() == 1 || is_obvious_param_name |
319 | } | 322 | } |
320 | 323 | ||
321 | fn get_fn_signature(sema: &Semantics<RootDatabase>, expr: &ast::Expr) -> Option<FunctionSignature> { | 324 | fn get_callable(sema: &Semantics<RootDatabase>, expr: &ast::Expr) -> Option<Callable> { |
322 | match expr { | 325 | match expr { |
323 | ast::Expr::CallExpr(expr) => { | 326 | ast::Expr::CallExpr(expr) => sema.type_of_expr(&expr.expr()?)?.as_callable(sema.db), |
324 | // FIXME: Type::as_callable is broken for closures | 327 | ast::Expr::MethodCallExpr(expr) => sema.resolve_method_call_as_callable(expr), |
325 | let callable = sema.type_of_expr(&expr.expr()?)?.as_callable(sema.db)?; | ||
326 | match callable.kind() { | ||
327 | hir::CallableKind::Function(it) => { | ||
328 | Some(FunctionSignature::from_hir(sema.db, it.into())) | ||
329 | } | ||
330 | hir::CallableKind::TupleStruct(it) => { | ||
331 | FunctionSignature::from_struct(sema.db, it.into()) | ||
332 | } | ||
333 | hir::CallableKind::TupleEnumVariant(it) => { | ||
334 | FunctionSignature::from_enum_variant(sema.db, it.into()) | ||
335 | } | ||
336 | } | ||
337 | } | ||
338 | ast::Expr::MethodCallExpr(expr) => { | ||
339 | let fn_def = sema.resolve_method_call(&expr)?; | ||
340 | Some(FunctionSignature::from_hir(sema.db, fn_def)) | ||
341 | } | ||
342 | _ => None, | 328 | _ => None, |
343 | } | 329 | } |
344 | } | 330 | } |
@@ -360,7 +346,7 @@ mod tests { | |||
360 | let inlay_hints = analysis.inlay_hints(file_id, &config).unwrap(); | 346 | let inlay_hints = analysis.inlay_hints(file_id, &config).unwrap(); |
361 | let actual = | 347 | let actual = |
362 | inlay_hints.into_iter().map(|it| (it.range, it.label.to_string())).collect::<Vec<_>>(); | 348 | inlay_hints.into_iter().map(|it| (it.range, it.label.to_string())).collect::<Vec<_>>(); |
363 | assert_eq!(expected, actual); | 349 | assert_eq!(expected, actual, "\nExpected:\n{:#?}\n\nActual:\n{:#?}", expected, actual); |
364 | } | 350 | } |
365 | 351 | ||
366 | fn check_expect(config: InlayHintsConfig, ra_fixture: &str, expect: Expect) { | 352 | fn check_expect(config: InlayHintsConfig, ra_fixture: &str, expect: Expect) { |