Skip to content

Commit 10ae5c9

Browse files
committed
Apparently we DO care about COM structures. Add missed ctor initialization.
1 parent db38004 commit 10ae5c9

File tree

9 files changed

+96
-44
lines changed

9 files changed

+96
-44
lines changed

Rubberduck.Parsing/ComReflection/ComField.cs

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
using System.Diagnostics;
22
using System.Runtime.InteropServices;
33
using System.Runtime.InteropServices.ComTypes;
4+
using System.Xml.Schema;
5+
using Rubberduck.Parsing.Symbols;
46
using VARDESC = System.Runtime.InteropServices.ComTypes.VARDESC;
57
using VARFLAGS = System.Runtime.InteropServices.ComTypes.VARFLAGS;
68

@@ -9,31 +11,31 @@ namespace Rubberduck.Parsing.ComReflection
911
[DebuggerDisplay("{Name}")]
1012
public class ComField
1113
{
12-
public string Name { get; set; }
13-
public int Index { get; set; }
14-
public bool IsConstant { get; set; }
14+
public string Name { get; private set; }
15+
public int Index { get; private set; }
16+
public DeclarationType Type { get; private set; }
1517
public object DefaultValue { get; set; }
16-
public VarEnum DefaultValueType { get; set; }
18+
public string ValueType { get; set; }
1719
public VARFLAGS Flags { get; set; }
1820

19-
public ComField(ITypeInfo info, VARDESC varDesc, int index)
21+
public ComField(string name, VARDESC varDesc, int index, DeclarationType type)
2022
{
23+
Name = name;
2124
Index = index;
25+
Type = type;
2226

23-
var names = new string[255];
24-
int length;
25-
info.GetNames(varDesc.memid, names, 255, out length);
26-
Debug.Assert(length >= 1);
27-
Name = names[0];
28-
29-
IsConstant = varDesc.varkind.HasFlag(VARKIND.VAR_CONST);
3027
Flags = (VARFLAGS)varDesc.wVarFlags;
3128

32-
if (IsConstant)
29+
if (Type == DeclarationType.Constant)
3330
{
3431
var value = new ComVariant(varDesc.desc.lpvarValue);
3532
DefaultValue = value.Value;
36-
DefaultValueType = value.VariantType;
33+
string typeName;
34+
ValueType = ComVariant.TypeNames.TryGetValue(value.VariantType, out typeName) ? typeName : "Object";
35+
}
36+
else
37+
{
38+
3739
}
3840
}
3941
}

Rubberduck.Parsing/ComReflection/ComModule.cs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
namespace Rubberduck.Parsing.ComReflection
1313
{
14-
public class ComModule : ComType, IComTypeWithMembers
14+
public class ComModule : ComType, IComTypeWithMembers, IComTypeWithFields
1515
{
1616
private readonly List<ComMember> _members = new List<ComMember>();
1717
public IEnumerable<ComMember> Members
@@ -42,14 +42,18 @@ public ComModule(ITypeLib typeLib, ITypeInfo info, TYPEATTR attrib, int index) :
4242

4343
private void GetComFields(ITypeInfo info, TYPEATTR attrib)
4444
{
45+
var names = new string[255];
4546
for (var index = 0; index < attrib.cVars; index++)
4647
{
47-
IntPtr ppVarDesc;
48-
info.GetVarDesc(index, out ppVarDesc);
49-
var varDesc = (VARDESC)Marshal.PtrToStructure(ppVarDesc, typeof(VARDESC));
48+
IntPtr varPtr;
49+
info.GetVarDesc(index, out varPtr);
50+
var desc = (VARDESC)Marshal.PtrToStructure(varPtr, typeof(VARDESC));
51+
int length;
52+
info.GetNames(desc.memid, names, 255, out length);
53+
Debug.Assert(length == 1);
5054

51-
_fields.Add(new ComField(info, varDesc, index));
52-
info.ReleaseVarDesc(ppVarDesc);
55+
_fields.Add(new ComField(names[0], desc, index, DeclarationType.Constant));
56+
info.ReleaseVarDesc(varPtr);
5357
}
5458
}
5559

Rubberduck.Parsing/ComReflection/ComProject.cs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,14 +49,21 @@ public IEnumerable<ComModule> Modules
4949
get { return _modules; }
5050
}
5151

52+
private readonly List<ComStruct> _structs = new List<ComStruct>();
53+
public IEnumerable<ComStruct> Structs
54+
{
55+
get { return _structs; }
56+
}
57+
5258
public IEnumerable<IComType> Members
5359
{
5460
get
5561
{
5662
return _modules.Cast<IComType>()
5763
.Union(_interfaces)
5864
.Union(_classes)
59-
.Union(_enumerations);
65+
.Union(_enumerations)
66+
.Union(_structs);
6067
}
6168
}
6269

@@ -118,8 +125,9 @@ private void LoadModules(ITypeLib typeLibrary)
118125
if (type != null) KnownTypes.TryAdd(typeAttributes.guid, intface);
119126
break;
120127
case TYPEKIND.TKIND_RECORD:
121-
//IIR these aren't available to VBA. I could quite possibly be wrong though.
122-
throw new NotImplementedException(string.Format("Didn't expect to find a TKIND_RECORD in {0}.", Path));
128+
var structure = new ComStruct(typeLibrary, info, typeAttributes, index);
129+
_structs.Add(structure);
130+
break;
123131
case TYPEKIND.TKIND_MODULE:
124132
var module = type ?? new ComModule(typeLibrary, info, typeAttributes, index);
125133
_modules.Add(module as ComModule);
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Diagnostics;
4+
using System.Runtime.InteropServices;
5+
using System.Runtime.InteropServices.ComTypes;
6+
using Rubberduck.Parsing.Symbols;
7+
using TYPEATTR = System.Runtime.InteropServices.ComTypes.TYPEATTR;
8+
using VARDESC = System.Runtime.InteropServices.ComTypes.VARDESC;
9+
10+
namespace Rubberduck.Parsing.ComReflection
11+
{
12+
public class ComStruct : ComType, IComTypeWithFields
13+
{
14+
private readonly List<ComField> _fields = new List<ComField>();
15+
public IEnumerable<ComField> Fields
16+
{
17+
get { return _fields; }
18+
}
19+
20+
public ComStruct(ITypeLib typeLib, ITypeInfo info, TYPEATTR attrib, int index)
21+
: base(typeLib, attrib, index)
22+
{
23+
_fields = new List<ComField>();
24+
Type = DeclarationType.UserDefinedType;
25+
GetFields(info, attrib);
26+
}
27+
28+
private void GetFields(ITypeInfo info, TYPEATTR attrib)
29+
{
30+
var names = new string[255];
31+
for (var index = 0; index < attrib.cVars; index++)
32+
{
33+
IntPtr varPtr;
34+
info.GetVarDesc(index, out varPtr);
35+
var desc = (VARDESC)Marshal.PtrToStructure(varPtr, typeof(VARDESC));
36+
int length;
37+
info.GetNames(desc.memid, names, 255, out length);
38+
Debug.Assert(length == 1);
39+
40+
_fields.Add(new ComField(names[0], desc, index, DeclarationType.UserDefinedTypeMember));
41+
info.ReleaseVarDesc(varPtr);
42+
}
43+
}
44+
}
45+
}

Rubberduck.Parsing/ComReflection/ComType.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@ public interface IComTypeWithMembers : IComType
1717
IEnumerable<ComMember> Members { get; }
1818
}
1919

