Skip to content

Commit 3e4e561

Browse files
committed
COM type info fixes (#1583)
* added AsTypeName to the context-sensitive commandbar * clear built-in references at every resolution; fixed issue with null parse trees, given built-in modules get a module state instance. * fixed OverflowException in GetTypeName; built-in parameters now have return type info :) * returning built-in members now have return type info as well
1 parent be38cf2 commit 3e4e561

File tree

1 file changed

+13
-47
lines changed

1 file changed

+13
-47
lines changed

Rubberduck.Parsing/Symbols/ReferencedDeclarationsCollector.cs

Lines changed: 13 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ private enum REGKIND
7070
{VarEnum.VT_INT, "Long"}, // same as I4
7171
{VarEnum.VT_UINT, "Variant"}, // same as UI4
7272
{VarEnum.VT_DATE, "Date"},
73+
{VarEnum.VT_CY, "Currency"},
7374
{VarEnum.VT_DECIMAL, "Currency"}, // best match?
7475
{VarEnum.VT_EMPTY, "Empty"},
7576
{VarEnum.VT_R4, "Single"},
@@ -89,9 +90,9 @@ private string GetTypeName(TYPEDESC desc, ITypeInfo info)
8990
case VarEnum.VT_USERDEFINED:
9091
unchecked
9192
{
92-
var href = desc.lpValue.ToInt64();
93+
var href = (int)desc.lpValue.ToInt64(); // todo: verify this also works on 32-bit
9394
ITypeInfo refTypeInfo;
94-
info.GetRefTypeInfo((int)href, out refTypeInfo);
95+
info.GetRefTypeInfo(href, out refTypeInfo);
9596
return GetTypeName(refTypeInfo);
9697
}
9798
case VarEnum.VT_CARRAY:
@@ -105,7 +106,6 @@ private string GetTypeName(TYPEDESC desc, ITypeInfo info)
105106
}
106107
break;
107108
}
108-
109109
return "UNKNOWN";
110110
}
111111

