diff options
Diffstat (limited to 'crates/ra_lsp_server/src/main_loop')
-rw-r--r-- | crates/ra_lsp_server/src/main_loop/handlers.rs | 131 |
1 files changed, 121 insertions, 10 deletions
diff --git a/crates/ra_lsp_server/src/main_loop/handlers.rs b/crates/ra_lsp_server/src/main_loop/handlers.rs index 331beab13..a592f0a12 100644 --- a/crates/ra_lsp_server/src/main_loop/handlers.rs +++ b/crates/ra_lsp_server/src/main_loop/handlers.rs | |||
@@ -5,13 +5,16 @@ use std::{fmt::Write as _, io::Write as _}; | |||
5 | 5 | ||
6 | use lsp_server::ErrorCode; | 6 | use lsp_server::ErrorCode; |
7 | use lsp_types::{ | 7 | use lsp_types::{ |
8 | CallHierarchyIncomingCall, CallHierarchyIncomingCallsParams, CallHierarchyItem, | ||
9 | CallHierarchyOutgoingCall, CallHierarchyOutgoingCallsParams, CallHierarchyPrepareParams, | ||
8 | CodeAction, CodeActionResponse, CodeLens, Command, CompletionItem, Diagnostic, | 10 | CodeAction, CodeActionResponse, CodeLens, Command, CompletionItem, Diagnostic, |
9 | DocumentFormattingParams, DocumentHighlight, DocumentSymbol, FoldingRange, FoldingRangeParams, | 11 | DocumentFormattingParams, DocumentHighlight, DocumentSymbol, FoldingRange, FoldingRangeParams, |
10 | Hover, HoverContents, Location, MarkupContent, MarkupKind, Position, PrepareRenameResponse, | 12 | Hover, HoverContents, Location, MarkupContent, MarkupKind, Position, PrepareRenameResponse, |
11 | Range, RenameParams, SymbolInformation, TextDocumentIdentifier, TextEdit, WorkspaceEdit, | 13 | Range, RenameParams, SymbolInformation, TextDocumentIdentifier, TextEdit, WorkspaceEdit, |
12 | }; | 14 | }; |
13 | use ra_ide::{ | 15 | use ra_ide::{ |
14 | AssistId, FileId, FilePosition, FileRange, Query, Runnable, RunnableKind, SearchScope, | 16 | AssistId, FileId, FilePosition, FileRange, Query, RangeInfo, Runnable, RunnableKind, |
17 | SearchScope, | ||
15 | }; | 18 | }; |
16 | use ra_prof::profile; | 19 | use ra_prof::profile; |
17 | use ra_syntax::{AstNode, SyntaxKind, TextRange, TextUnit}; | 20 | use ra_syntax::{AstNode, SyntaxKind, TextRange, TextUnit}; |
@@ -21,7 +24,10 @@ use serde_json::to_value; | |||
21 | 24 | ||
22 | use crate::{ | 25 | use crate::{ |
23 | cargo_target_spec::{runnable_args, CargoTargetSpec}, | 26 | cargo_target_spec::{runnable_args, CargoTargetSpec}, |
24 | conv::{to_location, Conv, ConvWith, FoldConvCtx, MapConvWith, TryConvWith, TryConvWithToVec}, | 27 | conv::{ |
28 | to_call_hierarchy_item, to_location, Conv, ConvWith, FoldConvCtx, MapConvWith, TryConvWith, | ||
29 | TryConvWithToVec, | ||
30 | }, | ||
25 | req::{self, Decoration, InlayHint, InlayHintsParams, InlayKind}, | 31 | req::{self, Decoration, InlayHint, InlayHintsParams, InlayKind}, |
26 | world::WorldSnapshot, | 32 | world::WorldSnapshot, |
27 | LspError, Result, | 33 | LspError, Result, |
@@ -530,18 +536,32 @@ pub fn handle_references( | |||
530 | 536 | ||
531 | let locations = if params.context.include_declaration { | 537 | let locations = if params.context.include_declaration { |
532 | refs.into_iter() | 538 | refs.into_iter() |
533 | .filter_map(|r| { | 539 | .filter_map(|reference| { |
534 | let line_index = world.analysis().file_line_index(r.file_id).ok()?; | 540 | let line_index = |
535 | to_location(r.file_id, r.range, &world, &line_index).ok() | 541 | world.analysis().file_line_index(reference.file_range.file_id).ok()?; |
542 | to_location( | ||
543 | reference.file_range.file_id, | ||
544 | reference.file_range.range, | ||
545 | &world, | ||
546 | &line_index, | ||
547 | ) | ||
548 | .ok() | ||
536 | }) | 549 | }) |
537 | .collect() | 550 | .collect() |
538 | } else { | 551 | } else { |
539 | // Only iterate over the references if include_declaration was false | 552 | // Only iterate over the references if include_declaration was false |
540 | refs.references() | 553 | refs.references() |
541 | .iter() | 554 | .iter() |
542 | .filter_map(|r| { | 555 | .filter_map(|reference| { |
543 | let line_index = world.analysis().file_line_index(r.file_id).ok()?; | 556 | let line_index = |
544 | to_location(r.file_id, r.range, &world, &line_index).ok() | 557 | world.analysis().file_line_index(reference.file_range.file_id).ok()?; |
558 | to_location( | ||
559 | reference.file_range.file_id, | ||
560 | reference.file_range.range, | ||
561 | &world, | ||
562 | &line_index, | ||
563 | ) | ||
564 | .ok() | ||
545 | }) | 565 | }) |
546 | .collect() | 566 | .collect() |
547 | }; | 567 | }; |
@@ -830,8 +850,11 @@ pub fn handle_document_highlight( | |||
830 | 850 | ||
831 | Ok(Some( | 851 | Ok(Some( |
832 | refs.into_iter() | 852 | refs.into_iter() |
833 | .filter(|r| r.file_id == file_id) | 853 | .filter(|reference| reference.file_range.file_id == file_id) |
834 | .map(|r| DocumentHighlight { range: r.range.conv_with(&line_index), kind: None }) | 854 | .map(|reference| DocumentHighlight { |
855 | range: reference.file_range.range.conv_with(&line_index), | ||
856 | kind: reference.access.map(|it| it.conv()), | ||
857 | }) | ||
835 | .collect(), | 858 | .collect(), |
836 | )) | 859 | )) |
837 | } | 860 | } |
@@ -933,3 +956,91 @@ pub fn handle_inlay_hints( | |||
933 | }) | 956 | }) |
934 | .collect()) | 957 | .collect()) |
935 | } | 958 | } |
959 | |||
960 | pub fn handle_call_hierarchy_prepare( | ||
961 | world: WorldSnapshot, | ||
962 | params: CallHierarchyPrepareParams, | ||
963 | ) -> Result<Option<Vec<CallHierarchyItem>>> { | ||
964 | let _p = profile("handle_call_hierarchy_prepare"); | ||
965 | let position = params.text_document_position_params.try_conv_with(&world)?; | ||
966 | let file_id = position.file_id; | ||
967 | |||
968 | let nav_info = match world.analysis().call_hierarchy(position)? { | ||
969 | None => return Ok(None), | ||
970 | Some(it) => it, | ||
971 | }; | ||
972 | |||
973 | let line_index = world.analysis().file_line_index(file_id)?; | ||
974 | let RangeInfo { range, info: navs } = nav_info; | ||
975 | let res = navs | ||
976 | .into_iter() | ||
977 | .filter(|it| it.kind() == SyntaxKind::FN_DEF) | ||
978 | .filter_map(|it| to_call_hierarchy_item(file_id, range, &world, &line_index, it).ok()) | ||
979 | .collect(); | ||
980 | |||
981 | Ok(Some(res)) | ||
982 | } | ||
983 | |||
984 | pub fn handle_call_hierarchy_incoming( | ||
985 | world: WorldSnapshot, | ||
986 | params: CallHierarchyIncomingCallsParams, | ||
987 | ) -> Result<Option<Vec<CallHierarchyIncomingCall>>> { | ||
988 | let _p = profile("handle_call_hierarchy_incoming"); | ||
989 | let item = params.item; | ||
990 | |||
991 | let doc = TextDocumentIdentifier::new(item.uri); | ||
992 | let frange: FileRange = (&doc, item.range).try_conv_with(&world)?; | ||
993 | let fpos = FilePosition { file_id: frange.file_id, offset: frange.range.start() }; | ||
994 | |||
995 | let call_items = match world.analysis().incoming_calls(fpos)? { | ||
996 | None => return Ok(None), | ||
997 | Some(it) => it, | ||
998 | }; | ||
999 | |||
1000 | let mut res = vec![]; | ||
1001 | |||
1002 | for call_item in call_items.into_iter() { | ||
1003 | let file_id = call_item.target.file_id(); | ||
1004 | let line_index = world.analysis().file_line_index(file_id)?; | ||
1005 | let range = call_item.target.range(); | ||
1006 | let item = to_call_hierarchy_item(file_id, range, &world, &line_index, call_item.target)?; | ||
1007 | res.push(CallHierarchyIncomingCall { | ||
1008 | from: item, | ||
1009 | from_ranges: call_item.ranges.iter().map(|it| it.conv_with(&line_index)).collect(), | ||
1010 | }); | ||
1011 | } | ||
1012 | |||
1013 | Ok(Some(res)) | ||
1014 | } | ||
1015 | |||
1016 | pub fn handle_call_hierarchy_outgoing( | ||
1017 | world: WorldSnapshot, | ||
1018 | params: CallHierarchyOutgoingCallsParams, | ||
1019 | ) -> Result<Option<Vec<CallHierarchyOutgoingCall>>> { | ||
1020 | let _p = profile("handle_call_hierarchy_outgoing"); | ||
1021 | let item = params.item; | ||
1022 | |||
1023 | let doc = TextDocumentIdentifier::new(item.uri); | ||
1024 | let frange: FileRange = (&doc, item.range).try_conv_with(&world)?; | ||
1025 | let fpos = FilePosition { file_id: frange.file_id, offset: frange.range.start() }; | ||
1026 | |||
1027 | let call_items = match world.analysis().outgoing_calls(fpos)? { | ||
1028 | None => return Ok(None), | ||
1029 | Some(it) => it, | ||
1030 | }; | ||
1031 | |||
1032 | let mut res = vec![]; | ||
1033 | |||
1034 | for call_item in call_items.into_iter() { | ||
1035 | let file_id = call_item.target.file_id(); | ||
1036 | let line_index = world.analysis().file_line_index(file_id)?; | ||
1037 | let range = call_item.target.range(); | ||
1038 | let item = to_call_hierarchy_item(file_id, range, &world, &line_index, call_item.target)?; | ||
1039 | res.push(CallHierarchyOutgoingCall { | ||
1040 | to: item, | ||
1041 | from_ranges: call_item.ranges.iter().map(|it| it.conv_with(&line_index)).collect(), | ||
1042 | }); | ||
1043 | } | ||
1044 | |||
1045 | Ok(Some(res)) | ||
1046 | } | ||