Skip to content

Commit

Permalink
Merge branch 'next' of https://github.com/rubberduck-vba/Rubberduck i…
Browse files Browse the repository at this point in the history
…nto next
  • Loading branch information
ThunderFrame committed Jun 2, 2016
2 parents 81f1352 + 335d3ff commit 81399f5
Show file tree
Hide file tree
Showing 9 changed files with 469 additions and 50 deletions.
2 changes: 1 addition & 1 deletion RetailCoder.VBE/UI/Command/MenuItems/UiDispatcher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ public static class UiDispatcher
// thanks to Pellared on http://stackoverflow.com/a/12909070/1188513

private static SynchronizationContext UiContext { get; set; }

public static void Initialize()
{
if (UiContext == null)
Expand Down
52 changes: 30 additions & 22 deletions RetailCoder.VBE/UI/UnitTesting/TestExplorerModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows.Media;
using System.Windows.Threading;
using Microsoft.Vbe.Interop;
using Rubberduck.Parsing.VBA;
using Rubberduck.UI.Command.MenuItems;
Expand All @@ -13,12 +14,15 @@ public class TestExplorerModel : ViewModelBase
{
private readonly VBE _vbe;
private readonly RubberduckParserState _state;
private readonly Dispatcher _dispatcher;

public TestExplorerModel(VBE vbe, RubberduckParserState state)
{
_vbe = vbe;
_state = state;
_state.StateChanged += State_StateChanged;

_dispatcher = Dispatcher.CurrentDispatcher;
}

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

// remove old tests
foreach (var test in removedTests)
_dispatcher.Invoke(() =>
{
UiDispatcher.Invoke(() => { Tests.Remove(test); });
}
// update declarations for existing tests--declarations are immutable
foreach (var test in Tests.Except(removedTests))
{
var declaration = tests.First(t =>
t.Declaration.ComponentName == test.Declaration.ComponentName &&
t.Declaration.IdentifierName == test.Declaration.IdentifierName &&
t.Declaration.ProjectId == test.Declaration.ProjectId).Declaration;
// remove old tests
foreach (var test in removedTests)
{
Tests.Remove(test);
}
test.SetDeclaration(declaration);
}
// update declarations for existing tests--declarations are immutable
foreach (var test in Tests.Except(removedTests))
{
var declaration = tests.First(t =>
t.Declaration.ComponentName == test.Declaration.ComponentName &&
t.Declaration.IdentifierName == test.Declaration.IdentifierName &&
t.Declaration.ProjectId == test.Declaration.ProjectId).Declaration;
// add new tests
foreach (var test in tests)
{
if (!Tests.Any(t =>
t.Declaration.ComponentName == test.Declaration.ComponentName &&
t.Declaration.IdentifierName == test.Declaration.IdentifierName &&
t.Declaration.ProjectId == test.Declaration.ProjectId))
test.SetDeclaration(declaration);
}
// add new tests
foreach (var test in tests)
{
UiDispatcher.Invoke(() => { Tests.Add(test); });
if (!Tests.Any(t =>
t.Declaration.ComponentName == test.Declaration.ComponentName &&
t.Declaration.IdentifierName == test.Declaration.IdentifierName &&
t.Declaration.ProjectId == test.Declaration.ProjectId))
{
Tests.Add(test);
}
}
}
});
}

private readonly ObservableCollection<TestMethod> _tests = new ObservableCollection<TestMethod>();
Expand Down
49 changes: 27 additions & 22 deletions Rubberduck.Parsing/Symbols/ReferencedDeclarationsCollector.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using Microsoft.Vbe.Interop;
Expand All @@ -19,7 +18,6 @@
using TYPEFLAGS = System.Runtime.InteropServices.ComTypes.TYPEFLAGS;
using VARDESC = System.Runtime.InteropServices.ComTypes.VARDESC;
using Rubberduck.Parsing.Annotations;
using System.Linq;
using Rubberduck.Parsing.Grammar;

namespace Rubberduck.Parsing.Symbols
Expand Down Expand Up @@ -130,21 +128,22 @@ private string GetTypeName(ITypeInfo info)
return typeName;
}