@@ -238,7 +238,7 @@ public IEnumerable<Declaration> GetDeclarationsForReference(Reference reference)
238238
var parameterCount = memberDescriptor.cParams - 1;
239239
for (var paramIndex = 0; paramIndex < parameterCount; paramIndex++)
240240
{
241-
var parameter = CreateParameterDeclaration(memberNames, paramIndex, memberDescriptor, typeQualifiedModuleName, memberDeclaration);
241+
var parameter = CreateParameterDeclaration(memberNames, paramIndex, memberDescriptor, typeQualifiedModuleName, memberDeclaration, info);
242242
if (memberDeclaration is IDeclarationWithParameter)
243243
{
244244
((IDeclarationWithParameter)memberDeclaration).AddParameter(parameter);
@@ -278,24 +278,9 @@ private Declaration CreateMemberDeclaration(out FUNCDESC memberDescriptor, TYPEK
278278
var memberDeclarationType = GetDeclarationType(memberDescriptor, funcValueType, typeKind);
279279

280280
var asTypeName = string.Empty;
281-
if (memberDeclarationType != DeclarationType.Procedure && !TypeNames.TryGetValue(funcValueType, out asTypeName))
281+
if (memberDeclarationType != DeclarationType.Procedure)
282282
{
283-
if (funcValueType == VarEnum.VT_PTR)
284-
{
285-
try
286-
{
287-
var asTypeDesc = (TYPEDESC)Marshal.PtrToStructure(memberDescriptor.elemdescFunc.tdesc.lpValue, typeof(TYPEDESC));
288-
asTypeName = GetTypeName(asTypeDesc, info);
289-
}
290-
catch
291-
{
292-
asTypeName = funcValueType.ToString(); //TypeNames[VarEnum.VT_VARIANT];
293-
}
294-
}
295-
else
296-
{
297-
asTypeName = funcValueType.ToString(); //TypeNames[VarEnum.VT_VARIANT];
298-
}
283+
asTypeName = GetTypeName(memberDescriptor.elemdescFunc.tdesc, info);
299284
}
300285
var attributes = new Attributes();
301286
if (memberName == "_NewEnum" && ((FUNCFLAGS)memberDescriptor.wFuncFlags).HasFlag(FUNCFLAGS.FUNCFLAG_FNONBROWSABLE))
@@ -305,7 +290,6 @@ private Declaration CreateMemberDeclaration(out FUNCDESC memberDescriptor, TYPEK
305290
else if (memberDescriptor.memid == 0)
306291
{
307292
attributes.AddDefaultMemberAttribute(memberName);
308-
//Debug.WriteLine("Default member found: {0}.{1} ({2} / {3})", moduleDeclaration.IdentifierName, memberName, memberDeclarationType, (VarEnum)memberDescriptor.elemdescFunc.tdesc.vt);
309293
}
310294
else if (((FUNCFLAGS)memberDescriptor.wFuncFlags).HasFlag(FUNCFLAGS.FUNCFLAG_FHIDDEN))
311295
{
@@ -426,54 +410,36 @@ private Declaration CreateFieldDeclaration(ITypeInfo info, int fieldIndex, Decla
426410
info.GetNames(varDesc.memid, names, 255, out namesArrayLength);
427411

428412
var fieldName = names[0];
429-
var fieldValueType = (VarEnum)varDesc.elemdescVar.tdesc.vt;
430413
var memberType = GetDeclarationType(varDesc, typeDeclarationType);
431414

432-
string asTypeName;
433-
if (!TypeNames.TryGetValue(fieldValueType, out asTypeName))
434-
{
435-
asTypeName = TypeNames[VarEnum.VT_VARIANT];
436-
}
415+
var asTypeName = GetTypeName(varDesc.elemdescVar.tdesc, info);
416+
437417
return new Declaration(new QualifiedMemberName(typeQualifiedModuleName, fieldName),
438418
moduleDeclaration, moduleDeclaration, asTypeName, null, false, false, Accessibility.Global, memberType, null,
439419
Selection.Home, false, null);
440420
}
441421

442-
private static ParameterDeclaration CreateParameterDeclaration(IReadOnlyList<string> memberNames, int paramIndex,
443-
FUNCDESC memberDescriptor, QualifiedModuleName typeQualifiedModuleName, Declaration memberDeclaration)
422+
private ParameterDeclaration CreateParameterDeclaration(IReadOnlyList<string> memberNames, int paramIndex,
423+
FUNCDESC memberDescriptor, QualifiedModuleName typeQualifiedModuleName, Declaration memberDeclaration, ITypeInfo info)
444424
{
445425
var paramName = memberNames[paramIndex + 1];
446426

447427
var paramPointer = new IntPtr(memberDescriptor.lprgelemdescParam.ToInt64() + Marshal.SizeOf(typeof(ELEMDESC)) * paramIndex);
448428
var elementDesc = (ELEMDESC)Marshal.PtrToStructure(paramPointer, typeof(ELEMDESC));
449429
var isOptional = elementDesc.desc.paramdesc.wParamFlags.HasFlag(PARAMFLAG.PARAMFLAG_FOPT);
450-
var asParamTypeName = string.Empty;
451430

452-
var isByRef = false;
431+
var isByRef = elementDesc.desc.paramdesc.wParamFlags.HasFlag(PARAMFLAG.PARAMFLAG_FOUT);
453432
var isArray = false;
454433
var paramDesc = elementDesc.tdesc;
455434
var valueType = (VarEnum)paramDesc.vt;
456-
if (valueType == VarEnum.VT_PTR || valueType == VarEnum.VT_BYREF)
457-
{
458-
//var paramTypeDesc = (TYPEDESC) Marshal.PtrToStructure(paramDesc.lpValue, typeof (TYPEDESC));
459-
isByRef = true;
460-
var paramValueType = (VarEnum)paramDesc.vt;
461-
if (!TypeNames.TryGetValue(paramValueType, out asParamTypeName))
462-
{
463-
asParamTypeName = TypeNames[VarEnum.VT_VARIANT];
464-
}
465-
//var href = paramDesc.lpValue.ToInt32();
466-
//ITypeInfo refTypeInfo;
467-
//info.GetRefTypeInfo(href, out refTypeInfo);
468-
469-
// todo: get type info?
470-
}
471435
if (valueType == VarEnum.VT_CARRAY || valueType == VarEnum.VT_ARRAY || valueType == VarEnum.VT_SAFEARRAY)
472436
{
473437
// todo: tell ParamArray arrays from normal arrays
474438
isArray = true;
475439
}
476440

441+
var asParamTypeName = GetTypeName(paramDesc, info);
442+
477443
return new ParameterDeclaration(new QualifiedMemberName(typeQualifiedModuleName, paramName), memberDeclaration, asParamTypeName, null, null, isOptional, isByRef, isArray);
478444
}
479445

0 commit comments

Comments
 (0)