diff options
author | Aleksey Kladov <[email protected]> | 2021-04-12 21:08:56 +0100 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2021-04-13 08:59:15 +0100 |
commit | 460f0ef6695d58f21e431331ad60d9a76d40d064 (patch) | |
tree | a8c644918ec7c67988cf7292df93ac4709aaec3a /crates/rust-analyzer/src/handlers.rs | |
parent | 27e80e943824855c5913f20a776b3a5fa959e942 (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.rs | 100 |
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 | ||
10 | use ide::{ | 10 | use 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 | }; |
14 | use ide_db::SymbolKind; | 14 | use ide_db::SymbolKind; |
15 | use itertools::Itertools; | 15 | use itertools::Itertools; |
@@ -17,7 +17,7 @@ use lsp_server::ErrorCode; | |||
17 | use lsp_types::{ | 17 | use 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, ¶ms.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, ¶ms.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 ¶ms.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 | ||
1031 | fn 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 | ||
1067 | pub(crate) fn handle_code_action_resolve( | 1047 | pub(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 | } |