2 using System
.Collections
.Generic
;
6 namespace Mono
.ApiTools
{
10 public TypeHelper (bool ignoreResolutionErrors
, bool ignoreInheritedInterfaces
)
12 IgnoreResolutionErrors
= ignoreResolutionErrors
;
13 IgnoreInheritedInterfaces
= ignoreInheritedInterfaces
;
16 public bool IgnoreResolutionErrors { get; }
18 public bool IgnoreInheritedInterfaces { get; }
20 public AssemblyResolver Resolver { get; }
= new AssemblyResolver();
22 internal bool TryResolve (CustomAttribute attribute
)
24 if (attribute
== null)
25 throw new ArgumentNullException (nameof (attribute
));
28 var has
= attribute
.HasProperties
;
30 } catch (AssemblyResolutionException
) when (IgnoreResolutionErrors
) {
35 internal bool IsPublic (TypeReference typeref
)
38 throw new ArgumentNullException ("typeref");
41 var td
= typeref
.Resolve ();
45 return td
.IsPublic
|| (td
.IsNestedPublic
&& IsPublic (td
.DeclaringType
));
46 } catch (AssemblyResolutionException
) when (IgnoreResolutionErrors
) {
51 internal bool IsDelegate (TypeReference typeref
)
53 return IsDerivedFrom (typeref
, "System.MulticastDelegate");
56 internal bool IsDerivedFrom (TypeReference type
, string derivedFrom
)
59 foreach (var def
in WalkHierarchy (type
)) {
65 if (def
.FullName
== derivedFrom
)
72 internal IEnumerable
<TypeDefinition
> WalkHierarchy (TypeReference type
)
74 for (var def
= type
.Resolve (); def
!= null; def
= GetBaseType (def
))
78 internal IEnumerable
<TypeReference
> GetInterfaces (TypeReference type
)
80 var ifaces
= new Dictionary
<string, TypeReference
> ();
82 foreach (var def
in WalkHierarchy (type
)) {
83 foreach (var iface
in def
.Interfaces
)
84 ifaces
[iface
.InterfaceType
.FullName
] = iface
.InterfaceType
;
85 if (IgnoreInheritedInterfaces
)
92 internal TypeDefinition
GetBaseType (TypeDefinition child
)
94 if (child
.BaseType
== null)
98 return child
.BaseType
.Resolve ();
99 } catch (AssemblyResolutionException
) when (IgnoreResolutionErrors
) {
104 internal MethodDefinition
GetMethod (MethodReference method
)
107 throw new ArgumentNullException (nameof (method
));
110 return method
.Resolve ();
111 } catch (AssemblyResolutionException
) when (IgnoreResolutionErrors
) {
116 internal bool IsPublic (CustomAttribute att
)
118 return IsPublic (att
.AttributeType
);
121 internal string GetFullName (CustomAttribute att
)
123 return att
.AttributeType
.FullName
;
126 internal TypeDefinition
GetTypeDefinition (CustomAttribute att
)
128 return att
.AttributeType
.Resolve ();
131 bool IsOverride (MethodDefinition method
)
133 return method
.IsVirtual
&& !method
.IsNewSlot
;
136 public MethodDefinition
GetBaseMethodInTypeHierarchy (MethodDefinition method
)
138 if (!IsOverride (method
))
141 var @base = GetBaseType (method
.DeclaringType
);
142 while (@base != null) {
143 MethodDefinition base_method
= TryMatchMethod (@base.Resolve (), method
);
144 if (base_method
!= null)
145 return GetBaseMethodInTypeHierarchy (base_method
) ?? base_method
;
147 @base = GetBaseType (@base);
153 MethodDefinition
TryMatchMethod (TypeDefinition type
, MethodDefinition method
)
155 if (!type
.HasMethods
)
158 foreach (MethodDefinition candidate
in type
.Methods
)
159 if (MethodMatch (candidate
, method
))
165 bool MethodMatch (MethodDefinition candidate
, MethodDefinition method
)
167 if (!candidate
.IsVirtual
)
170 if (candidate
.Name
!= method
.Name
)
173 if (!TypeMatch (candidate
.ReturnType
, method
.ReturnType
))
176 if (candidate
.Parameters
.Count
!= method
.Parameters
.Count
)
179 for (int i
= 0; i
< candidate
.Parameters
.Count
; i
++)
180 if (!TypeMatch (candidate
.Parameters
[i
].ParameterType
, method
.Parameters
[i
].ParameterType
))
186 public bool TypeMatch (IModifierType a
, IModifierType b
)
188 if (!TypeMatch (a
.ModifierType
, b
.ModifierType
))
191 return TypeMatch (a
.ElementType
, b
.ElementType
);
194 public bool TypeMatch (TypeSpecification a
, TypeSpecification b
)
196 if (a
is GenericInstanceType
)
197 return TypeMatch ((GenericInstanceType
) a
, (GenericInstanceType
) b
);
199 if (a
is IModifierType
)
200 return TypeMatch ((IModifierType
) a
, (IModifierType
) b
);
202 return TypeMatch (a
.ElementType
, b
.ElementType
);
205 public bool TypeMatch (GenericInstanceType a
, GenericInstanceType b
)
207 if (!TypeMatch (a
.ElementType
, b
.ElementType
))
210 if (a
.GenericArguments
.Count
!= b
.GenericArguments
.Count
)
213 if (a
.GenericArguments
.Count
== 0)
216 for (int i
= 0; i
< a
.GenericArguments
.Count
; i
++)
217 if (!TypeMatch (a
.GenericArguments
[i
], b
.GenericArguments
[i
]))
223 public bool TypeMatch (TypeReference a
, TypeReference b
)
225 if (a
is GenericParameter
)
228 if (a
is TypeSpecification
|| b
is TypeSpecification
) {
229 if (a
.GetType () != b
.GetType ())
232 return TypeMatch ((TypeSpecification
) a
, (TypeSpecification
) b
);
235 return a
.FullName
== b
.FullName
;