@@ -703,6 +703,88 @@ impl GlobalState {
703
703
704
704
/// Handles an incoming notification.
705
705
fn on_notification ( & mut self , not : Notification ) -> Result < ( ) > {
706
+ // FIXME: Move these implementations out into a module similar to on_request
707
+ fn run_flycheck ( this : & mut GlobalState , vfs_path : VfsPath ) -> bool {
708
+ let file_id = this. vfs . read ( ) . 0 . file_id ( & vfs_path) ;
709
+ if let Some ( file_id) = file_id {
710
+ let world = this. snapshot ( ) ;
711
+ let mut updated = false ;
712
+ let task = move || -> std:: result:: Result < ( ) , ide:: Cancelled > {
713
+ // Trigger flychecks for all workspaces that depend on the saved file
714
+ // Crates containing or depending on the saved file
715
+ let crate_ids: Vec < _ > = world
716
+ . analysis
717
+ . crates_for ( file_id) ?
718
+ . into_iter ( )
719
+ . flat_map ( |id| world. analysis . transitive_rev_deps ( id) )
720
+ . flatten ( )
721
+ . sorted ( )
722
+ . unique ( )
723
+ . collect ( ) ;
724
+
725
+ let crate_root_paths: Vec < _ > = crate_ids
726
+ . iter ( )
727
+ . filter_map ( |& crate_id| {
728
+ world
729
+ . analysis
730
+ . crate_root ( crate_id)
731
+ . map ( |file_id| {
732
+ world
733
+ . file_id_to_file_path ( file_id)
734
+ . as_path ( )
735
+ . map ( ToOwned :: to_owned)
736
+ } )
737
+ . transpose ( )
738
+ } )
739
+ . collect :: < ide:: Cancellable < _ > > ( ) ?;
740
+ let crate_root_paths: Vec < _ > =
741
+ crate_root_paths. iter ( ) . map ( Deref :: deref) . collect ( ) ;
742
+
743
+ // Find all workspaces that have at least one target containing the saved file
744
+ let workspace_ids =
745
+ world. workspaces . iter ( ) . enumerate ( ) . filter ( |( _, ws) | match ws {
746
+ project_model:: ProjectWorkspace :: Cargo { cargo, .. } => {
747
+ cargo. packages ( ) . any ( |pkg| {
748
+ cargo[ pkg] . targets . iter ( ) . any ( |& it| {
749
+ crate_root_paths. contains ( & cargo[ it] . root . as_path ( ) )
750
+ } )
751
+ } )
752
+ }
753
+ project_model:: ProjectWorkspace :: Json { project, .. } => project
754
+ . crates ( )
755
+ . any ( |( c, _) | crate_ids. iter ( ) . any ( |& crate_id| crate_id == c) ) ,
756
+ project_model:: ProjectWorkspace :: DetachedFiles { .. } => false ,
757
+ } ) ;
758
+
759
+ // Find and trigger corresponding flychecks
760
+ for flycheck in world. flycheck . iter ( ) {
761
+ for ( id, _) in workspace_ids. clone ( ) {
762
+ if id == flycheck. id ( ) {
763
+ updated = true ;
764
+ flycheck. restart ( ) ;
765
+ continue ;
766
+ }
767
+ }
768
+ }
769
+ // No specific flycheck was triggered, so let's trigger all of them.
770
+ if !updated {
771
+ for flycheck in world. flycheck . iter ( ) {
772
+ flycheck. restart ( ) ;
773
+ }
774
+ }
775
+ Ok ( ( ) )
776
+ } ;
777
+ this. task_pool . handle . spawn_with_sender ( move |_| {
778
+ if let Err ( e) = std:: panic:: catch_unwind ( task) {
779
+ tracing:: error!( "flycheck task panicked: {e:?}" )
780
+ }
781
+ } ) ;
782
+ true
783
+ } else {
784
+ false
785
+ }
786
+ }
787
+
706
788
NotificationDispatcher { not : Some ( not) , global_state : self }
707
789
. on :: < lsp_types:: notification:: Cancel > ( |this, params| {
708
790
let id: lsp_server:: RequestId = match params. id {
@@ -782,6 +864,20 @@ impl GlobalState {
782
864
}
783
865
Ok ( ( ) )
784
866
} ) ?
867
+ . on :: < lsp_ext:: RunFlycheck > ( |this, params| {
868
+ if let Some ( text_document) = params. text_document {
869
+ if let Ok ( vfs_path) = from_proto:: vfs_path ( & text_document. uri ) {
870
+ if run_flycheck ( this, vfs_path) {
871
+ return Ok ( ( ) ) ;
872
+ }
873
+ }
874
+ }
875
+ // No specific flycheck was triggered, so let's trigger all of them.
876
+ for flycheck in this. flycheck . iter ( ) {
877
+ flycheck. restart ( ) ;
878
+ }
879
+ Ok ( ( ) )
880
+ } ) ?
785
881
. on :: < lsp_types:: notification:: DidSaveTextDocument > ( |this, params| {
786
882
if let Ok ( vfs_path) = from_proto:: vfs_path ( & params. text_document . uri ) {
787
883
// Re-fetch workspaces if a workspace related file has changed
@@ -792,82 +888,7 @@ impl GlobalState {
792
888
}
793
889
}
794
890
795
- let file_id = this. vfs . read ( ) . 0 . file_id ( & vfs_path) ;
796
- if let Some ( file_id) = file_id {
797
- let world = this. snapshot ( ) ;
798
- let mut updated = false ;
799
- let task = move || -> std:: result:: Result < ( ) , ide:: Cancelled > {
800
- // Trigger flychecks for all workspaces that depend on the saved file
801
- // Crates containing or depending on the saved file
802
- let crate_ids: Vec < _ > = world
803
- . analysis
804
- . crates_for ( file_id) ?
805
- . into_iter ( )
806
- . flat_map ( |id| world. analysis . transitive_rev_deps ( id) )
807
- . flatten ( )
808
- . sorted ( )
809
- . unique ( )
810
- . collect ( ) ;
811
-
812
- let crate_root_paths: Vec < _ > = crate_ids
813
- . iter ( )
814
- . filter_map ( |& crate_id| {
815
- world
816
- . analysis
817
- . crate_root ( crate_id)
818
- . map ( |file_id| {
819
- world
820
- . file_id_to_file_path ( file_id)
821
- . as_path ( )
822
- . map ( ToOwned :: to_owned)
823
- } )
824
- . transpose ( )
825
- } )
826
- . collect :: < ide:: Cancellable < _ > > ( ) ?;
827
- let crate_root_paths: Vec < _ > =
828
- crate_root_paths. iter ( ) . map ( Deref :: deref) . collect ( ) ;
829
-
830
- // Find all workspaces that have at least one target containing the saved file
831
- let workspace_ids =
832
- world. workspaces . iter ( ) . enumerate ( ) . filter ( |( _, ws) | match ws {
833
- project_model:: ProjectWorkspace :: Cargo { cargo, .. } => {
834
- cargo. packages ( ) . any ( |pkg| {
835
- cargo[ pkg] . targets . iter ( ) . any ( |& it| {
836
- crate_root_paths. contains ( & cargo[ it] . root . as_path ( ) )
837
- } )
838
- } )
839
- }
840
- project_model:: ProjectWorkspace :: Json { project, .. } => {
841
- project. crates ( ) . any ( |( c, _) | {
842
- crate_ids. iter ( ) . any ( |& crate_id| crate_id == c)
843
- } )
844
- }
845
- project_model:: ProjectWorkspace :: DetachedFiles { .. } => false ,
846
- } ) ;
847
-
848
- // Find and trigger corresponding flychecks
849
- for flycheck in world. flycheck . iter ( ) {
850
- for ( id, _) in workspace_ids. clone ( ) {
851
- if id == flycheck. id ( ) {
852
- updated = true ;
853
- flycheck. restart ( ) ;
854
- continue ;
855
- }
856
- }
857
- }
858
- // No specific flycheck was triggered, so let's trigger all of them.
859
- if !updated {
860
- for flycheck in world. flycheck . iter ( ) {
861
- flycheck. restart ( ) ;
862
- }
863
- }
864
- Ok ( ( ) )
865
- } ;
866
- this. task_pool . handle . spawn_with_sender ( move |_| {
867
- if let Err ( e) = std:: panic:: catch_unwind ( task) {
868
- tracing:: error!( "DidSaveTextDocument flycheck task panicked: {e:?}" )
869
- }
870
- } ) ;
891
+ if run_flycheck ( this, vfs_path) {
871
892
return Ok ( ( ) ) ;
872
893
}
873
894
}
0 commit comments