Skip to content

Commit 7873285

Browse files
committed
Merge pull request #1366 from retailcoder/next
Addresses major issues of 2.0 alpha-pre
2 parents 4a402f8 + a9d57e0 commit 7873285

File tree

10 files changed

+281
-114
lines changed

10 files changed

+281
-114
lines changed

RetailCoder.VBE/App.cs

Lines changed: 51 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
using Rubberduck.UI.Command.MenuItems;
1818
using Infralution.Localization.Wpf;
1919
using Rubberduck.Common.Dispatch;
20+
using Rubberduck.VBEditor.Extensions;
2021

2122
namespace Rubberduck
2223
{
@@ -39,10 +40,10 @@ public class App : IDisposable
3940
private readonly IConnectionPoint _projectsEventsConnectionPoint;
4041
private readonly int _projectsEventsCookie;
4142

42-
private readonly IDictionary<VBProjectsEventsSink, Tuple<IConnectionPoint, int>> _componentsEventsConnectionPoints =
43-
new Dictionary<VBProjectsEventsSink, Tuple<IConnectionPoint, int>>();
44-
private readonly IDictionary<VBProjectsEventsSink, Tuple<IConnectionPoint, int>> _referencesEventsConnectionPoints =
45-
new Dictionary<VBProjectsEventsSink, Tuple<IConnectionPoint, int>>();
43+
private readonly IDictionary<string, Tuple<IConnectionPoint, int>> _componentsEventsConnectionPoints =
44+
new Dictionary<string, Tuple<IConnectionPoint, int>>();
45+
private readonly IDictionary<string, Tuple<IConnectionPoint, int>> _referencesEventsConnectionPoints =
46+
new Dictionary<string, Tuple<IConnectionPoint, int>>();
4647

4748
public App(VBE vbe, IMessageBox messageBox,
4849
IRubberduckParser parser,
@@ -127,11 +128,6 @@ public void Startup()
127128
{
128129
CleanReloadConfig();
129130

130-
foreach (var project in _vbe.VBProjects.Cast<VBProject>())
131-
{
132-
_parser.State.AddProject(project);
133-
}
134-
135131
_appMenus.Initialize();
136132
_appMenus.Localize();
137133

@@ -150,40 +146,51 @@ public void Startup()
150146
#region sink handlers. todo: move to another class
151147
async void sink_ProjectRemoved(object sender, DispatcherEventArgs<VBProject> e)
152148
{
153-
var sink = (VBProjectsEventsSink)sender;
154-
_componentsEventSinks.Remove(sink);
155-
_referencesEventsSinks.Remove(sink);
149+
if (e.Item.Protection == vbext_ProjectProtection.vbext_pp_locked)
150+
{
151+
Debug.WriteLine(string.Format("Locked project '{0}' was removed.", e.Item.Name));
152+
return;
153+
}
154+
155+
var projectId = e.Item.HelpFile;
156+
_componentsEventsSinks.Remove(projectId);
157+
_referencesEventsSinks.Remove(projectId);
156158
_parser.State.RemoveProject(e.Item);
157159

158160
Debug.WriteLine(string.Format("Project '{0}' was removed.", e.Item.Name));
159161
Tuple<IConnectionPoint, int> componentsTuple;
160-
if (_componentsEventsConnectionPoints.TryGetValue(sink, out componentsTuple))
162+
if (_componentsEventsConnectionPoints.TryGetValue(projectId, out componentsTuple))
161163
{
162164
componentsTuple.Item1.Unadvise(componentsTuple.Item2);
163-
_componentsEventsConnectionPoints.Remove(sink);
165+
_componentsEventsConnectionPoints.Remove(projectId);
164166
}
165167

166168
Tuple<IConnectionPoint, int> referencesTuple;
167-
if (_referencesEventsConnectionPoints.TryGetValue(sink, out referencesTuple))
169+
if (_referencesEventsConnectionPoints.TryGetValue(projectId, out referencesTuple))
168170
{
169171
referencesTuple.Item1.Unadvise(referencesTuple.Item2);
170-
_referencesEventsConnectionPoints.Remove(sink);
172+
_referencesEventsConnectionPoints.Remove(projectId);
171173
}
172-
173-
_parser.State.ClearDeclarations(e.Item);
174174
}
175175

176-
private readonly IDictionary<VBProjectsEventsSink, VBComponentsEventsSink> _componentsEventSinks =
177-
new Dictionary<VBProjectsEventsSink, VBComponentsEventsSink>();
176+
private readonly IDictionary<string,VBComponentsEventsSink> _componentsEventsSinks =
177+
new Dictionary<string,VBComponentsEventsSink>();
178178

179-
private readonly IDictionary<VBProjectsEventsSink, ReferencesEventsSink> _referencesEventsSinks =
180-
new Dictionary<VBProjectsEventsSink, ReferencesEventsSink>();
179+
private readonly IDictionary<string,ReferencesEventsSink> _referencesEventsSinks =
180+
new Dictionary<string, ReferencesEventsSink>();
181181

182182
async void sink_ProjectAdded(object sender, DispatcherEventArgs<VBProject> e)
183183
{
184-
var sink = (VBProjectsEventsSink)sender;
185-
RegisterComponentsEventSink(e, sink);
186-
_parser.State.AddProject(e.Item);
184+
Debug.WriteLine(string.Format("Project '{0}' was added.", e.Item.Name));
185+
if (e.Item.Protection == vbext_ProjectProtection.vbext_pp_locked)
186+
{
187+
Debug.WriteLine("Project is protected and will not be added to parser state.");
188+
return;
189+
}
190+
191+
_parser.State.AddProject(e.Item); // note side-effect: assigns ProjectId/HelpFile
192+
var projectId = e.Item.HelpFile;
193+
RegisterComponentsEventSink(e.Item.VBComponents, projectId);
187194

188195
if (!_parser.State.AllDeclarations.Any())
189196
{
@@ -193,13 +200,19 @@ async void sink_ProjectAdded(object sender, DispatcherEventArgs<VBProject> e)
193200
return;
194201
}
195202

196-
Debug.WriteLine(string.Format("Project '{0}' was added.", e.Item.Name));
197203
_parser.State.OnParseRequested(sender);
198204
}
199205

200-
private void RegisterComponentsEventSink(DispatcherEventArgs<VBProject> e, VBProjectsEventsSink sink)
206+
private void RegisterComponentsEventSink(VBComponents components, string projectId)
201207
{
202-
var connectionPointContainer = (IConnectionPointContainer) e.Item.VBComponents;
208+
if (_componentsEventsSinks.ContainsKey(projectId))
209+
{
210+
// already registered - this is caused by the initial load+rename of a project in the VBE
211+
Debug.WriteLine("Components sink already registered.");
212+
return;
213+
}
214+
215+
var connectionPointContainer = (IConnectionPointContainer)components;
203216
var interfaceId = typeof (_dispVBComponentsEvents).GUID;
204217

205218
IConnectionPoint connectionPoint;
@@ -212,12 +225,13 @@ private void RegisterComponentsEventSink(DispatcherEventArgs<VBProject> e, VBPro
212225
componentsSink.ComponentRemoved += sink_ComponentRemoved;
213226
componentsSink.ComponentRenamed += sink_ComponentRenamed;
214227
componentsSink.ComponentSelected += sink_ComponentSelected;
215-
//_componentsEventSinks.Add(sink, componentsSink);
228+
_componentsEventsSinks.Add(projectId, componentsSink);
216229

217-
//int cookie;
218-
//connectionPoint.Advise(componentsSink, out cookie);
230+
int cookie;
231+
connectionPoint.Advise(componentsSink, out cookie);
219232

220-
//_componentsEventsConnectionPoints.Add(sink, Tuple.Create(connectionPoint, cookie));
233+
_componentsEventsConnectionPoints.Add(projectId, Tuple.Create(connectionPoint, cookie));
234+
Debug.WriteLine("Components sink registered and advising.");
221235
}
222236

223237
async void sink_ComponentSelected(object sender, DispatcherEventArgs<VBComponent> e)
@@ -251,7 +265,7 @@ async void sink_ComponentRemoved(object sender, DispatcherEventArgs<VBComponent>
251265
}
252266

253267
Debug.WriteLine(string.Format("Component '{0}' was removed.", e.Item.Name));
254-
_parser.State.ClearDeclarations(e.Item);
268+
_parser.State.ClearStateCache(e.Item);
255269
}
256270

257271
async void sink_ComponentReloaded(object sender, DispatcherEventArgs<VBComponent> e)
@@ -364,7 +378,10 @@ public void Dispose()
364378
{
365379
item.Value.Item1.Unadvise(item.Value.Item2);
366380
}
367-
381+
foreach (var item in _referencesEventsConnectionPoints)
382+
{
383+
item.Value.Item1.Unadvise(item.Value.Item2);
384+
}
368385
_hooks.Dispose();
369386
}
370387
}

RetailCoder.VBE/UI/Command/MenuItems/RubberduckCommandBar.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,9 @@ private void _statusButton_Click(CommandBarButton Ctrl, ref bool CancelDefault)
4141

4242
public void SetStatusText(string value = null)
4343
{
44-
Debug.WriteLine(string.Format("RubberduckCommandBar status text changes to '{0}'.", value));
45-
UiDispatcher.Invoke(() => _statusButton.Caption = value ?? RubberduckUI.ResourceManager.GetString("ParserState_" + _state.Status));
44+
var text = value ?? RubberduckUI.ResourceManager.GetString("ParserState_" + _state.Status);
45+
Debug.WriteLine(string.Format("RubberduckCommandBar status text changes to '{0}'.", text));
46+
UiDispatcher.Invoke(() => _statusButton.Caption = text);
4647
}
4748

4849
public void SetSelectionText(Declaration declaration)

Rubberduck.Parsing/Symbols/DeclarationFinder.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,10 +97,11 @@ public IEnumerable<Declaration> MatchName(string name)
9797
{
9898
return result;
9999
}
100+
100101
return new List<Declaration>();
101102
}
102103

