aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_ide')
-rw-r--r--crates/ra_ide/src/inlay_hints.rs64
1 files changed, 52 insertions, 12 deletions
diff --git a/crates/ra_ide/src/inlay_hints.rs b/crates/ra_ide/src/inlay_hints.rs
index 8eb2c4412..746306428 100644
--- a/crates/ra_ide/src/inlay_hints.rs
+++ b/crates/ra_ide/src/inlay_hints.rs
@@ -144,7 +144,7 @@ fn get_param_name_hints(
144 .iter() 144 .iter()
145 .skip(n_params_to_skip) 145 .skip(n_params_to_skip)
146 .zip(args) 146 .zip(args)
147 .filter(|(param, arg)| should_show_param_name_hint(&fn_signature, param, &arg)) 147 .filter(|(param, arg)| should_show_param_name_hint(sema, &fn_signature, param, &arg))
148 .map(|(param_name, arg)| InlayHint { 148 .map(|(param_name, arg)| InlayHint {
149 range: arg.syntax().text_range(), 149 range: arg.syntax().text_range(),
150 kind: InlayKind::ParameterHint, 150 kind: InlayKind::ParameterHint,
@@ -231,14 +231,15 @@ fn should_not_display_type_hint(db: &RootDatabase, bind_pat: &ast::BindPat, pat_
231} 231}
232 232
233fn should_show_param_name_hint( 233fn should_show_param_name_hint(
234 sema: &Semantics<RootDatabase>,
234 fn_signature: &FunctionSignature, 235 fn_signature: &FunctionSignature,
235 param_name: &str, 236 param_name: &str,
236 argument: &ast::Expr, 237 argument: &ast::Expr,
237) -> bool { 238) -> bool {
239 let param_name = param_name.trim_start_matches('_');
238 if param_name.is_empty() 240 if param_name.is_empty()
239 || is_argument_similar_to_param_name(argument, param_name) 241 || Some(param_name) == fn_signature.name.as_ref().map(|s| s.trim_start_matches('_'))
240 || Some(param_name.trim_start_matches('_')) 242 || is_argument_similar_to_param_name(sema, argument, param_name)
241 == fn_signature.name.as_ref().map(|s| s.trim_start_matches('_'))
242 { 243 {
243 return false; 244 return false;
244 } 245 }
@@ -254,15 +255,47 @@ fn should_show_param_name_hint(
254 parameters_len != 1 || !is_obvious_param(param_name) 255 parameters_len != 1 || !is_obvious_param(param_name)
255} 256}
256 257
257fn is_argument_similar_to_param_name(argument: &ast::Expr, param_name: &str) -> bool { 258fn is_argument_similar_to_param_name(
258 let argument_string = if let Some(repr) = get_string_representation(argument) { 259 sema: &Semantics<RootDatabase>,
259 repr 260 argument: &ast::Expr,
261 param_name: &str,
262) -> bool {
263 if is_enum_name_similar_to_param_name(sema, argument, param_name) {
264 return true;
260 } else { 265 } else {
261 return false; 266 let argument_string = if let Some(repr) = get_string_representation(argument) {
262 }; 267 repr
263 let param_name = param_name.trim_start_matches('_'); 268 } else {
264 let argument_string = argument_string.trim_start_matches('_'); 269 return false;
265 argument_string.starts_with(&param_name) || argument_string.ends_with(&param_name) 270 };
271 let argument_string = argument_string.trim_start_matches('_');
272 argument_string.starts_with(param_name) || argument_string.ends_with(param_name)
273 }
274}
275
276fn is_enum_name_similar_to_param_name(
277 sema: &Semantics<RootDatabase>,
278 argument: &ast::Expr,
279 param_name: &str,
280) -> bool {
281 match sema.type_of_expr(argument).and_then(|t| t.as_adt()) {
282 Some(Adt::Enum(e)) => &camel_case_to_snake_case(e.name(sema.db).to_string()) == param_name,
283 _ => false,
284 }
285}
286
287fn camel_case_to_snake_case(s: String) -> String {
288 let mut buf = String::with_capacity(s.len());
289 let mut prev = false;
290 for c in s.chars() {
291 if c.is_ascii_uppercase() && prev {
292 buf.push('_')
293 }
294 prev = true;
295
296 buf.push(c.to_ascii_lowercase());
297 }
298 buf
266} 299}
267 300
268fn get_string_representation(expr: &ast::Expr) -> Option<String> { 301fn get_string_representation(expr: &ast::Expr) -> Option<String> {
@@ -1109,10 +1142,15 @@ struct Param {}
1109fn different_order(param: &Param) {} 1142fn different_order(param: &Param) {}
1110fn different_order_mut(param: &mut Param) {} 1143fn different_order_mut(param: &mut Param) {}
1111fn has_underscore(_param: bool) {} 1144fn has_underscore(_param: bool) {}
1145fn enum_matches_param_name(completion_kind: CompletionKind) {}
1112 1146
1113fn twiddle(twiddle: bool) {} 1147fn twiddle(twiddle: bool) {}
1114fn doo(_doo: bool) {} 1148fn doo(_doo: bool) {}
1115 1149
1150enum CompletionKind {
1151 Keyword,
1152}
1153
1116fn main() { 1154fn main() {
1117 let container: TestVarContainer = TestVarContainer { test_var: 42 }; 1155 let container: TestVarContainer = TestVarContainer { test_var: 42 };
1118 let test: Test = Test {}; 1156 let test: Test = Test {};
@@ -1138,6 +1176,8 @@ fn main() {
1138 let param: bool = true; 1176 let param: bool = true;
1139 has_underscore(param); 1177 has_underscore(param);
1140 1178
1179 enum_matches_param_name(CompletionKind::Keyword);
1180
1141 let a: f64 = 7.0; 1181 let a: f64 = 7.0;
1142 let b: f64 = 4.0; 1182 let b: f64 = 4.0;
1143 let _: f64 = a.div_euclid(b); 1183 let _: f64 = a.div_euclid(b);