@@ -10,7 +10,6 @@ use lsp_types::{
10
10
DidOpenTextDocumentParams , DidSaveTextDocumentParams , WorkDoneProgressCancelParams ,
11
11
} ;
12
12
use paths:: Utf8PathBuf ;
13
- use stdx:: TupleExt ;
14
13
use triomphe:: Arc ;
15
14
use vfs:: { AbsPathBuf , ChangeKind , VfsPath } ;
16
15
@@ -75,7 +74,6 @@ pub(crate) fn handle_did_open_text_document(
75
74
tracing:: error!( "duplicate DidOpenTextDocument: {}" , path) ;
76
75
}
77
76
78
- tracing:: info!( "New file content set {:?}" , params. text_document. text) ;
79
77
state. vfs . write ( ) . 0 . set_file_contents ( path, Some ( params. text_document . text . into_bytes ( ) ) ) ;
80
78
if state. config . discover_workspace_config ( ) . is_some ( ) {
81
79
tracing:: debug!( "queuing task" ) ;
@@ -296,41 +294,62 @@ fn run_flycheck(state: &mut GlobalState, vfs_path: VfsPath) -> bool {
296
294
let may_flycheck_workspace = state. config . flycheck_workspace ( None ) ;
297
295
let mut updated = false ;
298
296
let task = move || -> std:: result:: Result < ( ) , ide:: Cancelled > {
299
- // Is the target binary? If so we let flycheck run only for the workspace that contains the crate.
300
297
let target = TargetSpec :: for_file ( & world, file_id) ?. and_then ( |it| {
301
298
let tgt_kind = it. target_kind ( ) ;
302
- let ( tgt_name, crate_id ) = match it {
303
- TargetSpec :: Cargo ( c) => ( c. target , c. crate_id ) ,
304
- TargetSpec :: ProjectJson ( p ) => ( p . label , p . crate_id ) ,
299
+ let ( tgt_name, root , package ) = match it {
300
+ TargetSpec :: Cargo ( c) => ( c. target , c. workspace_root , c . package ) ,
301
+ _ => return None ,
305
302
} ;
306
303
307
304
let tgt = match tgt_kind {
308
305
project_model:: TargetKind :: Bin => Target :: Bin ( tgt_name) ,
309
306
project_model:: TargetKind :: Example => Target :: Example ( tgt_name) ,
310
307
project_model:: TargetKind :: Test => Target :: Test ( tgt_name) ,
311
308
project_model:: TargetKind :: Bench => Target :: Benchmark ( tgt_name) ,
312
- _ => return None ,
309
+ _ => return Some ( ( None , root , package ) ) ,
313
310
} ;
314
311
315
- Some ( ( tgt, crate_id ) )
312
+ Some ( ( Some ( tgt) , root , package ) )
316
313
} ) ;
317
-
318
- let crate_ids = match target {
319
- // Trigger flychecks for the only crate which the target belongs to
320
- Some ( ( _, krate) ) => vec ! [ krate] ,
321
- None => {
322
- // Trigger flychecks for all workspaces that depend on the saved file
323
- // Crates containing or depending on the saved file
324
- world
325
- . analysis
326
- . crates_for ( file_id) ?
327
- . into_iter ( )
328
- . flat_map ( |id| world. analysis . transitive_rev_deps ( id) )
329
- . flatten ( )
330
- . unique ( )
331
- . collect :: < Vec < _ > > ( )
314
+ tracing:: debug!( ?target, "flycheck target" ) ;
315
+ // we have a specific non-library target, attempt to only check that target, nothing
316
+ // else will be affected
317
+ if let Some ( ( target, root, package) ) = target {
318
+ // trigger a package check if we have a non-library target as that can't affect
319
+ // anything else in the workspace OR if we're not allowed to check the workspace as
320
+ // the user opted into package checks then
321
+ let package_check_allowed = target. is_some ( ) || !may_flycheck_workspace;
322
+ if package_check_allowed {
323
+ let workspace =
324
+ world. workspaces . iter ( ) . enumerate ( ) . find ( |( _, ws) | match & ws. kind {
325
+ project_model:: ProjectWorkspaceKind :: Cargo { cargo, .. }
326
+ | project_model:: ProjectWorkspaceKind :: DetachedFile {
327
+ cargo : Some ( ( cargo, _, _) ) ,
328
+ ..
329
+ } => * cargo. workspace_root ( ) == root,
330
+ _ => false ,
331
+ } ) ;
332
+ if let Some ( ( idx, _) ) = workspace {
333
+ world. flycheck [ idx] . restart_for_package ( package, target) ;
334
+ }
332
335
}
333
- } ;
336
+ }
337
+
338
+ if !may_flycheck_workspace {
339
+ return Ok ( ( ) ) ;
340
+ }
341
+
342
+ // Trigger flychecks for all workspaces that depend on the saved file
343
+ // Crates containing or depending on the saved file
344
+ let crate_ids = world
345
+ . analysis
346
+ . crates_for ( file_id) ?
347
+ . into_iter ( )
348
+ . flat_map ( |id| world. analysis . transitive_rev_deps ( id) )
349
+ . flatten ( )
350
+ . unique ( )
351
+ . collect :: < Vec < _ > > ( ) ;
352
+ tracing:: debug!( ?crate_ids, "flycheck crate ids" ) ;
334
353
let crate_root_paths: Vec < _ > = crate_ids
335
354
. iter ( )
336
355
. filter_map ( |& crate_id| {
@@ -344,53 +363,41 @@ fn run_flycheck(state: &mut GlobalState, vfs_path: VfsPath) -> bool {
344
363
} )
345
364
. collect :: < ide:: Cancellable < _ > > ( ) ?;
346
365
let crate_root_paths: Vec < _ > = crate_root_paths. iter ( ) . map ( Deref :: deref) . collect ( ) ;
366
+ tracing:: debug!( ?crate_root_paths, "flycheck crate roots" ) ;
347
367
348
368
// Find all workspaces that have at least one target containing the saved file
349
- let workspace_ids = world . workspaces . iter ( ) . enumerate ( ) . filter_map ( | ( idx , ws ) | {
350
- let package = match & ws. kind {
369
+ let workspace_ids =
370
+ world . workspaces . iter ( ) . enumerate ( ) . filter ( | ( _ , ws ) | match & ws. kind {
351
371
project_model:: ProjectWorkspaceKind :: Cargo { cargo, .. }
352
372
| project_model:: ProjectWorkspaceKind :: DetachedFile {
353
373
cargo : Some ( ( cargo, _, _) ) ,
354
374
..
355
- } => cargo. packages ( ) . find_map ( |pkg| {
356
- let has_target_with_root = cargo[ pkg]
375
+ } => cargo. packages ( ) . any ( |pkg| {
376
+ cargo[ pkg]
357
377
. targets
358
378
. iter ( )
359
- . any ( |& it| crate_root_paths. contains ( & cargo[ it] . root . as_path ( ) ) ) ;
360
- has_target_with_root. then ( || cargo. package_flag ( & cargo[ pkg] ) )
379
+ . any ( |& it| crate_root_paths. contains ( & cargo[ it] . root . as_path ( ) ) )
361
380
} ) ,
362
- project_model:: ProjectWorkspaceKind :: Json ( project) => {
363
- if !project. crates ( ) . any ( |( _, krate) | {
364
- crate_root_paths. contains ( & krate. root_module . as_path ( ) )
365
- } ) {
366
- return None ;
367
- }
368
- None
369
- }
370
- project_model:: ProjectWorkspaceKind :: DetachedFile { .. } => return None ,
371
- } ;
372
- Some ( ( idx, package) )
373
- } ) ;
381
+ project_model:: ProjectWorkspaceKind :: Json ( project) => project
382
+ . crates ( )
383
+ . any ( |( _, krate) | crate_root_paths. contains ( & krate. root_module . as_path ( ) ) ) ,
384
+ project_model:: ProjectWorkspaceKind :: DetachedFile { .. } => false ,
385
+ } ) ;
374
386
375
387
let saved_file = vfs_path. as_path ( ) . map ( |p| p. to_owned ( ) ) ;
376
388
377
389
// Find and trigger corresponding flychecks
378
390
' flychecks: for flycheck in world. flycheck . iter ( ) {
379
- for ( id, package ) in workspace_ids. clone ( ) {
391
+ for ( id, _ ) in workspace_ids. clone ( ) {
380
392
if id == flycheck. id ( ) {
381
393
updated = true ;
382
- if may_flycheck_workspace {
383
- flycheck. restart_workspace ( saved_file. clone ( ) )
384
- } else if let Some ( package) = package {
385
- flycheck
386
- . restart_for_package ( package, target. clone ( ) . map ( TupleExt :: head) )
387
- }
394
+ flycheck. restart_workspace ( saved_file. clone ( ) ) ;
388
395
continue ' flychecks;
389
396
}
390
397
}
391
398
}
392
399
// No specific flycheck was triggered, so let's trigger all of them.
393
- if !updated && may_flycheck_workspace {
400
+ if !updated {
394
401
for flycheck in world. flycheck . iter ( ) {
395
402
flycheck. restart_workspace ( saved_file. clone ( ) ) ;
396
403
}
0 commit comments