@@ -64,17 +64,35 @@ pub(crate) fn inlay_hints(
6464 let file = sema. parse ( file_id) ;
6565
6666 let mut res = Vec :: new ( ) ;
67- for node in file. syntax ( ) . descendants ( ) {
68- if let Some ( expr) = ast:: Expr :: cast ( node. clone ( ) ) {
69- get_chaining_hints ( & mut res, & sema, config, expr) ;
70- }
67+ let mut queue = vec ! [ file. syntax( ) . preorder( ) ] ;
7168
72- match_ast ! {
73- match node {
74- ast:: CallExpr ( it) => { get_param_name_hints( & mut res, & sema, config, ast:: Expr :: from( it) ) ; } ,
75- ast:: MethodCallExpr ( it) => { get_param_name_hints( & mut res, & sema, config, ast:: Expr :: from( it) ) ; } ,
76- ast:: IdentPat ( it) => { get_bind_pat_hints( & mut res, & sema, config, it) ; } ,
77- _ => ( ) ,
69+ while let Some ( mut preorder) = queue. pop ( ) {
70+ while let Some ( event) = preorder. next ( ) {
71+ let node = match event {
72+ syntax:: WalkEvent :: Enter ( node) => node,
73+ syntax:: WalkEvent :: Leave ( _) => continue ,
74+ } ;
75+ if let Some ( node) =
76+ ast:: Item :: cast ( node. clone ( ) ) . and_then ( |item| sema. expand_attr_macro ( & item) )
77+ {
78+ preorder. skip_subtree ( ) ;
79+ queue. push ( node. preorder ( ) ) ;
80+ continue ;
81+ }
82+
83+ if let Some ( expr) = ast:: Expr :: cast ( node. clone ( ) ) {
84+ get_chaining_hints ( & mut res, & sema, config, & expr) ;
85+ match expr {
86+ ast:: Expr :: CallExpr ( it) => {
87+ get_param_name_hints ( & mut res, & sema, config, ast:: Expr :: from ( it) ) ;
88+ }
89+ ast:: Expr :: MethodCallExpr ( it) => {
90+ get_param_name_hints ( & mut res, & sema, config, ast:: Expr :: from ( it) ) ;
91+ }
92+ _ => ( ) ,
93+ }
94+ } else if let Some ( it) = ast:: IdentPat :: cast ( node. clone ( ) ) {
95+ get_bind_pat_hints ( & mut res, & sema, config, it) ;
7896 }
7997 }
8098 }
@@ -85,7 +103,7 @@ fn get_chaining_hints(
85103 acc : & mut Vec < InlayHint > ,
86104 sema : & Semantics < RootDatabase > ,
87105 config : & InlayHintsConfig ,
88- expr : ast:: Expr ,
106+ expr : & ast:: Expr ,
89107) -> Option < ( ) > {
90108 if !config. chaining_hints {
91109 return None ;
@@ -117,7 +135,7 @@ fn get_chaining_hints(
117135 next_next = tokens. next ( ) ?. kind ( ) ;
118136 }
119137 if next_next == T ! [ . ] {
120- let ty = sema. type_of_expr ( & expr) ?. original ;
138+ let ty = sema. type_of_expr ( expr) ?. original ;
121139 if ty. is_unknown ( ) {
122140 return None ;
123141 }
@@ -129,7 +147,7 @@ fn get_chaining_hints(
129147 }
130148 }
131149 acc. push ( InlayHint {
132- range : expr. syntax ( ) . text_range ( ) ,
150+ range : sema . original_range ( expr. syntax ( ) ) . range ,
133151 kind : InlayKind :: ChainingHint ,
134152 label : hint_iterator ( sema, & famous_defs, config, & ty) . unwrap_or_else ( || {
135153 ty. display_truncated ( sema. db , config. max_length ) . to_string ( ) . into ( )
@@ -167,7 +185,7 @@ fn get_param_name_hints(
167185 } )
168186 . filter ( |( param_name, arg) | !should_hide_param_name_hint ( sema, & callable, param_name, arg) )
169187 . map ( |( param_name, arg) | InlayHint {
170- range : arg. syntax ( ) . text_range ( ) ,
188+ range : sema . original_range ( arg. syntax ( ) ) . range ,
171189 kind : InlayKind :: ParameterHint ,
172190 label : param_name. into ( ) ,
173191 } ) ;
@@ -197,8 +215,8 @@ fn get_bind_pat_hints(
197215
198216 acc. push ( InlayHint {
199217 range : match pat. name ( ) {
200- Some ( name) => name. syntax ( ) . text_range ( ) ,
201- None => pat. syntax ( ) . text_range ( ) ,
218+ Some ( name) => sema . original_range ( name. syntax ( ) ) . range ,
219+ None => sema . original_range ( pat. syntax ( ) ) . range ,
202220 } ,
203221 kind : InlayKind :: TypeHint ,
204222 label : hint_iterator ( sema, & famous_defs, config, & ty)
@@ -1467,4 +1485,67 @@ fn main() {
14671485 "# ] ] ,
14681486 ) ;
14691487 }
1488+
1489+ #[ test]
1490+ fn hints_in_attr_call ( ) {
1491+ // chaining hints do not currently work as macros lose all whitespace information
1492+ check_expect (
1493+ TEST_CONFIG ,
1494+ r#"
1495+ //- proc_macros: identity, input_replace
1496+ struct Struct;
1497+ impl Struct {
1498+ fn chain(self) -> Self {
1499+ self
1500+ }
1501+ }
1502+
1503+ #[proc_macros::identity]
1504+ fn main() {
1505+ let strukt = Struct;
1506+ strukt
1507+ .chain()
1508+ .chain()
1509+ .chain();
1510+ Struct::chain(strukt);
1511+ }
1512+
1513+ #[proc_macros::input_replace(
1514+ fn not_main() {
1515+ let strukt = Struct;
1516+ strukt
1517+ .chain()
1518+ .chain()
1519+ .chain();
1520+ Struct::chain(strukt);
1521+ }
1522+ )]
1523+ fn main() {}
1524+ "# ,
1525+ expect ! [ [ r#"
1526+ [
1527+ InlayHint {
1528+ range: 297..303,
1529+ kind: TypeHint,
1530+ label: "Struct",
1531+ },
1532+ InlayHint {
1533+ range: 415..421,
1534+ kind: ParameterHint,
1535+ label: "self",
1536+ },
1537+ InlayHint {
1538+ range: 125..131,
1539+ kind: TypeHint,
1540+ label: "Struct",
1541+ },
1542+ InlayHint {
1543+ range: 223..229,
1544+ kind: ParameterHint,
1545+ label: "self",
1546+ },
1547+ ]
1548+ "# ] ] ,
1549+ ) ;
1550+ }
14701551}
0 commit comments