Skip to content

Commit f843f49

Browse files
authored
Merge pull request #1986 from Hosch250/cacheBugs
Fix 101 bugs in various parts of the project.
2 parents c764b1e + 0f81ef7 commit f843f49

File tree

5 files changed

+39
-158
lines changed

5 files changed

+39
-158
lines changed

RetailCoder.VBE/API/ParserState.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ public void Initialize(VBE vbe)
6868

6969
Func<IVBAPreprocessor> preprocessorFactory = () => new VBAPreprocessor(double.Parse(vbe.Version, CultureInfo.InvariantCulture));
7070
_attributeParser = new AttributeParser(new ModuleExporter(), preprocessorFactory);
71-
_parser = new RubberduckParser(vbe, _state, _attributeParser, preprocessorFactory,
71+
_parser = new RubberduckParser(_state, _attributeParser, preprocessorFactory,
7272
new List<ICustomDeclarationLoader> { new DebugDeclarations(_state), new FormEventDeclarations(_state) });
7373
}
7474

RetailCoder.VBE/Navigation/CodeExplorer/CodeExplorerViewModel.cs

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
using System.Collections.Generic;
33
using System.Collections.ObjectModel;
44
using System.Linq;
5-
using System.Windows.Input;
65
using Microsoft.Vbe.Interop;
76
using NLog;
87
using Rubberduck.Navigation.Folders;
@@ -87,17 +86,6 @@ public CodeExplorerItemViewModel SelectedItem
8786
_selectedItem = value;
8887
OnPropertyChanged();
8988

90-
if (_selectedItem is CodeExplorerProjectViewModel)
91-
{
92-
var vbe = _selectedItem.GetSelectedDeclaration().Project.VBE;
93-
var project = vbe.VBProjects.Cast<VBProject>().FirstOrDefault(f => f.HelpFile == _selectedItem.GetSelectedDeclaration().Project.HelpFile);
94-
95-
if (project != null)
96-
{
97-
vbe.ActiveVBProject = project;
98-
}
99-
}
100-
10189
// ReSharper disable ExplicitCallerInfoArgument
10290
OnPropertyChanged("CanExecuteIndenterCommand");
10391
OnPropertyChanged("CanExecuteRenameCommand");

Rubberduck.Parsing/VBA/RubberduckParser.cs

Lines changed: 10 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
using Rubberduck.VBEditor;
1111
using Rubberduck.Parsing.Preprocessing;
1212
using System.Diagnostics;
13-
using Rubberduck.VBEditor.Extensions;
1413
using System.IO;
1514
using NLog;
1615
// ReSharper disable LoopCanBeConvertedToQuery
@@ -26,22 +25,19 @@ public class RubberduckParser : IRubberduckParser
2625

2726
private readonly IDictionary<VBComponent, IDictionary<Tuple<string, DeclarationType>, Attributes>> _componentAttributes
2827
= new Dictionary<VBComponent, IDictionary<Tuple<string, DeclarationType>, Attributes>>();
29-
30-
private readonly VBE _vbe;
28+
3129
private readonly RubberduckParserState _state;
3230
private readonly IAttributeParser _attributeParser;
3331
private readonly Func<IVBAPreprocessor> _preprocessorFactory;
3432
private readonly IEnumerable<ICustomDeclarationLoader> _customDeclarationLoaders;
3533
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
3634