20+
public interface IComTypeWithFields : IComType
21+
{
22+
IEnumerable<ComField> Fields { get; }
23+
}
24+
2025
[DebuggerDisplay("{Name}")]
2126
public abstract class ComType : ComBase, IComType
2227
{

Rubberduck.Parsing/Rubberduck.Parsing.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@
116116
<Compile Include="ComReflection\ComEnumeration.cs" />
117117
<Compile Include="ComReflection\ComEnumerationMember.cs" />
118118
<Compile Include="ComReflection\ComInterface.cs" />
119+
<Compile Include="ComReflection\ComStruct.cs" />
119120
<Compile Include="ComReflection\ComType.cs" />
120121
<Compile Include="ComReflection\ComVariant.cs" />
121122
<Compile Include="Grammar\Annotations.cs" />

Rubberduck.Parsing/Symbols/ClassModuleDeclaration.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,8 @@ public ClassModuleDeclaration(ComCoClass coClass, Declaration parent, QualifiedM
7575
coClass.ImplementedInterfaces.Where(i => !i.IsRestricted && !IgnoredInterfaces.Contains(i.Name))
7676
.Select(i => i.Name)
7777
.ToList();
78+
_supertypes = new HashSet<Declaration>();
79+
_subtypes = new HashSet<Declaration>();
7880
}
7981

8082
public ClassModuleDeclaration(ComInterface intrface, Declaration parent, QualifiedModuleName module,

Rubberduck.Parsing/Symbols/Declaration.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -200,15 +200,15 @@ public Declaration(ComEnumerationMember member, Declaration parent, QualifiedMod
200200

201201
public Declaration(ComField field, Declaration parent, QualifiedModuleName module)
202202
: this(
203-
new QualifiedMemberName(module, string.IsNullOrEmpty(field.Name) ? "Foo" : field.Name),
203+
new QualifiedMemberName(module, field.Name),
204204
parent,
205205
parent,
206-
string.IsNullOrEmpty(field.Name) ? "Foo" : field.Name,
206+
field.Name,
207207
null,
208208
false,
209209
false,
210210
Accessibility.Global,
211-
field.IsConstant ? DeclarationType.Constant : DeclarationType.UserDefinedType, //TODO: This is wrong.
211+
field.Type,
212212
null,
213213
Selection.Home,
214214
false,

Rubberduck.Parsing/Symbols/ReferencedDeclarationsCollector.cs

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,8 @@ public List<Declaration> GetDeclarationsForReference(IReference reference)
150150
output.Add(enumDeclaration);
151151
output.AddRange(members);
152152
}
153-
var fields = module as ComModule;
153+
154+
var fields = module as IComTypeWithFields;
154155
if (fields == null || !fields.Fields.Any())
155156
{
156157
continue;
@@ -224,23 +225,7 @@ private Declaration CreateMemberDeclaration(ComMember member, QualifiedModuleNam
224225
return new PropertyLetDeclaration(member, parent, module, attributes);
225226
default:
226227
Debug.Assert(false);
227-
return new Declaration(
228-
new QualifiedMemberName(module, member.Name),
229-
parent,
230-
parent,
231-
string.Empty, // asTypeName.Name,
232-
null,
233-
false,
234-
false,
235-
Accessibility.Global,
236-
member.Type,
237-
null,
238-
Selection.Home,
239-
false,
240-
null,
241-
true,
242-
null,
243-
attributes);
228+
return null as Declaration;
244229
}
245230
}
246231
}

0 commit comments

Comments
 (0)