diff options
-rw-r--r-- | crates/rust-analyzer/src/handlers.rs | 92 |
1 files changed, 46 insertions, 46 deletions
diff --git a/crates/rust-analyzer/src/handlers.rs b/crates/rust-analyzer/src/handlers.rs index 66f8bee99..a51a9293f 100644 --- a/crates/rust-analyzer/src/handlers.rs +++ b/crates/rust-analyzer/src/handlers.rs | |||
@@ -865,10 +865,52 @@ pub(crate) fn handle_formatting( | |||
865 | } | 865 | } |
866 | } | 866 | } |
867 | 867 | ||
868 | fn handle_fixes( | 868 | pub(crate) fn handle_code_action( |
869 | mut snap: GlobalStateSnapshot, | ||
870 | params: lsp_types::CodeActionParams, | ||
871 | ) -> Result<Option<Vec<lsp_ext::CodeAction>>> { | ||
872 | let _p = profile::span("handle_code_action"); | ||
873 | // We intentionally don't support command-based actions, as those either | ||
874 | // requires custom client-code anyway, or requires server-initiated edits. | ||
875 | // Server initiated edits break causality, so we avoid those as well. | ||
876 | if !snap.config.client_caps.code_action_literals { | ||
877 | return Ok(None); | ||
878 | } | ||
879 | |||
880 | let file_id = from_proto::file_id(&snap, ¶ms.text_document.uri)?; | ||
881 | let line_index = snap.analysis.file_line_index(file_id)?; | ||
882 | let range = from_proto::text_range(&line_index, params.range); | ||
883 | let frange = FileRange { file_id, range }; | ||
884 | |||
885 | snap.config.assist.allowed = params | ||
886 | .clone() | ||
887 | .context | ||
888 | .only | ||
889 | .map(|it| it.into_iter().filter_map(from_proto::assist_kind).collect()); | ||
890 | |||
891 | let mut res: Vec<lsp_ext::CodeAction> = Vec::new(); | ||
892 | |||
893 | add_quick_fixes(&snap, ¶ms, &mut res)?; | ||
894 | |||
895 | if snap.config.client_caps.code_action_resolve { | ||
896 | for (index, assist) in | ||
897 | snap.analysis.unresolved_assists(&snap.config.assist, frange)?.into_iter().enumerate() | ||
898 | { | ||
899 | res.push(to_proto::unresolved_code_action(&snap, params.clone(), assist, index)?); | ||
900 | } | ||
901 | } else { | ||
902 | for assist in snap.analysis.resolved_assists(&snap.config.assist, frange)?.into_iter() { | ||
903 | res.push(to_proto::resolved_code_action(&snap, assist)?); | ||
904 | } | ||
905 | } | ||
906 | |||
907 | Ok(Some(res)) | ||
908 | } | ||
909 | |||
910 | fn add_quick_fixes( | ||
869 | snap: &GlobalStateSnapshot, | 911 | snap: &GlobalStateSnapshot, |
870 | params: &lsp_types::CodeActionParams, | 912 | params: &lsp_types::CodeActionParams, |
871 | res: &mut Vec<lsp_ext::CodeAction>, | 913 | acc: &mut Vec<lsp_ext::CodeAction>, |
872 | ) -> Result<()> { | 914 | ) -> Result<()> { |
873 | let file_id = from_proto::file_id(&snap, ¶ms.text_document.uri)?; | 915 | let file_id = from_proto::file_id(&snap, ¶ms.text_document.uri)?; |
874 | let line_index = snap.analysis.file_line_index(file_id)?; | 916 | let line_index = snap.analysis.file_line_index(file_id)?; |
@@ -902,7 +944,7 @@ fn handle_fixes( | |||
902 | is_preferred: Some(false), | 944 | is_preferred: Some(false), |
903 | data: None, | 945 | data: None, |
904 | }; | 946 | }; |
905 | res.push(action); | 947 | acc.push(action); |
906 | } | 948 | } |
907 | 949 | ||
908 | for fix in snap.check_fixes.get(&file_id).into_iter().flatten() { | 950 | for fix in snap.check_fixes.get(&file_id).into_iter().flatten() { |
@@ -910,53 +952,11 @@ fn handle_fixes( | |||
910 | if fix_range.intersect(range).is_none() { | 952 | if fix_range.intersect(range).is_none() { |
911 | continue; | 953 | continue; |
912 | } | 954 | } |
913 | res.push(fix.action.clone()); | 955 | acc.push(fix.action.clone()); |
914 | } | 956 | } |
915 | Ok(()) | 957 | Ok(()) |
916 | } | 958 | } |
917 | 959 | ||
918 | pub(crate) fn handle_code_action( | ||
919 | mut snap: GlobalStateSnapshot, | ||
920 | params: lsp_types::CodeActionParams, | ||
921 | ) -> Result<Option<Vec<lsp_ext::CodeAction>>> { | ||
922 | let _p = profile::span("handle_code_action"); | ||
923 | // We intentionally don't support command-based actions, as those either | ||
924 | // requires custom client-code anyway, or requires server-initiated edits. | ||
925 | // Server initiated edits break causality, so we avoid those as well. | ||
926 | if !snap.config.client_caps.code_action_literals { | ||
927 | return Ok(None); | ||
928 | } | ||
929 | |||
930 | let file_id = from_proto::file_id(&snap, ¶ms.text_document.uri)?; | ||
931 | let line_index = snap.analysis.file_line_index(file_id)?; | ||
932 | let range = from_proto::text_range(&line_index, params.range); | ||
933 | let frange = FileRange { file_id, range }; | ||
934 | |||
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()); | ||
940 | |||
941 | let mut res: Vec<lsp_ext::CodeAction> = Vec::new(); | ||
942 | |||
943 | handle_fixes(&snap, ¶ms, &mut res)?; | ||
944 | |||
945 | if snap.config.client_caps.code_action_resolve { | ||
946 | for (index, assist) in | ||
947 | snap.analysis.unresolved_assists(&snap.config.assist, frange)?.into_iter().enumerate() | ||
948 | { | ||
949 | res.push(to_proto::unresolved_code_action(&snap, params.clone(), assist, index)?); | ||
950 | } | ||
951 | } else { | ||
952 | for assist in snap.analysis.resolved_assists(&snap.config.assist, frange)?.into_iter() { | ||
953 | res.push(to_proto::resolved_code_action(&snap, assist)?); | ||
954 | } | ||
955 | } | ||
956 | |||
957 | Ok(Some(res)) | ||
958 | } | ||
959 | |||
960 | pub(crate) fn handle_code_action_resolve( | 960 | pub(crate) fn handle_code_action_resolve( |
961 | mut snap: GlobalStateSnapshot, | 961 | mut snap: GlobalStateSnapshot, |
962 | mut code_action: lsp_ext::CodeAction, | 962 | mut code_action: lsp_ext::CodeAction, |