aboutsummaryrefslogtreecommitdiff
path: root/crates/rust-analyzer/src/handlers.rs
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2021-04-12 21:08:56 +0100
committerAleksey Kladov <[email protected]>2021-04-13 08:59:15 +0100
commit460f0ef6695d58f21e431331ad60d9a76d40d064 (patch)
treea8c644918ec7c67988cf7292df93ac4709aaec3a /crates/rust-analyzer/src/handlers.rs
parent27e80e943824855c5913f20a776b3a5fa959e942 (diff)
internal: unfork code paths for unresolved and resolved assist
Diffstat (limited to 'crates/rust-analyzer/src/handlers.rs')
-rw-r--r--crates/rust-analyzer/src/handlers.rs100
1 files changed, 40 insertions, 60 deletions
diff --git a/crates/rust-analyzer/src/handlers.rs b/crates/rust-analyzer/src/handlers.rs
index 107685c63..85c70373a 100644
--- a/crates/rust-analyzer/src/handlers.rs
+++ b/crates/rust-analyzer/src/handlers.rs
@@ -8,8 +8,8 @@ use std::{
8}; 8};
9 9
10use ide::{ 10use ide::{
11 AnnotationConfig, FileId, FilePosition, FileRange, HoverAction, HoverGotoTypeData, Query, 11 AnnotationConfig, AssistKind, FileId, FilePosition, FileRange, HoverAction, HoverGotoTypeData,
12 RangeInfo, Runnable, RunnableKind, SearchScope, SourceChange, TextEdit, 12 Query, RangeInfo, Runnable, RunnableKind, SearchScope, SourceChange, TextEdit,
13}; 13};
14use ide_db::SymbolKind; 14use ide_db::SymbolKind;
15use itertools::Itertools; 15use itertools::Itertools;
@@ -17,7 +17,7 @@ use lsp_server::ErrorCode;
17use lsp_types::{ 17use lsp_types::{
18 CallHierarchyIncomingCall, CallHierarchyIncomingCallsParams, CallHierarchyItem, 18 CallHierarchyIncomingCall, CallHierarchyIncomingCallsParams, CallHierarchyItem,
19 CallHierarchyOutgoingCall, CallHierarchyOutgoingCallsParams, CallHierarchyPrepareParams, 19 CallHierarchyOutgoingCall, CallHierarchyOutgoingCallsParams, CallHierarchyPrepareParams,
20 CodeActionKind, CodeLens, CompletionItem, Diagnostic, DiagnosticTag, DocumentFormattingParams, 20 CodeLens, CompletionItem, Diagnostic, DiagnosticTag, DocumentFormattingParams,
21 DocumentHighlight, FoldingRange, FoldingRangeParams, HoverContents, Location, NumberOrString, 21 DocumentHighlight, FoldingRange, FoldingRangeParams, HoverContents, Location, NumberOrString,
22 Position, PrepareRenameResponse, Range, RenameParams, SemanticTokensDeltaParams, 22 Position, PrepareRenameResponse, Range, RenameParams, SemanticTokensDeltaParams,
23 SemanticTokensFullDeltaResult, SemanticTokensParams, SemanticTokensRangeParams, 23 SemanticTokensFullDeltaResult, SemanticTokensParams, SemanticTokensRangeParams,
@@ -36,7 +36,7 @@ use crate::{
36 diff::diff, 36 diff::diff,
37 from_proto, 37 from_proto,
38 global_state::{GlobalState, GlobalStateSnapshot}, 38 global_state::{GlobalState, GlobalStateSnapshot},
39 line_index::{LineEndings, LineIndex}, 39 line_index::LineEndings,
40 lsp_ext::{self, InlayHint, InlayHintsParams}, 40 lsp_ext::{self, InlayHint, InlayHintsParams},
41 lsp_utils::all_edits_are_disjoint, 41 lsp_utils::all_edits_are_disjoint,
42 to_proto, LspError, Result, 42 to_proto, LspError, Result,
@@ -982,86 +982,66 @@ pub(crate) fn handle_code_action(
982 params: lsp_types::CodeActionParams, 982 params: lsp_types::CodeActionParams,
983) -> Result<Option<Vec<lsp_ext::CodeAction>>> { 983) -> Result<Option<Vec<lsp_ext::CodeAction>>> {
984 let _p = profile::span("handle_code_action"); 984 let _p = profile::span("handle_code_action");
985 // We intentionally don't support command-based actions, as those either 985
986 // requires custom client-code anyway, or requires server-initiated edits.
987 // Server initiated edits break causality, so we avoid those as well.
988 if !snap.config.code_action_literals() { 986 if !snap.config.code_action_literals() {
987 // We intentionally don't support command-based actions, as those either
988 // require either custom client-code or server-initiated edits. Server
989 // initiated edits break causality, so we avoid those.
989 return Ok(None); 990 return Ok(None);
990 } 991 }
991 992
992 let file_id = from_proto::file_id(&snap, &params.text_document.uri)?; 993 let line_index =
993 let line_index = snap.file_line_index(file_id)?; 994 snap.file_line_index(from_proto::file_id(&snap, &params.text_document.uri)?)?;
994 let range = from_proto::text_range(&line_index, params.range); 995 let frange = from_proto::file_range(&snap, params.text_document.clone(), params.range)?;
995 let frange = FileRange { file_id, range };
996 996
997 let mut assists_config = snap.config.assist(); 997 let mut assists_config = snap.config.assist();
998 assists_config.allowed = params 998 assists_config.allowed = params
999 .clone()
1000 .context 999 .context
1001 .only 1000 .only
1001 .clone()
1002 .map(|it| it.into_iter().filter_map(from_proto::assist_kind).collect()); 1002 .map(|it| it.into_iter().filter_map(from_proto::assist_kind).collect());
1003 1003
1004 let mut res: Vec<lsp_ext::CodeAction> = Vec::new(); 1004 let mut res: Vec<lsp_ext::CodeAction> = Vec::new();
1005 1005
1006 let include_quick_fixes = match &params.context.only { 1006 let include_quick_fixes = match &assists_config.allowed {
1007 Some(v) => v.iter().any(|it| { 1007 Some(v) => v.iter().any(|it| it == &AssistKind::None || it == &AssistKind::QuickFix),
1008 it == &lsp_types::CodeActionKind::EMPTY || it == &lsp_types::CodeActionKind::QUICKFIX
1009 }),
1010 None => true, 1008 None => true,
1011 }; 1009 };
1012 if include_quick_fixes { 1010 let code_action_resolve_cap = snap.config.code_action_resolve();
1013 add_quick_fixes(&snap, frange, &line_index, &mut res)?;
1014 }
1015
1016 if snap.config.code_action_resolve() {
1017 for (index, assist) in
1018 snap.analysis.assists(&assists_config, false, frange)?.into_iter().enumerate()
1019 {
1020 res.push(to_proto::unresolved_code_action(&snap, params.clone(), assist, index)?);
1021 }
1022 } else {
1023 for assist in snap.analysis.assists(&assists_config, true, frange)?.into_iter() {
1024 res.push(to_proto::resolved_code_action(&snap, assist)?);
1025 }
1026 }
1027 1011
1028 Ok(Some(res)) 1012 let mut assists = Vec::new();
1029}
1030 1013
1031fn add_quick_fixes( 1014 // Fixes from native diagnostics.
1032 snap: &GlobalStateSnapshot, 1015 if include_quick_fixes {
1033 frange: FileRange, 1016 let diagnostics = snap.analysis.diagnostics(&snap.config.diagnostics(), frange.file_id)?;
1034 line_index: &LineIndex, 1017 assists.extend(
1035 acc: &mut Vec<lsp_ext::CodeAction>, 1018 diagnostics
1036) -> Result<()> { 1019 .into_iter()
1037 let diagnostics = snap.analysis.diagnostics(&snap.config.diagnostics(), frange.file_id)?; 1020 .filter_map(|d| d.fix)
1021 .filter(|fix| fix.target.intersect(frange.range).is_some()),
1022 )
1023 }
1038 1024
1039 for fix in diagnostics 1025 // Assists proper.
1040 .into_iter() 1026 assists.extend(snap.analysis.assists(&assists_config, !code_action_resolve_cap, frange)?);
1041 .filter_map(|d| d.fix) 1027 for (index, assist) in assists.into_iter().enumerate() {
1042 .filter(|fix| fix.target.intersect(frange.range).is_some()) 1028 let resolve_data =
1043 { 1029 if code_action_resolve_cap { Some((index, params.clone())) } else { None };
1044 if let Some(source_change) = fix.source_change { 1030 let code_action = to_proto::code_action(&snap, assist, resolve_data)?;
1045 let edit = to_proto::snippet_workspace_edit(&snap, source_change)?; 1031 res.push(code_action)
1046 let action = lsp_ext::CodeAction {
1047 title: fix.label.to_string(),
1048 group: None,
1049 kind: Some(CodeActionKind::QUICKFIX),
1050 edit: Some(edit),
1051 is_preferred: Some(false),
1052 data: None,
1053 };
1054 acc.push(action);
1055 }
1056 } 1032 }
1057 1033
1034 // Fixes from `cargo check`.
1058 for fix in snap.check_fixes.get(&frange.file_id).into_iter().flatten() { 1035 for fix in snap.check_fixes.get(&frange.file_id).into_iter().flatten() {
1036 // FIXME: this mapping is awkward and shouldn't exist. Refactor
1037 // `snap.check_fixes` to not convert to LSP prematurely.
1059 let fix_range = from_proto::text_range(&line_index, fix.range); 1038 let fix_range = from_proto::text_range(&line_index, fix.range);
1060 if fix_range.intersect(frange.range).is_some() { 1039 if fix_range.intersect(frange.range).is_some() {
1061 acc.push(fix.action.clone()); 1040 res.push(fix.action.clone());
1062 } 1041 }
1063 } 1042 }
1064 Ok(()) 1043
1044 Ok(Some(res))
1065} 1045}
1066 1046
1067pub(crate) fn handle_code_action_resolve( 1047pub(crate) fn handle_code_action_resolve(
@@ -1091,7 +1071,7 @@ pub(crate) fn handle_code_action_resolve(
1091 let index = index.parse::<usize>().unwrap(); 1071 let index = index.parse::<usize>().unwrap();
1092 let assist = &assists[index]; 1072 let assist = &assists[index];
1093 assert!(assist.id.0 == id); 1073 assert!(assist.id.0 == id);
1094 let edit = to_proto::resolved_code_action(&snap, assist.clone())?.edit; 1074 let edit = to_proto::code_action(&snap, assist.clone(), None)?.edit;
1095 code_action.edit = edit; 1075 code_action.edit = edit;
1096 Ok(code_action) 1076 Ok(code_action)
1097} 1077}