@@ -5,7 +5,7 @@ use ra_ide_db::RootDatabase;
55use ra_prof:: profile;
66use ra_syntax:: {
77 ast:: { self , ArgListOwner , AstNode , TypeAscriptionOwner } ,
8- match_ast, SmolStr , SyntaxNode , TextRange ,
8+ match_ast, SmolStr , TextRange ,
99} ;
1010
1111use crate :: { FileId , FunctionSignature } ;
@@ -28,50 +28,76 @@ pub(crate) fn inlay_hints(
2828 file_id : FileId ,
2929 max_inlay_hint_length : Option < usize > ,
3030) -> Vec < InlayHint > {
31+ let _p = profile ( "inlay_hints" ) ;
3132 let sema = Semantics :: new ( db) ;
3233 let file = sema. parse ( file_id) ;
34+
3335 let mut res = Vec :: new ( ) ;
3436 for node in file. syntax ( ) . descendants ( ) {
35- get_inlay_hints ( & mut res, & sema, & node, max_inlay_hint_length) ;
37+ match_ast ! {
38+ match node {
39+ ast:: CallExpr ( it) => { get_param_name_hints( & mut res, & sema, ast:: Expr :: from( it) ) ; } ,
40+ ast:: MethodCallExpr ( it) => { get_param_name_hints( & mut res, & sema, ast:: Expr :: from( it) ) ; } ,
41+ ast:: BindPat ( it) => { get_bind_pat_hints( & mut res, & sema, max_inlay_hint_length, it) ; } ,
42+ _ => ( ) ,
43+ }
44+ }
3645 }
3746 res
3847}
3948
40- fn get_inlay_hints (
49+ fn get_param_name_hints (
50+ acc : & mut Vec < InlayHint > ,
51+ sema : & Semantics < RootDatabase > ,
52+ expr : ast:: Expr ,
53+ ) -> Option < ( ) > {
54+ let args = match & expr {
55+ ast:: Expr :: CallExpr ( expr) => expr. arg_list ( ) ?. args ( ) ,
56+ ast:: Expr :: MethodCallExpr ( expr) => expr. arg_list ( ) ?. args ( ) ,
57+ _ => return None ,
58+ } ;
59+ let args_count = args. clone ( ) . count ( ) ;
60+
61+ let fn_signature = get_fn_signature ( sema, & expr) ?;
62+ let n_params_to_skip =
63+ if fn_signature. has_self_param && fn_signature. parameter_names . len ( ) > args_count {
64+ 1
65+ } else {
66+ 0
67+ } ;
68+ let hints = fn_signature
69+ . parameter_names
70+ . iter ( )
71+ . skip ( n_params_to_skip)
72+ . zip ( args)
73+ . filter ( |( param, arg) | should_show_param_hint ( & fn_signature, param, & arg) )
74+ . map ( |( param_name, arg) | InlayHint {
75+ range : arg. syntax ( ) . text_range ( ) ,
76+ kind : InlayKind :: ParameterHint ,
77+ label : param_name. into ( ) ,
78+ } ) ;
79+
80+ acc. extend ( hints) ;
81+ Some ( ( ) )
82+ }
83+
84+ fn get_bind_pat_hints (
4185 acc : & mut Vec < InlayHint > ,
4286 sema : & Semantics < RootDatabase > ,
43- node : & SyntaxNode ,
4487 max_inlay_hint_length : Option < usize > ,
88+ pat : ast:: BindPat ,
4589) -> Option < ( ) > {
46- let _p = profile ( "get_inlay_hints" ) ;
47- let db = sema. db ;
48- match_ast ! {
49- match node {
50- ast:: CallExpr ( it) => {
51- get_param_name_hints( acc, sema, ast:: Expr :: from( it) ) ;
52- } ,
53- ast:: MethodCallExpr ( it) => {
54- get_param_name_hints( acc, sema, ast:: Expr :: from( it) ) ;
55- } ,
56- ast:: BindPat ( it) => {
57- let pat = ast:: Pat :: from( it. clone( ) ) ;
58- let ty = sema. type_of_pat( & pat) ?;
59-
60- if should_not_display_type_hint( db, & it, & ty) {
61- return None ;
62- }
90+ let ty = sema. type_of_pat ( & pat. clone ( ) . into ( ) ) ?;
6391
64- acc. push(
65- InlayHint {
66- range: pat. syntax( ) . text_range( ) ,
67- kind: InlayKind :: TypeHint ,
68- label: ty. display_truncated( db, max_inlay_hint_length) . to_string( ) . into( ) ,
69- }
70- ) ;
71- } ,
72- _ => ( ) ,
73- }
74- } ;
92+ if should_not_display_type_hint ( sema. db , & pat, & ty) {
93+ return None ;
94+ }
95+
96+ acc. push ( InlayHint {
97+ range : pat. syntax ( ) . text_range ( ) ,
98+ kind : InlayKind :: TypeHint ,
99+ label : ty. display_truncated ( sema. db , max_inlay_hint_length) . to_string ( ) . into ( ) ,
100+ } ) ;
75101 Some ( ( ) )
76102}
77103
@@ -120,43 +146,6 @@ fn should_not_display_type_hint(db: &RootDatabase, bind_pat: &ast::BindPat, pat_
120146 false
121147}
122148
123- fn get_param_name_hints (
124- acc : & mut Vec < InlayHint > ,
125- sema : & Semantics < RootDatabase > ,
126- expr : ast:: Expr ,
127- ) -> Option < ( ) > {
128- let args = match & expr {
129- ast:: Expr :: CallExpr ( expr) => expr. arg_list ( ) ?. args ( ) ,
130- ast:: Expr :: MethodCallExpr ( expr) => expr. arg_list ( ) ?. args ( ) ,
131- _ => return None ,
132- }
133- . into_iter ( )
134- // we need args len to determine whether to skip or not the &self parameter
135- . collect :: < Vec < _ > > ( ) ;
136-
137- let fn_signature = get_fn_signature ( sema, & expr) ?;
138- let n_params_to_skip =
139- if fn_signature. has_self_param && fn_signature. parameter_names . len ( ) > args. len ( ) {
140- 1
141- } else {
142- 0
143- } ;
144- let hints = fn_signature
145- . parameter_names
146- . iter ( )
147- . skip ( n_params_to_skip)
148- . zip ( args)
149- . filter ( |( param, arg) | should_show_param_hint ( & fn_signature, param, & arg) )
150- . map ( |( param_name, arg) | InlayHint {
151- range : arg. syntax ( ) . text_range ( ) ,
152- kind : InlayKind :: ParameterHint ,
153- label : param_name. into ( ) ,
154- } ) ;
155-
156- acc. extend ( hints) ;
157- Some ( ( ) )
158- }
159-
160149fn should_show_param_hint (
161150 fn_signature : & FunctionSignature ,
162151 param_name : & str ,
0 commit comments