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 | |
parent | 27e80e943824855c5913f20a776b3a5fa959e942 (diff) |
internal: unfork code paths for unresolved and resolved assist
-rw-r--r-- | crates/ide_assists/src/lib.rs | 2 | ||||
-rw-r--r-- | crates/rust-analyzer/src/from_proto.rs | 30 | ||||
-rw-r--r-- | crates/rust-analyzer/src/handlers.rs | 100 | ||||
-rw-r--r-- | crates/rust-analyzer/src/to_proto.rs | 39 | ||||
-rw-r--r-- | crates/rust-analyzer/tests/rust-analyzer/main.rs | 2 |
5 files changed, 72 insertions, 101 deletions
diff --git a/crates/ide_assists/src/lib.rs b/crates/ide_assists/src/lib.rs index 3e2c82dac..3694f468f 100644 --- a/crates/ide_assists/src/lib.rs +++ b/crates/ide_assists/src/lib.rs | |||
@@ -28,7 +28,9 @@ pub use assist_config::AssistConfig; | |||
28 | 28 | ||
29 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] | 29 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] |
30 | pub enum AssistKind { | 30 | pub enum AssistKind { |
31 | // FIXME: does the None variant make sense? Probably not. | ||
31 | None, | 32 | None, |
33 | |||
32 | QuickFix, | 34 | QuickFix, |
33 | Generate, | 35 | Generate, |
34 | Refactor, | 36 | Refactor, |
diff --git a/crates/rust-analyzer/src/from_proto.rs b/crates/rust-analyzer/src/from_proto.rs index 5b02b2598..712d5a9c2 100644 --- a/crates/rust-analyzer/src/from_proto.rs +++ b/crates/rust-analyzer/src/from_proto.rs | |||
@@ -42,27 +42,27 @@ pub(crate) fn text_range(line_index: &LineIndex, range: lsp_types::Range) -> Tex | |||
42 | TextRange::new(start, end) | 42 | TextRange::new(start, end) |
43 | } | 43 | } |
44 | 44 | ||
45 | pub(crate) fn file_id(world: &GlobalStateSnapshot, url: &lsp_types::Url) -> Result<FileId> { | 45 | pub(crate) fn file_id(snap: &GlobalStateSnapshot, url: &lsp_types::Url) -> Result<FileId> { |
46 | world.url_to_file_id(url) | 46 | snap.url_to_file_id(url) |
47 | } | 47 | } |
48 | 48 | ||
49 | pub(crate) fn file_position( | 49 | pub(crate) fn file_position( |
50 | world: &GlobalStateSnapshot, | 50 | snap: &GlobalStateSnapshot, |
51 | tdpp: lsp_types::TextDocumentPositionParams, | 51 | tdpp: lsp_types::TextDocumentPositionParams, |
52 | ) -> Result<FilePosition> { | 52 | ) -> Result<FilePosition> { |
53 | let file_id = file_id(world, &tdpp.text_document.uri)?; | 53 | let file_id = file_id(snap, &tdpp.text_document.uri)?; |
54 | let line_index = world.file_line_index(file_id)?; | 54 | let line_index = snap.file_line_index(file_id)?; |
55 | let offset = offset(&line_index, tdpp.position); | 55 | let offset = offset(&line_index, tdpp.position); |
56 | Ok(FilePosition { file_id, offset }) | 56 | Ok(FilePosition { file_id, offset }) |
57 | } | 57 | } |
58 | 58 | ||
59 | pub(crate) fn file_range( | 59 | pub(crate) fn file_range( |
60 | world: &GlobalStateSnapshot, | 60 | snap: &GlobalStateSnapshot, |
61 | text_document_identifier: lsp_types::TextDocumentIdentifier, | 61 | text_document_identifier: lsp_types::TextDocumentIdentifier, |
62 | range: lsp_types::Range, | 62 | range: lsp_types::Range, |
63 | ) -> Result<FileRange> { | 63 | ) -> Result<FileRange> { |
64 | let file_id = file_id(world, &text_document_identifier.uri)?; | 64 | let file_id = file_id(snap, &text_document_identifier.uri)?; |
65 | let line_index = world.file_line_index(file_id)?; | 65 | let line_index = snap.file_line_index(file_id)?; |
66 | let range = text_range(&line_index, range); | 66 | let range = text_range(&line_index, range); |
67 | Ok(FileRange { file_id, range }) | 67 | Ok(FileRange { file_id, range }) |
68 | } | 68 | } |
@@ -82,7 +82,7 @@ pub(crate) fn assist_kind(kind: lsp_types::CodeActionKind) -> Option<AssistKind> | |||
82 | } | 82 | } |
83 | 83 | ||
84 | pub(crate) fn annotation( | 84 | pub(crate) fn annotation( |
85 | world: &GlobalStateSnapshot, | 85 | snap: &GlobalStateSnapshot, |
86 | code_lens: lsp_types::CodeLens, | 86 | code_lens: lsp_types::CodeLens, |
87 | ) -> Result<Annotation> { | 87 | ) -> Result<Annotation> { |
88 | let data = code_lens.data.unwrap(); | 88 | let data = code_lens.data.unwrap(); |
@@ -91,25 +91,25 @@ pub(crate) fn annotation( | |||
91 | match resolve { | 91 | match resolve { |
92 | lsp_ext::CodeLensResolveData::Impls(params) => { | 92 | lsp_ext::CodeLensResolveData::Impls(params) => { |
93 | let file_id = | 93 | let file_id = |
94 | world.url_to_file_id(¶ms.text_document_position_params.text_document.uri)?; | 94 | snap.url_to_file_id(¶ms.text_document_position_params.text_document.uri)?; |
95 | let line_index = world.file_line_index(file_id)?; | 95 | let line_index = snap.file_line_index(file_id)?; |
96 | 96 | ||
97 | Ok(Annotation { | 97 | Ok(Annotation { |
98 | range: text_range(&line_index, code_lens.range), | 98 | range: text_range(&line_index, code_lens.range), |
99 | kind: AnnotationKind::HasImpls { | 99 | kind: AnnotationKind::HasImpls { |
100 | position: file_position(world, params.text_document_position_params)?, | 100 | position: file_position(snap, params.text_document_position_params)?, |
101 | data: None, | 101 | data: None, |
102 | }, | 102 | }, |
103 | }) | 103 | }) |
104 | } | 104 | } |
105 | lsp_ext::CodeLensResolveData::References(params) => { | 105 | lsp_ext::CodeLensResolveData::References(params) => { |
106 | let file_id = world.url_to_file_id(¶ms.text_document.uri)?; | 106 | let file_id = snap.url_to_file_id(¶ms.text_document.uri)?; |
107 | let line_index = world.file_line_index(file_id)?; | 107 | let line_index = snap.file_line_index(file_id)?; |
108 | 108 | ||
109 | Ok(Annotation { | 109 | Ok(Annotation { |
110 | range: text_range(&line_index, code_lens.range), | 110 | range: text_range(&line_index, code_lens.range), |
111 | kind: AnnotationKind::HasReferences { | 111 | kind: AnnotationKind::HasReferences { |
112 | position: file_position(world, params)?, | 112 | position: file_position(snap, params)?, |
113 | data: None, | 113 | data: None, |
114 | }, | 114 | }, |
115 | }) | 115 | }) |
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 | } |
diff --git a/crates/rust-analyzer/src/to_proto.rs b/crates/rust-analyzer/src/to_proto.rs index 9fac562ff..53852bfdc 100644 --- a/crates/rust-analyzer/src/to_proto.rs +++ b/crates/rust-analyzer/src/to_proto.rs | |||
@@ -843,40 +843,31 @@ pub(crate) fn code_action_kind(kind: AssistKind) -> lsp_types::CodeActionKind { | |||
843 | } | 843 | } |
844 | } | 844 | } |
845 | 845 | ||
846 | pub(crate) fn unresolved_code_action( | 846 | pub(crate) fn code_action( |
847 | snap: &GlobalStateSnapshot, | 847 | snap: &GlobalStateSnapshot, |
848 | code_action_params: lsp_types::CodeActionParams, | ||
849 | assist: Assist, | 848 | assist: Assist, |
850 | index: usize, | 849 | resolve_data: Option<(usize, lsp_types::CodeActionParams)>, |
851 | ) -> Result<lsp_ext::CodeAction> { | 850 | ) -> Result<lsp_ext::CodeAction> { |
852 | assert!(assist.source_change.is_none()); | 851 | let mut res = lsp_ext::CodeAction { |
853 | let res = lsp_ext::CodeAction { | ||
854 | title: assist.label.to_string(), | 852 | title: assist.label.to_string(), |
855 | group: assist.group.filter(|_| snap.config.code_action_group()).map(|gr| gr.0), | 853 | group: assist.group.filter(|_| snap.config.code_action_group()).map(|gr| gr.0), |
856 | kind: Some(code_action_kind(assist.id.1)), | 854 | kind: Some(code_action_kind(assist.id.1)), |
857 | edit: None, | 855 | edit: None, |
858 | is_preferred: None, | 856 | is_preferred: None, |
859 | data: Some(lsp_ext::CodeActionData { | ||
860 | id: format!("{}:{}", assist.id.0, index.to_string()), | ||
861 | code_action_params, | ||
862 | }), | ||
863 | }; | ||
864 | Ok(res) | ||
865 | } | ||
866 | |||
867 | pub(crate) fn resolved_code_action( | ||
868 | snap: &GlobalStateSnapshot, | ||
869 | assist: Assist, | ||
870 | ) -> Result<lsp_ext::CodeAction> { | ||
871 | let change = assist.source_change.unwrap(); | ||
872 | let res = lsp_ext::CodeAction { | ||
873 | edit: Some(snippet_workspace_edit(snap, change)?), | ||
874 | title: assist.label.to_string(), | ||
875 | group: assist.group.filter(|_| snap.config.code_action_group()).map(|gr| gr.0), | ||
876 | kind: Some(code_action_kind(assist.id.1)), | ||
877 | is_preferred: None, | ||
878 | data: None, | 857 | data: None, |
879 | }; | 858 | }; |
859 | match (assist.source_change, resolve_data) { | ||
860 | (Some(it), _) => res.edit = Some(snippet_workspace_edit(snap, it)?), | ||
861 | (None, Some((index, code_action_params))) => { | ||
862 | res.data = Some(lsp_ext::CodeActionData { | ||
863 | id: format!("{}:{}", assist.id.0, index.to_string()), | ||
864 | code_action_params, | ||
865 | }); | ||
866 | } | ||
867 | (None, None) => { | ||
868 | stdx::never!("assist should always be resolved if client can't do lazy resolving") | ||
869 | } | ||
870 | }; | ||
880 | Ok(res) | 871 | Ok(res) |
881 | } | 872 | } |
882 | 873 | ||
diff --git a/crates/rust-analyzer/tests/rust-analyzer/main.rs b/crates/rust-analyzer/tests/rust-analyzer/main.rs index 1e4c04bbf..52a2674d5 100644 --- a/crates/rust-analyzer/tests/rust-analyzer/main.rs +++ b/crates/rust-analyzer/tests/rust-analyzer/main.rs | |||
@@ -340,7 +340,6 @@ fn main() {} | |||
340 | } | 340 | } |
341 | ] | 341 | ] |
342 | }, | 342 | }, |
343 | "isPreferred": false, | ||
344 | "kind": "quickfix", | 343 | "kind": "quickfix", |
345 | "title": "Create module" | 344 | "title": "Create module" |
346 | }]), | 345 | }]), |
@@ -411,7 +410,6 @@ fn main() {{}} | |||
411 | } | 410 | } |
412 | ] | 411 | ] |
413 | }, | 412 | }, |
414 | "isPreferred": false, | ||
415 | "kind": "quickfix", | 413 | "kind": "quickfix", |
416 | "title": "Create module" | 414 | "title": "Create module" |
417 | }]), | 415 | }]), |