public IEnumerable<Declaration> GetDeclarationsForReference(Reference reference)
public List<Declaration> GetDeclarationsForReference(Reference reference)
{
var output = new List<Declaration>();
var projectName = reference.Name;
var path = reference.FullPath;
ITypeLib typeLibrary;
// Failure to load might mean that it's a "normal" VBProject that will get parsed by us anyway.
LoadTypeLibEx(path, REGKIND.REGKIND_NONE, out typeLibrary);
if (typeLibrary == null)
{
yield break;
return output;
}
var projectQualifiedModuleName = new QualifiedModuleName(projectName, path, projectName);
var projectQualifiedMemberName = new QualifiedMemberName(projectQualifiedModuleName, projectName);
var projectDeclaration = new ProjectDeclaration(projectQualifiedMemberName, projectName, isBuiltIn: true);
yield return projectDeclaration;
output.Add(projectDeclaration);

var typeCount = typeLibrary.GetTypeInfoCount();
for (var i = 0; i < typeCount; i++)
Expand All @@ -156,7 +155,7 @@ public IEnumerable<Declaration> GetDeclarationsForReference(Reference reference)
}
catch (NullReferenceException)
{
yield break;
return output;
}

if (info == null)
Expand Down Expand Up @@ -241,53 +240,56 @@ public IEnumerable<Declaration> GetDeclarationsForReference(Reference reference)
attributes);
break;
}
info.ReleaseTypeAttr(typeAttributesPointer);

yield return moduleDeclaration;
output.Add(moduleDeclaration);

for (var memberIndex = 0; memberIndex < typeAttributes.cFuncs; memberIndex++)
{
FUNCDESC memberDescriptor;
string[] memberNames;
var memberDeclaration = CreateMemberDeclaration(out memberDescriptor, typeAttributes.typekind, info, memberIndex, typeQualifiedModuleName, moduleDeclaration, out memberNames);

IntPtr memberDescriptorPointer;
info.GetFuncDesc(memberIndex, out memberDescriptorPointer);
var memberDescriptor = (FUNCDESC)Marshal.PtrToStructure(memberDescriptorPointer, typeof(FUNCDESC));
var memberDeclaration = CreateMemberDeclaration(memberDescriptor, typeAttributes.typekind, info, memberIndex, typeQualifiedModuleName, moduleDeclaration, out memberNames);
if (memberDeclaration == null)
{
info.ReleaseFuncDesc(memberDescriptorPointer);
continue;
}
if (moduleDeclaration.DeclarationType == DeclarationType.ClassModule && memberDeclaration is ICanBeDefaultMember && ((ICanBeDefaultMember)memberDeclaration).IsDefaultMember)
{
((ClassModuleDeclaration)moduleDeclaration).DefaultMember = memberDeclaration;
}
yield return memberDeclaration;
output.Add(memberDeclaration);

var parameterCount = memberDescriptor.cParams - 1;
for (var paramIndex = 0; paramIndex < parameterCount; paramIndex++)
{
var parameter = CreateParameterDeclaration(memberNames, paramIndex, memberDescriptor, typeQualifiedModuleName, memberDeclaration, info);
if (memberDeclaration is IDeclarationWithParameter)
var declaration = memberDeclaration as IDeclarationWithParameter;
if (declaration != null)
{
((IDeclarationWithParameter)memberDeclaration).AddParameter(parameter);
declaration.AddParameter(parameter);
}
yield return parameter;
output.Add(parameter);
}
info.ReleaseFuncDesc(memberDescriptorPointer);
}

for (var fieldIndex = 0; fieldIndex < typeAttributes.cVars; fieldIndex++)
{
yield return CreateFieldDeclaration(info, fieldIndex, typeDeclarationType, typeQualifiedModuleName, moduleDeclaration);
output.Add(CreateFieldDeclaration(info, fieldIndex, typeDeclarationType, typeQualifiedModuleName, moduleDeclaration));
}
}
return output;
}

