@@ -13,10 +13,11 @@ use tower_lsp_server::lsp_types::{
1313 DidChangeWorkspaceFoldersParams , DidCloseTextDocumentParams , DidOpenTextDocumentParams ,
1414 DidSaveTextDocumentParams , ExecuteCommandParams , GotoDefinitionParams , GotoDefinitionResponse ,
1515 Hover , HoverParams , HoverProviderCapability , InitializeParams , InitializeResult ,
16- InitializedParams , Location , MarkupContent , MarkupKind , MessageType , OneOf , Range , SaveOptions ,
17- SemanticTokensParams , SemanticTokensResult , ServerCapabilities , TextDocumentSyncCapability ,
18- TextDocumentSyncKind , TextDocumentSyncOptions , TextDocumentSyncSaveOptions , Uri ,
19- WorkDoneProgressOptions , WorkspaceFoldersServerCapabilities , WorkspaceServerCapabilities ,
16+ InitializedParams , Location , MarkupContent , MarkupKind , MessageType , OneOf , Position , Range ,
17+ ReferenceParams , SaveOptions , SemanticTokensParams , SemanticTokensResult , ServerCapabilities ,
18+ TextDocumentSyncCapability , TextDocumentSyncKind , TextDocumentSyncOptions ,
19+ TextDocumentSyncSaveOptions , Uri , WorkDoneProgressOptions , WorkspaceFoldersServerCapabilities ,
20+ WorkspaceServerCapabilities ,
2021} ;
2122use tower_lsp_server:: { Client , LanguageServer } ;
2223
@@ -31,7 +32,8 @@ use crate::completion::{self, CompletionProvider};
3132use crate :: error:: LspError ;
3233use crate :: function:: Functions ;
3334use crate :: utils:: {
34- find_related_call, get_call_span, get_comments_from_lines, position_to_span, span_to_positions,
35+ find_all_references, find_related_call, get_call_span, get_comments_from_lines,
36+ position_to_span, span_contains, span_to_positions,
3537} ;
3638
3739#[ derive( Debug ) ]
@@ -86,6 +88,7 @@ impl LanguageServer for Backend {
8688 } ) ,
8789 hover_provider : Some ( HoverProviderCapability :: Simple ( true ) ) ,
8890 definition_provider : Some ( OneOf :: Left ( true ) ) ,
91+ references_provider : Some ( OneOf :: Left ( true ) ) ,
8992 ..ServerCapabilities :: default ( )
9093 } ,
9194 } )
@@ -308,6 +311,67 @@ impl LanguageServer for Backend {
308311 _ => Ok ( None ) ,
309312 }
310313 }
314+
315+ async fn references ( & self , params : ReferenceParams ) -> Result < Option < Vec < Location > > > {
316+ let documents = self . document_map . read ( ) . await ;
317+ let uri = & params. text_document_position . text_document . uri ;
318+
319+ let doc = documents
320+ . get ( uri)
321+ . ok_or ( LspError :: DocumentNotFound ( uri. to_owned ( ) ) ) ?;
322+ let functions = doc. functions . functions ( ) ;
323+
324+ let token_position = params. text_document_position . position ;
325+
326+ let token_span = position_to_span ( token_position) ?;
327+
328+ let line = doc
329+ . text
330+ . lines ( )
331+ . nth ( token_position. line as usize )
332+ . ok_or ( LspError :: Internal ( "Rope proccesing error" . into ( ) ) ) ?;
333+
334+ let line_str = line. as_str ( ) . ok_or ( LspError :: ConversionFailed (
335+ "RopeSlice to str conversion failed" . into ( ) ,
336+ ) ) ?;
337+
338+ let func = functions
339+ . iter ( )
340+ . find ( |func| span_contains ( func. span ( ) , & token_span) )
341+ . ok_or ( LspError :: CallNotFound (
342+ "Span of the call is not inside function." . into ( ) ,
343+ ) ) ?;
344+
345+ let Some ( pos) = line_str. find ( func. name ( ) . as_inner ( ) ) else {
346+ return Ok ( None ) ;
347+ } ;
348+
349+ let ( start, end) = (
350+ Position {
351+ line : token_position. line ,
352+ character : u32:: try_from ( pos) . map_err ( LspError :: from) ?,
353+ } ,
354+ Position {
355+ line : token_position. line ,
356+ character : u32:: try_from ( pos + func. name ( ) . as_inner ( ) . len ( ) )
357+ . map_err ( LspError :: from) ?,
358+ } ,
359+ ) ;
360+
361+ if token_position <= end && token_position >= start {
362+ Ok ( Some (
363+ find_all_references ( & functions, func. name ( ) ) ?
364+ . iter ( )
365+ . map ( |range| Location {
366+ range : * range,
367+ uri : uri. clone ( ) ,
368+ } )
369+ . collect ( ) ,
370+ ) )
371+ } else {
372+ Ok ( None )
373+ }
374+ }
311375}
312376
313377impl Backend {
0 commit comments