@@ -11,6 +11,7 @@ use ide::{
1111 FileId , FilePosition , FileRange , HoverAction , HoverGotoTypeData , NavigationTarget , Query ,
1212 RangeInfo , Runnable , RunnableKind , SearchScope , TextEdit ,
1313} ;
14+ use itertools:: Itertools ;
1415use lsp_server:: ErrorCode ;
1516use lsp_types:: {
1617 CallHierarchyIncomingCall , CallHierarchyIncomingCallsParams , CallHierarchyItem ,
@@ -952,13 +953,30 @@ pub(crate) fn handle_code_lens(
952953 } ) ,
953954 ) ;
954955 }
956+
957+ if snap. config . lens . references ( ) {
958+ lenses. extend ( snap. analysis . find_all_methods ( file_id) ?. into_iter ( ) . map ( |it| {
959+ let range = to_proto:: range ( & line_index, it. range ) ;
960+ let position = to_proto:: position ( & line_index, it. range . start ( ) ) ;
961+ let lens_params =
962+ lsp_types:: TextDocumentPositionParams :: new ( params. text_document . clone ( ) , position) ;
963+
964+ CodeLens {
965+ range,
966+ command : None ,
967+ data : Some ( to_value ( CodeLensResolveData :: References ( lens_params) ) . unwrap ( ) ) ,
968+ }
969+ } ) ) ;
970+ }
971+
955972 Ok ( Some ( lenses) )
956973}
957974
958975#[ derive( Debug , Serialize , Deserialize ) ]
959976#[ serde( rename_all = "camelCase" ) ]
960977enum CodeLensResolveData {
961978 Impls ( lsp_types:: request:: GotoImplementationParams ) ,
979+ References ( lsp_types:: TextDocumentPositionParams ) ,
962980}
963981
964982pub ( crate ) fn handle_code_lens_resolve (
@@ -990,6 +1008,34 @@ pub(crate) fn handle_code_lens_resolve(
9901008 ) ;
9911009 Ok ( CodeLens { range : code_lens. range , command : Some ( cmd) , data : None } )
9921010 }
1011+ Some ( CodeLensResolveData :: References ( doc_position) ) => {
1012+ let position = from_proto:: file_position ( & snap, doc_position. clone ( ) ) ?;
1013+ let locations = snap
1014+ . analysis
1015+ . find_all_refs ( position, None )
1016+ . unwrap_or ( None )
1017+ . map ( |r| {
1018+ r. references ( )
1019+ . iter ( )
1020+ . filter_map ( |it| to_proto:: location ( & snap, it. file_range ) . ok ( ) )
1021+ . collect_vec ( )
1022+ } )
1023+ . unwrap_or_default ( ) ;
1024+
1025+ let title = reference_title ( locations. len ( ) ) ;
1026+ let cmd = if locations. is_empty ( ) {
1027+ Command { title, command : "" . into ( ) , arguments : None }
1028+ } else {
1029+ show_references_command (
1030+ title,
1031+ & doc_position. text_document . uri ,
1032+ code_lens. range . start ,
1033+ locations,
1034+ )
1035+ } ;
1036+
1037+ Ok ( CodeLens { range : code_lens. range , command : Some ( cmd) , data : None } )
1038+ }
9931039 None => Ok ( CodeLens {
9941040 range : code_lens. range ,
9951041 command : Some ( Command { title : "Error" . into ( ) , ..Default :: default ( ) } ) ,
@@ -1248,6 +1294,14 @@ fn implementation_title(count: usize) -> String {
12481294 }
12491295}
12501296
1297+ fn reference_title ( count : usize ) -> String {
1298+ if count == 1 {
1299+ "1 reference" . into ( )
1300+ } else {
1301+ format ! ( "{} references" , count)
1302+ }
1303+ }
1304+
12511305fn show_references_command (
12521306 title : String ,
12531307 uri : & lsp_types:: Url ,
0 commit comments