Skip to content

Commit 81399f5

Browse files
committed
Merge branch 'next' of https://github.com/rubberduck-vba/Rubberduck into next
2 parents 81f1352 + 335d3ff commit 81399f5

File tree

9 files changed

+469
-50
lines changed

9 files changed

+469
-50
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ public static class UiDispatcher
88
// thanks to Pellared on http://stackoverflow.com/a/12909070/1188513
99

1010
private static SynchronizationContext UiContext { get; set; }
11-
11+
1212
public static void Initialize()
1313
{
1414
if (UiContext == null)

RetailCoder.VBE/UI/UnitTesting/TestExplorerModel.cs

Lines changed: 30 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.Collections.ObjectModel;
33
using System.Linq;
44
using System.Windows.Media;
5+
using System.Windows.Threading;
56
using Microsoft.Vbe.Interop;
67
using Rubberduck.Parsing.VBA;
78
using Rubberduck.UI.Command.MenuItems;
@@ -13,12 +14,15 @@ public class TestExplorerModel : ViewModelBase
1314
{
1415
private readonly VBE _vbe;
1516
private readonly RubberduckParserState _state;
17+
private readonly Dispatcher _dispatcher;
1618

1719
public TestExplorerModel(VBE vbe, RubberduckParserState state)
1820
{
1921
_vbe = vbe;
2022
_state = state;
2123
_state.StateChanged += State_StateChanged;
24+
25+
_dispatcher = Dispatcher.CurrentDispatcher;
2226
}
2327

2428
private void State_StateChanged(object sender, ParserStateEventArgs e)
@@ -33,34 +37,38 @@ private void State_StateChanged(object sender, ParserStateEventArgs e)
3337
t.Declaration.IdentifierName == test.Declaration.IdentifierName &&
3438
t.Declaration.ProjectId == test.Declaration.ProjectId)).ToList();
3539

36-
// remove old tests
37-
foreach (var test in removedTests)
40+
_dispatcher.Invoke(() =>
3841
{
39-
UiDispatcher.Invoke(() => { Tests.Remove(test); });
40-
}
4142

42-
// update declarations for existing tests--declarations are immutable
43-
foreach (var test in Tests.Except(removedTests))
44-
{
45-
var declaration = tests.First(t =>
46-
t.Declaration.ComponentName == test.Declaration.ComponentName &&
47-
t.Declaration.IdentifierName == test.Declaration.IdentifierName &&
48-
t.Declaration.ProjectId == test.Declaration.ProjectId).Declaration;
43+
// remove old tests
44+
foreach (var test in removedTests)
45+
{
46+
Tests.Remove(test);
47+
}
4948

50-
test.SetDeclaration(declaration);
51-
}
49+
// update declarations for existing tests--declarations are immutable
50+
foreach (var test in Tests.Except(removedTests))
51+
{
52+
var declaration = tests.First(t =>
53+
t.Declaration.ComponentName == test.Declaration.ComponentName &&
54+
t.Declaration.IdentifierName == test.Declaration.IdentifierName &&
55+
t.Declaration.ProjectId == test.Declaration.ProjectId).Declaration;
5256

53-
// add new tests
54-
foreach (var test in tests)
55-
{
56-
if (!Tests.Any(t =>
57-
t.Declaration.ComponentName == test.Declaration.ComponentName &&
58-
t.Declaration.IdentifierName == test.Declaration.IdentifierName &&
59-
t.Declaration.ProjectId == test.Declaration.ProjectId))
57+
test.SetDeclaration(declaration);
58+
}
59+
60+
// add new tests
61+
foreach (var test in tests)
6062
{
61-
UiDispatcher.Invoke(() => { Tests.Add(test); });
63+
if (!Tests.Any(t =>
64+
t.Declaration.ComponentName == test.Declaration.ComponentName &&
65+
t.Declaration.IdentifierName == test.Declaration.IdentifierName &&
66+
t.Declaration.ProjectId == test.Declaration.ProjectId))
67+
{
68+
Tests.Add(test);
69+
}
6270
}
63-
}
71+
});
6472
}
6573

