3
3
//! `ra_ide` crate.
4
4
5
5
use std:: {
6
- collections:: hash_map:: Entry ,
7
6
fmt:: Write as _,
8
7
io:: Write as _,
9
8
process:: { self , Stdio } ,
@@ -13,15 +12,15 @@ use lsp_server::ErrorCode;
13
12
use lsp_types:: {
14
13
CallHierarchyIncomingCall , CallHierarchyIncomingCallsParams , CallHierarchyItem ,
15
14
CallHierarchyOutgoingCall , CallHierarchyOutgoingCallsParams , CallHierarchyPrepareParams ,
16
- CodeAction , CodeActionOrCommand , CodeActionResponse , CodeLens , Command , CompletionItem ,
17
- Diagnostic , DocumentFormattingParams , DocumentHighlight , DocumentSymbol , FoldingRange ,
18
- FoldingRangeParams , Hover , HoverContents , Location , MarkupContent , MarkupKind , Position ,
19
- PrepareRenameResponse , Range , RenameParams , SemanticTokens , SemanticTokensParams ,
20
- SemanticTokensRangeParams , SemanticTokensRangeResult , SemanticTokensResult , SymbolInformation ,
21
- TextDocumentIdentifier , TextEdit , WorkspaceEdit ,
15
+ CodeAction , CodeActionResponse , CodeLens , Command , CompletionItem , Diagnostic ,
16
+ DocumentFormattingParams , DocumentHighlight , DocumentSymbol , FoldingRange , FoldingRangeParams ,
17
+ Hover , HoverContents , Location , MarkupContent , MarkupKind , Position , PrepareRenameResponse ,
18
+ Range , RenameParams , SemanticTokens , SemanticTokensParams , SemanticTokensRangeParams ,
19
+ SemanticTokensRangeResult , SemanticTokensResult , SymbolInformation , TextDocumentIdentifier ,
20
+ TextEdit , WorkspaceEdit ,
22
21
} ;
23
22
use ra_ide:: {
24
- AssistId , FileId , FilePosition , FileRange , Query , RangeInfo , Runnable , RunnableKind ,
23
+ Assist , AssistId , FileId , FilePosition , FileRange , Query , RangeInfo , Runnable , RunnableKind ,
25
24
SearchScope ,
26
25
} ;
27
26
use ra_prof:: profile;
@@ -649,6 +648,31 @@ pub fn handle_formatting(
649
648
} ] ) )
650
649
}
651
650
651
+ fn create_single_code_action ( assist : Assist , world : & WorldSnapshot ) -> Result < CodeAction > {
652
+ let arg = to_value ( assist. source_change . try_conv_with ( world) ?) ?;
653
+ let title = assist. label ;
654
+ let command = Command {
655
+ title : title. clone ( ) ,
656
+ command : "rust-analyzer.applySourceChange" . to_string ( ) ,
657
+ arguments : Some ( vec ! [ arg] ) ,
658
+ } ;
659
+
660
+ let kind = match assist. id {
661
+ AssistId ( "introduce_variable" ) => Some ( "refactor.extract.variable" . to_string ( ) ) ,
662
+ AssistId ( "add_custom_impl" ) => Some ( "refactor.rewrite.add_custom_impl" . to_string ( ) ) ,
663
+ _ => None ,
664
+ } ;
665
+
666
+ Ok ( CodeAction {
667
+ title,
668
+ kind,
669
+ diagnostics : None ,
670
+ edit : None ,
671
+ command : Some ( command) ,
672
+ is_preferred : None ,
673
+ } )
674
+ }
675
+
652
676
pub fn handle_code_action (
653
677
world : WorldSnapshot ,
654
678
params : req:: CodeActionParams ,
@@ -695,59 +719,44 @@ pub fn handle_code_action(
695
719
res. push ( fix. action . clone ( ) ) ;
696
720
}
697
721
698
- let mut groups = FxHashMap :: default ( ) ;
722
+ let mut grouped_assists : FxHashMap < String , Vec < Assist > > = FxHashMap :: default ( ) ;
699
723
for assist in world. analysis ( ) . assists ( FileRange { file_id, range } ) ?. into_iter ( ) {
700
- let arg = to_value ( assist. source_change . try_conv_with ( & world) ?) ?;
701
-
702
- let ( command, title, arg) = match assist. group_label {
703
- None => ( "rust-analyzer.applySourceChange" , assist. label . clone ( ) , arg) ,
704
-
705
- // Group all assists with the same `group_label` into a single CodeAction.
706
- Some ( group_label) => {
707
- match groups. entry ( group_label. clone ( ) ) {
708
- Entry :: Occupied ( entry) => {
709
- let idx: usize = * entry. get ( ) ;
710
- match & mut res[ idx] {
711
- CodeActionOrCommand :: CodeAction ( CodeAction {
712
- command : Some ( Command { arguments : Some ( arguments) , .. } ) ,
713
- ..
714
- } ) => match arguments. as_mut_slice ( ) {
715
- [ serde_json:: Value :: Array ( arguments) ] => arguments. push ( arg) ,
716
- _ => panic ! ( "invalid group" ) ,
717
- } ,
718
- _ => panic ! ( "invalid group" ) ,
719
- }
720
- continue ;
721
- }
722
- Entry :: Vacant ( entry) => {
723
- entry. insert ( res. len ( ) ) ;
724
- }
725
- }
726
- ( "rust-analyzer.selectAndApplySourceChange" , group_label, to_value ( vec ! [ arg] ) ?)
727
- }
728
- } ;
729
-
730
- let command = Command {
731
- title : assist. label . clone ( ) ,
732
- command : command. to_string ( ) ,
733
- arguments : Some ( vec ! [ arg] ) ,
734
- } ;
724
+ match & assist. group_label {
725
+ Some ( label) => grouped_assists. entry ( label. to_owned ( ) ) . or_default ( ) . push ( assist) ,
726
+ None => res. push ( create_single_code_action ( assist, & world) ?. into ( ) ) ,
727
+ }
728
+ }
735
729
736
- let kind = match assist. id {
737
- AssistId ( "introduce_variable" ) => Some ( "refactor.extract.variable" . to_string ( ) ) ,
738
- AssistId ( "add_custom_impl" ) => Some ( "refactor.rewrite.add_custom_impl" . to_string ( ) ) ,
739
- _ => None ,
740
- } ;
730
+ for ( group_label, assists) in grouped_assists {
731
+ if assists. len ( ) == 1 {
732
+ res. push (
733
+ create_single_code_action ( assists. into_iter ( ) . next ( ) . unwrap ( ) , & world) ?. into ( ) ,
734
+ ) ;
735
+ } else {
736
+ let title = group_label;
737
+
738
+ let mut arguments = Vec :: with_capacity ( assists. len ( ) ) ;
739
+ for assist in assists {
740
+ arguments. push ( to_value ( assist. source_change . try_conv_with ( & world) ?) ?) ;
741
+ }
741
742
742
- let action = CodeAction {
743
- title,
744
- kind,
745
- diagnostics : None ,
746
- edit : None ,
747
- command : Some ( command) ,
748
- is_preferred : None ,
749
- } ;
750
- res. push ( action. into ( ) ) ;
743
+ let command = Some ( Command {
744
+ title : title. clone ( ) ,
745
+ command : "rust-analyzer.selectAndApplySourceChange" . to_string ( ) ,
746
+ arguments : Some ( vec ! [ serde_json:: Value :: Array ( arguments) ] ) ,
747
+ } ) ;
748
+ res. push (
749
+ CodeAction {
750
+ title,
751
+ kind : None ,
752
+ diagnostics : None ,
753
+ edit : None ,
754
+ command,
755
+ is_preferred : None ,
756
+ }
757
+ . into ( ) ,
758
+ ) ;
759
+ }
751
760
}
752
761
753
762
Ok ( Some ( res) )
0 commit comments