diff options
Diffstat (limited to 'crates')
-rw-r--r-- | crates/rust-analyzer/src/handlers.rs | 119 |
1 files changed, 58 insertions, 61 deletions
diff --git a/crates/rust-analyzer/src/handlers.rs b/crates/rust-analyzer/src/handlers.rs index 66f8bee99..55bc2bcec 100644 --- a/crates/rust-analyzer/src/handlers.rs +++ b/crates/rust-analyzer/src/handlers.rs | |||
@@ -5,11 +5,13 @@ | |||
5 | use std::{ | 5 | use std::{ |
6 | io::Write as _, | 6 | io::Write as _, |
7 | process::{self, Stdio}, | 7 | process::{self, Stdio}, |
8 | sync::Arc, | ||
8 | }; | 9 | }; |
9 | 10 | ||
10 | use ide::{ | 11 | use ide::{ |
11 | CompletionResolveCapability, FileId, FilePosition, FileRange, HoverAction, HoverGotoTypeData, | 12 | AssistConfig, CompletionResolveCapability, FileId, FilePosition, FileRange, HoverAction, |
12 | NavigationTarget, Query, RangeInfo, Runnable, RunnableKind, SearchScope, SymbolKind, TextEdit, | 13 | HoverGotoTypeData, LineIndex, NavigationTarget, Query, RangeInfo, Runnable, RunnableKind, |
14 | SearchScope, SymbolKind, TextEdit, | ||
13 | }; | 15 | }; |
14 | use itertools::Itertools; | 16 | use itertools::Itertools; |
15 | use lsp_server::ErrorCode; | 17 | use lsp_server::ErrorCode; |
@@ -865,58 +867,8 @@ pub(crate) fn handle_formatting( | |||
865 | } | 867 | } |
866 | } | 868 | } |
867 | 869 | ||
868 | fn handle_fixes( | ||
869 | snap: &GlobalStateSnapshot, | ||
870 | params: &lsp_types::CodeActionParams, | ||
871 | res: &mut Vec<lsp_ext::CodeAction>, | ||
872 | ) -> Result<()> { | ||
873 | let file_id = from_proto::file_id(&snap, ¶ms.text_document.uri)?; | ||
874 | let line_index = snap.analysis.file_line_index(file_id)?; | ||
875 | let range = from_proto::text_range(&line_index, params.range); | ||
876 | |||
877 | match ¶ms.context.only { | ||
878 | Some(v) => { | ||
879 | if !v.iter().any(|it| { | ||
880 | it == &lsp_types::CodeActionKind::EMPTY | ||
881 | || it == &lsp_types::CodeActionKind::QUICKFIX | ||
882 | }) { | ||
883 | return Ok(()); | ||
884 | } | ||
885 | } | ||
886 | None => {} | ||
887 | }; | ||
888 | |||
889 | let diagnostics = snap.analysis.diagnostics(&snap.config.diagnostics, file_id)?; | ||
890 | |||
891 | for fix in diagnostics | ||
892 | .into_iter() | ||
893 | .filter_map(|d| d.fix) | ||
894 | .filter(|fix| fix.fix_trigger_range.intersect(range).is_some()) | ||
895 | { | ||
896 | let edit = to_proto::snippet_workspace_edit(&snap, fix.source_change)?; | ||
897 | let action = lsp_ext::CodeAction { | ||
898 | title: fix.label.to_string(), | ||
899 | group: None, | ||
900 | kind: Some(CodeActionKind::QUICKFIX), | ||
901 | edit: Some(edit), | ||
902 | is_preferred: Some(false), | ||
903 | data: None, | ||
904 | }; | ||
905 | res.push(action); | ||
906 | } | ||
907 | |||
908 | for fix in snap.check_fixes.get(&file_id).into_iter().flatten() { | ||
909 | let fix_range = from_proto::text_range(&line_index, fix.range); | ||
910 | if fix_range.intersect(range).is_none() { | ||
911 | continue; | ||
912 | } | ||
913 | res.push(fix.action.clone()); | ||
914 | } | ||
915 | Ok(()) | ||
916 | } | ||
917 | |||
918 | pub(crate) fn handle_code_action( | 870 | pub(crate) fn handle_code_action( |
919 | mut snap: GlobalStateSnapshot, | 871 | snap: GlobalStateSnapshot, |
920 | params: lsp_types::CodeActionParams, | 872 | params: lsp_types::CodeActionParams, |
921 | ) -> Result<Option<Vec<lsp_ext::CodeAction>>> { | 873 | ) -> Result<Option<Vec<lsp_ext::CodeAction>>> { |
922 | let _p = profile::span("handle_code_action"); | 874 | let _p = profile::span("handle_code_action"); |
@@ -932,24 +884,35 @@ pub(crate) fn handle_code_action( | |||
932 | let range = from_proto::text_range(&line_index, params.range); | 884 | let range = from_proto::text_range(&line_index, params.range); |
933 | let frange = FileRange { file_id, range }; | 885 | let frange = FileRange { file_id, range }; |
934 | 886 | ||
935 | snap.config.assist.allowed = params | 887 | let assists_config = AssistConfig { |
936 | .clone() | 888 | allowed: params |
937 | .context | 889 | .clone() |
938 | .only | 890 | .context |
939 | .map(|it| it.into_iter().filter_map(from_proto::assist_kind).collect()); | 891 | .only |
892 | .map(|it| it.into_iter().filter_map(from_proto::assist_kind).collect()), | ||
893 | ..snap.config.assist | ||
894 | }; | ||
940 | 895 | ||
941 | let mut res: Vec<lsp_ext::CodeAction> = Vec::new(); | 896 | let mut res: Vec<lsp_ext::CodeAction> = Vec::new(); |
942 | 897 | ||
943 | handle_fixes(&snap, ¶ms, &mut res)?; | 898 | let include_quick_fixes = match ¶ms.context.only { |
899 | Some(v) => v.iter().any(|it| { | ||
900 | it == &lsp_types::CodeActionKind::EMPTY || it == &lsp_types::CodeActionKind::QUICKFIX | ||
901 | }), | ||
902 | None => true, | ||
903 | }; | ||
904 | if include_quick_fixes { | ||
905 | add_quick_fixes(&snap, frange, &line_index, &mut res)?; | ||
906 | } | ||
944 | 907 | ||
945 | if snap.config.client_caps.code_action_resolve { | 908 | if snap.config.client_caps.code_action_resolve { |
946 | for (index, assist) in | 909 | for (index, assist) in |
947 | snap.analysis.unresolved_assists(&snap.config.assist, frange)?.into_iter().enumerate() | 910 | snap.analysis.unresolved_assists(&assists_config, frange)?.into_iter().enumerate() |
948 | { | 911 | { |
949 | res.push(to_proto::unresolved_code_action(&snap, params.clone(), assist, index)?); | 912 | res.push(to_proto::unresolved_code_action(&snap, params.clone(), assist, index)?); |
950 | } | 913 | } |
951 | } else { | 914 | } else { |
952 | for assist in snap.analysis.resolved_assists(&snap.config.assist, frange)?.into_iter() { | 915 | for assist in snap.analysis.resolved_assists(&assists_config, frange)?.into_iter() { |
953 | res.push(to_proto::resolved_code_action(&snap, assist)?); | 916 | res.push(to_proto::resolved_code_action(&snap, assist)?); |
954 | } | 917 | } |
955 | } | 918 | } |
@@ -957,6 +920,40 @@ pub(crate) fn handle_code_action( | |||
957 | Ok(Some(res)) | 920 | Ok(Some(res)) |
958 | } | 921 | } |
959 | 922 | ||
923 | fn add_quick_fixes( | ||
924 | snap: &GlobalStateSnapshot, | ||
925 | frange: FileRange, | ||
926 | line_index: &Arc<LineIndex>, | ||
927 | acc: &mut Vec<lsp_ext::CodeAction>, | ||
928 | ) -> Result<()> { | ||
929 | let diagnostics = snap.analysis.diagnostics(&snap.config.diagnostics, frange.file_id)?; | ||
930 | |||
931 | for fix in diagnostics | ||
932 | .into_iter() | ||
933 | .filter_map(|d| d.fix) | ||
934 | .filter(|fix| fix.fix_trigger_range.intersect(frange.range).is_some()) | ||
935 | { | ||
936 | let edit = to_proto::snippet_workspace_edit(&snap, fix.source_change)?; | ||
937 | let action = lsp_ext::CodeAction { | ||
938 | title: fix.label.to_string(), | ||
939 | group: None, | ||
940 | kind: Some(CodeActionKind::QUICKFIX), | ||
941 | edit: Some(edit), | ||
942 | is_preferred: Some(false), | ||
943 | data: None, | ||
944 | }; | ||
945 | acc.push(action); | ||
946 | } | ||
947 | |||
948 | for fix in snap.check_fixes.get(&frange.file_id).into_iter().flatten() { | ||
949 | let fix_range = from_proto::text_range(&line_index, fix.range); | ||
950 | if fix_range.intersect(frange.range).is_some() { | ||
951 | acc.push(fix.action.clone()); | ||
952 | } | ||
953 | } | ||
954 | Ok(()) | ||
955 | } | ||
956 | |||
960 | pub(crate) fn handle_code_action_resolve( | 957 | pub(crate) fn handle_code_action_resolve( |
961 | mut snap: GlobalStateSnapshot, | 958 | mut snap: GlobalStateSnapshot, |
962 | mut code_action: lsp_ext::CodeAction, | 959 | mut code_action: lsp_ext::CodeAction, |