@@ -150,17 +150,11 @@ fn get_param_name_hints(
150
150
return None ;
151
151
}
152
152
153
- let args = match & expr {
154
- ast:: Expr :: CallExpr ( expr) => expr. arg_list ( ) ?. args ( ) ,
155
- ast:: Expr :: MethodCallExpr ( expr) => expr. arg_list ( ) ?. args ( ) ,
156
- _ => return None ,
157
- } ;
158
-
159
- let callable = get_callable ( sema, & expr) ?;
153
+ let ( callable, arg_list) = get_callable ( sema, & expr) ?;
160
154
let hints = callable
161
155
. params ( sema. db )
162
156
. into_iter ( )
163
- . zip ( args)
157
+ . zip ( arg_list . args ( ) )
164
158
. filter_map ( |( ( param, _ty) , arg) | {
165
159
let param_name = match param? {
166
160
Either :: Left ( _) => "self" . to_string ( ) ,
@@ -171,7 +165,7 @@ fn get_param_name_hints(
171
165
} ;
172
166
Some ( ( param_name, arg) )
173
167
} )
174
- . filter ( |( param_name, arg) | should_show_param_name_hint ( sema, & callable, param_name, & arg) )
168
+ . filter ( |( param_name, arg) | ! should_hide_param_name_hint ( sema, & callable, param_name, & arg) )
175
169
. map ( |( param_name, arg) | InlayHint {
176
170
range : arg. syntax ( ) . text_range ( ) ,
177
171
kind : InlayKind :: ParameterHint ,
@@ -289,15 +283,9 @@ fn should_not_display_type_hint(
289
283
for node in bind_pat. syntax ( ) . ancestors ( ) {
290
284
match_ast ! {
291
285
match node {
292
- ast:: LetStmt ( it) => {
293
- return it. ty( ) . is_some( )
294
- } ,
295
- ast:: Param ( it) => {
296
- return it. ty( ) . is_some( )
297
- } ,
298
- ast:: MatchArm ( _it) => {
299
- return pat_is_enum_variant( db, bind_pat, pat_ty) ;
300
- } ,
286
+ ast:: LetStmt ( it) => return it. ty( ) . is_some( ) ,
287
+ ast:: Param ( it) => return it. ty( ) . is_some( ) ,
288
+ ast:: MatchArm ( _it) => return pat_is_enum_variant( db, bind_pat, pat_ty) ,
301
289
ast:: IfExpr ( it) => {
302
290
return it. condition( ) . and_then( |condition| condition. pat( ) ) . is_some( )
303
291
&& pat_is_enum_variant( db, bind_pat, pat_ty) ;
@@ -322,76 +310,66 @@ fn should_not_display_type_hint(
322
310
false
323
311
}
324
312
325
- fn should_show_param_name_hint (
313
+ fn should_hide_param_name_hint (
326
314
sema : & Semantics < RootDatabase > ,
327
315
callable : & hir:: Callable ,
328
316
param_name : & str ,
329
317
argument : & ast:: Expr ,
330
318
) -> bool {
319
+ // hide when:
320
+ // - the parameter name is a suffix of the function's name
321
+ // - the argument is an enum whose name is equal to the parameter
322
+ // - exact argument<->parameter match(ignoring leading underscore) or argument is a prefix/suffix
323
+ // of parameter with _ splitting it off
324
+ // - param starts with `ra_fixture`
325
+ // - param is a well known name in an unary function
326
+
331
327
let param_name = param_name. trim_start_matches ( '_' ) ;
328
+ if param_name. is_empty ( ) {
329
+ return true ;
330
+ }
331
+
332
332
let fn_name = match callable. kind ( ) {
333
333
hir:: CallableKind :: Function ( it) => Some ( it. name ( sema. db ) . to_string ( ) ) ,
334
- hir:: CallableKind :: TupleStruct ( _)
335
- | hir:: CallableKind :: TupleEnumVariant ( _)
336
- | hir:: CallableKind :: Closure => None ,
334
+ _ => None ,
337
335
} ;
338
-
339
- if param_name. is_empty ( )
340
- || Some ( param_name) == fn_name. as_ref ( ) . map ( |s| s. trim_start_matches ( '_' ) )
341
- || is_argument_similar_to_param_name ( sema, argument, param_name)
342
- || is_param_name_similar_to_fn_name ( param_name, callable, fn_name. as_ref ( ) )
336
+ let fn_name = fn_name. as_deref ( ) ;
337
+ is_param_name_suffix_of_fn_name ( param_name, callable, fn_name)
338
+ || is_enum_name_similar_to_param_name ( sema, argument, param_name)
339
+ || is_argument_similar_to_param_name ( argument, param_name)
343
340
|| param_name. starts_with ( "ra_fixture" )
344
- {
345
- return false ;
346
- }
347
-
348
- // avoid displaying hints for common functions like map, filter, etc.
349
- // or other obvious words used in std
350
- !( callable. n_params ( ) == 1 && is_obvious_param ( param_name) )
341
+ || ( callable. n_params ( ) == 1 && is_obvious_param ( param_name) )
351
342
}
352
343
353
- fn is_argument_similar_to_param_name (
354
- sema : & Semantics < RootDatabase > ,
355
- argument : & ast:: Expr ,
356
- param_name : & str ,
357
- ) -> bool {
358
- if is_enum_name_similar_to_param_name ( sema, argument, param_name) {
359
- return true ;
360
- }
344
+ fn is_argument_similar_to_param_name ( argument : & ast:: Expr , param_name : & str ) -> bool {
361
345
match get_string_representation ( argument) {
362
346
None => false ,
363
- Some ( argument_string) => {
364
- let num_leading_underscores =
365
- argument_string. bytes ( ) . take_while ( |& c| c == b'_' ) . count ( ) ;
366
-
367
- // Does the argument name begin with the parameter name? Ignore leading underscores.
368
- let mut arg_bytes = argument_string. bytes ( ) . skip ( num_leading_underscores) ;
369
- let starts_with_pattern = param_name. bytes ( ) . all (
370
- |expected| matches ! ( arg_bytes. next( ) , Some ( actual) if expected. eq_ignore_ascii_case( & actual) ) ,
371
- ) ;
372
-
373
- if starts_with_pattern {
374
- return true ;
347
+ Some ( argument) => {
348
+ let mut res = false ;
349
+ if let Some ( first) = argument. bytes ( ) . skip_while ( |& c| c == b'_' ) . position ( |c| c == b'_' )
350
+ {
351
+ res |= param_name == argument[ ..first] . trim_start_matches ( '_' ) ;
375
352
}
376
-
377
- // Does the argument name end with the parameter name?
378
- let mut arg_bytes = argument_string. bytes ( ) . skip ( num_leading_underscores) ;
379
- param_name. bytes ( ) . rev ( ) . all (
380
- |expected| matches ! ( arg_bytes. next_back( ) , Some ( actual) if expected. eq_ignore_ascii_case( & actual) ) ,
381
- )
353
+ if let Some ( last) =
354
+ argument. bytes ( ) . rev ( ) . skip_while ( |& c| c == b'_' ) . position ( |c| c == b'_' )
355
+ {
356
+ res |= param_name == argument[ last..] . trim_end_matches ( '_' ) ;
357
+ }
358
+ res |= argument == param_name;
359
+ res
382
360
}
383
361
}
384
362
}
385
363
386
- fn is_param_name_similar_to_fn_name (
364
+ /// Hide the parameter name of an unary function if it is a `_` - prefixed suffix of the function's name, or equal.
365
+ ///
366
+ /// `fn strip_suffix(suffix)` will be hidden.
367
+ /// `fn stripsuffix(suffix)` will not be hidden.
368
+ fn is_param_name_suffix_of_fn_name (
387
369
param_name : & str ,
388
370
callable : & Callable ,
389
- fn_name : Option < & String > ,
371
+ fn_name : Option < & str > ,
390
372
) -> bool {
391
- // if it's the only parameter, don't show it if:
392
- // - is the same as the function name, or
393
- // - the function ends with '_' + param_name
394
-
395
373
match ( callable. n_params ( ) , fn_name) {
396
374
( 1 , Some ( function) ) => {
397
375
function == param_name
@@ -424,23 +402,32 @@ fn get_string_representation(expr: &ast::Expr) -> Option<String> {
424
402
}
425
403
}
426
404
ast:: Expr :: FieldExpr ( field_expr) => Some ( field_expr. name_ref ( ) ?. to_string ( ) ) ,
427
- ast:: Expr :: PathExpr ( path_expr) => Some ( path_expr. to_string ( ) ) ,
405
+ ast:: Expr :: PathExpr ( path_expr) => Some ( path_expr. path ( ) ? . segment ( ) ? . to_string ( ) ) ,
428
406
ast:: Expr :: PrefixExpr ( prefix_expr) => get_string_representation ( & prefix_expr. expr ( ) ?) ,
429
407
ast:: Expr :: RefExpr ( ref_expr) => get_string_representation ( & ref_expr. expr ( ) ?) ,
430
408
_ => None ,
431
409
}
432
410
}
433
411
434
412
fn is_obvious_param ( param_name : & str ) -> bool {
413
+ // avoid displaying hints for common functions like map, filter, etc.
414
+ // or other obvious words used in std
435
415
let is_obvious_param_name =
436
416
matches ! ( param_name, "predicate" | "value" | "pat" | "rhs" | "other" ) ;
437
417
param_name. len ( ) == 1 || is_obvious_param_name
438
418
}
439
419
440
- fn get_callable ( sema : & Semantics < RootDatabase > , expr : & ast:: Expr ) -> Option < hir:: Callable > {
420
+ fn get_callable (
421
+ sema : & Semantics < RootDatabase > ,
422
+ expr : & ast:: Expr ,
423
+ ) -> Option < ( hir:: Callable , ast:: ArgList ) > {
441
424
match expr {
442
- ast:: Expr :: CallExpr ( expr) => sema. type_of_expr ( & expr. expr ( ) ?) ?. as_callable ( sema. db ) ,
443
- ast:: Expr :: MethodCallExpr ( expr) => sema. resolve_method_call_as_callable ( expr) ,
425
+ ast:: Expr :: CallExpr ( expr) => {
426
+ sema. type_of_expr ( & expr. expr ( ) ?) ?. as_callable ( sema. db ) . zip ( expr. arg_list ( ) )
427
+ }
428
+ ast:: Expr :: MethodCallExpr ( expr) => {
429
+ sema. resolve_method_call_as_callable ( expr) . zip ( expr. arg_list ( ) )
430
+ }
444
431
_ => None ,
445
432
}
446
433
}
0 commit comments