aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/rust-analyzer/src/handlers.rs119
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 @@
5use std::{ 5use std::{
6 io::Write as _, 6 io::Write as _,
7 process::{self, Stdio}, 7 process::{self, Stdio},
8 sync::Arc,
8}; 9};
9 10
10use ide::{ 11use 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};
14use itertools::Itertools; 16use itertools::Itertools;
15use lsp_server::ErrorCode; 17use lsp_server::ErrorCode;
@@ -865,58 +867,8 @@ pub(crate) fn handle_formatting(
865 } 867 }
866} 868}
867 869
868fn 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, &params.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 &params.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
918pub(crate) fn handle_code_action( 870pub(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, &params, &mut res)?; 898 let include_quick_fixes = match &params.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
923fn 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
960pub(crate) fn handle_code_action_resolve( 957pub(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,