@@ -9,6 +9,7 @@ use ra_syntax::{
9
9
} ;
10
10
11
11
use crate :: { FileId , FunctionSignature } ;
12
+ use stdx:: to_lower_snake_case;
12
13
13
14
#[ derive( Clone , Debug , PartialEq , Eq ) ]
14
15
pub struct InlayHintsConfig {
@@ -144,7 +145,7 @@ fn get_param_name_hints(
144
145
. iter ( )
145
146
. skip ( n_params_to_skip)
146
147
. 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) )
148
149
. map ( |( param_name, arg) | InlayHint {
149
150
range : arg. syntax ( ) . text_range ( ) ,
150
151
kind : InlayKind :: ParameterHint ,
@@ -181,7 +182,7 @@ fn get_bind_pat_hints(
181
182
182
183
fn pat_is_enum_variant ( db : & RootDatabase , bind_pat : & ast:: BindPat , pat_ty : & Type ) -> bool {
183
184
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 ( ) ;
185
186
enum_data
186
187
. variants ( db)
187
188
. into_iter ( )
@@ -198,7 +199,7 @@ fn should_not_display_type_hint(db: &RootDatabase, bind_pat: &ast::BindPat, pat_
198
199
}
199
200
200
201
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 ( ) {
202
203
return true ;
203
204
}
204
205
}
@@ -230,15 +231,16 @@ fn should_not_display_type_hint(db: &RootDatabase, bind_pat: &ast::BindPat, pat_
230
231
false
231
232
}
232
233
233
- fn should_show_param_hint (
234
+ fn should_show_param_name_hint (
235
+ sema : & Semantics < RootDatabase > ,
234
236
fn_signature : & FunctionSignature ,
235
237
param_name : & str ,
236
238
argument : & ast:: Expr ,
237
239
) -> bool {
240
+ let param_name = param_name. trim_start_matches ( '_' ) ;
238
241
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)
242
244
{
243
245
return false ;
244
246
}
@@ -254,20 +256,42 @@ fn should_show_param_hint(
254
256
parameters_len != 1 || !is_obvious_param ( param_name)
255
257
}
256
258
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
+ }
262
285
}
263
286
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 ( ) )
268
291
}
292
+ ast:: Expr :: RefExpr ( ref_expr) => get_string_representation ( & ref_expr. expr ( ) ?) ,
293
+ _ => Some ( expr. to_string ( ) ) ,
269
294
}
270
- expr
271
295
}
272
296
273
297
fn is_obvious_param ( param_name : & str ) -> bool {
@@ -1073,6 +1097,12 @@ struct TestVarContainer {
1073
1097
test_var: i32,
1074
1098
}
1075
1099
1100
+ impl TestVarContainer {
1101
+ fn test_var(&self) -> i32 {
1102
+ self.test_var
1103
+ }
1104
+ }
1105
+
1076
1106
struct Test {}
1077
1107
1078
1108
impl Test {
@@ -1098,10 +1128,15 @@ struct Param {}
1098
1128
fn different_order(param: &Param) {}
1099
1129
fn different_order_mut(param: &mut Param) {}
1100
1130
fn has_underscore(_param: bool) {}
1131
+ fn enum_matches_param_name(completion_kind: CompletionKind) {}
1101
1132
1102
1133
fn twiddle(twiddle: bool) {}
1103
1134
fn doo(_doo: bool) {}
1104
1135
1136
+ enum CompletionKind {
1137
+ Keyword,
1138
+ }
1139
+
1105
1140
fn main() {
1106
1141
let container: TestVarContainer = TestVarContainer { test_var: 42 };
1107
1142
let test: Test = Test {};
@@ -1114,18 +1149,21 @@ fn main() {
1114
1149
let test_var: i32 = 55;
1115
1150
test_processed.no_hints_expected(22, test_var);
1116
1151
test_processed.no_hints_expected(33, container.test_var);
1152
+ test_processed.no_hints_expected(44, container.test_var());
1117
1153
test_processed.frob(false);
1118
1154
1119
1155
twiddle(true);
1120
1156
doo(true);
1121
1157
1122
- let param_begin: Param = Param {};
1158
+ let mut param_begin: Param = Param {};
1123
1159
different_order(¶m_begin);
1124
1160
different_order(&mut param_begin);
1125
1161
1126
1162
let param: bool = true;
1127
1163
has_underscore(param);
1128
1164
1165
+ enum_matches_param_name(CompletionKind::Keyword);
1166
+
1129
1167
let a: f64 = 7.0;
1130
1168
let b: f64 = 4.0;
1131
1169
let _: f64 = a.div_euclid(b);
0 commit comments