diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2020-01-08 16:42:56 +0000 |
---|---|---|
committer | GitHub <[email protected]> | 2020-01-08 16:42:56 +0000 |
commit | 2e66bed78296d12f1127ca8cd7cdeafc6c9b78c1 (patch) | |
tree | e4f8f3dac6a05b92247e75c9bba71a2e6afd5745 /crates/ra_lsp_server/src/main_loop | |
parent | 928ecd069a508845ef4dbfd1bc1b9bf975d76e5b (diff) | |
parent | c7b2bc1363c8422122a0d1fbd5ff68b5984cf173 (diff) |
Merge #2698
2698: Call Hierarchy r=kjeremy a=kjeremy
Support experiment incoming and outgoing calls.
Fixes #2546
Co-authored-by: Jeremy Kolb <[email protected]>
Co-authored-by: kjeremy <[email protected]>
Diffstat (limited to 'crates/ra_lsp_server/src/main_loop')
-rw-r--r-- | crates/ra_lsp_server/src/main_loop/handlers.rs | 98 |
1 files changed, 96 insertions, 2 deletions
diff --git a/crates/ra_lsp_server/src/main_loop/handlers.rs b/crates/ra_lsp_server/src/main_loop/handlers.rs index c8f52eb0e..a5b6f48af 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, |
@@ -936,3 +942,91 @@ pub fn handle_inlay_hints( | |||
936 | }) | 942 | }) |
937 | .collect()) | 943 | .collect()) |
938 | } | 944 | } |
945 | |||
946 | pub fn handle_call_hierarchy_prepare( | ||
947 | world: WorldSnapshot, | ||
948 | params: CallHierarchyPrepareParams, | ||
949 | ) -> Result<Option<Vec<CallHierarchyItem>>> { | ||
950 | let _p = profile("handle_call_hierarchy_prepare"); | ||
951 | let position = params.text_document_position_params.try_conv_with(&world)?; | ||
952 | let file_id = position.file_id; | ||
953 | |||
954 | let nav_info = match world.analysis().call_hierarchy(position)? { | ||
955 | None => return Ok(None), | ||
956 | Some(it) => it, | ||
957 | }; | ||
958 | |||
959 | let line_index = world.analysis().file_line_index(file_id)?; | ||
960 | let RangeInfo { range, info: navs } = nav_info; | ||
961 | let res = navs | ||
962 | .into_iter() | ||
963 | .filter(|it| it.kind() == SyntaxKind::FN_DEF) | ||
964 | .filter_map(|it| to_call_hierarchy_item(file_id, range, &world, &line_index, it).ok()) | ||
965 | .collect(); | ||
966 | |||
967 | Ok(Some(res)) | ||
968 | } | ||
969 | |||
970 | pub fn handle_call_hierarchy_incoming( | ||
971 | world: WorldSnapshot, | ||
972 | params: CallHierarchyIncomingCallsParams, | ||
973 | ) -> Result<Option<Vec<CallHierarchyIncomingCall>>> { | ||
974 | let _p = profile("handle_call_hierarchy_incoming"); | ||
975 | let item = params.item; | ||
976 | |||
977 | let doc = TextDocumentIdentifier::new(item.uri); | ||
978 | let frange: FileRange = (&doc, item.range).try_conv_with(&world)?; | ||
979 | let fpos = FilePosition { file_id: frange.file_id, offset: frange.range.start() }; | ||
980 | |||
981 | let call_items = match world.analysis().incoming_calls(fpos)? { | ||
982 | None => return Ok(None), | ||
983 | Some(it) => it, | ||
984 | }; | ||
985 | |||
986 | let mut res = vec![]; | ||
987 | |||
988 | for call_item in call_items.into_iter() { | ||
989 | let file_id = call_item.target.file_id(); | ||
990 | let line_index = world.analysis().file_line_index(file_id)?; | ||
991 | let range = call_item.target.range(); | ||
992 | let item = to_call_hierarchy_item(file_id, range, &world, &line_index, call_item.target)?; | ||
993 | res.push(CallHierarchyIncomingCall { | ||
994 | from: item, | ||
995 | from_ranges: call_item.ranges.iter().map(|it| it.conv_with(&line_index)).collect(), | ||
996 | }); | ||
997 | } | ||
998 | |||
999 | Ok(Some(res)) | ||
1000 | } | ||
1001 | |||
1002 | pub fn handle_call_hierarchy_outgoing( | ||
1003 | world: WorldSnapshot, | ||
1004 | params: CallHierarchyOutgoingCallsParams, | ||
1005 | ) -> Result<Option<Vec<CallHierarchyOutgoingCall>>> { | ||
1006 | let _p = profile("handle_call_hierarchy_outgoing"); | ||
1007 | let item = params.item; | ||
1008 | |||
1009 | let doc = TextDocumentIdentifier::new(item.uri); | ||
1010 | let frange: FileRange = (&doc, item.range).try_conv_with(&world)?; | ||
1011 | let fpos = FilePosition { file_id: frange.file_id, offset: frange.range.start() }; | ||
1012 | |||
1013 | let call_items = match world.analysis().outgoing_calls(fpos)? { | ||
1014 | None => return Ok(None), | ||
1015 | Some(it) => it, | ||
1016 | }; | ||
1017 | |||
1018 | let mut res = vec![]; | ||
1019 | |||
1020 | for call_item in call_items.into_iter() { | ||
1021 | let file_id = call_item.target.file_id(); | ||
1022 | let line_index = world.analysis().file_line_index(file_id)?; | ||
1023 | let range = call_item.target.range(); | ||
1024 | let item = to_call_hierarchy_item(file_id, range, &world, &line_index, call_item.target)?; | ||
1025 | res.push(CallHierarchyOutgoingCall { | ||
1026 | to: item, | ||
1027 | from_ranges: call_item.ranges.iter().map(|it| it.conv_with(&line_index)).collect(), | ||
1028 | }); | ||
1029 | } | ||
1030 | |||
1031 | Ok(Some(res)) | ||
1032 | } | ||