Skip to content

Commit a177cc5

Browse files
authored
Merge pull request #4466 from bclothier/FixReferences
Fix references count
2 parents ca8beff + 991e650 commit a177cc5

File tree

1 file changed

+31
-19
lines changed

1 file changed

+31
-19
lines changed

Rubberduck.Parsing/Symbols/Declaration.cs

Lines changed: 31 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -292,8 +292,8 @@ public static Declaration GetProjectParent(Declaration declaration)
292292
public ParserRuleContext Context { get; }
293293
public ParserRuleContext AttributesPassContext { get; }
294294

295-
private ConcurrentBag<IdentifierReference> _references = new ConcurrentBag<IdentifierReference>();
296-
public IEnumerable<IdentifierReference> References => _references;
295+
private ConcurrentDictionary<IdentifierReference, int> _references = new ConcurrentDictionary<IdentifierReference, int>();
296+
public IEnumerable<IdentifierReference> References => _references.Keys;
297297

298298
protected IEnumerable<IAnnotation> _annotations;
299299
public IEnumerable<IAnnotation> Annotations => _annotations ?? new List<IAnnotation>();
@@ -371,19 +371,32 @@ public void AddReference(
371371
bool isSetAssigned = false
372372
)
373373
{
374-
_references.Add(
375-
new IdentifierReference(
376-
module,
377-
scope,
378-
parent,
379-
identifier,
380-
selection,
381-
callSiteContext,
382-
callee,
383-
isAssignmentTarget,
384-
hasExplicitLetStatement,
385-
annotations,
386-
isSetAssigned));
374+
var oldReference = _references.FirstOrDefault(r =>
375+
r.Key.QualifiedModuleName == module &&
376+
// ReSharper disable once PossibleUnintendedReferenceComparison
377+
r.Key.ParentScoping == scope &&
378+
// ReSharper disable once PossibleUnintendedReferenceComparison
379+
r.Key.ParentNonScoping == parent &&
380+
r.Key.IdentifierName == identifier &&
381+
r.Key.Selection == selection);
382+
if (oldReference.Key != null)
383+
{
384+
_references.TryRemove(oldReference.Key, out _);
385+
}
386+
387+
var newReference = new IdentifierReference(
388+
module,
389+
scope,
390+
parent,
391+
identifier,
392+
selection,
393+
callSiteContext,
394+
callee,
395+
isAssignmentTarget,
396+
hasExplicitLetStatement,
397+
annotations,
398+
isSetAssigned);
399+
_references.AddOrUpdate(newReference, 1, (key, value) => 1);
387400
}
388401

389402
/// <summary>
@@ -601,14 +614,13 @@ public override int GetHashCode()
601614

602615
public void ClearReferences()
603616
{
604-
_references = new ConcurrentBag<IdentifierReference>();
617+
_references = new ConcurrentDictionary<IdentifierReference, int>();
605618
}
606619

607620
public void RemoveReferencesFrom(IReadOnlyCollection<QualifiedModuleName> modulesByWhichToRemoveReferences)
608621
{
609-
//This gets replaced with a new ConcurrentBag because one cannot remove specific items from a ConcurrentBag.
610-
//Moreover, changing to a ConcurrentDictionary<IdentifierReference,byte> breaks all sorts of tests, for some obscure reason.
611-
_references = new ConcurrentBag<IdentifierReference>(_references.Where(reference => !modulesByWhichToRemoveReferences.Contains(reference.QualifiedModuleName)));
622+
_references = new ConcurrentDictionary<IdentifierReference, int>(_references.Where(reference => !modulesByWhichToRemoveReferences.Contains(reference.Key.QualifiedModuleName)));
612623
}
613624
}
614625
}
626+

0 commit comments

Comments
 (0)