Skip to content

Commit e5eadea

Browse files
committed
tried (failed) to add ItemAdded/ItemRemoved support for ReferencesEvents.
1 parent 424b943 commit e5eadea

File tree

4 files changed

+86
-28
lines changed

4 files changed

+86
-28
lines changed

RetailCoder.VBE/App.cs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,20 @@ public App(VBE vbe, IMessageBox messageBox,
9393
UiDispatcher.Initialize();
9494
}
9595

96+
private void ReferencesEvents_ItemAdded(Reference reference)
97+
{
98+
var state = _parser.State.Status;
99+
_parser.LoadComReference(reference);
100+
_parser.State.SetModuleState(state);
101+
}
102+
103+
private void ReferencesEvents_ItemRemoved(Reference reference)
104+
{
105+
var state = _parser.State.Status;
106+
_parser.UnloadComReference(reference);
107+
_parser.State.SetModuleState(state);
108+
}
109+
96110
private void _hooks_MessageReceived(object sender, HookEventArgs e)
97111
{
98112
var hookType = sender.GetType();
@@ -145,14 +159,15 @@ public void Startup()
145159
{
146160
_parser.State.OnParseRequested(this);
147161
});
148-
}, new StaTaskScheduler()).ConfigureAwait(false);
162+
}).ConfigureAwait(false);
149163

150164
_hooks.HookHotkeys();
151165
}
152166