103-
public Declaration FindProject(Declaration currentScope, string name)
104+
public Declaration FindProject(string name, Declaration currentScope = null)
104105
{
105106
Declaration result = null;
106107
try

Rubberduck.Parsing/Symbols/IdentifierReferenceResolver.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ private Declaration ResolveType(VBAParser.ComplexTypeContext context)
202202
private Declaration ResolveType(IList<VBAParser.IdentifierContext> identifiers)
203203
{
204204
var first = identifiers[0].GetText();
205-
var projectMatch = _declarationFinder.FindProject(_currentScope, first);
205+
var projectMatch = _declarationFinder.FindProject(first, _currentScope);
206206

207207
if (projectMatch != null)
208208
{
@@ -1108,7 +1108,7 @@ private Declaration FindModuleScopeDeclaration(string identifierName, Declaratio
11081108
.ToList();
11091109
}
11101110

1111-
return result.Count == 1 ? result.SingleOrDefault() : null;
1111+
return result.Count == 1 ? result.SingleOrDefault() : null; // return null for multiple matches
11121112
}
11131113

11141114
private bool IsLocalEvent(Declaration item, Declaration localScope)

Rubberduck.Parsing/Symbols/ReferencedDeclarationsCollector.cs

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System;
22
using System.Collections.Generic;
33
using System.Diagnostics;
4+
using System.Diagnostics.Eventing.Reader;
45
using System.Runtime.InteropServices;
56
using System.Runtime.InteropServices.ComTypes;
67
using Microsoft.Vbe.Interop;
@@ -76,6 +77,39 @@ private enum REGKIND
7677
{VarEnum.VT_R8, "Double"},
7778
};
7879

80+
private string GetTypeName(TYPEDESC desc, ITypeInfo info)
81+
{
82+
var vt = (VarEnum)desc.vt;
83+
TYPEDESC tdesc;
84+
85+
switch (vt)
86+
{
87+
case VarEnum.VT_PTR:
88+
tdesc = (TYPEDESC) Marshal.PtrToStructure(desc.lpValue, typeof (TYPEDESC));
89+
return GetTypeName(tdesc, info);
90+
case VarEnum.VT_USERDEFINED:
91+
unchecked
92+
{
93+
var href = desc.lpValue.ToInt32();
94+
ITypeInfo refTypeInfo;
95+
info.GetRefTypeInfo(href, out refTypeInfo);
96+
return GetTypeName(refTypeInfo);
97+
}
98+
case VarEnum.VT_CARRAY:
99+
tdesc = (TYPEDESC) Marshal.PtrToStructure(desc.lpValue, typeof (TYPEDESC));
100+
return GetTypeName(tdesc, info) + "()";
101+
default:
102+
string result;
103+
if (TypeNames.TryGetValue(vt, out result))
104+
{
105+
return result;
106+
}
107+
break;
108+
}
109+
110+
return "UNKNOWN";
111+
}
112+
79113
private string GetTypeName(ITypeInfo info)
80114
{
81115
string typeName;
@@ -211,7 +245,22 @@ private Declaration CreateMemberDeclaration(out FUNCDESC memberDescriptor, TYPEK
211245
var asTypeName = string.Empty;
212246
if (memberDeclarationType != DeclarationType.Procedure && !TypeNames.TryGetValue(funcValueType, out asTypeName))
213247
{
214-
asTypeName = funcValueType.ToString(); //TypeNames[VarEnum.VT_VARIANT];
248+
if (funcValueType == VarEnum.VT_PTR)
249+
{
250+
try
251+
{
252+
var asTypeDesc = (TYPEDESC) Marshal.PtrToStructure(memberDescriptor.elemdescFunc.tdesc.lpValue, typeof (TYPEDESC));
253+
asTypeName = GetTypeName(asTypeDesc, info);
254+
}
255+
catch
256+
{
257+
asTypeName = funcValueType.ToString(); //TypeNames[VarEnum.VT_VARIANT];
258+
}
259+
}
260+
else
261+
{
262+
asTypeName = funcValueType.ToString(); //TypeNames[VarEnum.VT_VARIANT];
263+
}
215264
}
216265

217266
var attributes = new Attributes();
@@ -222,7 +271,7 @@ private Declaration CreateMemberDeclaration(out FUNCDESC memberDescriptor, TYPEK
222271
else if (memberDescriptor.memid == 0)
223272
{
224273
attributes.AddDefaultMemberAttribute(memberName);
225-
Debug.WriteLine("Default member found: {0}.{1} ({2} / {3})", moduleDeclaration.IdentifierName, memberName, memberDeclarationType, (VarEnum)memberDescriptor.elemdescFunc.tdesc.vt);
274+
//Debug.WriteLine("Default member found: {0}.{1} ({2} / {3})", moduleDeclaration.IdentifierName, memberName, memberDeclarationType, (VarEnum)memberDescriptor.elemdescFunc.tdesc.vt);
226275
}
227276
else if (((FUNCFLAGS)memberDescriptor.wFuncFlags).HasFlag(FUNCFLAGS.FUNCFLAG_FHIDDEN))
228277
{

Rubberduck.Parsing/Symbols/SyntaxErrorException.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Diagnostics;
23
using Antlr4.Runtime;
34

45
namespace Rubberduck.Parsing.Symbols
@@ -16,6 +17,8 @@ public SyntaxErrorException(string message, RecognitionException innerException,
1617
_token = offendingSymbol;
1718
_line = line;
1819
_position = position;
20+
Debug.WriteLine(innerException.ToString());
21+
Debug.WriteLine("Token: {0} (L{1}C{2})", offendingSymbol.Text, line, position);
1922
}
2023

2124
private readonly IToken _token;

0 commit comments

Comments
 (0)