diff options
author | ivan770 <[email protected]> | 2021-02-13 11:07:47 +0000 |
---|---|---|
committer | ivan770 <[email protected]> | 2021-02-13 11:07:47 +0000 |
commit | 185da286d26ea7f892097c48b79a28acd7e5f172 (patch) | |
tree | 925bdb4be5377544323989476b0d30e091287ea5 /crates/rust-analyzer/src/to_proto.rs | |
parent | 935830d05bcf5f0c648e636dcbc8848a201467c0 (diff) |
Moved CodeLens to ide crate
Diffstat (limited to 'crates/rust-analyzer/src/to_proto.rs')
-rw-r--r-- | crates/rust-analyzer/src/to_proto.rs | 145 |
1 files changed, 141 insertions, 4 deletions
diff --git a/crates/rust-analyzer/src/to_proto.rs b/crates/rust-analyzer/src/to_proto.rs index be10ac1ae..29fac96fb 100644 --- a/crates/rust-analyzer/src/to_proto.rs +++ b/crates/rust-analyzer/src/to_proto.rs | |||
@@ -5,13 +5,15 @@ use std::{ | |||
5 | }; | 5 | }; |
6 | 6 | ||
7 | use ide::{ | 7 | use ide::{ |
8 | Assist, AssistKind, CallInfo, CompletionItem, CompletionItemKind, Documentation, FileId, | 8 | Annotation, AnnotationKind, Assist, AssistKind, CallInfo, CompletionItem, CompletionItemKind, |
9 | FileRange, FileSystemEdit, Fold, FoldKind, Highlight, HlMod, HlPunct, HlRange, HlTag, Indel, | 9 | Documentation, FileId, FileRange, FileSystemEdit, Fold, FoldKind, Highlight, HlMod, HlPunct, |
10 | InlayHint, InlayKind, InsertTextFormat, LineIndex, Markup, NavigationTarget, ReferenceAccess, | 10 | HlRange, HlTag, Indel, InlayHint, InlayKind, InsertTextFormat, LineIndex, Markup, |
11 | RenameError, Runnable, Severity, SourceChange, TextEdit, TextRange, TextSize, | 11 | NavigationTarget, ReferenceAccess, RenameError, Runnable, Severity, SourceChange, TextEdit, |
12 | TextRange, TextSize, | ||
12 | }; | 13 | }; |
13 | use ide_db::SymbolKind; | 14 | use ide_db::SymbolKind; |
14 | use itertools::Itertools; | 15 | use itertools::Itertools; |
16 | use serde_json::to_value; | ||
15 | 17 | ||
16 | use crate::{ | 18 | use crate::{ |
17 | cargo_target_spec::CargoTargetSpec, global_state::GlobalStateSnapshot, | 19 | cargo_target_spec::CargoTargetSpec, global_state::GlobalStateSnapshot, |
@@ -863,6 +865,141 @@ pub(crate) fn runnable( | |||
863 | }) | 865 | }) |
864 | } | 866 | } |
865 | 867 | ||
868 | pub(crate) fn code_lens( | ||
869 | snap: &GlobalStateSnapshot, | ||
870 | annotation: Annotation, | ||
871 | ) -> Result<lsp_types::CodeLens> { | ||
872 | match annotation.kind { | ||
873 | AnnotationKind::Runnable { debug, runnable: run } => { | ||
874 | let line_index = snap.analysis.file_line_index(run.nav.file_id)?; | ||
875 | let annotation_range = range(&line_index, annotation.range); | ||
876 | |||
877 | let action = run.action(); | ||
878 | let r = runnable(&snap, run.nav.file_id, run)?; | ||
879 | |||
880 | let command = if debug { | ||
881 | lsp_types::Command { | ||
882 | title: action.run_title.to_string(), | ||
883 | command: "rust-analyzer.runSingle".into(), | ||
884 | arguments: Some(vec![to_value(r).unwrap()]), | ||
885 | } | ||
886 | } else { | ||
887 | lsp_types::Command { | ||
888 | title: "Debug".into(), | ||
889 | command: "rust-analyzer.debugSingle".into(), | ||
890 | arguments: Some(vec![to_value(r).unwrap()]), | ||
891 | } | ||
892 | }; | ||
893 | |||
894 | Ok(lsp_types::CodeLens { range: annotation_range, command: Some(command), data: None }) | ||
895 | } | ||
896 | AnnotationKind::HasImpls { position: file_position, data } => { | ||
897 | let line_index = snap.analysis.file_line_index(file_position.file_id)?; | ||
898 | let annotation_range = range(&line_index, annotation.range); | ||
899 | let url = url(snap, file_position.file_id); | ||
900 | |||
901 | let position = position(&line_index, file_position.offset); | ||
902 | |||
903 | let id = lsp_types::TextDocumentIdentifier { uri: url.clone() }; | ||
904 | |||
905 | let doc_pos = lsp_types::TextDocumentPositionParams::new(id.clone(), position); | ||
906 | |||
907 | let goto_params = lsp_types::request::GotoImplementationParams { | ||
908 | text_document_position_params: doc_pos.clone(), | ||
909 | work_done_progress_params: Default::default(), | ||
910 | partial_result_params: Default::default(), | ||
911 | }; | ||
912 | |||
913 | let command = data.map(|ranges| { | ||
914 | let locations: Vec<lsp_types::Location> = ranges | ||
915 | .into_iter() | ||
916 | .filter_map(|target| { | ||
917 | location( | ||
918 | snap, | ||
919 | FileRange { file_id: target.file_id, range: target.full_range }, | ||
920 | ) | ||
921 | .ok() | ||
922 | }) | ||
923 | .collect(); | ||
924 | |||
925 | show_references_command( | ||
926 | implementation_title(locations.len()), | ||
927 | &url, | ||
928 | position, | ||
929 | locations, | ||
930 | ) | ||
931 | }); | ||
932 | |||
933 | Ok(lsp_types::CodeLens { | ||
934 | range: annotation_range, | ||
935 | command, | ||
936 | data: Some(to_value(lsp_ext::CodeLensResolveData::Impls(goto_params)).unwrap()), | ||
937 | }) | ||
938 | } | ||
939 | AnnotationKind::HasReferences { position: file_position, data } => { | ||
940 | let line_index = snap.analysis.file_line_index(file_position.file_id)?; | ||
941 | let annotation_range = range(&line_index, annotation.range); | ||
942 | let url = url(snap, file_position.file_id); | ||
943 | |||
944 | let position = position(&line_index, file_position.offset); | ||
945 | |||
946 | let id = lsp_types::TextDocumentIdentifier { uri: url.clone() }; | ||
947 | |||
948 | let doc_pos = lsp_types::TextDocumentPositionParams::new(id, position); | ||
949 | |||
950 | let command = data.map(|ranges| { | ||
951 | let locations: Vec<lsp_types::Location> = | ||
952 | ranges.into_iter().filter_map(|range| location(snap, range).ok()).collect(); | ||
953 | |||
954 | show_references_command(reference_title(locations.len()), &url, position, locations) | ||
955 | }); | ||
956 | |||
957 | Ok(lsp_types::CodeLens { | ||
958 | range: annotation_range, | ||
959 | command, | ||
960 | data: Some(to_value(lsp_ext::CodeLensResolveData::References(doc_pos)).unwrap()), | ||
961 | }) | ||
962 | } | ||
963 | } | ||
964 | } | ||
965 | |||
966 | pub(crate) fn show_references_command( | ||
967 | title: String, | ||
968 | uri: &lsp_types::Url, | ||
969 | position: lsp_types::Position, | ||
970 | locations: Vec<lsp_types::Location>, | ||
971 | ) -> lsp_types::Command { | ||
972 | // We cannot use the 'editor.action.showReferences' command directly | ||
973 | // because that command requires vscode types which we convert in the handler | ||
974 | // on the client side. | ||
975 | |||
976 | lsp_types::Command { | ||
977 | title, | ||
978 | command: "rust-analyzer.showReferences".into(), | ||
979 | arguments: Some(vec![ | ||
980 | to_value(uri).unwrap(), | ||
981 | to_value(position).unwrap(), | ||
982 | to_value(locations).unwrap(), | ||
983 | ]), | ||
984 | } | ||
985 | } | ||
986 | |||
987 | pub(crate) fn implementation_title(count: usize) -> String { | ||
988 | if count == 1 { | ||
989 | "1 implementation".into() | ||
990 | } else { | ||
991 | format!("{} implementations", count) | ||
992 | } | ||
993 | } | ||
994 | |||
995 | pub(crate) fn reference_title(count: usize) -> String { | ||
996 | if count == 1 { | ||
997 | "1 reference".into() | ||
998 | } else { | ||
999 | format!("{} references", count) | ||
1000 | } | ||
1001 | } | ||
1002 | |||
866 | pub(crate) fn markup_content(markup: Markup) -> lsp_types::MarkupContent { | 1003 | pub(crate) fn markup_content(markup: Markup) -> lsp_types::MarkupContent { |
867 | let value = crate::markdown::format_docs(markup.as_str()); | 1004 | let value = crate::markdown::format_docs(markup.as_str()); |
868 | lsp_types::MarkupContent { kind: lsp_types::MarkupKind::Markdown, value } | 1005 | lsp_types::MarkupContent { kind: lsp_types::MarkupKind::Markdown, value } |