diff options
-rw-r--r-- | crates/ra_ide/src/inlay_hints.rs | 64 |
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 | ||
233 | fn should_show_param_name_hint( | 233 | fn 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 | ||
257 | fn is_argument_similar_to_param_name(argument: &ast::Expr, param_name: &str) -> bool { | 258 | fn 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(¶m_name) || argument_string.ends_with(¶m_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 | |||
276 | fn 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 | |||
287 | fn 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 | ||
268 | fn get_string_representation(expr: &ast::Expr) -> Option<String> { | 301 | fn get_string_representation(expr: &ast::Expr) -> Option<String> { |
@@ -1109,10 +1142,15 @@ struct Param {} | |||
1109 | fn different_order(param: &Param) {} | 1142 | fn different_order(param: &Param) {} |
1110 | fn different_order_mut(param: &mut Param) {} | 1143 | fn different_order_mut(param: &mut Param) {} |
1111 | fn has_underscore(_param: bool) {} | 1144 | fn has_underscore(_param: bool) {} |
1145 | fn enum_matches_param_name(completion_kind: CompletionKind) {} | ||
1112 | 1146 | ||
1113 | fn twiddle(twiddle: bool) {} | 1147 | fn twiddle(twiddle: bool) {} |
1114 | fn doo(_doo: bool) {} | 1148 | fn doo(_doo: bool) {} |
1115 | 1149 | ||
1150 | enum CompletionKind { | ||
1151 | Keyword, | ||
1152 | } | ||
1153 | |||
1116 | fn main() { | 1154 | fn 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); |