55use std:: {
66 io:: Write as _,
77 process:: { self , Stdio } ,
8+ sync:: Arc ,
89} ;
910
1011use ide:: {
11- CompletionResolveCapability , FileId , FilePosition , FileRange , HoverAction , HoverGotoTypeData ,
12- NavigationTarget , Query , RangeInfo , Runnable , RunnableKind , SearchScope , SymbolKind , TextEdit ,
12+ AssistConfig , CompletionResolveCapability , FileId , FilePosition , FileRange , HoverAction ,
13+ HoverGotoTypeData , LineIndex , NavigationTarget , Query , RangeInfo , Runnable , RunnableKind ,
14+ SearchScope , SymbolKind , TextEdit ,
1315} ;
1416use itertools:: Itertools ;
1517use lsp_server:: ErrorCode ;
@@ -865,58 +867,8 @@ pub(crate) fn handle_formatting(
865867 }
866868}
867869
868- fn handle_fixes (
869- snap : & GlobalStateSnapshot ,
870- params : & lsp_types:: CodeActionParams ,
871- res : & mut Vec < lsp_ext:: CodeAction > ,
872- ) -> Result < ( ) > {
873- let file_id = from_proto:: file_id ( & snap, & params. text_document . uri ) ?;
874- let line_index = snap. analysis . file_line_index ( file_id) ?;
875- let range = from_proto:: text_range ( & line_index, params. range ) ;
876-
877- match & params. context . only {
878- Some ( v) => {
879- if !v. iter ( ) . any ( |it| {
880- it == & lsp_types:: CodeActionKind :: EMPTY
881- || it == & lsp_types:: CodeActionKind :: QUICKFIX
882- } ) {
883- return Ok ( ( ) ) ;
884- }
885- }
886- None => { }
887- } ;
888-
889- let diagnostics = snap. analysis . diagnostics ( & snap. config . diagnostics , file_id) ?;
890-
891- for fix in diagnostics
892- . into_iter ( )
893- . filter_map ( |d| d. fix )
894- . filter ( |fix| fix. fix_trigger_range . intersect ( range) . is_some ( ) )
895- {
896- let edit = to_proto:: snippet_workspace_edit ( & snap, fix. source_change ) ?;
897- let action = lsp_ext:: CodeAction {
898- title : fix. label . to_string ( ) ,
899- group : None ,
900- kind : Some ( CodeActionKind :: QUICKFIX ) ,
901- edit : Some ( edit) ,
902- is_preferred : Some ( false ) ,
903- data : None ,
904- } ;
905- res. push ( action) ;
906- }
907-
908- for fix in snap. check_fixes . get ( & file_id) . into_iter ( ) . flatten ( ) {
909- let fix_range = from_proto:: text_range ( & line_index, fix. range ) ;
910- if fix_range. intersect ( range) . is_none ( ) {
911- continue ;
912- }
913- res. push ( fix. action . clone ( ) ) ;
914- }
915- Ok ( ( ) )
916- }
917-
918870pub ( crate ) fn handle_code_action (
919- mut snap : GlobalStateSnapshot ,
871+ snap : GlobalStateSnapshot ,
920872 params : lsp_types:: CodeActionParams ,
921873) -> Result < Option < Vec < lsp_ext:: CodeAction > > > {
922874 let _p = profile:: span ( "handle_code_action" ) ;
@@ -932,31 +884,76 @@ pub(crate) fn handle_code_action(
932884 let range = from_proto:: text_range ( & line_index, params. range ) ;
933885 let frange = FileRange { file_id, range } ;
934886
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 ( ) ) ;
887+ let assists_config = AssistConfig {
888+ allowed : params
889+ . clone ( )
890+ . context
891+ . only
892+ . map ( |it| it. into_iter ( ) . filter_map ( from_proto:: assist_kind) . collect ( ) ) ,
893+ ..snap. config . assist
894+ } ;
940895
941896 let mut res: Vec < lsp_ext:: CodeAction > = Vec :: new ( ) ;
942897
943- handle_fixes ( & snap, & params, & mut res) ?;
898+ let include_quick_fixes = match & params. context . only {
899+ Some ( v) => v. iter ( ) . any ( |it| {
900+ it == & lsp_types:: CodeActionKind :: EMPTY || it == & lsp_types:: CodeActionKind :: QUICKFIX
901+ } ) ,
902+ None => true ,
903+ } ;
904+ if include_quick_fixes {
905+ add_quick_fixes ( & snap, frange, & line_index, & mut res) ?;
906+ }
944907
945908 if snap. config . client_caps . code_action_resolve {
946909 for ( index, assist) in
947- snap. analysis . unresolved_assists ( & snap . config . assist , frange) ?. into_iter ( ) . enumerate ( )
910+ snap. analysis . unresolved_assists ( & assists_config , frange) ?. into_iter ( ) . enumerate ( )
948911 {
949912 res. push ( to_proto:: unresolved_code_action ( & snap, params. clone ( ) , assist, index) ?) ;
950913 }
951914 } else {
952- for assist in snap. analysis . resolved_assists ( & snap . config . assist , frange) ?. into_iter ( ) {
915+ for assist in snap. analysis . resolved_assists ( & assists_config , frange) ?. into_iter ( ) {
953916 res. push ( to_proto:: resolved_code_action ( & snap, assist) ?) ;
954917 }
955918 }
956919
957920 Ok ( Some ( res) )
958921}
959922
923+ fn add_quick_fixes (
924+ snap : & GlobalStateSnapshot ,
925+ frange : FileRange ,
926+ line_index : & Arc < LineIndex > ,
927+ acc : & mut Vec < lsp_ext:: CodeAction > ,
928+ ) -> Result < ( ) > {
929+ let diagnostics = snap. analysis . diagnostics ( & snap. config . diagnostics , frange. file_id ) ?;
930+
931+ for fix in diagnostics
932+ . into_iter ( )
933+ . filter_map ( |d| d. fix )
934+ . filter ( |fix| fix. fix_trigger_range . intersect ( frange. range ) . is_some ( ) )
935+ {
936+ let edit = to_proto:: snippet_workspace_edit ( & snap, fix. source_change ) ?;
937+ let action = lsp_ext:: CodeAction {
938+ title : fix. label . to_string ( ) ,
939+ group : None ,
940+ kind : Some ( CodeActionKind :: QUICKFIX ) ,
941+ edit : Some ( edit) ,
942+ is_preferred : Some ( false ) ,
943+ data : None ,
944+ } ;
945+ acc. push ( action) ;
946+ }
947+
948+ for fix in snap. check_fixes . get ( & frange. file_id ) . into_iter ( ) . flatten ( ) {
949+ let fix_range = from_proto:: text_range ( & line_index, fix. range ) ;
950+ if fix_range. intersect ( frange. range ) . is_some ( ) {
951+ acc. push ( fix. action . clone ( ) ) ;
952+ }
953+ }
954+ Ok ( ( ) )
955+ }
956+
960957pub ( crate ) fn handle_code_action_resolve (
961958 mut snap : GlobalStateSnapshot ,
962959 mut code_action : lsp_ext:: CodeAction ,
0 commit comments