@@ -83,29 +83,30 @@ impl<'a> InlayHintCollector<'a> {
83
83
let location = Location :: new ( ident. span ( ) , self . file_id ) ;
84
84
if let Some ( lsp_location) = to_lsp_location ( self . files , self . file_id , span) {
85
85
if let Some ( referenced) = self . interner . find_referenced ( location) {
86
+ let include_colon = true ;
86
87
match referenced {
87
88
ReferenceId :: Global ( global_id) => {
88
89
let global_info = self . interner . get_global ( global_id) ;
89
90
let definition_id = global_info. definition_id ;
90
91
let typ = self . interner . definition_type ( definition_id) ;
91
- self . push_type_hint ( lsp_location, & typ, editable) ;
92
+ self . push_type_hint ( lsp_location, & typ, editable, include_colon ) ;
92
93
}
93
94
ReferenceId :: Local ( definition_id) => {
94
95
let typ = self . interner . definition_type ( definition_id) ;
95
- self . push_type_hint ( lsp_location, & typ, editable) ;
96
+ self . push_type_hint ( lsp_location, & typ, editable, include_colon ) ;
96
97
}
97
98
ReferenceId :: StructMember ( struct_id, field_index) => {
98
99
let struct_type = self . interner . get_type ( struct_id) ;
99
100
let struct_type = struct_type. borrow ( ) ;
100
101
let field = struct_type. field_at ( field_index) ;
101
- self . push_type_hint ( lsp_location, & field. typ , false ) ;
102
+ self . push_type_hint ( lsp_location, & field. typ , false , include_colon ) ;
102
103
}
103
104
ReferenceId :: EnumVariant ( type_id, variant_index) => {
104
105
let typ = self . interner . get_type ( type_id) ;
105
106
let shared_type = typ. clone ( ) ;
106
107
let typ = typ. borrow ( ) ;
107
108
let variant_type = typ. variant_function_type ( variant_index, shared_type) ;
108
- self . push_type_hint ( lsp_location, & variant_type, false ) ;
109
+ self . push_type_hint ( lsp_location, & variant_type, false , include_colon ) ;
109
110
}
110
111
ReferenceId :: Module ( _)
111
112
| ReferenceId :: Struct ( _)
@@ -119,11 +120,21 @@ impl<'a> InlayHintCollector<'a> {
119
120
}
120
121
}
121
122
122
- fn push_type_hint ( & mut self , location : lsp_types:: Location , typ : & Type , editable : bool ) {
123
+ fn push_type_hint (
124
+ & mut self ,
125
+ location : lsp_types:: Location ,
126
+ typ : & Type ,
127
+ editable : bool ,
128
+ include_colon : bool ,
129
+ ) {
123
130
let position = location. range . end ;
124
131
125
132
let mut parts = Vec :: new ( ) ;
126
- parts. push ( string_part ( ": " ) ) ;
133
+ if include_colon {
134
+ parts. push ( string_part ( ": " ) ) ;
135
+ } else {
136
+ parts. push ( string_part ( " " ) ) ;
137
+ }
127
138
push_type_parts ( typ, & mut parts, self . files ) ;
128
139
129
140
self . inlay_hints . push ( InlayHint {
@@ -217,6 +228,36 @@ impl<'a> InlayHintCollector<'a> {
217
228
}
218
229
}
219
230
231
+ fn collect_method_call_chain_hints ( & mut self , method : & MethodCallExpression ) {
232
+ let Some ( object_lsp_location) =
233
+ to_lsp_location ( self . files , self . file_id , method. object . span )
234
+ else {
235
+ return ;
236
+ } ;
237
+
238
+ let Some ( name_lsp_location) =
239
+ to_lsp_location ( self . files , self . file_id , method. method_name . span ( ) )
240
+ else {
241
+ return ;
242
+ } ;
243
+
244
+ if object_lsp_location. range . end . line >= name_lsp_location. range . start . line {
245
+ return ;
246
+ }
247
+
248
+ let object_location = Location :: new ( method. object . span , self . file_id ) ;
249
+ let Some ( typ) = self . interner . type_at_location ( object_location) else {
250
+ return ;
251
+ } ;
252
+
253
+ self . push_type_hint (
254
+ object_lsp_location,
255
+ & typ,
256
+ false , // not editable
257
+ false , // don't include colon
258
+ ) ;
259
+ }
260
+
220
261
fn get_pattern_name ( & self , pattern : & HirPattern ) -> Option < String > {
221
262
match pattern {
222
263
HirPattern :: Identifier ( ident) => {
@@ -357,6 +398,10 @@ impl<'a> Visitor for InlayHintCollector<'a> {
357
398
& method_call_expression. arguments ,
358
399
) ;
359
400
401
+ if self . options . chaining_hints . enabled {
402
+ self . collect_method_call_chain_hints ( method_call_expression) ;
403
+ }
404
+
360
405
true
361
406
}
362
407
@@ -548,7 +593,9 @@ fn get_expression_name(expression: &Expression) -> Option<String> {
548
593
#[ cfg( test) ]
549
594
mod inlay_hints_tests {
550
595
use crate :: {
551
- requests:: { ClosingBraceHintsOptions , ParameterHintsOptions , TypeHintsOptions } ,
596
+ requests:: {
597
+ ChainingHintsOptions , ClosingBraceHintsOptions , ParameterHintsOptions , TypeHintsOptions ,
598
+ } ,
552
599
test_utils,
553
600
} ;
554
601
@@ -585,6 +632,7 @@ mod inlay_hints_tests {
585
632
type_hints : TypeHintsOptions { enabled : false } ,
586
633
parameter_hints : ParameterHintsOptions { enabled : false } ,
587
634
closing_brace_hints : ClosingBraceHintsOptions { enabled : false , min_lines : 25 } ,
635
+ chaining_hints : ChainingHintsOptions { enabled : false } ,
588
636
}
589
637
}
590
638
@@ -593,6 +641,7 @@ mod inlay_hints_tests {
593
641
type_hints : TypeHintsOptions { enabled : true } ,
594
642
parameter_hints : ParameterHintsOptions { enabled : false } ,
595
643
closing_brace_hints : ClosingBraceHintsOptions { enabled : false , min_lines : 25 } ,
644
+ chaining_hints : ChainingHintsOptions { enabled : false } ,
596
645
}
597
646
}
598
647
@@ -601,6 +650,7 @@ mod inlay_hints_tests {
601
650
type_hints : TypeHintsOptions { enabled : false } ,
602
651
parameter_hints : ParameterHintsOptions { enabled : true } ,
603
652
closing_brace_hints : ClosingBraceHintsOptions { enabled : false , min_lines : 25 } ,
653
+ chaining_hints : ChainingHintsOptions { enabled : false } ,
604
654
}
605
655
}
606
656
@@ -609,6 +659,16 @@ mod inlay_hints_tests {
609
659
type_hints : TypeHintsOptions { enabled : false } ,
610
660
parameter_hints : ParameterHintsOptions { enabled : false } ,
611
661
closing_brace_hints : ClosingBraceHintsOptions { enabled : true , min_lines } ,
662
+ chaining_hints : ChainingHintsOptions { enabled : false } ,
663
+ }
664
+ }
665
+
666
+ fn chaining_hints ( ) -> InlayHintsOptions {
667
+ InlayHintsOptions {
668
+ type_hints : TypeHintsOptions { enabled : false } ,
669
+ parameter_hints : ParameterHintsOptions { enabled : false } ,
670
+ closing_brace_hints : ClosingBraceHintsOptions { enabled : false , min_lines : 0 } ,
671
+ chaining_hints : ChainingHintsOptions { enabled : true } ,
612
672
}
613
673
}
614
674
@@ -963,4 +1023,39 @@ mod inlay_hints_tests {
963
1023
panic ! ( "Expected InlayHintLabel::String, got {:?}" , inlay_hint. label) ;
964
1024
}
965
1025
}
1026
+
1027
+ #[ test]
1028
+ async fn test_shows_receiver_type_in_multiline_method_call ( ) {
1029
+ let mut inlay_hints = get_inlay_hints ( 125 , 130 , chaining_hints ( ) ) . await ;
1030
+ assert_eq ! ( inlay_hints. len( ) , 3 ) ;
1031
+
1032
+ inlay_hints. sort_by_key ( |hint| hint. position . line ) ;
1033
+
1034
+ let inlay_hint = & inlay_hints[ 0 ] ;
1035
+ assert_eq ! ( inlay_hint. position. line, 125 ) ;
1036
+ assert_eq ! ( inlay_hint. position. character, 59 ) ;
1037
+ let InlayHintLabel :: LabelParts ( parts) = & inlay_hint. label else {
1038
+ panic ! ( "Expected label parts" ) ;
1039
+ } ;
1040
+ let label = parts. iter ( ) . map ( |part| part. value . clone ( ) ) . collect :: < Vec < _ > > ( ) . join ( "" ) ;
1041
+ assert_eq ! ( label, " [u32; 14]" ) ;
1042
+
1043
+ let inlay_hint = & inlay_hints[ 1 ] ;
1044
+ assert_eq ! ( inlay_hint. position. line, 126 ) ;
1045
+ assert_eq ! ( inlay_hint. position. character, 37 ) ;
1046
+ let InlayHintLabel :: LabelParts ( parts) = & inlay_hint. label else {
1047
+ panic ! ( "Expected label parts" ) ;
1048
+ } ;
1049
+ let label = parts. iter ( ) . map ( |part| part. value . clone ( ) ) . collect :: < Vec < _ > > ( ) . join ( "" ) ;
1050
+ assert_eq ! ( label, " [u32; 14]" ) ;
1051
+
1052
+ let inlay_hint = & inlay_hints[ 2 ] ;
1053
+ assert_eq ! ( inlay_hint. position. line, 127 ) ;
1054
+ assert_eq ! ( inlay_hint. position. character, 23 ) ;
1055
+ let InlayHintLabel :: LabelParts ( parts) = & inlay_hint. label else {
1056
+ panic ! ( "Expected label parts" ) ;
1057
+ } ;
1058
+ let label = parts. iter ( ) . map ( |part| part. value . clone ( ) ) . collect :: < Vec < _ > > ( ) . join ( "" ) ;
1059
+ assert_eq ! ( label, " bool" ) ;
1060
+ }
966
1061
}
0 commit comments