diff options
Diffstat (limited to 'crates')
-rw-r--r-- | crates/ra_ide/src/inlay_hints.rs | 61 |
1 files changed, 34 insertions, 27 deletions
diff --git a/crates/ra_ide/src/inlay_hints.rs b/crates/ra_ide/src/inlay_hints.rs index ddf67af4a..09a463a4b 100644 --- a/crates/ra_ide/src/inlay_hints.rs +++ b/crates/ra_ide/src/inlay_hints.rs | |||
@@ -1,12 +1,12 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! FIXME: write short doc here |
2 | 2 | ||
3 | use hir::{HirDisplay, SourceAnalyzer, SourceBinder}; | 3 | use hir::{Function, HirDisplay, SourceAnalyzer, SourceBinder}; |
4 | use once_cell::unsync::Lazy; | 4 | use once_cell::unsync::Lazy; |
5 | use ra_ide_db::RootDatabase; | 5 | use ra_ide_db::RootDatabase; |
6 | use ra_prof::profile; | 6 | use ra_prof::profile; |
7 | use ra_syntax::{ | 7 | use ra_syntax::{ |
8 | ast::{self, ArgListOwner, AstNode, TypeAscriptionOwner}, | 8 | ast::{self, ArgListOwner, AstNode, TypeAscriptionOwner}, |
9 | match_ast, SmolStr, SourceFile, SyntaxKind, SyntaxNode, TextRange, | 9 | match_ast, SmolStr, SourceFile, SyntaxNode, TextRange, |
10 | }; | 10 | }; |
11 | 11 | ||
12 | use crate::{FileId, FunctionSignature}; | 12 | use crate::{FileId, FunctionSignature}; |
@@ -107,28 +107,33 @@ fn get_param_name_hints( | |||
107 | ast::Expr::CallExpr(expr) => expr.arg_list()?.args(), | 107 | ast::Expr::CallExpr(expr) => expr.arg_list()?.args(), |
108 | ast::Expr::MethodCallExpr(expr) => expr.arg_list()?.args(), | 108 | ast::Expr::MethodCallExpr(expr) => expr.arg_list()?.args(), |
109 | _ => return None, | 109 | _ => return None, |
110 | } | ||
111 | .into_iter() | ||
112 | // we need args len to determine whether to skip or not the &self parameter | ||
113 | .collect::<Vec<_>>(); | ||
114 | |||
115 | let (has_self_param, fn_signature) = get_fn_signature(db, analyzer, &expr)?; | ||
116 | let parameters = if has_self_param && fn_signature.parameter_names.len() > args.len() { | ||
117 | fn_signature.parameter_names.into_iter().skip(1) | ||
118 | } else { | ||
119 | fn_signature.parameter_names.into_iter().skip(0) | ||
110 | }; | 120 | }; |
111 | 121 | ||
112 | let mut parameters = get_fn_signature(db, analyzer, &expr)?.parameter_names.into_iter(); | 122 | let hints = |
113 | 123 | parameters | |
114 | if let ast::Expr::MethodCallExpr(_) = &expr { | 124 | .zip(args) |
115 | parameters.next(); | 125 | .filter_map(|(param, arg)| { |
116 | }; | 126 | if !param.is_empty() { |
117 | 127 | Some((arg.syntax().text_range(), param)) | |
118 | let hints = parameters | 128 | } else { |
119 | .zip(args) | 129 | None |
120 | .filter_map(|(param, arg)| { | 130 | } |
121 | if arg.syntax().kind() == SyntaxKind::LITERAL && !param.is_empty() { | 131 | }) |
122 | Some((arg.syntax().text_range(), param)) | 132 | .map(|(range, param_name)| InlayHint { |
123 | } else { | 133 | range, |
124 | None | 134 | kind: InlayKind::ParameterHint, |
125 | } | 135 | label: param_name.into(), |
126 | }) | 136 | }); |
127 | .map(|(range, param_name)| InlayHint { | ||
128 | range, | ||
129 | kind: InlayKind::ParameterHint, | ||
130 | label: param_name.into(), | ||
131 | }); | ||
132 | 137 | ||
133 | acc.extend(hints); | 138 | acc.extend(hints); |
134 | Some(()) | 139 | Some(()) |
@@ -138,25 +143,27 @@ fn get_fn_signature( | |||
138 | db: &RootDatabase, | 143 | db: &RootDatabase, |
139 | analyzer: &SourceAnalyzer, | 144 | analyzer: &SourceAnalyzer, |
140 | expr: &ast::Expr, | 145 | expr: &ast::Expr, |
141 | ) -> Option<FunctionSignature> { | 146 | ) -> Option<(bool, FunctionSignature)> { |
142 | match expr { | 147 | match expr { |
143 | ast::Expr::CallExpr(expr) => { | 148 | ast::Expr::CallExpr(expr) => { |
144 | // FIXME: Type::as_callable is broken for closures | 149 | // FIXME: Type::as_callable is broken for closures |
145 | let callable_def = analyzer.type_of(db, &expr.expr()?)?.as_callable()?; | 150 | let callable_def = analyzer.type_of(db, &expr.expr()?)?.as_callable()?; |
146 | match callable_def { | 151 | match callable_def { |
147 | hir::CallableDef::FunctionId(it) => { | 152 | hir::CallableDef::FunctionId(it) => { |
148 | let fn_def = it.into(); | 153 | let fn_def: Function = it.into(); |
149 | Some(FunctionSignature::from_hir(db, fn_def)) | 154 | Some((fn_def.has_self_param(db), FunctionSignature::from_hir(db, fn_def))) |
150 | } | 155 | } |
151 | hir::CallableDef::StructId(it) => FunctionSignature::from_struct(db, it.into()), | 156 | hir::CallableDef::StructId(it) => FunctionSignature::from_struct(db, it.into()) |
157 | .map(|signature| (false, signature)), | ||
152 | hir::CallableDef::EnumVariantId(it) => { | 158 | hir::CallableDef::EnumVariantId(it) => { |
153 | FunctionSignature::from_enum_variant(db, it.into()) | 159 | FunctionSignature::from_enum_variant(db, it.into()) |
160 | .map(|signature| (false, signature)) | ||
154 | } | 161 | } |
155 | } | 162 | } |
156 | } | 163 | } |
157 | ast::Expr::MethodCallExpr(expr) => { | 164 | ast::Expr::MethodCallExpr(expr) => { |
158 | let fn_def = analyzer.resolve_method_call(&expr)?; | 165 | let fn_def = analyzer.resolve_method_call(&expr)?; |
159 | Some(FunctionSignature::from_hir(db, fn_def)) | 166 | Some((fn_def.has_self_param(db), FunctionSignature::from_hir(db, fn_def))) |
160 | } | 167 | } |
161 | _ => None, | 168 | _ => None, |
162 | } | 169 | } |