private Declaration CreateMemberDeclaration(out FUNCDESC memberDescriptor, TYPEKIND typeKind, ITypeInfo info, int memberIndex,
private Declaration CreateMemberDeclaration(FUNCDESC memberDescriptor, TYPEKIND typeKind, ITypeInfo info, int memberIndex,
QualifiedModuleName typeQualifiedModuleName, Declaration moduleDeclaration, out string[] memberNames)
{
IntPtr memberDescriptorPointer;
info.GetFuncDesc(memberIndex, out memberDescriptorPointer);
memberDescriptor = (FUNCDESC)Marshal.PtrToStructure(memberDescriptorPointer, typeof(FUNCDESC));

if (memberDescriptor.callconv != CALLCONV.CC_STDCALL)
{
memberDescriptor = new FUNCDESC();
memberNames = new string[] { };
return null;
}
Expand Down Expand Up @@ -425,7 +427,8 @@ public IEnumerable<Declaration> GetDeclarationsForReference(Reference reference)
var fieldName = names[0];
var memberType = GetDeclarationType(varDesc, typeDeclarationType);

var asTypeName = GetTypeName(varDesc.elemdescVar.tdesc, info);
var asTypeName = GetTypeName(varDesc.elemdescVar.tdesc, info);
info.ReleaseVarDesc(ppVarDesc);

return new Declaration(new QualifiedMemberName(typeQualifiedModuleName, fieldName),
moduleDeclaration, moduleDeclaration, asTypeName, null, false, false, Accessibility.Global, memberType, null,
Expand Down Expand Up @@ -458,6 +461,7 @@ public IEnumerable<Declaration> GetDeclarationsForReference(Reference reference)

private IEnumerable<string> GetImplementedInterfaceNames(TYPEATTR typeAttr, ITypeInfo info)
{
var output = new List<string>();
for (var implIndex = 0; implIndex < typeAttr.cImplTypes; implIndex++)
{
int href;
Expand All @@ -470,10 +474,11 @@ private IEnumerable<string> GetImplementedInterfaceNames(TYPEATTR typeAttr, ITyp
if (implTypeName != "IDispatch" && implTypeName != "IUnknown")
{
// skip IDispatch.. just about everything implements it and RD doesn't need to care about it; don't care about IUnknown either
yield return implTypeName;
output.Add(implTypeName);
}
//Debug.WriteLine(string.Format("\tImplements {0}", implTypeName));
}
return output;
}

private DeclarationType GetDeclarationType(ITypeLib typeLibrary, int i)
Expand Down
2 changes: 1 addition & 1 deletion Rubberduck.Parsing/VBA/RubberduckParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,7 @@ private void SyncComReferences(IReadOnlyList<VBProject> projects)
if (!map.IsLoaded)
{
_state.OnStatusMessageUpdate(ParserState.LoadingReference.ToString());
var items = _comReflector.GetDeclarationsForReference(reference).ToList();
var items = _comReflector.GetDeclarationsForReference(reference);
foreach (var declaration in items)
{
_state.AddDeclaration(declaration);
Expand Down
9 changes: 6 additions & 3 deletions Rubberduck.VBEEditor/QualifiedModuleName.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,15 @@ private static string GetDisplayName(VBProject project)
//Eg. A Workbook's parent is the application, so read the workbook's name
try
{
var nameProperty = project.VBComponents.Cast<VBComponent>()
var component = project.VBComponents.Cast<VBComponent>()
.FirstOrDefault(comp => comp.Type == vbext_ComponentType.vbext_ct_Document
&& comp.Properties.Item("Name").Value != null
&& comp.Properties.Item("Parent")
.Object.Equals(comp.Properties.Item("Application").Object))
.Properties.Cast<Property>().FirstOrDefault(property => property.Name == "Name");
.Object.Equals(comp.Properties.Item("Application").Object));

if (component == null) { return null; }

var nameProperty = component.Properties.Cast<Property>().FirstOrDefault(property => property.Name == "Name");
return nameProperty == null
? null
: nameProperty.Value.ToString();
Expand Down
6 changes: 5 additions & 1 deletion RubberduckTests/Mocks/MockProjectBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ public class MockProjectBuilder
private readonly Mock<References> _vbReferences;

private readonly List<Mock<VBComponent>> _componentsMock = new List<Mock<VBComponent>>();
//private readonly List<VBComponent> _components = new List<VBComponent>();
private readonly List<Reference> _references = new List<Reference>();

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

public void RemoveComponent(Mock<VBComponent> component)
{
_componentsMock.Remove(component);
}

public MockProjectBuilder(string name, string filename, vbext_ProjectProtection protection, Func<VBE> getVbe, MockVbeBuilder mockVbeBuilder)
{
_getVbe = getVbe;
Expand Down
1 change: 1 addition & 0 deletions RubberduckTests/RubberduckTests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@
<Compile Include="UnitTesting\AssertTests.cs" />
<Compile Include="UnitTesting\EngineTests.cs" />
<Compile Include="UnitTesting\DiscoveryTests.cs" />
<Compile Include="UnitTesting\ViewModelTests.cs" />
<Compile Include="VbeTestBase.cs" />
</ItemGroup>
<ItemGroup>
Expand Down
3 changes: 3 additions & 0 deletions RubberduckTests/UnitTesting/DiscoveryTests.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
using System.Linq;
using System.Threading;
using Microsoft.Vbe.Interop;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using Rubberduck.Parsing.VBA;
using Rubberduck.UI.Command.MenuItems;
using Rubberduck.UI.UnitTesting;
using Rubberduck.UnitTesting;
using Rubberduck.VBEditor;
using Rubberduck.VBEditor.VBEHost;
Expand Down

0 comments on commit 81399f5

Please sign in to comment.