Skip to content

Commit 211b965

Browse files
committed
Make parser update invalid cache values caused by components being removed while the code is running
1 parent a6eb196 commit 211b965

File tree

2 files changed

+79
-1
lines changed

2 files changed

+79
-1
lines changed

Rubberduck.Parsing/VBA/RubberduckParser.cs

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ public void Parse()
124124
// tests do not fire events when components are removed--clear components
125125
foreach (var tree in State.ParseTrees)
126126
{
127-
State.ClearStateCache(tree.Key.Component);
127+
State.ClearStateCache(tree.Key); // handle potentially removed components without crashing
128128
}
129129

130130
SyncComReferences(State.Projects);
@@ -205,6 +205,32 @@ private void ParseAll()
205205
}
206206
}
207207

208+
var componentsRemoved = false;
209+
foreach (var declaration in State.AllUserDeclarations)
210+
{
211+
if (!declaration.DeclarationType.HasFlag(DeclarationType.Module))
212+
{
213+
continue;
214+
}
215+
216+
var componentExists = false;
217+
foreach (var component in components)
218+
{
219+
if (component.Name == declaration.ComponentName &&
220+
component.Collection.Parent.HelpFile == declaration.ProjectId)
221+
{
222+
componentExists = true;
223+
break;
224+
}
225+
}
226+
227+
if (!componentExists)
228+
{
229+
componentsRemoved = true;
230+
State.ClearStateCache(declaration.QualifiedName.QualifiedModuleName);
231+
}
232+
}
233+
208234
var toParse = new List<VBComponent>();
209235
var unchanged = new List<VBComponent>();
210236

@@ -225,6 +251,11 @@ private void ParseAll()
225251

226252
if (toParse.Count == 0)
227253
{
254+
if (componentsRemoved) // trigger UI updates
255+
{
256+
State.SetStatusAndFireStateChanged(ParserState.ResolvedDeclarations);
257+
}
258+
228259
State.SetStatusAndFireStateChanged(State.Status);
229260
return;
230261
}

Rubberduck.Parsing/VBA/RubberduckParserState.cs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -677,6 +677,53 @@ public bool ClearStateCache(VBComponent component, bool notifyStateChanged = fal
677677
return success;
678678
}
679679

680+
public bool ClearStateCache(QualifiedModuleName component, bool notifyStateChanged = false)
681+
{
682+
var keys = new List<QualifiedModuleName> { component };
683+
foreach (var key in _moduleStates.Keys)
684+
{
685+
if (key.Equals(component) && !keys.Contains(key))
686+
{
687+
keys.Add(key);
688+
}
689+
}
690+
691+
var success = RemoveKeysFromCollections(keys);
692+
693+
var projectId = component.ProjectId;
694+
var sameProjectDeclarations = new List<KeyValuePair<QualifiedModuleName, ModuleState>>();
695+
foreach (var item in _moduleStates)
696+
{
697+
if (item.Key.ProjectId == projectId)
698+
{
699+
sameProjectDeclarations.Add(new KeyValuePair<QualifiedModuleName, ModuleState>(item.Key, item.Value));
700+
}
701+
}
702+
703+
var projectCount = 0;
704+
foreach (var item in sameProjectDeclarations)
705+
{
706+
if (item.Value.Declarations == null) { continue; }
707+
708+
foreach (var declaration in item.Value.Declarations)
709+
{
710+
if (declaration.Key.DeclarationType == DeclarationType.Project)
711+
{
712+
projectCount++;
713+
break;
714+
}
715+
}
716+
}
717+
718+
if (notifyStateChanged)
719+
{
720+
OnStateChanged(ParserState.ResolvedDeclarations); // trigger test explorer and code explorer updates
721+
OnStateChanged(ParserState.Ready); // trigger find all references &c. updates
722+
}
723+
724+
return success;
725+
}
726+
680727
public bool RemoveRenamedComponent(VBComponent component, string oldComponentName)
681728
{
682729
var match = new QualifiedModuleName(component, oldComponentName);

0 commit comments

Comments
 (0)