@@ -25,12 +25,14 @@ namespace Rubberduck.Parsing.VBA
25
25
{
26
26
public class ParserStateEventArgs : EventArgs
27
27
{
28
- public ParserStateEventArgs ( ParserState state )
28
+ public ParserStateEventArgs ( ParserState state , CancellationToken token )
29
29
{
30
30
State = state ;
31
+ Token = token ;
31
32
}
32
33
33
34
public ParserState State { get ; }
35
+ public CancellationToken Token { get ; }
34
36
}
35
37
36
38
public class RubberduckStatusMessageEventArgs : EventArgs
@@ -256,11 +258,11 @@ public void RefreshProjects()
256
258
_projectRepository . Refresh ( ) ;
257
259
}
258
260
259
- private void RefreshProject ( string projectId , bool notifyStateChanged = false )
261
+ private void RefreshProject ( string projectId )
260
262
{
261
263
_projectRepository . Refresh ( projectId ) ;
262
264
263
- ClearStateCache ( projectId , notifyStateChanged ) ;
265
+ ClearStateCache ( projectId ) ;
264
266
}
265
267
266
268
public List < IVBProject > Projects => _projectRepository . Projects ( ) . Select ( tpl => tpl . Project ) . ToList ( ) ;
@@ -289,37 +291,44 @@ public IReadOnlyList<Tuple<QualifiedModuleName, SyntaxErrorException>> ModuleExc
289
291
public event EventHandler < ParserStateEventArgs > StateChanged ;
290
292
291
293
private int _stateChangedInvocations ;
292
- private void OnStateChanged ( object requestor , ParserState state = ParserState . Pending )
294
+ private void OnStateChanged ( object requestor , CancellationToken token , ParserState state = ParserState . Pending )
293
295
{
294
296
Interlocked . Increment ( ref _stateChangedInvocations ) ;
295
297
296
298
Logger . Info ( $ "{ nameof ( RubberduckParserState ) } ({ _stateChangedInvocations } ) is invoking { nameof ( StateChanged ) } ({ Status } )") ;
297
- StateChanged ? . Invoke ( requestor , new ParserStateEventArgs ( state ) ) ;
299
+ var handler = StateChanged ;
300
+ if ( handler != null && ! token . IsCancellationRequested )
301
+ {
302
+ var args = new ParserStateEventArgs ( state , token ) ;
303
+ handler . Invoke ( requestor , args ) ;
304
+ }
298
305
}
299
306
300
307
public event EventHandler < ParseProgressEventArgs > ModuleStateChanged ;
301
308
302
309
//Never spawn new threads changing module states in the handler! This will cause deadlocks.
303
- private void OnModuleStateChanged ( QualifiedModuleName module , ParserState state , ParserState oldState )
310
+ private void OnModuleStateChanged ( QualifiedModuleName module , ParserState state , ParserState oldState , CancellationToken token )
304
311
{
305
312
var handler = ModuleStateChanged ;
306
- if ( handler != null )
313
+ if ( handler != null && ! token . IsCancellationRequested )
307
314
{
308
- var args = new ParseProgressEventArgs ( module , state , oldState ) ;
315
+ var args = new ParseProgressEventArgs ( module , state , oldState , token ) ;
309
316
handler . Invoke ( this , args ) ;
310
317
}
311
318
}
312
319
320
+ public void SetModuleState ( QualifiedModuleName module , ParserState state , SyntaxErrorException parserError = null , bool evaluateOverallState = true )
321
+ {
322
+ SetModuleState ( module , state , CancellationToken . None , parserError , evaluateOverallState ) ;
323
+ }
324
+
313
325
public void SetModuleState ( QualifiedModuleName module , ParserState state , CancellationToken token , SyntaxErrorException parserError = null , bool evaluateOverallState = true )
314
326
{
315
- if ( ! token . IsCancellationRequested )
327
+ if ( token . IsCancellationRequested )
316
328
{
317
- SetModuleState ( module , state , parserError , evaluateOverallState ) ;
329
+ return ;
318
330
}
319
- }
320
331
321
- public void SetModuleState ( QualifiedModuleName module , ParserState state , SyntaxErrorException parserError = null , bool evaluateOverallState = true )
322
- {
323
332
if ( AllUserDeclarations . Any ( ) )
324
333
{
325
334
var projectId = module . ProjectId ;
@@ -339,21 +348,30 @@ public void SetModuleState(QualifiedModuleName module, ParserState state, Syntax
339
348
_moduleStates . AddOrUpdate ( module , new ModuleState ( state ) , ( c , e ) => e . SetState ( state ) ) ;
340
349
_moduleStates . AddOrUpdate ( module , new ModuleState ( parserError ) , ( c , e ) => e . SetModuleException ( parserError ) ) ;
341
350
Logger . Debug ( "Module '{0}' state is changing to '{1}' (thread {2})" , module . ComponentName , state , Thread . CurrentThread . ManagedThreadId ) ;
342
- OnModuleStateChanged ( module , state , oldState ) ;
351
+ OnModuleStateChanged ( module , state , oldState , token ) ;
343
352
if ( evaluateOverallState )
344
353
{
345
- EvaluateParserState ( ) ;
354
+ EvaluateParserState ( token ) ;
346
355
}
347
356
}
348
357
349
358
private IVBProject GetProject ( string projectId )
350
359
{
351
360
return _projectRepository . Project ( projectId ) ;
352
- }
361
+ }
353
362
354
363
public void EvaluateParserState ( )
355
364
{
356
- lock ( _statusLockObject ) Status = OverallParserStateFromModuleStates ( ) ;
365
+ EvaluateParserState ( CancellationToken . None ) ;
366
+ }
367
+
368
+ public void EvaluateParserState ( CancellationToken token )
369
+ {
370
+ lock ( _statusLockObject )
371
+ {
372
+ var newState = OverallParserStateFromModuleStates ( ) ;
373
+ SetStatusWithCancellation ( newState , token ) ;
374
+ }
357
375
}
358
376
359
377
private ParserState OverallParserStateFromModuleStates ( )
@@ -489,26 +507,33 @@ public ParserState GetModuleState(QualifiedModuleName module)
489
507
private ParserState _status ;
490
508
public ParserState Status
491
509
{
492
- get { return _status ; }
493
- private set
510
+ get => _status ;
511
+ private set => SetStatusWithCancellation ( value , CancellationToken . None ) ;
512
+ }
513
+
514
+ private void SetStatusWithCancellation ( ParserState value , CancellationToken token )
515
+ {
516
+ if ( _status != value )
494
517
{
495
- if ( _status != value )
496
- {
497
- _status = value ;
498
- OnStateChanged ( this , _status ) ;
499
- }
518
+ _status = value ;
519
+ OnStateChanged ( this , token , _status ) ;
500
520
}
501
521
}
502
522
503
523
public void SetStatusAndFireStateChanged ( object requestor , ParserState status )
524
+ {
525
+ SetStatusAndFireStateChanged ( requestor , status , CancellationToken . None ) ;
526
+ }
527
+
528
+ public void SetStatusAndFireStateChanged ( object requestor , ParserState status , CancellationToken token )
504
529
{
505
530
if ( Status == status )
506
531
{
507
- OnStateChanged ( requestor , status ) ;
532
+ OnStateChanged ( requestor , token , status ) ;
508
533
}
509
534
else
510
535
{
511
- Status = status ;
536
+ SetStatusWithCancellation ( status , token ) ;
512
537
}
513
538
}
514
539
@@ -654,8 +679,7 @@ public void AddUnresolvedMemberDeclaration(UnboundMemberDeclaration declaration)
654
679
655
680
if ( declarations . ContainsKey ( declaration ) )
656
681
{
657
- byte _ ;
658
- while ( ! declarations . TryRemove ( declaration , out _ ) )
682
+ while ( ! declarations . TryRemove ( declaration , out var _ ) )
659
683
{
660
684
Logger . Warn ( "Could not remove existing unresolved member declaration for '{0}' ({1}). Retrying." , declaration . IdentifierName , declaration . DeclarationType ) ;
661
685
}
@@ -666,7 +690,7 @@ public void AddUnresolvedMemberDeclaration(UnboundMemberDeclaration declaration)
666
690
}
667
691
}
668
692
669
- public void ClearStateCache ( string projectId , bool notifyStateChanged = false )
693
+ public void ClearStateCache ( string projectId )
670
694
{
671
695
try
672
696
{
@@ -696,16 +720,10 @@ public void ClearStateCache(string projectId, bool notifyStateChanged = false)
696
720
Logger . Error ( exception , $ "Unexpected COMException while clearing the project with projectId { projectId } . Clearing all modules.") ;
697
721
_moduleStates . Clear ( ) ;
698
722
}
699
-
700
- if ( notifyStateChanged )
701
- {
702
- OnStateChanged ( this , ParserState . ResolvedDeclarations ) ; // trigger test explorer and code explorer updates
703
- OnStateChanged ( this , ParserState . Ready ) ; // trigger find all references &c. updates
704
- }
705
723
}
706
724
707
725
708
- public bool ClearStateCache ( QualifiedModuleName module , bool notifyStateChanged = false )
726
+ public bool ClearStateCache ( QualifiedModuleName module )
709
727
{
710
728
var keys = new List < QualifiedModuleName > { module } ;
711
729
foreach ( var key in _moduleStates . Keys )
@@ -718,12 +736,6 @@ public bool ClearStateCache(QualifiedModuleName module, bool notifyStateChanged
718
736
719
737
var success = RemoveKeysFromCollections ( keys ) ;
720
738
721
- if ( notifyStateChanged )
722
- {
723
- OnStateChanged ( this , ParserState . ResolvedDeclarations ) ; // trigger test explorer and code explorer updates
724
- OnStateChanged ( this , ParserState . Ready ) ; // trigger find all references &c. updates
725
- }
726
-
727
739
return success ;
728
740
}
729
741
0 commit comments