153167
#region sink handlers. todo: move to another class
154168
async void sink_ProjectRemoved(object sender, DispatcherEventArgs<VBProject> e)
155169
{
170+
_vbe.Events.ReferencesEvents[e.Item].ItemAdded -= ReferencesEvents_ItemAdded;
156171
_parser.State.RemoveProject(e.Item);
157172

158173
Debug.WriteLine(string.Format("Project '{0}' was removed.", e.Item.Name));
@@ -168,6 +183,8 @@ async void sink_ProjectRemoved(object sender, DispatcherEventArgs<VBProject> e)
168183

169184
async void sink_ProjectAdded(object sender, DispatcherEventArgs<VBProject> e)
170185
{
186+
_vbe.Events.ReferencesEvents[e.Item].ItemAdded += ReferencesEvents_ItemAdded;
187+
_vbe.Events.ReferencesEvents[e.Item].ItemRemoved += ReferencesEvents_ItemRemoved;
171188
_parser.State.AddProject(e.Item);
172189

173190
if (!_parser.State.AllDeclarations.Any())

Rubberduck.Parsing/IRubberduckParser.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System;
12
using System.Threading;
23
using System.Threading.Tasks;
34
using Antlr4.Runtime;
@@ -9,6 +10,8 @@ namespace Rubberduck.Parsing
910
public interface IRubberduckParser
1011
{
1112
RubberduckParserState State { get; }
13+
void LoadComReference(Reference item);
14+
void UnloadComReference(Reference reference);
1215
void ParseComponent(VBComponent component, TokenStreamRewriter rewriter = null);
1316
Task ParseAsync(VBComponent component, CancellationToken token, TokenStreamRewriter rewriter = null);
1417
void Cancel(VBComponent component = null);

Rubberduck.Parsing/VBA/RubberduckParser.cs

Lines changed: 40 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -102,23 +102,9 @@ public void Parse()
102102
.ToList();
103103

104104
var components = projects.SelectMany(p => p.VBComponents.Cast<VBComponent>()).ToList();
105-
foreach (var component in components)
106-
{
107-
_state.SetModuleState(component, ParserState.LoadingReference);
108-
}
105+
_state.SetModuleState(ParserState.LoadingReference);
109106

110-
if (!_state.AllDeclarations.Any(item => item.IsBuiltIn))
111-
{
112-
var references = projects.SelectMany(p => p.References.Cast<Reference>()).ToList();
113-
foreach (var reference in references)
114-
{
115-
var items = _comReflector.GetDeclarationsForReference(reference);
116-
foreach (var declaration in items)
117-
{
118-
_state.AddDeclaration(declaration);
119-
}
120-
}
121-
}
107+
LoadComReferences(projects);
122108

123109
foreach (var component in components)
124110
{
@@ -152,7 +138,9 @@ private void ParseAll()
152138

153139
var components = projects.SelectMany(p => p.VBComponents.Cast<VBComponent>()).ToList();
154140
var modified = components.Where(_state.IsModified).ToList();
155-
LoadComReferences(components, projects);
141+
142+
_state.SetModuleState(ParserState.LoadingReference);
143+
LoadComReferences(projects);
156144

157145
foreach (var component in modified)
158146
{
@@ -173,26 +161,51 @@ private void ParseAll()
173161
}
174162
}
175163

176-
private void LoadComReferences(IEnumerable<VBComponent> components, IEnumerable<VBProject> projects)
164+
private readonly HashSet<Guid> _loadedReferences = new HashSet<Guid>();
165+
private void LoadComReferences(IEnumerable<VBProject> projects)
166+
{
167+
var references = projects.SelectMany(p => p.References.Cast<Reference>()).ToList();
168+
var newReferences = references
169+
.Select(reference => new {Guid = new Guid(reference.Guid), Reference = reference})
170+
.Where(item => !_loadedReferences.Contains(item.Guid));
171+
172+
foreach (var item in newReferences)
173+
{
174+
LoadComReference(item.Reference);
175+
}
176+
}
177+
178+
public void LoadComReference(Reference item)
177179
{
178-
if (_state.AllDeclarations.Any(item => item.IsBuiltIn))
180+
var guid = new Guid(item.Guid);
181+
if (_loadedReferences.Contains(guid))
179182
{
180183
return;
181184
}
182185

183-
foreach (var component in components)
186+
var items = _comReflector.GetDeclarationsForReference(item).ToList();
187+
foreach (var declaration in items)
184188
{
185-
_state.SetModuleState(component, ParserState.LoadingReference);
189+
_state.AddDeclaration(declaration);
186190
}
187191

192+
_loadedReferences.Add(new Guid(item.Guid));
193+
}
194+
195+
public void UnloadComReference(Reference reference)
196+
{
197+
var projects = _state.Projects
198+
.Where(project => project.Protection == vbext_ProjectProtection.vbext_pp_none)
199+
.ToList();
200+
188201
var references = projects.SelectMany(p => p.References.Cast<Reference>()).ToList();
189-
foreach (var reference in references)
202+
var target = references
203+
.Select(item => new { Guid = new Guid(item.Guid), Reference = item })
204+
.SingleOrDefault(item => _loadedReferences.Contains(item.Guid) && reference.Guid == item.Guid.ToString());
205+
206+
if (target != null)
190207
{
191-
var items = _comReflector.GetDeclarationsForReference(reference).ToList();
192-
foreach (var declaration in items)
193-
{
194-
_state.AddDeclaration(declaration);
195-
}
208+
_state.RemoveBuiltInDeclarations(target.Reference);
196209
}
197210
}
198211

Rubberduck.Parsing/VBA/RubberduckParserState.cs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,19 @@ private void OnModuleStateChanged(VBComponent component, ParserState state)
138138
}
139139
}
140140

141+
public void SetModuleState(ParserState state)
142+
{
143+
var projects = Projects
144+
.Where(project => project.Protection == vbext_ProjectProtection.vbext_pp_none)
145+
.ToList();
146+
147+
var components = projects.SelectMany(p => p.VBComponents.Cast<VBComponent>()).ToList();
148+
foreach (var component in components)
149+
{
150+
SetModuleState(component, state);
151+
}
152+
}
153+
141154
public void SetModuleState(VBComponent component, ParserState state, SyntaxErrorException parserError = null)
142155
{
143156
if (AllUserDeclarations.Any())
@@ -551,5 +564,17 @@ private static bool IsSelectedReference(QualifiedSelection selection, Identifier
551564
return reference.QualifiedModuleName.Equals(selection.QualifiedName)
552565
&& reference.Selection.ContainsFirstCharacter(selection.Selection);
553566
}
567+
568+
public void RemoveBuiltInDeclarations(Reference reference)
569+
{
570+
var projectName = reference.Name;
571+
var key = new QualifiedModuleName(projectName, projectName);
572+
573+
ConcurrentDictionary<Declaration, byte> items;
574+
if (!_declarations.TryRemove(key, out items))
575+
{
576+
Debug.WriteLine("Could not remove declarations for removed reference '{0}' ({1}).", reference.Name, reference.Guid);
577+
}
578+
}
554579
}
555580
}

0 commit comments

Comments
 (0)