3735
public RubberduckParser(
38-
VBE vbe,
3936
RubberduckParserState state,
4037
IAttributeParser attributeParser,
4138
Func<IVBAPreprocessor> preprocessorFactory,
4239
IEnumerable<ICustomDeclarationLoader> customDeclarationLoaders)
4340
{
44-
_vbe = vbe;
4541
_state = state;
4642
_attributeParser = attributeParser;
4743
_preprocessorFactory = preprocessorFactory;
@@ -106,13 +102,7 @@ private void ReparseRequested(object sender, ParseRequestEventArgs e)
106102
/// </summary>
107103
public void Parse(CancellationTokenSource token)
108104
{
109-
if (State.Projects.Count == 0)
110-
{
111-
foreach (var project in _vbe.VBProjects.UnprotectedProjects())
112-
{
113-
State.AddProject(project.HelpFile);
114-
}
115-
}
105+
State.RefreshProjects();
116106

117107
var components = new List<VBComponent>();
118108
foreach (var project in State.Projects)
@@ -188,13 +178,7 @@ public void Parse(CancellationTokenSource token)
188178
/// </summary>
189179
private void ParseAll(CancellationTokenSource token)
190180
{
191-
if (State.Projects.Count == 0)
192-
{
193-
foreach (var project in _vbe.VBProjects.UnprotectedProjects())
194-
{
195-
State.AddProject(project.HelpFile);
196-
}
197-
}
181+
State.RefreshProjects();
198182

199183
var components = new List<VBComponent>();
200184
foreach (var project in State.Projects)
@@ -232,7 +216,6 @@ private void ParseAll(CancellationTokenSource token)
232216
}
233217

234218
var toParse = new List<VBComponent>();
235-
236219
foreach (var component in components)
237220
{
238221
if (State.IsNewOrModified(component))
@@ -310,6 +293,13 @@ private void ParseAll(CancellationTokenSource token)
310293

311294
Task.WaitAll(parseTasks);
312295

296+
if (token.IsCancellationRequested)
297+
{
298+
return;
299+
}
300+
301+
Debug.Assert(State.ParseTrees.Count == components.Count);
302+
313303
if (State.Status < ParserState.Error)
314304
{
315305
State.SetStatusAndFireStateChanged(ParserState.ResolvedDeclarations);

Rubberduck.Parsing/VBA/RubberduckParserState.cs

Lines changed: 27 additions & 124 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ private void Sinks_ProjectAdded(object sender, IProjectEventArgs e)
9696

9797
Logger.Debug("Project '{0}' was added.", e.ProjectId);
9898

99-
AddProject(e.ProjectId); // note side-effect: assigns ProjectId/HelpFile
99+
RefreshProjects(); // note side-effect: assigns ProjectId/HelpFile
100100
OnParseRequested(sender);
101101
}
102102

@@ -122,7 +122,7 @@ private void Sinks_ProjectRenamed(object sender, IProjectRenamedEventArgs e)
122122
Logger.Debug("Project {0} was renamed.", e.ProjectId);
123123

124124
RemoveProject(e.ProjectId);
125-
AddProject(e.ProjectId);
125+
RefreshProjects();
126126

127127
OnParseRequested(sender);
128128
}
@@ -189,7 +189,7 @@ private void Sinks_ComponentRenamed(object sender, IComponentRenamedEventArgs e)
189189
RemoveProject(e.ProjectId);
190190
Logger.Debug("Project '{0}' was removed.", e.ComponentName);
191191

192-
AddProject(e.ProjectId);
192+
RefreshProjects();
193193
}
194194
else
195195
{
@@ -209,49 +209,23 @@ public void OnStatusMessageUpdate(string message)
209209
}
210210
}
211211

212-
public void AddProject(string projectId)
212+
/// <summary>
213+
/// Refreshes our list of cached projects.
214+
/// Be sure to reparse after calling this in case there
215+
/// were projects with duplicate ID's to clear the old
216+
/// declarations referencing the project by the old ID.
217+
/// </summary>
218+
public void RefreshProjects()
213219
{
214-
var projects = new List<VBProject>();
215-
foreach (VBProject p in _vbe.VBProjects)
220+
_projects.Clear();
221+
foreach (VBProject project in _vbe.VBProjects)
216222
{
217-
if (p.HelpFile != null && _projects.Keys.Contains(p.HelpFile))
223+
if (string.IsNullOrEmpty(project.HelpFile) || _projects.Keys.Contains(project.HelpFile))
218224
{
219-
continue;
225+
project.AssignProjectId();
220226
}
221227

222-
projects.Add(p);
223-
}
224-
225-
if (projects.Count == 0)
226-
{
227-
Logger.Debug("Project was not found and will not be added to parser state.");
228-
return;
229-
}
230-
231-
foreach (var project in projects)
232-
{
233-
if (project.Protection == vbext_ProjectProtection.vbext_pp_locked)
234-
{
235-
// adding protected project to parser state is asking for COMExceptions..
236-
Logger.Debug("Project is protected and will not be added to parser state.");
237-
return;
238-
}
239-
240-
if (string.IsNullOrEmpty(project.HelpFile))
241-
{
242-
// assigns the help file and returns the value to reduce COM calls
243-
projectId = project.AssignProjectId();
244-
}
245-
246-
if (!_projects.ContainsKey(projectId))
247-
{
248-
_projects.Add(projectId, project);
249-
}
250-
251-
foreach (VBComponent component in project.VBComponents)
252-
{
253-
_moduleStates.TryAdd(new QualifiedModuleName(component), new ModuleState(ParserState.Pending));
254-
}
228+
_projects.Add(project.HelpFile, project);
255229
}
256230
}
257231

