@@ -31,6 +31,7 @@ public class ParseCoordinator : IParseCoordinator
31
31
private const int _maxDegreeOfDeclarationResolverParallelism = - 1 ;
32
32
private const int _maxDegreeOfReferenceResolverParallelism = - 1 ;
33
33
private const int _maxDegreeOfModuleStateChangeParallelism = - 1 ;
34
+ private const int _maxDegreeOfReferenceRemovalParallelism = - 1 ;
34
35
private const int _maxReferenceLoadingConcurrency = - 1 ;
35
36
36
37
private readonly IDictionary < IVBComponent , IDictionary < Tuple < string , DeclarationType > , Attributes > > _componentAttributes
@@ -185,7 +186,7 @@ private void ClearComponentStateCacheForTests()
185
186
}
186
187
}
187
188
188
- private void CleanUpComponentAttributes ( List < IVBComponent > components )
189
+ private void CleanUpComponentAttributes ( ICollection < IVBComponent > components )
189
190
{
190
191
foreach ( var key in _componentAttributes . Keys )
191
192
{
@@ -214,8 +215,9 @@ private void ExecuteCommonParseActivities(List<IVBComponent> toParse, Cancellati
214
215
215
216
token . ThrowIfCancellationRequested ( ) ;
216
217
217
- var toResolveReferences = ModulesForWhichToResolveReferences ( toParse ) ;
218
- PerformPreParseCleanup ( toParse , toResolveReferences ) ;
218
+ var modulesToParse = toParse . Select ( component => new QualifiedModuleName ( component ) ) . ToHashSet ( ) ;
219
+ var toResolveReferences = ModulesForWhichToResolveReferences ( modulesToParse ) ;
220
+ PerformPreParseCleanup ( modulesToParse , toResolveReferences , token ) ;
219
221
220
222
ParseComponents ( toParse , token ) ;
221
223
@@ -268,28 +270,48 @@ private void SetModuleStates(List<IVBComponent> components, ParserState parserSt
268
270
}
269
271
}
270
272
271
- private ICollection < QualifiedModuleName > ModulesForWhichToResolveReferences ( List < IVBComponent > toParse )
273
+ private ICollection < QualifiedModuleName > ModulesForWhichToResolveReferences ( ICollection < QualifiedModuleName > modulesToParse )
272
274
{
273
- var toResolveReferences = toParse . Select ( component => new QualifiedModuleName ( component ) ) . ToHashSet ( ) ;
274
- foreach ( var qmn in toParse . Select ( component => new QualifiedModuleName ( component ) ) )
275
+ var toResolveReferences = modulesToParse . ToHashSet ( ) ;
276
+ foreach ( var qmn in modulesToParse )
275
277
{
276
278
toResolveReferences . UnionWith ( State . ModulesReferencing ( qmn ) ) ;
277
279
}
278
280
return toResolveReferences ;
279
281
}
280
282
281
- private void PerformPreParseCleanup ( List < IVBComponent > toParse , ICollection < QualifiedModuleName > toResolveReferences )
283
+ private void PerformPreParseCleanup ( ICollection < QualifiedModuleName > modulesToParse , ICollection < QualifiedModuleName > toResolveReferences , CancellationToken token )
282
284
{
283
- ClearModuleToModuleReferences ( toParse ) ;
284
- State . RemoveAllReferencesBy ( toResolveReferences ) ;
285
+ ClearModuleToModuleReferences ( modulesToParse ) ;
286
+ RemoveAllReferencesBy ( toResolveReferences , modulesToParse , State . DeclarationFinder , token ) ; //All declarations on the modulesToParse get destroyed anyway.
285
287
_projectDeclarations . Clear ( ) ;
286
288
}
287
289
288
- private void ClearModuleToModuleReferences ( List < IVBComponent > toClear )
290
+ private void ClearModuleToModuleReferences ( ICollection < QualifiedModuleName > toClear )
289
291
{
290
- foreach ( var component in toClear )
292
+ foreach ( var qmn in toClear )
291
293
{
292
- State . ClearModuleToModuleReferencesFromModule ( new QualifiedModuleName ( component ) ) ;
294
+ State . ClearModuleToModuleReferencesFromModule ( qmn ) ;
295
+ }
296
+ }
297
+
298
+ //This doesn not live on the RubberduckParserState to keep concurrency haanlding out of it.
299
+ public void RemoveAllReferencesBy ( ICollection < QualifiedModuleName > referencesFromToRemove , ICollection < QualifiedModuleName > modulesNotNeedingReferenceRemoval , DeclarationFinder finder , CancellationToken token )
300
+ {
301
+ var referencedModulesNeedingReferenceRemoval = State . ModulesReferencedBy ( referencesFromToRemove ) . Where ( qmn => ! modulesNotNeedingReferenceRemoval . Contains ( qmn ) ) ;
302
+
303
+ var options = new ParallelOptions ( ) ;
304
+ options . CancellationToken = token ;
305
+ options . MaxDegreeOfParallelism = _maxDegreeOfReferenceRemovalParallelism ;
306
+
307
+ Parallel . ForEach ( referencedModulesNeedingReferenceRemoval , options , qmn => RemoveReferences ( finder . Members ( qmn ) , referencesFromToRemove ) ) ;
308
+ }
309
+
310
+ private void RemoveReferences ( IEnumerable < Declaration > declarations , ICollection < QualifiedModuleName > referencesFromToRemove )
311
+ {
312
+ foreach ( var declaration in declarations )
313
+ {
314
+ declaration . RemoveReferencesFrom ( referencesFromToRemove ) ;
293
315
}
294
316
}
295
317
@@ -688,7 +710,7 @@ private void ParseAllInternal(object requestor, CancellationToken token)
688
710
689
711
token . ThrowIfCancellationRequested ( ) ;
690
712
691
- var componentsRemoved = CleanUpRemovedComponents ( components ) ;
713
+ var componentsRemoved = CleanUpRemovedComponents ( components , token ) ;
692
714
693
715
token . ThrowIfCancellationRequested ( ) ;
694
716
@@ -721,21 +743,24 @@ private void ParseAllInternal(object requestor, CancellationToken token)
721
743
/// Clears state cache of removed components.
722
744
/// Returns whether components have been removed.
723
745
/// </summary>
724
- private bool CleanUpRemovedComponents ( List < IVBComponent > components )
746
+ private bool CleanUpRemovedComponents ( ICollection < IVBComponent > components , CancellationToken token )
725
747
{
726
748
var removedModuledecalrations = RemovedModuleDeclarations ( components ) ;
727
749
var componentRemoved = removedModuledecalrations . Any ( ) ;
728
750
var removedModules = removedModuledecalrations . Select ( declaration => declaration . QualifiedName . QualifiedModuleName ) . ToHashSet ( ) ;
729
- State . RemoveAllReferencesBy ( removedModules ) ;
730
- foreach ( var qmn in removedModules )
751
+ if ( removedModules . Any ( ) )
731
752
{
732
- State . ClearModuleToModuleReferencesFromModule ( qmn ) ;
733
- State . ClearStateCache ( qmn ) ;
753
+ RemoveAllReferencesBy ( removedModules , removedModules , State . DeclarationFinder , token ) ;
754
+ foreach ( var qmn in removedModules )
755
+ {
756
+ State . ClearModuleToModuleReferencesFromModule ( qmn ) ;
757
+ State . ClearStateCache ( qmn ) ;
758
+ }
734
759
}
735
760
return componentRemoved ;
736
761
}
737
762
738
- private IEnumerable < Declaration > RemovedModuleDeclarations ( List < IVBComponent > components )
763
+ private IEnumerable < Declaration > RemovedModuleDeclarations ( ICollection < IVBComponent > components )
739
764
{
740
765
var moduleDeclarations = State . AllUserDeclarations . Where ( declaration => declaration . DeclarationType . HasFlag ( DeclarationType . Module ) ) ;
741
766
var componentKeys = components . Select ( component => new { name = component . Name , projectId = component . Collection . Parent . HelpFile } ) . ToHashSet ( ) ;
0 commit comments