aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/ra_ide/src/inlay_hints.rs61
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
3use hir::{HirDisplay, SourceAnalyzer, SourceBinder}; 3use hir::{Function, HirDisplay, SourceAnalyzer, SourceBinder};
4use once_cell::unsync::Lazy; 4use once_cell::unsync::Lazy;
5use ra_ide_db::RootDatabase; 5use ra_ide_db::RootDatabase;
6use ra_prof::profile; 6use ra_prof::profile;
7use ra_syntax::{ 7use 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
12use crate::{FileId, FunctionSignature}; 12use 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 }