@@ -723,70 +697,18 @@ public void ClearBuiltInReferences()
723697
{
724698
continue;
725699
}
726-
727-
var hasReference = false;
700+
728701
foreach (var reference in declaration.References)
729-
{
730-
hasReference = true;
731-
break;
732-
}
733-
734-
if (hasReference)
735702
{
736703
declaration.ClearReferences();
704+
break;
737705
}
738706
}
739707
}
740708

741709
public bool ClearStateCache(VBComponent component, bool notifyStateChanged = false)
742710
{
743-
if (component == null) { return false; }
744-
745-
var match = new QualifiedModuleName(component);
746-
747-
var keys = new List<QualifiedModuleName> { match };
748-
foreach (var key in _moduleStates.Keys)
749-
{
750-
if (key.Equals(match) && !keys.Contains(key))
751-
{
752-
keys.Add(key);
753-
}
754-
}
755-
756-
var success = RemoveKeysFromCollections(keys);
757-
758-
var projectId = component.Collection.Parent.HelpFile;
759-
var sameProjectDeclarations = new List<KeyValuePair<QualifiedModuleName, ModuleState>>();
760-
foreach (var item in _moduleStates)
761-
{
762-
if (item.Key.ProjectId == projectId)
763-
{
764-
sameProjectDeclarations.Add(new KeyValuePair<QualifiedModuleName, ModuleState>(item.Key, item.Value));
765-
}
766-
}
767-
768-
var projectCount = 0;
769-
foreach (var item in sameProjectDeclarations)
770-
{
771-
if (item.Value.Declarations == null) { continue; }
772-
773-
foreach (var declaration in item.Value.Declarations)
774-
{
775-
if (declaration.Key.DeclarationType == DeclarationType.Project)
776-
{
777-
projectCount++;
778-
break;
779-
}
780-
}
781-
}
782-
783-
if (notifyStateChanged)
784-
{
785-
OnStateChanged(ParserState.ResolvedDeclarations); // trigger test explorer and code explorer updates
786-
OnStateChanged(ParserState.Ready); // trigger find all references &c. updates
787-
}
788-
789-
return success;
711+
return component != null && ClearStateCache(new QualifiedModuleName(component), notifyStateChanged);
790712
}
791713

792714
public bool ClearStateCache(QualifiedModuleName component, bool notifyStateChanged = false)
@@ -802,31 +724,6 @@ public bool ClearStateCache(QualifiedModuleName component, bool notifyStateChang
802724

803725
var success = RemoveKeysFromCollections(keys);
804726

805-
var projectId = component.ProjectId;
806-
var sameProjectDeclarations = new List<KeyValuePair<QualifiedModuleName, ModuleState>>();
807-
foreach (var item in _moduleStates)
808-
{
809-
if (item.Key.ProjectId == projectId)
810-
{
811-
sameProjectDeclarations.Add(new KeyValuePair<QualifiedModuleName, ModuleState>(item.Key, item.Value));
812-
}
813-
}
814-
815-
var projectCount = 0;
816-
foreach (var item in sameProjectDeclarations)
817-
{
818-
if (item.Value.Declarations == null) { continue; }
819-
820-
foreach (var declaration in item.Value.Declarations)
821-
{
822-
if (declaration.Key.DeclarationType == DeclarationType.Project)
823-
{
824-
projectCount++;
825-
break;
826-
}
827-
}
828-
}
829-
830727
if (notifyStateChanged)
831728
{
832729
OnStateChanged(ParserState.ResolvedDeclarations); // trigger test explorer and code explorer updates
@@ -914,13 +811,19 @@ public bool IsDirty()
914811
{
915812
foreach (var project in Projects)
916813
{
917-
foreach (VBComponent component in project.VBComponents)
814+
try
918815
{
919-
if (IsNewOrModified(component))
816+
foreach (VBComponent component in project.VBComponents)
920817
{
921-
return true;
818+
if (IsNewOrModified(component))
819+
{
820+
return true;
821+
}
922822
}
923823
}
824+
catch (COMException)
825+
{
826+
}
924827
}
925828

926829
return false;

RubberduckTests/MockParser.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public static RubberduckParser Create(VBE vbe, RubberduckParserState state)
4141

4242
public static RubberduckParser Create(VBE vbe, RubberduckParserState state, IAttributeParser attributeParser)
4343
{
44-
return new RubberduckParser(vbe, state, attributeParser,
44+
return new RubberduckParser(state, attributeParser,
4545
() => new VBAPreprocessor(double.Parse(vbe.Version, CultureInfo.InvariantCulture)),
4646
new List<ICustomDeclarationLoader> {new DebugDeclarations(state), new FormEventDeclarations(state)});
4747
}

0 commit comments

Comments
 (0)