Skip to content

Commit 3b1d983

Browse files
Merge #4282
4282: More name hints omitting heuristics r=matklad a=SomeoneToIgnore Omit parameter name hints for cases like the first two parameters from the screenshot: <img width="394" alt="Screenshot 2020-05-03 at 15 06 34" src="https://user-images.githubusercontent.com/2690773/80914717-165b2f80-8d56-11ea-8675-040972f70d98.png"> Co-authored-by: Kirill Bulatov <[email protected]>
2 parents d855280 + 30817de commit 3b1d983

File tree

2 files changed

+70
-18
lines changed

2 files changed

+70
-18
lines changed

crates/ra_ide/src/inlay_hints.rs

Lines changed: 56 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use ra_syntax::{
99
};
1010

1111
use crate::{FileId, FunctionSignature};
12+
use stdx::to_lower_snake_case;
1213

1314
#[derive(Clone, Debug, PartialEq, Eq)]
1415
pub struct InlayHintsConfig {
@@ -144,7 +145,7 @@ fn get_param_name_hints(
144145
.iter()
145146
.skip(n_params_to_skip)
146147
.zip(args)
147-
.filter(|(param, arg)| should_show_param_hint(&fn_signature, param, &arg))
148+
.filter(|(param, arg)| should_show_param_name_hint(sema, &fn_signature, param, &arg))
148149
.map(|(param_name, arg)| InlayHint {
149150
range: arg.syntax().text_range(),
150151
kind: InlayKind::ParameterHint,
@@ -181,7 +182,7 @@ fn get_bind_pat_hints(
181182

182183
fn pat_is_enum_variant(db: &RootDatabase, bind_pat: &ast::BindPat, pat_ty: &Type) -> bool {
183184
if let Some(Adt::Enum(enum_data)) = pat_ty.as_adt() {
184-
let pat_text = bind_pat.syntax().to_string();
185+
let pat_text = bind_pat.to_string();
185186
enum_data
186187
.variants(db)
187188
.into_iter()
@@ -198,7 +199,7 @@ fn should_not_display_type_hint(db: &RootDatabase, bind_pat: &ast::BindPat, pat_
198199
}
199200

200201
if let Some(Adt::Struct(s)) = pat_ty.as_adt() {
201-
if s.fields(db).is_empty() && s.name(db).to_string() == bind_pat.syntax().to_string() {
202+
if s.fields(db).is_empty() && s.name(db).to_string() == bind_pat.to_string() {
202203
return true;
203204
}
204205
}
@@ -230,15 +231,16 @@ fn should_not_display_type_hint(db: &RootDatabase, bind_pat: &ast::BindPat, pat_
230231
false
231232
}
232233

233-
fn should_show_param_hint(
234+
fn should_show_param_name_hint(
235+
sema: &Semantics<RootDatabase>,
234236
fn_signature: &FunctionSignature,
235237
param_name: &str,
236238
argument: &ast::Expr,
237239
) -> bool {
240+
let param_name = param_name.trim_start_matches('_');
238241
if param_name.is_empty()
239-
|| is_argument_similar_to_param(argument, param_name)
240-
|| Some(param_name.trim_start_matches('_'))
241-
== fn_signature.name.as_ref().map(|s| s.trim_start_matches('_'))
242+
|| Some(param_name) == fn_signature.name.as_ref().map(|s| s.trim_start_matches('_'))
243+
|| is_argument_similar_to_param_name(sema, argument, param_name)
242244
{
243245
return false;
244246
}
@@ -254,20 +256,42 @@ fn should_show_param_hint(
254256
parameters_len != 1 || !is_obvious_param(param_name)
255257
}
256258

257-
fn is_argument_similar_to_param(argument: &ast::Expr, param_name: &str) -> bool {
258-
let argument_string = remove_ref(argument.clone()).syntax().to_string();
259-
let param_name = param_name.trim_start_matches('_');
260-
let argument_string = argument_string.trim_start_matches('_');
261-
argument_string.starts_with(&param_name) || argument_string.ends_with(&param_name)
259+
fn is_argument_similar_to_param_name(
260+
sema: &Semantics<RootDatabase>,
261+
argument: &ast::Expr,
262+
param_name: &str,
263+
) -> bool {
264+
if is_enum_name_similar_to_param_name(sema, argument, param_name) {
265+
return true;
266+
}
267+
match get_string_representation(argument) {
268+
None => false,
269+
Some(repr) => {
270+
let argument_string = repr.trim_start_matches('_');
271+
argument_string.starts_with(param_name) || argument_string.ends_with(param_name)
272+
}
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)) => to_lower_snake_case(&e.name(sema.db).to_string()) == param_name,
283+
_ => false,
284+
}
262285
}
263286

264-
fn remove_ref(expr: ast::Expr) -> ast::Expr {
265-
if let ast::Expr::RefExpr(ref_expr) = &expr {
266-
if let Some(inner) = ref_expr.expr() {
267-
return inner;
287+
fn get_string_representation(expr: &ast::Expr) -> Option<String> {
288+
match expr {
289+
ast::Expr::MethodCallExpr(method_call_expr) => {
290+
Some(method_call_expr.name_ref()?.to_string())
268291
}
292+
ast::Expr::RefExpr(ref_expr) => get_string_representation(&ref_expr.expr()?),
293+
_ => Some(expr.to_string()),
269294
}
270-
expr
271295
}
272296

273297
fn is_obvious_param(param_name: &str) -> bool {
@@ -1073,6 +1097,12 @@ struct TestVarContainer {
10731097
test_var: i32,
10741098
}
10751099
1100+
impl TestVarContainer {
1101+
fn test_var(&self) -> i32 {
1102+
self.test_var
1103+
}
1104+
}
1105+
10761106
struct Test {}
10771107
10781108
impl Test {
@@ -1098,10 +1128,15 @@ struct Param {}
10981128
fn different_order(param: &Param) {}
10991129
fn different_order_mut(param: &mut Param) {}
11001130
fn has_underscore(_param: bool) {}
1131+
fn enum_matches_param_name(completion_kind: CompletionKind) {}
11011132
11021133
fn twiddle(twiddle: bool) {}
11031134
fn doo(_doo: bool) {}
11041135
1136+
enum CompletionKind {
1137+
Keyword,
1138+
}
1139+
11051140
fn main() {
11061141
let container: TestVarContainer = TestVarContainer { test_var: 42 };
11071142
let test: Test = Test {};
@@ -1114,18 +1149,21 @@ fn main() {
11141149
let test_var: i32 = 55;
11151150
test_processed.no_hints_expected(22, test_var);
11161151
test_processed.no_hints_expected(33, container.test_var);
1152+
test_processed.no_hints_expected(44, container.test_var());
11171153
test_processed.frob(false);
11181154
11191155
twiddle(true);
11201156
doo(true);
11211157
1122-
let param_begin: Param = Param {};
1158+
let mut param_begin: Param = Param {};
11231159
different_order(&param_begin);
11241160
different_order(&mut param_begin);
11251161
11261162
let param: bool = true;
11271163
has_underscore(param);
11281164
1165+
enum_matches_param_name(CompletionKind::Keyword);
1166+
11291167
let a: f64 = 7.0;
11301168
let b: f64 = 4.0;
11311169
let _: f64 = a.div_euclid(b);

crates/stdx/src/lib.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,3 +102,17 @@ pub fn timeit(label: &'static str) -> impl Drop {
102102

103103
Guard { label, start: Instant::now() }
104104
}
105+
106+
pub fn to_lower_snake_case(s: &str) -> String {
107+
let mut buf = String::with_capacity(s.len());
108+
let mut prev = false;
109+
for c in s.chars() {
110+
if c.is_ascii_uppercase() && prev {
111+
buf.push('_')
112+
}
113+
prev = true;
114+
115+
buf.push(c.to_ascii_lowercase());
116+
}
117+
buf
118+
}

0 commit comments

Comments
 (0)