From 8eb820f460f00ab20b9b8d952c600755ecadee2c Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Sun, 3 May 2020 15:07:57 +0300 Subject: Omit name hints for method names similar to parameter names --- crates/ra_ide/src/inlay_hints.rs | 38 +++++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/crates/ra_ide/src/inlay_hints.rs b/crates/ra_ide/src/inlay_hints.rs index 98483df32..8eb2c4412 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( .iter() .skip(n_params_to_skip) .zip(args) - .filter(|(param, arg)| should_show_param_hint(&fn_signature, param, &arg)) + .filter(|(param, arg)| should_show_param_name_hint(&fn_signature, param, &arg)) .map(|(param_name, arg)| InlayHint { range: arg.syntax().text_range(), kind: InlayKind::ParameterHint, @@ -181,7 +181,7 @@ fn get_bind_pat_hints( fn pat_is_enum_variant(db: &RootDatabase, bind_pat: &ast::BindPat, pat_ty: &Type) -> bool { if let Some(Adt::Enum(enum_data)) = pat_ty.as_adt() { - let pat_text = bind_pat.syntax().to_string(); + let pat_text = bind_pat.to_string(); enum_data .variants(db) .into_iter() @@ -198,7 +198,7 @@ fn should_not_display_type_hint(db: &RootDatabase, bind_pat: &ast::BindPat, pat_ } if let Some(Adt::Struct(s)) = pat_ty.as_adt() { - if s.fields(db).is_empty() && s.name(db).to_string() == bind_pat.syntax().to_string() { + if s.fields(db).is_empty() && s.name(db).to_string() == bind_pat.to_string() { return true; } } @@ -230,13 +230,13 @@ fn should_not_display_type_hint(db: &RootDatabase, bind_pat: &ast::BindPat, pat_ false } -fn should_show_param_hint( +fn should_show_param_name_hint( fn_signature: &FunctionSignature, param_name: &str, argument: &ast::Expr, ) -> bool { if param_name.is_empty() - || is_argument_similar_to_param(argument, param_name) + || is_argument_similar_to_param_name(argument, param_name) || Some(param_name.trim_start_matches('_')) == fn_signature.name.as_ref().map(|s| s.trim_start_matches('_')) { @@ -254,20 +254,25 @@ fn should_show_param_hint( parameters_len != 1 || !is_obvious_param(param_name) } -fn is_argument_similar_to_param(argument: &ast::Expr, param_name: &str) -> bool { - let argument_string = remove_ref(argument.clone()).syntax().to_string(); +fn is_argument_similar_to_param_name(argument: &ast::Expr, param_name: &str) -> bool { + let argument_string = if let Some(repr) = get_string_representation(argument) { + repr + } else { + return false; + }; let param_name = param_name.trim_start_matches('_'); let argument_string = argument_string.trim_start_matches('_'); argument_string.starts_with(¶m_name) || argument_string.ends_with(¶m_name) } -fn remove_ref(expr: ast::Expr) -> ast::Expr { - if let ast::Expr::RefExpr(ref_expr) = &expr { - if let Some(inner) = ref_expr.expr() { - return inner; +fn get_string_representation(expr: &ast::Expr) -> Option { + match expr { + ast::Expr::MethodCallExpr(method_call_expr) => { + Some(method_call_expr.name_ref()?.to_string()) } + ast::Expr::RefExpr(ref_expr) => get_string_representation(&ref_expr.expr()?), + _ => Some(expr.to_string()), } - expr } fn is_obvious_param(param_name: &str) -> bool { @@ -1073,6 +1078,12 @@ struct TestVarContainer { test_var: i32, } +impl TestVarContainer { + fn test_var(&self) -> i32 { + self.test_var + } +} + struct Test {} impl Test { @@ -1114,12 +1125,13 @@ fn main() { let test_var: i32 = 55; test_processed.no_hints_expected(22, test_var); test_processed.no_hints_expected(33, container.test_var); + test_processed.no_hints_expected(44, container.test_var()); test_processed.frob(false); twiddle(true); doo(true); - let param_begin: Param = Param {}; + let mut param_begin: Param = Param {}; different_order(¶m_begin); different_order(&mut param_begin); -- cgit v1.2.3 From ba8ffab6444e0a6f4b9e5254adbef2adc6169cf9 Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Sun, 3 May 2020 15:50:35 +0300 Subject: Omit name hints for enum names similar to parameter names --- crates/ra_ide/src/inlay_hints.rs | 64 ++++++++++++++++++++++++++++++++-------- 1 file 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( .iter() .skip(n_params_to_skip) .zip(args) - .filter(|(param, arg)| should_show_param_name_hint(&fn_signature, param, &arg)) + .filter(|(param, arg)| should_show_param_name_hint(sema, &fn_signature, param, &arg)) .map(|(param_name, arg)| InlayHint { range: arg.syntax().text_range(), kind: InlayKind::ParameterHint, @@ -231,14 +231,15 @@ fn should_not_display_type_hint(db: &RootDatabase, bind_pat: &ast::BindPat, pat_ } fn should_show_param_name_hint( + sema: &Semantics, fn_signature: &FunctionSignature, param_name: &str, argument: &ast::Expr, ) -> bool { + let param_name = param_name.trim_start_matches('_'); if param_name.is_empty() - || is_argument_similar_to_param_name(argument, param_name) - || Some(param_name.trim_start_matches('_')) - == fn_signature.name.as_ref().map(|s| s.trim_start_matches('_')) + || Some(param_name) == fn_signature.name.as_ref().map(|s| s.trim_start_matches('_')) + || is_argument_similar_to_param_name(sema, argument, param_name) { return false; } @@ -254,15 +255,47 @@ fn should_show_param_name_hint( parameters_len != 1 || !is_obvious_param(param_name) } -fn is_argument_similar_to_param_name(argument: &ast::Expr, param_name: &str) -> bool { - let argument_string = if let Some(repr) = get_string_representation(argument) { - repr +fn is_argument_similar_to_param_name( + sema: &Semantics, + argument: &ast::Expr, + param_name: &str, +) -> bool { + if is_enum_name_similar_to_param_name(sema, argument, param_name) { + return true; } else { - return false; - }; - let param_name = param_name.trim_start_matches('_'); - let argument_string = argument_string.trim_start_matches('_'); - argument_string.starts_with(¶m_name) || argument_string.ends_with(¶m_name) + let argument_string = if let Some(repr) = get_string_representation(argument) { + repr + } else { + return false; + }; + let argument_string = argument_string.trim_start_matches('_'); + argument_string.starts_with(param_name) || argument_string.ends_with(param_name) + } +} + +fn is_enum_name_similar_to_param_name( + sema: &Semantics, + argument: &ast::Expr, + param_name: &str, +) -> bool { + match sema.type_of_expr(argument).and_then(|t| t.as_adt()) { + Some(Adt::Enum(e)) => &camel_case_to_snake_case(e.name(sema.db).to_string()) == param_name, + _ => false, + } +} + +fn camel_case_to_snake_case(s: String) -> String { + let mut buf = String::with_capacity(s.len()); + let mut prev = false; + for c in s.chars() { + if c.is_ascii_uppercase() && prev { + buf.push('_') + } + prev = true; + + buf.push(c.to_ascii_lowercase()); + } + buf } fn get_string_representation(expr: &ast::Expr) -> Option { @@ -1109,10 +1142,15 @@ struct Param {} fn different_order(param: &Param) {} fn different_order_mut(param: &mut Param) {} fn has_underscore(_param: bool) {} +fn enum_matches_param_name(completion_kind: CompletionKind) {} fn twiddle(twiddle: bool) {} fn doo(_doo: bool) {} +enum CompletionKind { + Keyword, +} + fn main() { let container: TestVarContainer = TestVarContainer { test_var: 42 }; let test: Test = Test {}; @@ -1138,6 +1176,8 @@ fn main() { let param: bool = true; has_underscore(param); + enum_matches_param_name(CompletionKind::Keyword); + let a: f64 = 7.0; let b: f64 = 4.0; let _: f64 = a.div_euclid(b); -- cgit v1.2.3 From 66882f1a249983a1b262a219dbcd47a0e2835418 Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Sun, 3 May 2020 21:35:21 +0300 Subject: Move snake case method to heck --- crates/ra_ide/src/inlay_hints.rs | 17 ++--------------- crates/stdx/src/lib.rs | 14 ++++++++++++++ 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/crates/ra_ide/src/inlay_hints.rs b/crates/ra_ide/src/inlay_hints.rs index 746306428..79c6ff4e1 100644 --- a/crates/ra_ide/src/inlay_hints.rs +++ b/crates/ra_ide/src/inlay_hints.rs @@ -9,6 +9,7 @@ use ra_syntax::{ }; use crate::{FileId, FunctionSignature}; +use stdx::to_lower_snake_case; #[derive(Clone, Debug, PartialEq, Eq)] pub struct InlayHintsConfig { @@ -279,25 +280,11 @@ fn is_enum_name_similar_to_param_name( param_name: &str, ) -> bool { match sema.type_of_expr(argument).and_then(|t| t.as_adt()) { - Some(Adt::Enum(e)) => &camel_case_to_snake_case(e.name(sema.db).to_string()) == param_name, + Some(Adt::Enum(e)) => to_lower_snake_case(&e.name(sema.db).to_string()) == param_name, _ => false, } } -fn camel_case_to_snake_case(s: String) -> String { - let mut buf = String::with_capacity(s.len()); - let mut prev = false; - for c in s.chars() { - if c.is_ascii_uppercase() && prev { - buf.push('_') - } - prev = true; - - buf.push(c.to_ascii_lowercase()); - } - buf -} - fn get_string_representation(expr: &ast::Expr) -> Option { match expr { ast::Expr::MethodCallExpr(method_call_expr) => { diff --git a/crates/stdx/src/lib.rs b/crates/stdx/src/lib.rs index 01cdf452c..0f34ce70e 100644 --- a/crates/stdx/src/lib.rs +++ b/crates/stdx/src/lib.rs @@ -102,3 +102,17 @@ pub fn timeit(label: &'static str) -> impl Drop { Guard { label, start: Instant::now() } } + +pub fn to_lower_snake_case(s: &str) -> String { + let mut buf = String::with_capacity(s.len()); + let mut prev = false; + for c in s.chars() { + if c.is_ascii_uppercase() && prev { + buf.push('_') + } + prev = true; + + buf.push(c.to_ascii_lowercase()); + } + buf +} -- cgit v1.2.3 From 30817de3affd9376eed4ff164c42fe0e00a1ac37 Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Mon, 4 May 2020 10:58:21 +0300 Subject: Code review fixes Co-authored-by: Edwin Cheng --- crates/ra_ide/src/inlay_hints.rs | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/crates/ra_ide/src/inlay_hints.rs b/crates/ra_ide/src/inlay_hints.rs index 79c6ff4e1..b391f903a 100644 --- a/crates/ra_ide/src/inlay_hints.rs +++ b/crates/ra_ide/src/inlay_hints.rs @@ -263,14 +263,13 @@ fn is_argument_similar_to_param_name( ) -> bool { if is_enum_name_similar_to_param_name(sema, argument, param_name) { return true; - } else { - let argument_string = if let Some(repr) = get_string_representation(argument) { - repr - } else { - return false; - }; - let argument_string = argument_string.trim_start_matches('_'); - argument_string.starts_with(param_name) || argument_string.ends_with(param_name) + } + match get_string_representation(argument) { + None => false, + Some(repr) => { + let argument_string = repr.trim_start_matches('_'); + argument_string.starts_with(param_name) || argument_string.ends_with(param_name) + } } } -- cgit v1.2.3