6674
private readonly ObservableCollection<TestMethod> _tests = new ObservableCollection<TestMethod>();

Rubberduck.Parsing/Symbols/ReferencedDeclarationsCollector.cs

Lines changed: 27 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
using System;
22
using System.Collections.Generic;
3-
using System.Diagnostics;
43
using System.Runtime.InteropServices;
54
using System.Runtime.InteropServices.ComTypes;
65
using Microsoft.Vbe.Interop;
@@ -19,7 +18,6 @@
1918
using TYPEFLAGS = System.Runtime.InteropServices.ComTypes.TYPEFLAGS;
2019
using VARDESC = System.Runtime.InteropServices.ComTypes.VARDESC;
2120
using Rubberduck.Parsing.Annotations;
22-
using System.Linq;
2321
using Rubberduck.Parsing.Grammar;
2422

2523
namespace Rubberduck.Parsing.Symbols
@@ -130,21 +128,22 @@ private string GetTypeName(ITypeInfo info)
130128
return typeName;
131129
}
132130

133-
public IEnumerable<Declaration> GetDeclarationsForReference(Reference reference)
131+
public List<Declaration> GetDeclarationsForReference(Reference reference)
134132
{
133+
var output = new List<Declaration>();
135134
var projectName = reference.Name;
136135
var path = reference.FullPath;
137136
ITypeLib typeLibrary;
138137
// Failure to load might mean that it's a "normal" VBProject that will get parsed by us anyway.
139138
LoadTypeLibEx(path, REGKIND.REGKIND_NONE, out typeLibrary);
140139
if (typeLibrary == null)
141140
{
142-
yield break;
141+
return output;
143142
}
144143
var projectQualifiedModuleName = new QualifiedModuleName(projectName, path, projectName);
145144
var projectQualifiedMemberName = new QualifiedMemberName(projectQualifiedModuleName, projectName);
146145
var projectDeclaration = new ProjectDeclaration(projectQualifiedMemberName, projectName, isBuiltIn: true);
147-
yield return projectDeclaration;
146+
output.Add(projectDeclaration);
148147

149148
var typeCount = typeLibrary.GetTypeInfoCount();
150149
for (var i = 0; i < typeCount; i++)
@@ -156,7 +155,7 @@ public IEnumerable<Declaration> GetDeclarationsForReference(Reference reference)
156155
}
157156
catch (NullReferenceException)
158157
{
159-
yield break;
158+
return output;
160159
}
161160

162161
if (info == null)
@@ -241,53 +240,56 @@ public IEnumerable<Declaration> GetDeclarationsForReference(Reference reference)
241240
attributes);
242241
break;
243242
}
243+
info.ReleaseTypeAttr(typeAttributesPointer);
244244

245-
yield return moduleDeclaration;
245+
output.Add(moduleDeclaration);
246246

247247
for (var memberIndex = 0; memberIndex < typeAttributes.cFuncs; memberIndex++)
248248
{
249-
FUNCDESC memberDescriptor;
250249
string[] memberNames;
251-
var memberDeclaration = CreateMemberDeclaration(out memberDescriptor, typeAttributes.typekind, info, memberIndex, typeQualifiedModuleName, moduleDeclaration, out memberNames);
250+
251+
IntPtr memberDescriptorPointer;
252+
info.GetFuncDesc(memberIndex, out memberDescriptorPointer);
253+
var memberDescriptor = (FUNCDESC)Marshal.PtrToStructure(memberDescriptorPointer, typeof(FUNCDESC));
254+
var memberDeclaration = CreateMemberDeclaration(memberDescriptor, typeAttributes.typekind, info, memberIndex, typeQualifiedModuleName, moduleDeclaration, out memberNames);
252255
if (memberDeclaration == null)
253256
{
257+
info.ReleaseFuncDesc(memberDescriptorPointer);
254258
continue;
255259
}
256260
if (moduleDeclaration.DeclarationType == DeclarationType.ClassModule && memberDeclaration is ICanBeDefaultMember && ((ICanBeDefaultMember)memberDeclaration).IsDefaultMember)
257261
{
258262
((ClassModuleDeclaration)moduleDeclaration).DefaultMember = memberDeclaration;
259263
}
260-
yield return memberDeclaration;
264+
output.Add(memberDeclaration);
261265

262266
var parameterCount = memberDescriptor.cParams - 1;
263267
for (var paramIndex = 0; paramIndex < parameterCount; paramIndex++)
264268
{
265269
var parameter = CreateParameterDeclaration(memberNames, paramIndex, memberDescriptor, typeQualifiedModuleName, memberDeclaration, info);
266-
if (memberDeclaration is IDeclarationWithParameter)
270+
var declaration = memberDeclaration as IDeclarationWithParameter;
271+
if (declaration != null)
267272
{
268-
((IDeclarationWithParameter)memberDeclaration).AddParameter(parameter);
273+
declaration.AddParameter(parameter);
269274
}
270-
yield return parameter;
275+
output.Add(parameter);
271276
}
277+
info.ReleaseFuncDesc(memberDescriptorPointer);
272278
}
273279

