11use either:: Either ;
22use hir:: { known, Callable , HasVisibility , HirDisplay , Semantics , TypeInfo } ;
3- use ide_db:: helpers:: FamousDefs ;
43use ide_db:: RootDatabase ;
4+ use ide_db:: { base_db:: FileRange , helpers:: FamousDefs } ;
55use stdx:: to_lower_snake_case;
66use syntax:: {
77 ast:: { self , ArgListOwner , AstNode , NameOwner } ,
@@ -79,7 +79,7 @@ pub(crate) fn inlay_hints(
7979 _ => ( ) ,
8080 }
8181 } else if let Some ( it) = ast:: IdentPat :: cast ( node. clone ( ) ) {
82- get_bind_pat_hints ( & mut res, & sema, config, it) ;
82+ get_bind_pat_hints ( & mut res, & sema, config, & it) ;
8383 }
8484 }
8585 res
@@ -99,7 +99,9 @@ fn get_chaining_hints(
9999 return None ;
100100 }
101101
102- let krate = sema. scope ( expr. syntax ( ) ) . module ( ) . map ( |it| it. krate ( ) ) ;
102+ let descended = sema. descend_node_into_attributes ( expr. clone ( ) ) . pop ( ) ;
103+ let desc_expr = descended. as_ref ( ) . unwrap_or ( expr) ;
104+ let krate = sema. scope ( desc_expr. syntax ( ) ) . module ( ) . map ( |it| it. krate ( ) ) ;
103105 let famous_defs = FamousDefs ( sema, krate) ;
104106
105107 let mut tokens = expr
@@ -121,7 +123,7 @@ fn get_chaining_hints(
121123 next_next = tokens. next ( ) ?. kind ( ) ;
122124 }
123125 if next_next == T ! [ . ] {
124- let ty = sema. type_of_expr ( expr ) ?. original ;
126+ let ty = sema. type_of_expr ( desc_expr ) ?. original ;
125127 if ty. is_unknown ( ) {
126128 return None ;
127129 }
@@ -133,7 +135,7 @@ fn get_chaining_hints(
133135 }
134136 }
135137 acc. push ( InlayHint {
136- range : sema . original_range ( expr. syntax ( ) ) . range ,
138+ range : expr. syntax ( ) . text_range ( ) ,
137139 kind : InlayKind :: ChainingHint ,
138140 label : hint_iterator ( sema, & famous_defs, config, & ty) . unwrap_or_else ( || {
139141 ty. display_truncated ( sema. db , config. max_length ) . to_string ( ) . into ( )
@@ -160,18 +162,22 @@ fn get_param_name_hints(
160162 . into_iter ( )
161163 . zip ( arg_list. args ( ) )
162164 . filter_map ( |( ( param, _ty) , arg) | {
165+ // Only annotate hints for expressions that exist in the original file
166+ let range = sema. original_range_opt ( arg. syntax ( ) ) ?;
163167 let param_name = match param? {
164168 Either :: Left ( _) => "self" . to_string ( ) ,
165169 Either :: Right ( pat) => match pat {
166170 ast:: Pat :: IdentPat ( it) => it. name ( ) ?. to_string ( ) ,
167171 _ => return None ,
168172 } ,
169173 } ;
170- Some ( ( param_name, arg) )
174+ Some ( ( param_name, arg, range ) )
171175 } )
172- . filter ( |( param_name, arg) | !should_hide_param_name_hint ( sema, & callable, param_name, arg) )
173- . map ( |( param_name, arg) | InlayHint {
174- range : sema. original_range ( arg. syntax ( ) ) . range ,
176+ . filter ( |( param_name, arg, _) | {
177+ !should_hide_param_name_hint ( sema, & callable, param_name, arg)
178+ } )
179+ . map ( |( param_name, _, FileRange { range, .. } ) | InlayHint {
180+ range,
175181 kind : InlayKind :: ParameterHint ,
176182 label : param_name. into ( ) ,
177183 } ) ;
@@ -184,25 +190,27 @@ fn get_bind_pat_hints(
184190 acc : & mut Vec < InlayHint > ,
185191 sema : & Semantics < RootDatabase > ,
186192 config : & InlayHintsConfig ,
187- pat : ast:: IdentPat ,
193+ pat : & ast:: IdentPat ,
188194) -> Option < ( ) > {
189195 if !config. type_hints {
190196 return None ;
191197 }
192198
193- let krate = sema. scope ( pat. syntax ( ) ) . module ( ) . map ( |it| it. krate ( ) ) ;
199+ let descended = sema. descend_node_into_attributes ( pat. clone ( ) ) . pop ( ) ;
200+ let desc_pat = descended. as_ref ( ) . unwrap_or ( pat) ;
201+ let krate = sema. scope ( desc_pat. syntax ( ) ) . module ( ) . map ( |it| it. krate ( ) ) ;
194202 let famous_defs = FamousDefs ( sema, krate) ;
195203
196- let ty = sema. type_of_pat ( & pat . clone ( ) . into ( ) ) ?. original ;
204+ let ty = sema. type_of_pat ( & desc_pat . clone ( ) . into ( ) ) ?. original ;
197205
198206 if should_not_display_type_hint ( sema, & pat, & ty) {
199207 return None ;
200208 }
201209
202210 acc. push ( InlayHint {
203211 range : match pat. name ( ) {
204- Some ( name) => sema . original_range ( name. syntax ( ) ) . range ,
205- None => sema . original_range ( pat. syntax ( ) ) . range ,
212+ Some ( name) => name. syntax ( ) . text_range ( ) ,
213+ None => pat. syntax ( ) . text_range ( ) ,
206214 } ,
207215 kind : InlayKind :: TypeHint ,
208216 label : hint_iterator ( sema, & famous_defs, config, & ty)
@@ -435,9 +443,13 @@ fn get_callable(
435443) -> Option < ( hir:: Callable , ast:: ArgList ) > {
436444 match expr {
437445 ast:: Expr :: CallExpr ( expr) => {
446+ let descended = sema. descend_node_into_attributes ( expr. clone ( ) ) . pop ( ) ;
447+ let expr = descended. as_ref ( ) . unwrap_or ( expr) ;
438448 sema. type_of_expr ( & expr. expr ( ) ?) ?. original . as_callable ( sema. db ) . zip ( expr. arg_list ( ) )
439449 }
440450 ast:: Expr :: MethodCallExpr ( expr) => {
451+ let descended = sema. descend_node_into_attributes ( expr. clone ( ) ) . pop ( ) ;
452+ let expr = descended. as_ref ( ) . unwrap_or ( expr) ;
441453 sema. resolve_method_call_as_callable ( expr) . zip ( expr. arg_list ( ) )
442454 }
443455 _ => None ,
@@ -1471,4 +1483,53 @@ fn main() {
14711483 "# ] ] ,
14721484 ) ;
14731485 }
1486+
1487+ #[ test]
1488+ fn hints_in_attr_call ( ) {
1489+ check_expect (
1490+ TEST_CONFIG ,
1491+ r#"
1492+ //- proc_macros: identity, input_replace
1493+ struct Struct;
1494+ impl Struct {
1495+ fn chain(self) -> Self {
1496+ self
1497+ }
1498+ }
1499+ #[proc_macros::identity]
1500+ fn main() {
1501+ let strukt = Struct;
1502+ strukt
1503+ .chain()
1504+ .chain()
1505+ .chain();
1506+ Struct::chain(strukt);
1507+ }
1508+ "# ,
1509+ expect ! [ [ r#"
1510+ [
1511+ InlayHint {
1512+ range: 124..130,
1513+ kind: TypeHint,
1514+ label: "Struct",
1515+ },
1516+ InlayHint {
1517+ range: 145..185,
1518+ kind: ChainingHint,
1519+ label: "Struct",
1520+ },
1521+ InlayHint {
1522+ range: 145..168,
1523+ kind: ChainingHint,
1524+ label: "Struct",
1525+ },
1526+ InlayHint {
1527+ range: 222..228,
1528+ kind: ParameterHint,
1529+ label: "self",
1530+ },
1531+ ]
1532+ "# ] ] ,
1533+ ) ;
1534+ }
14741535}
0 commit comments