aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/rust-analyzer/src/handlers.rs47
1 files changed, 20 insertions, 27 deletions
diff --git a/crates/rust-analyzer/src/handlers.rs b/crates/rust-analyzer/src/handlers.rs
index 83b3a343c..55bc2bcec 100644
--- a/crates/rust-analyzer/src/handlers.rs
+++ b/crates/rust-analyzer/src/handlers.rs
@@ -5,12 +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 AssistConfig, CompletionResolveCapability, FileId, FilePosition, FileRange, HoverAction, 12 AssistConfig, CompletionResolveCapability, FileId, FilePosition, FileRange, HoverAction,
12 HoverGotoTypeData, NavigationTarget, Query, RangeInfo, Runnable, RunnableKind, SearchScope, 13 HoverGotoTypeData, LineIndex, NavigationTarget, Query, RangeInfo, Runnable, RunnableKind,
13 SymbolKind, TextEdit, 14 SearchScope, SymbolKind, TextEdit,
14}; 15};
15use itertools::Itertools; 16use itertools::Itertools;
16use lsp_server::ErrorCode; 17use lsp_server::ErrorCode;
@@ -867,7 +868,7 @@ pub(crate) fn handle_formatting(
867} 868}
868 869
869pub(crate) fn handle_code_action( 870pub(crate) fn handle_code_action(
870 mut snap: GlobalStateSnapshot, 871 snap: GlobalStateSnapshot,
871 params: lsp_types::CodeActionParams, 872 params: lsp_types::CodeActionParams,
872) -> Result<Option<Vec<lsp_ext::CodeAction>>> { 873) -> Result<Option<Vec<lsp_ext::CodeAction>>> {
873 let _p = profile::span("handle_code_action"); 874 let _p = profile::span("handle_code_action");
@@ -894,7 +895,15 @@ pub(crate) fn handle_code_action(
894 895
895 let mut res: Vec<lsp_ext::CodeAction> = Vec::new(); 896 let mut res: Vec<lsp_ext::CodeAction> = Vec::new();
896 897
897 add_quick_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 }
898 907
899 if snap.config.client_caps.code_action_resolve { 908 if snap.config.client_caps.code_action_resolve {
900 for (index, assist) in 909 for (index, assist) in
@@ -913,31 +922,16 @@ pub(crate) fn handle_code_action(
913 922
914fn add_quick_fixes( 923fn add_quick_fixes(
915 snap: &GlobalStateSnapshot, 924 snap: &GlobalStateSnapshot,
916 params: &lsp_types::CodeActionParams, 925 frange: FileRange,
926 line_index: &Arc<LineIndex>,
917 acc: &mut Vec<lsp_ext::CodeAction>, 927 acc: &mut Vec<lsp_ext::CodeAction>,
918) -> Result<()> { 928) -> Result<()> {
919 let file_id = from_proto::file_id(&snap, &params.text_document.uri)?; 929 let diagnostics = snap.analysis.diagnostics(&snap.config.diagnostics, frange.file_id)?;
920 let line_index = snap.analysis.file_line_index(file_id)?;
921 let range = from_proto::text_range(&line_index, params.range);
922
923 match &params.context.only {
924 Some(v) => {
925 if !v.iter().any(|it| {
926 it == &lsp_types::CodeActionKind::EMPTY
927 || it == &lsp_types::CodeActionKind::QUICKFIX
928 }) {
929 return Ok(());
930 }
931 }
932 None => {}
933 };
934
935 let diagnostics = snap.analysis.diagnostics(&snap.config.diagnostics, file_id)?;
936 930
937 for fix in diagnostics 931 for fix in diagnostics
938 .into_iter() 932 .into_iter()
939 .filter_map(|d| d.fix) 933 .filter_map(|d| d.fix)
940 .filter(|fix| fix.fix_trigger_range.intersect(range).is_some()) 934 .filter(|fix| fix.fix_trigger_range.intersect(frange.range).is_some())
941 { 935 {
942 let edit = to_proto::snippet_workspace_edit(&snap, fix.source_change)?; 936 let edit = to_proto::snippet_workspace_edit(&snap, fix.source_change)?;
943 let action = lsp_ext::CodeAction { 937 let action = lsp_ext::CodeAction {
@@ -951,12 +945,11 @@ fn add_quick_fixes(
951 acc.push(action); 945 acc.push(action);
952 } 946 }
953 947
954 for fix in snap.check_fixes.get(&file_id).into_iter().flatten() { 948 for fix in snap.check_fixes.get(&frange.file_id).into_iter().flatten() {
955 let fix_range = from_proto::text_range(&line_index, fix.range); 949 let fix_range = from_proto::text_range(&line_index, fix.range);
956 if fix_range.intersect(range).is_none() { 950 if fix_range.intersect(frange.range).is_some() {
957 continue; 951 acc.push(fix.action.clone());
958 } 952 }
959 acc.push(fix.action.clone());
960 } 953 }
961 Ok(()) 954 Ok(())
962} 955}