private static TypeDefinitionTreatment GenerateRedirectionInformation(TypeDefinition type, out Collection<MethodDefinition> redirectedMethods, out Collection<KeyValuePair<InterfaceImplementation, InterfaceImplementation>> redirectedInterfaces)
{
bool implementsProjectedInterface = false;
redirectedMethods = null;
redirectedInterfaces = null;
foreach (var implementedInterface in type.Interfaces) {
if (IsRedirectedType (implementedInterface.InterfaceType)) {
implementsProjectedInterface = true;
break;
}
}
if (!implementsProjectedInterface)
return TypeDefinitionTreatment.NormalType;
var allImplementedInterfaces = new HashSet<TypeReference> (new TypeReferenceEqualityComparer ());
redirectedMethods = new Collection<MethodDefinition> ();
redirectedInterfaces = new Collection<KeyValuePair<InterfaceImplementation, InterfaceImplementation>> ();
foreach (var @interface in type.Interfaces) {
var interfaceType = @interface.InterfaceType;
if (IsRedirectedType (interfaceType)) {
allImplementedInterfaces.Add (interfaceType);
CollectImplementedInterfaces (interfaceType, allImplementedInterfaces);
}
}
foreach (var implementedInterface in type.Interfaces) {
var interfaceType = implementedInterface.InterfaceType;
if (IsRedirectedType (implementedInterface.InterfaceType)) {
var etype = interfaceType.GetElementType ();
var unprojectedType = new TypeReference (etype.Namespace, etype.Name, etype.Module, etype.Scope) {
DeclaringType = etype.DeclaringType,
projection = etype.projection
};
RemoveProjection (unprojectedType);
var genericInstanceType = interfaceType as GenericInstanceType;
if (genericInstanceType != null) {
var genericUnprojectedType = new GenericInstanceType (unprojectedType);
foreach (var genericArgument in genericInstanceType.GenericArguments)
genericUnprojectedType.GenericArguments.Add (genericArgument);
unprojectedType = genericUnprojectedType;
}
var unprojectedInterface = new InterfaceImplementation (unprojectedType);
redirectedInterfaces.Add (new KeyValuePair<InterfaceImplementation, InterfaceImplementation> (implementedInterface, unprojectedInterface));
}
}
// Interfaces don't inherit methods of the interfaces they implement
if (!type.IsInterface) {
foreach (var implementedInterface in allImplementedInterfaces) {
RedirectInterfaceMethods (implementedInterface, redirectedMethods);
}
}
return TypeDefinitionTreatment.RedirectImplementedMethods;
}