Skip to content

Commit 0dec77a

Browse files
bors[bot]matklad
andauthored
Merge #7018
7018: Cleanup handle_code_action r=matklad a=matklad bors r+ 🤖 Co-authored-by: Aleksey Kladov <[email protected]>
2 parents fd1fcf2 + 2ec92b3 commit 0dec77a

File tree

1 file changed

+58
-61
lines changed

1 file changed

+58
-61
lines changed

crates/rust-analyzer/src/handlers.rs

Lines changed: 58 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,13 @@
55
use std::{
66
io::Write as _,
77
process::{self, Stdio},
8+
sync::Arc,
89
};
910

1011
use ide::{
11-
CompletionResolveCapability, FileId, FilePosition, FileRange, HoverAction, HoverGotoTypeData,
12-
NavigationTarget, Query, RangeInfo, Runnable, RunnableKind, SearchScope, SymbolKind, TextEdit,
12+
AssistConfig, CompletionResolveCapability, FileId, FilePosition, FileRange, HoverAction,
13+
HoverGotoTypeData, LineIndex, NavigationTarget, Query, RangeInfo, Runnable, RunnableKind,
14+
SearchScope, SymbolKind, TextEdit,
1315
};
1416
use itertools::Itertools;
1517
use lsp_server::ErrorCode;
@@ -865,58 +867,8 @@ pub(crate) fn handle_formatting(
865867
}
866868
}
867869

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, &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-
918870
pub(crate) fn handle_code_action(
919-
mut snap: GlobalStateSnapshot,
871+
snap: GlobalStateSnapshot,
920872
params: lsp_types::CodeActionParams,
921873
) -> Result<Option<Vec<lsp_ext::CodeAction>>> {
922874
let _p = profile::span("handle_code_action");
@@ -932,31 +884,76 @@ pub(crate) fn handle_code_action(
932884
let range = from_proto::text_range(&line_index, params.range);
933885
let frange = FileRange { file_id, range };
934886

935-
snap.config.assist.allowed = params
936-
.clone()
937-
.context
938-
.only
939-
.map(|it| it.into_iter().filter_map(from_proto::assist_kind).collect());
887+
let assists_config = AssistConfig {
888+
allowed: params
889+
.clone()
890+
.context
891+
.only
892+
.map(|it| it.into_iter().filter_map(from_proto::assist_kind).collect()),
893+
..snap.config.assist
894+
};
940895

941896
let mut res: Vec<lsp_ext::CodeAction> = Vec::new();
942897

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+
}
944907

945908
if snap.config.client_caps.code_action_resolve {
946909
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()
948911
{
949912
res.push(to_proto::unresolved_code_action(&snap, params.clone(), assist, index)?);
950913
}
951914
} 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() {
953916
res.push(to_proto::resolved_code_action(&snap, assist)?);
954917
}
955918
}
956919

957920
Ok(Some(res))
958921
}
959922

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+
960957
pub(crate) fn handle_code_action_resolve(
961958
mut snap: GlobalStateSnapshot,
962959
mut code_action: lsp_ext::CodeAction,

0 commit comments

Comments
 (0)