@@ -55,6 +55,8 @@ public ReferencedDeclarationsCollector(RubberduckParserState state)
55
55
_state = state ;
56
56
}
57
57
58
+ private static readonly HashSet < string > IgnoredInterfaceMembers = new HashSet < string > { "QueryInterface" , "AddRef" , "Release" , "GetTypeInfoCount" , "GetTypeInfo" , "GetIDsOfNames" , "Invoke" } ;
59
+
58
60
private static readonly IDictionary < VarEnum , string > TypeNames = new Dictionary < VarEnum , string >
59
61
{
60
62
{ VarEnum . VT_DISPATCH , "DISPATCH" } ,
@@ -87,7 +89,7 @@ public ReferencedDeclarationsCollector(RubberduckParserState state)
87
89
88
90
private readonly Dictionary < Guid , ComInformation > _comInformation = new Dictionary < Guid , ComInformation > ( ) ;
89
91
90
- private string GetTypeName ( TYPEDESC desc , ITypeInfo info )
92
+ private ComParameter GetParameterInfo ( TYPEDESC desc , ITypeInfo info )
91
93
{
92
94
var vt = ( VarEnum ) desc . vt ;
93
95
TYPEDESC tdesc ;
@@ -96,7 +98,9 @@ private string GetTypeName(TYPEDESC desc, ITypeInfo info)
96
98
{
97
99
case VarEnum . VT_PTR :
98
100
tdesc = ( TYPEDESC ) Marshal . PtrToStructure ( desc . lpValue , typeof ( TYPEDESC ) ) ;
99
- return GetTypeName ( tdesc , info ) ;
101
+ var pointer = GetParameterInfo ( tdesc , info ) ;
102
+ pointer . IsByRef = true ;
103
+ return pointer ;
100
104
case VarEnum . VT_USERDEFINED :
101
105
int href ;
102
106
unchecked
@@ -107,24 +111,29 @@ private string GetTypeName(TYPEDESC desc, ITypeInfo info)
107
111
{
108
112
ITypeInfo refTypeInfo ;
109
113
info . GetRefTypeInfo ( href , out refTypeInfo ) ;
110
- return GetTypeName ( refTypeInfo ) ;
114
+ return new ComParameter ( GetTypeName ( refTypeInfo ) , false ) ;
111
115
}
112
116
catch ( Exception )
113
117
{
114
- return "Object" ;
118
+ return new ComParameter ( "Object" , false ) ;
115
119
}
120
+ case VarEnum . VT_SAFEARRAY :
116
121
case VarEnum . VT_CARRAY :
122
+ case VarEnum . VT_ARRAY :
117
123
tdesc = ( TYPEDESC ) Marshal . PtrToStructure ( desc . lpValue , typeof ( TYPEDESC ) ) ;
118
- return GetTypeName ( tdesc , info ) + "()" ;
124
+ var array = GetParameterInfo ( tdesc , info ) ;
125
+ array . IsArray = true ;
126
+ array . Name += "()" ;
127
+ return array ;
119
128
default :
120
129
string result ;
121
130
if ( TypeNames . TryGetValue ( vt , out result ) )
122
131
{
123
- return result ;
132
+ return new ComParameter ( result , false ) ;
124
133
}
125
134
break ;
126
135
}
127
- return "Object" ;
136
+ return new ComParameter ( "Object" , false ) ;
128
137
}
129
138
130
139
private string GetTypeName ( ITypeInfo info )
@@ -191,10 +200,9 @@ public List<Declaration> GetDeclarationsForReference(Reference reference)
191
200
192
201
IntPtr typeAttributesPointer ;
193
202
info . GetTypeAttr ( out typeAttributesPointer ) ;
194
-
195
203
var typeAttributes = ( TYPEATTR ) Marshal . PtrToStructure ( typeAttributesPointer , typeof ( TYPEATTR ) ) ;
196
-
197
204
var attributes = new Attributes ( ) ;
205
+
198
206
if ( typeAttributes . wTypeFlags . HasFlag ( TYPEFLAGS . TYPEFLAG_FPREDECLID ) )
199
207
{
200
208
attributes . AddPredeclaredIdTypeAttribute ( ) ;
@@ -294,20 +302,25 @@ memberDeclaration is ICanBeDefaultMember &&
294
302
}
295
303
output . Add ( memberDeclaration ) ;
296
304
297
- var parameterCount = memberDescriptor . cParams -
298
- ( memberDescriptor . invkind . HasFlag ( INVOKEKIND . INVOKE_PROPERTYGET ) ? 0 : 1 ) ;
305
+ var parameterCount = memberDescriptor . cParams - ( memberDescriptor . invkind . HasFlag ( INVOKEKIND . INVOKE_PROPERTYGET ) ? 0 : 1 ) ;
306
+ var parameters = new List < ParameterDeclaration > ( ) ;
299
307
for ( var paramIndex = 0 ; paramIndex < parameterCount ; paramIndex ++ )
300
308
{
301
309
var parameter = CreateParameterDeclaration ( memberNames , paramIndex , memberDescriptor ,
302
310
member . TypeQualifiedModuleName , memberDeclaration , member . TypeInfo ) ;
303
311
var declaration = memberDeclaration as IDeclarationWithParameter ;
304
312
if ( declaration != null )
305
313
{
314
+ parameters . Add ( parameter ) ;
306
315
declaration . AddParameter ( parameter ) ;
307
316
}
308
317
output . Add ( parameter ) ;
309
318
}
310
319
member . TypeInfo . ReleaseFuncDesc ( memberDescriptorPointer ) ;
320
+ if ( parameters . Any ( ) && memberDescriptor . cParamsOpt == - 1 )
321
+ {
322
+ parameters . Last ( ) . IsParamArray = true ;
323
+ }
311
324
}
312
325
313
326
for ( var fieldIndex = 0 ; fieldIndex < member . TypeAttributes . cVars ; fieldIndex ++ )
@@ -337,10 +350,10 @@ private Declaration CreateMemberDeclaration(FUNCDESC memberDescriptor, TYPEKIND
337
350
var funcValueType = ( VarEnum ) memberDescriptor . elemdescFunc . tdesc . vt ;
338
351
var memberDeclarationType = GetDeclarationType ( memberName , memberDescriptor , funcValueType , typeKind , parentImplFlags ) ;
339
352
340
- var asTypeName = string . Empty ;
353
+ var asTypeName = new ComParameter ( string . Empty , false ) ;
341
354
if ( memberDeclarationType != DeclarationType . Procedure )
342
355
{
343
- asTypeName = GetTypeName ( memberDescriptor . elemdescFunc . tdesc , info ) ;
356
+ asTypeName = GetParameterInfo ( memberDescriptor . elemdescFunc . tdesc , info ) ;
344
357
}
345
358
var attributes = new Attributes ( ) ;
346
359
if ( memberName == "_NewEnum" && ( ( FUNCFLAGS ) memberDescriptor . wFuncFlags ) . HasFlag ( FUNCFLAGS . FUNCFLAG_FNONBROWSABLE ) )
@@ -363,7 +376,7 @@ private Declaration CreateMemberDeclaration(FUNCDESC memberDescriptor, TYPEKIND
363
376
new QualifiedMemberName ( typeQualifiedModuleName , memberName ) ,
364
377
moduleDeclaration ,
365
378
moduleDeclaration ,
366
- asTypeName ,
379
+ asTypeName . Name ,
367
380
Accessibility . Global ,
368
381
null ,
369
382
Selection . Home ,
@@ -375,14 +388,13 @@ private Declaration CreateMemberDeclaration(FUNCDESC memberDescriptor, TYPEKIND
375
388
new QualifiedMemberName ( typeQualifiedModuleName , memberName ) ,
376
389
moduleDeclaration ,
377
390
moduleDeclaration ,
378
- asTypeName ,
391
+ asTypeName . Name ,
379
392
null ,
380
393
null ,
381
394
Accessibility . Global ,
382
395
null ,
383
396
Selection . Home ,
384
- // TODO: how to find out if it's an array?
385
- false ,
397
+ asTypeName . IsArray ,
386
398
true ,
387
399
null ,
388
400
attributes ) ;
@@ -391,14 +403,13 @@ private Declaration CreateMemberDeclaration(FUNCDESC memberDescriptor, TYPEKIND
391
403
new QualifiedMemberName ( typeQualifiedModuleName , memberName ) ,
392
404
moduleDeclaration ,
393
405
moduleDeclaration ,
394
- asTypeName ,
406
+ asTypeName . Name ,
395
407
null ,
396
408
null ,
397
409
Accessibility . Global ,
398
410
null ,
399
411
Selection . Home ,
400
- // TODO: how to find out if it's an array?
401
- false ,
412
+ asTypeName . IsArray ,
402
413
true ,
403
414
null ,
404
415
attributes ) ;
@@ -407,7 +418,7 @@ private Declaration CreateMemberDeclaration(FUNCDESC memberDescriptor, TYPEKIND
407
418
new QualifiedMemberName ( typeQualifiedModuleName , memberName ) ,
408
419
moduleDeclaration ,
409
420
moduleDeclaration ,
410
- asTypeName ,
421
+ asTypeName . Name ,
411
422
Accessibility . Global ,
412
423
null ,
413
424
Selection . Home ,
@@ -419,7 +430,7 @@ private Declaration CreateMemberDeclaration(FUNCDESC memberDescriptor, TYPEKIND
419
430
new QualifiedMemberName ( typeQualifiedModuleName , memberName ) ,
420
431
moduleDeclaration ,
421
432
moduleDeclaration ,
422
- asTypeName ,
433
+ asTypeName . Name ,
423
434
Accessibility . Global ,
424
435
null ,
425
436
Selection . Home ,
@@ -431,7 +442,7 @@ private Declaration CreateMemberDeclaration(FUNCDESC memberDescriptor, TYPEKIND
431
442
new QualifiedMemberName ( typeQualifiedModuleName , memberName ) ,
432
443
moduleDeclaration ,
433
444
moduleDeclaration ,
434
- asTypeName ,
445
+ asTypeName . Name ,
435
446
null ,
436
447
false ,
437
448
false ,
@@ -462,11 +473,11 @@ private Declaration CreateFieldDeclaration(ITypeInfo info, int fieldIndex, Decla
462
473
var fieldName = names [ 0 ] ;
463
474
var memberType = GetDeclarationType ( varDesc , typeDeclarationType ) ;
464
475
465
- var asTypeName = GetTypeName ( varDesc . elemdescVar . tdesc , info ) ;
476
+ var asTypeName = GetParameterInfo ( varDesc . elemdescVar . tdesc , info ) ;
466
477
info . ReleaseVarDesc ( ppVarDesc ) ;
467
478
468
479
return new Declaration ( new QualifiedMemberName ( typeQualifiedModuleName , fieldName ) ,
469
- moduleDeclaration , moduleDeclaration , asTypeName , null , false , false , Accessibility . Global , memberType , null ,
480
+ moduleDeclaration , moduleDeclaration , asTypeName . Name , null , false , false , Accessibility . Global , memberType , null ,
470
481
Selection . Home , false , null ) ;
471
482
}
472
483
@@ -478,20 +489,10 @@ private ParameterDeclaration CreateParameterDeclaration(IReadOnlyList<string> me
478
489
var paramPointer = new IntPtr ( memberDescriptor . lprgelemdescParam . ToInt64 ( ) + Marshal . SizeOf ( typeof ( ELEMDESC ) ) * paramIndex ) ;
479
490
var elementDesc = ( ELEMDESC ) Marshal . PtrToStructure ( paramPointer , typeof ( ELEMDESC ) ) ;
480
491
var isOptional = elementDesc . desc . paramdesc . wParamFlags . HasFlag ( PARAMFLAG . PARAMFLAG_FOPT ) ;
481
-
482
- var isByRef = elementDesc . desc . paramdesc . wParamFlags . HasFlag ( PARAMFLAG . PARAMFLAG_FOUT ) ;
483
- var isArray = false ;
484
492
var paramDesc = elementDesc . tdesc ;
485
- var valueType = ( VarEnum ) paramDesc . vt ;
486
- if ( valueType == VarEnum . VT_CARRAY || valueType == VarEnum . VT_ARRAY || valueType == VarEnum . VT_SAFEARRAY )
487
- {
488
- // todo: tell ParamArray arrays from normal arrays
489
- isArray = true ;
490
- }
491
-
492
- var asParamTypeName = GetTypeName ( paramDesc , info ) ;
493
+ var paramInfo = GetParameterInfo ( paramDesc , info ) ;
493
494
494
- return new ParameterDeclaration ( new QualifiedMemberName ( typeQualifiedModuleName , paramName ) , memberDeclaration , asParamTypeName , null , null , isOptional , isByRef , isArray ) ;
495
+ return new ParameterDeclaration ( new QualifiedMemberName ( typeQualifiedModuleName , paramName ) , memberDeclaration , paramInfo . Name , null , null , isOptional , paramInfo . IsByRef , paramInfo . IsArray ) ;
495
496
}
496
497
497
498
private IEnumerable < string > GetImplementedInterfaceNames ( TYPEATTR typeAttr , ITypeInfo info )
@@ -587,7 +588,7 @@ private DeclarationType GetDeclarationType(string memberName, FUNCDESC funcDesc,
587
588
}
588
589
else if ( ( parentImplTypeFlags . HasFlag ( IMPLTYPEFLAGS . IMPLTYPEFLAG_FSOURCE ) ||
589
590
( ( FUNCFLAGS ) funcDesc . wFuncFlags ) . HasFlag ( FUNCFLAGS . FUNCFLAG_FSOURCE ) ) &&
590
- ! new [ ] { "QueryInterface" , "AddRef" , "Release" , "GetTypeInfoCount" , "GetTypeInfo" , "GetIDsOfNames" , "Invoke" } . Contains ( memberName ) ) // quick-and-dirty for beta
591
+ ! IgnoredInterfaceMembers . Contains ( memberName ) ) // quick-and-dirty for beta
591
592
{
592
593
memberType = DeclarationType . Event ;
593
594
}
0 commit comments