@@ -10,7 +10,7 @@ use std::{
1010use always_assert:: always;
1111use crossbeam_channel:: { select, Receiver } ;
1212use flycheck:: FlycheckHandle ;
13- use ide_db:: base_db:: { SourceDatabase , SourceDatabaseExt , VfsPath } ;
13+ use ide_db:: base_db:: { SourceDatabaseExt , VfsPath } ;
1414use itertools:: Itertools ;
1515use lsp_server:: { Connection , Notification , Request } ;
1616use lsp_types:: notification:: Notification as _;
@@ -191,7 +191,7 @@ impl GlobalState {
191191 // NOTE: don't count blocking select! call as a loop-turn time
192192 let _p = profile:: span ( "GlobalState::handle_event" ) ;
193193
194- tracing:: debug!( "handle_event({:?})" , event) ;
194+ tracing:: debug!( "{:?} handle_event({:?})" , loop_start , event) ;
195195 let task_queue_len = self . task_pool . handle . len ( ) ;
196196 if task_queue_len > 0 {
197197 tracing:: info!( "task queue len: {}" , task_queue_len) ;
@@ -727,7 +727,7 @@ impl GlobalState {
727727 . insert ( path. clone ( ) , DocumentData :: new ( params. text_document . version ) )
728728 . is_err ( ) ;
729729 if already_exists {
730- tracing:: error!( "duplicate DidOpenTextDocument: {}" , path)
730+ tracing:: error!( "duplicate DidOpenTextDocument: {}" , path) ;
731731 }
732732 this. vfs
733733 . write ( )
@@ -774,83 +774,98 @@ impl GlobalState {
774774 Ok ( ( ) )
775775 } ) ?
776776 . on :: < lsp_types:: notification:: DidSaveTextDocument > ( |this, params| {
777- let mut updated = false ;
778777 if let Ok ( vfs_path) = from_proto:: vfs_path ( & params. text_document . uri ) {
779- let ( vfs, _) = & * this. vfs . read ( ) ;
780-
781- // Trigger flychecks for all workspaces that depend on the saved file
782- if let Some ( file_id) = vfs. file_id ( & vfs_path) {
783- let analysis = this. analysis_host . analysis ( ) ;
784- // Crates containing or depending on the saved file
785- let crate_ids: Vec < _ > = analysis
786- . crates_for ( file_id) ?
787- . into_iter ( )
788- . flat_map ( |id| {
789- this. analysis_host
790- . raw_database ( )
791- . crate_graph ( )
792- . transitive_rev_deps ( id)
793- } )
794- . sorted ( )
795- . unique ( )
796- . collect ( ) ;
797-
798- let crate_root_paths: Vec < _ > = crate_ids
799- . iter ( )
800- . filter_map ( |& crate_id| {
801- analysis
802- . crate_root ( crate_id)
803- . map ( |file_id| {
804- vfs. file_path ( file_id) . as_path ( ) . map ( ToOwned :: to_owned)
805- } )
806- . transpose ( )
807- } )
808- . collect :: < ide:: Cancellable < _ > > ( ) ?;
809- let crate_root_paths: Vec < _ > =
810- crate_root_paths. iter ( ) . map ( Deref :: deref) . collect ( ) ;
811-
812- // Find all workspaces that have at least one target containing the saved file
813- let workspace_ids =
814- this. workspaces . iter ( ) . enumerate ( ) . filter ( |( _, ws) | match ws {
815- project_model:: ProjectWorkspace :: Cargo { cargo, .. } => {
816- cargo. packages ( ) . any ( |pkg| {
817- cargo[ pkg] . targets . iter ( ) . any ( |& it| {
818- crate_root_paths. contains ( & cargo[ it] . root . as_path ( ) )
819- } )
820- } )
821- }
822- project_model:: ProjectWorkspace :: Json { project, .. } => project
823- . crates ( )
824- . any ( |( c, _) | crate_ids. iter ( ) . any ( |& crate_id| crate_id == c) ) ,
825- project_model:: ProjectWorkspace :: DetachedFiles { .. } => false ,
826- } ) ;
827-
828- // Find and trigger corresponding flychecks
829- for flycheck in & this. flycheck {
830- for ( id, _) in workspace_ids. clone ( ) {
831- if id == flycheck. id ( ) {
832- updated = true ;
833- flycheck. restart ( ) ;
834- continue ;
835- }
836- }
837- }
838- }
839-
840778 // Re-fetch workspaces if a workspace related file has changed
841779 if let Some ( abs_path) = vfs_path. as_path ( ) {
842780 if reload:: should_refresh_for_change ( & abs_path, ChangeKind :: Modify ) {
843781 this. fetch_workspaces_queue
844782 . request_op ( format ! ( "DidSaveTextDocument {}" , abs_path. display( ) ) ) ;
845783 }
846784 }
785+
786+ let file_id = this. vfs . read ( ) . 0 . file_id ( & vfs_path) ;
787+ if let Some ( file_id) = file_id {
788+ let world = this. snapshot ( ) ;
789+ let mut updated = false ;
790+ let task = move || -> std:: result:: Result < ( ) , ide:: Cancelled > {
791+ // Trigger flychecks for all workspaces that depend on the saved file
792+ // Crates containing or depending on the saved file
793+ let crate_ids: Vec < _ > = world
794+ . analysis
795+ . crates_for ( file_id) ?
796+ . into_iter ( )
797+ . flat_map ( |id| world. analysis . transitive_rev_deps ( id) )
798+ . flatten ( )
799+ . sorted ( )
800+ . unique ( )
801+ . collect ( ) ;
802+
803+ let crate_root_paths: Vec < _ > = crate_ids
804+ . iter ( )
805+ . filter_map ( |& crate_id| {
806+ world
807+ . analysis
808+ . crate_root ( crate_id)
809+ . map ( |file_id| {
810+ world
811+ . file_id_to_file_path ( file_id)
812+ . as_path ( )
813+ . map ( ToOwned :: to_owned)
814+ } )
815+ . transpose ( )
816+ } )
817+ . collect :: < ide:: Cancellable < _ > > ( ) ?;
818+ let crate_root_paths: Vec < _ > =
819+ crate_root_paths. iter ( ) . map ( Deref :: deref) . collect ( ) ;
820+
821+ // Find all workspaces that have at least one target containing the saved file
822+ let workspace_ids =
823+ world. workspaces . iter ( ) . enumerate ( ) . filter ( |( _, ws) | match ws {
824+ project_model:: ProjectWorkspace :: Cargo { cargo, .. } => {
825+ cargo. packages ( ) . any ( |pkg| {
826+ cargo[ pkg] . targets . iter ( ) . any ( |& it| {
827+ crate_root_paths. contains ( & cargo[ it] . root . as_path ( ) )
828+ } )
829+ } )
830+ }
831+ project_model:: ProjectWorkspace :: Json { project, .. } => {
832+ project. crates ( ) . any ( |( c, _) | {
833+ crate_ids. iter ( ) . any ( |& crate_id| crate_id == c)
834+ } )
835+ }
836+ project_model:: ProjectWorkspace :: DetachedFiles { .. } => false ,
837+ } ) ;
838+
839+ // Find and trigger corresponding flychecks
840+ for flycheck in world. flycheck . iter ( ) {
841+ for ( id, _) in workspace_ids. clone ( ) {
842+ if id == flycheck. id ( ) {
843+ updated = true ;
844+ flycheck. restart ( ) ;
845+ continue ;
846+ }
847+ }
848+ }
849+ // No specific flycheck was triggered, so let's trigger all of them.
850+ if !updated {
851+ for flycheck in world. flycheck . iter ( ) {
852+ flycheck. restart ( ) ;
853+ }
854+ }
855+ Ok ( ( ) )
856+ } ;
857+ this. task_pool . handle . spawn_with_sender ( move |_| {
858+ if let Err ( e) = std:: panic:: catch_unwind ( task) {
859+ tracing:: error!( "DidSaveTextDocument flycheck task panicked: {e:?}" )
860+ }
861+ } ) ;
862+ return Ok ( ( ) ) ;
863+ }
847864 }
848865
849866 // No specific flycheck was triggered, so let's trigger all of them.
850- if !updated {
851- for flycheck in & this. flycheck {
852- flycheck. restart ( ) ;
853- }
867+ for flycheck in this. flycheck . iter ( ) {
868+ flycheck. restart ( ) ;
854869 }
855870 Ok ( ( ) )
856871 } ) ?
0 commit comments