aboutsummaryrefslogtreecommitdiff
path: root/crates/rust-analyzer/src/main_loop/handlers.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/rust-analyzer/src/main_loop/handlers.rs')
-rw-r--r--crates/rust-analyzer/src/main_loop/handlers.rs64
1 files changed, 11 insertions, 53 deletions
diff --git a/crates/rust-analyzer/src/main_loop/handlers.rs b/crates/rust-analyzer/src/main_loop/handlers.rs
index 121964718..a9703e1d6 100644
--- a/crates/rust-analyzer/src/main_loop/handlers.rs
+++ b/crates/rust-analyzer/src/main_loop/handlers.rs
@@ -18,7 +18,7 @@ use lsp_types::{
18 SemanticTokensResult, SymbolInformation, TextDocumentIdentifier, Url, WorkspaceEdit, 18 SemanticTokensResult, SymbolInformation, TextDocumentIdentifier, Url, WorkspaceEdit,
19}; 19};
20use ra_ide::{ 20use ra_ide::{
21 Assist, FileId, FilePosition, FileRange, Query, RangeInfo, Runnable, RunnableKind, SearchScope, 21 FileId, FilePosition, FileRange, Query, RangeInfo, Runnable, RunnableKind, SearchScope,
22 TextEdit, 22 TextEdit,
23}; 23};
24use ra_prof::profile; 24use ra_prof::profile;
@@ -720,6 +720,7 @@ pub fn handle_code_action(
720 let file_id = from_proto::file_id(&world, &params.text_document.uri)?; 720 let file_id = from_proto::file_id(&world, &params.text_document.uri)?;
721 let line_index = world.analysis().file_line_index(file_id)?; 721 let line_index = world.analysis().file_line_index(file_id)?;
722 let range = from_proto::text_range(&line_index, params.range); 722 let range = from_proto::text_range(&line_index, params.range);
723 let frange = FileRange { file_id, range };
723 724
724 let diagnostics = world.analysis().diagnostics(file_id)?; 725 let diagnostics = world.analysis().diagnostics(file_id)?;
725 let mut res: Vec<lsp_ext::CodeAction> = Vec::new(); 726 let mut res: Vec<lsp_ext::CodeAction> = Vec::new();
@@ -730,10 +731,11 @@ pub fn handle_code_action(
730 .filter(|(diag_range, _fix)| diag_range.intersect(range).is_some()) 731 .filter(|(diag_range, _fix)| diag_range.intersect(range).is_some())
731 .map(|(_range, fix)| fix); 732 .map(|(_range, fix)| fix);
732 733
733 for source_edit in fixes_from_diagnostics { 734 for fix in fixes_from_diagnostics {
734 let title = source_edit.label.clone(); 735 let title = fix.label;
735 let edit = to_proto::snippet_workspace_edit(&world, source_edit)?; 736 let edit = to_proto::snippet_workspace_edit(&world, fix.source_change)?;
736 let action = lsp_ext::CodeAction { title, kind: None, edit: Some(edit), command: None }; 737 let action =
738 lsp_ext::CodeAction { title, group: None, kind: None, edit: Some(edit), command: None };
737 res.push(action); 739 res.push(action);
738 } 740 }
739 741
@@ -745,53 +747,9 @@ pub fn handle_code_action(
745 res.push(fix.action.clone()); 747 res.push(fix.action.clone());
746 } 748 }
747 749
748 let mut grouped_assists: FxHashMap<String, (usize, Vec<Assist>)> = FxHashMap::default(); 750 for assist in world.analysis().assists(&world.config.assist, frange)?.into_iter() {
749 for assist in 751 res.push(to_proto::code_action(&world, assist)?.into());
750 world.analysis().assists(&world.config.assist, FileRange { file_id, range })?.into_iter()
751 {
752 match &assist.group_label {
753 Some(label) => grouped_assists
754 .entry(label.to_owned())
755 .or_insert_with(|| {
756 let idx = res.len();
757 let dummy = lsp_ext::CodeAction {
758 title: String::new(),
759 kind: None,
760 command: None,
761 edit: None,
762 };
763 res.push(dummy);
764 (idx, Vec::new())
765 })
766 .1
767 .push(assist),
768 None => {
769 res.push(to_proto::code_action(&world, assist)?.into());
770 }
771 }
772 }
773
774 for (group_label, (idx, assists)) in grouped_assists {
775 if assists.len() == 1 {
776 res[idx] = to_proto::code_action(&world, assists.into_iter().next().unwrap())?.into();
777 } else {
778 let title = group_label;
779
780 let mut arguments = Vec::with_capacity(assists.len());
781 for assist in assists {
782 let source_change = to_proto::source_change(&world, assist.source_change)?;
783 arguments.push(to_value(source_change)?);
784 }
785
786 let command = Some(Command {
787 title: title.clone(),
788 command: "rust-analyzer.selectAndApplySourceChange".to_string(),
789 arguments: Some(vec![serde_json::Value::Array(arguments)]),
790 });
791 res[idx] = lsp_ext::CodeAction { title, kind: None, edit: None, command };
792 }
793 } 752 }
794
795 Ok(Some(res)) 753 Ok(Some(res))
796} 754}
797 755
@@ -986,11 +944,11 @@ pub fn handle_document_highlight(
986pub fn handle_ssr( 944pub fn handle_ssr(
987 world: WorldSnapshot, 945 world: WorldSnapshot,
988 params: lsp_ext::SsrParams, 946 params: lsp_ext::SsrParams,
989) -> Result<lsp_ext::SourceChange> { 947) -> Result<lsp_types::WorkspaceEdit> {
990 let _p = profile("handle_ssr"); 948 let _p = profile("handle_ssr");
991 let source_change = 949 let source_change =
992 world.analysis().structural_search_replace(&params.query, params.parse_only)??; 950 world.analysis().structural_search_replace(&params.query, params.parse_only)??;
993 to_proto::source_change(&world, source_change) 951 to_proto::workspace_edit(&world, source_change)
994} 952}
995 953
996pub fn publish_diagnostics(world: &WorldSnapshot, file_id: FileId) -> Result<DiagnosticTask> { 954pub fn publish_diagnostics(world: &WorldSnapshot, file_id: FileId) -> Result<DiagnosticTask> {