274280
for (var fieldIndex = 0; fieldIndex < typeAttributes.cVars; fieldIndex++)
275281
{
276-
yield return CreateFieldDeclaration(info, fieldIndex, typeDeclarationType, typeQualifiedModuleName, moduleDeclaration);
282+
output.Add(CreateFieldDeclaration(info, fieldIndex, typeDeclarationType, typeQualifiedModuleName, moduleDeclaration));
277283
}
278284
}
285+
return output;
279286
}
280287

281-
private Declaration CreateMemberDeclaration(out FUNCDESC memberDescriptor, TYPEKIND typeKind, ITypeInfo info, int memberIndex,
288+
private Declaration CreateMemberDeclaration(FUNCDESC memberDescriptor, TYPEKIND typeKind, ITypeInfo info, int memberIndex,
282289
QualifiedModuleName typeQualifiedModuleName, Declaration moduleDeclaration, out string[] memberNames)
283290
{
284-
IntPtr memberDescriptorPointer;
285-
info.GetFuncDesc(memberIndex, out memberDescriptorPointer);
286-
memberDescriptor = (FUNCDESC)Marshal.PtrToStructure(memberDescriptorPointer, typeof(FUNCDESC));
287-
288291
if (memberDescriptor.callconv != CALLCONV.CC_STDCALL)
289292
{
290-
memberDescriptor = new FUNCDESC();
291293
memberNames = new string[] { };
292294
return null;
293295
}
@@ -425,7 +427,8 @@ private Declaration CreateFieldDeclaration(ITypeInfo info, int fieldIndex, Decla
425427
var fieldName = names[0];
426428
var memberType = GetDeclarationType(varDesc, typeDeclarationType);
427429

428-
var asTypeName = GetTypeName(varDesc.elemdescVar.tdesc, info);
430+
var asTypeName = GetTypeName(varDesc.elemdescVar.tdesc, info);
431+
info.ReleaseVarDesc(ppVarDesc);
429432

430433
return new Declaration(new QualifiedMemberName(typeQualifiedModuleName, fieldName),
431434
moduleDeclaration, moduleDeclaration, asTypeName, null, false, false, Accessibility.Global, memberType, null,
@@ -458,6 +461,7 @@ private ParameterDeclaration CreateParameterDeclaration(IReadOnlyList<string> me
458461

459462
private IEnumerable<string> GetImplementedInterfaceNames(TYPEATTR typeAttr, ITypeInfo info)
460463
{
464+
var output = new List<string>();
461465
for (var implIndex = 0; implIndex < typeAttr.cImplTypes; implIndex++)
462466
{
463467
int href;
@@ -470,10 +474,11 @@ private IEnumerable<string> GetImplementedInterfaceNames(TYPEATTR typeAttr, ITyp
470474
if (implTypeName != "IDispatch" && implTypeName != "IUnknown")
471475
{
472476
// skip IDispatch.. just about everything implements it and RD doesn't need to care about it; don't care about IUnknown either
473-
yield return implTypeName;
477+
output.Add(implTypeName);
474478
}
475479
//Debug.WriteLine(string.Format("\tImplements {0}", implTypeName));
476480
}
481+
return output;
477482
}
478483

479484
private DeclarationType GetDeclarationType(ITypeLib typeLibrary, int i)

Rubberduck.Parsing/VBA/RubberduckParser.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,7 @@ private void SyncComReferences(IReadOnlyList<VBProject> projects)
348348
if (!map.IsLoaded)
349349
{
350350
_state.OnStatusMessageUpdate(ParserState.LoadingReference.ToString());
351-
var items = _comReflector.GetDeclarationsForReference(reference).ToList();
351+
var items = _comReflector.GetDeclarationsForReference(reference);
352352
foreach (var declaration in items)
353353
{
354354
_state.AddDeclaration(declaration);

Rubberduck.VBEEditor/QualifiedModuleName.cs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,15 @@ private static string GetDisplayName(VBProject project)
3030
//Eg. A Workbook's parent is the application, so read the workbook's name
3131
try
3232
{
33-
var nameProperty = project.VBComponents.Cast<VBComponent>()
33+
var component = project.VBComponents.Cast<VBComponent>()
3434
.FirstOrDefault(comp => comp.Type == vbext_ComponentType.vbext_ct_Document
3535
&& comp.Properties.Item("Name").Value != null
3636
&& comp.Properties.Item("Parent")
37-
.Object.Equals(comp.Properties.Item("Application").Object))
38-
.Properties.Cast<Property>().FirstOrDefault(property => property.Name == "Name");
37+
.Object.Equals(comp.Properties.Item("Application").Object));
38+
39+
if (component == null) { return null; }
40+
41+
var nameProperty = component.Properties.Cast<Property>().FirstOrDefault(property => property.Name == "Name");
3942
return nameProperty == null
4043
? null
4144
: nameProperty.Value.ToString();

RubberduckTests/Mocks/MockProjectBuilder.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ public class MockProjectBuilder
2121
private readonly Mock<References> _vbReferences;
2222

2323
private readonly List<Mock<VBComponent>> _componentsMock = new List<Mock<VBComponent>>();
24-
//private readonly List<VBComponent> _components = new List<VBComponent>();
2524
private readonly List<Reference> _references = new List<Reference>();
2625

2726
public Mock<VBComponents> MockVBComponents
@@ -39,6 +38,11 @@ private List<VBComponent> Components
3938
get { return _componentsMock.Select(m => m.Object).ToList(); }
4039
}
4140

41+
public void RemoveComponent(Mock<VBComponent> component)
42+
{
43+
_componentsMock.Remove(component);
44+
}
45+
4246
public MockProjectBuilder(string name, string filename, vbext_ProjectProtection protection, Func<VBE> getVbe, MockVbeBuilder mockVbeBuilder)
4347
{
4448
_getVbe = getVbe;

RubberduckTests/RubberduckTests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@
172172
<Compile Include="UnitTesting\AssertTests.cs" />
173173
<Compile Include="UnitTesting\EngineTests.cs" />
174174
<Compile Include="UnitTesting\DiscoveryTests.cs" />
175+
<Compile Include="UnitTesting\ViewModelTests.cs" />
175176
<Compile Include="VbeTestBase.cs" />
176177
</ItemGroup>
177178
<ItemGroup>

RubberduckTests/UnitTesting/DiscoveryTests.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
using System.Linq;
2+
using System.Threading;
23
using Microsoft.Vbe.Interop;
34
using Microsoft.VisualStudio.TestTools.UnitTesting;
45
using Moq;
56
using Rubberduck.Parsing.VBA;
7+
using Rubberduck.UI.Command.MenuItems;
8+
using Rubberduck.UI.UnitTesting;
69
using Rubberduck.UnitTesting;
710
using Rubberduck.VBEditor;
811
using Rubberduck.VBEditor.VBEHost;

0 commit comments

Comments
 (0)