/// <summary> /// </summary> /// <param name="allTypes"> /// </param> /// <param name="genericMethodSpecializations"> /// </param> private static void DiscoverAllGenericVirtualMethods( IEnumerable <IType> allTypes, ReadingTypesContext readingTypesContext) { var genericMethodSpecializations = readingTypesContext.GenericMethodSpecializations; // find all override of generic methods var flags = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance; var overrideSpecializedMethods = new List <IMethod>(); foreach ( var overrideGenericMethod in allTypes.SelectMany( t => t.GetMethods(flags).Where(m => m.IsOverride && m.IsGenericMethodDefinition))) { var method = overrideGenericMethod; var methodDefinition = overrideGenericMethod; overrideSpecializedMethods.AddRange( from methodSpecialization in genericMethodSpecializations.Where(m => m.IsVirtual || m.IsOverride || m.IsAbstract) where method.DeclaringType.IsDerivedFrom(methodSpecialization.DeclaringType) && method.IsMatchingOverride(methodSpecialization) select methodDefinition.ToSpecialization( MetadataGenericContext.CreateCustomMap(null, methodSpecialization, methodDefinition))); } // append to discovered foreach (var overrideSpecializedMethod in overrideSpecializedMethods) { genericMethodSpecializations.Add(overrideSpecializedMethod); // rediscover generic methods again overrideSpecializedMethod.DiscoverRequiredTypesAndMethodsInMethodBody( readingTypesContext.GenericTypeSpecializations, readingTypesContext.GenericMethodSpecializations, null, readingTypesContext.AdditionalTypesToProcess, new Queue <IMethod>()); } }
private static void DiscoverAllGenericMethodsOfInterfacesForMethod( IEnumerable <IType> allTypes, IGrouping <IType, IMethod> specializedTypeMethods, ReadingTypesContext readingTypesContext) { var types = allTypes.Where(t => t.GetAllInterfaces().Contains(specializedTypeMethods.Key)).ToList(); foreach (var interfaceMethodSpecialization in specializedTypeMethods) { var flags = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance; foreach (var classMethodDefinition in types.SelectMany( t => t.GetMethods(flags) .Where(m => m.IsGenericMethodDefinition && m.IsMatchingOverride(interfaceMethodSpecialization)))) { // find interface var @interfaceDefinition = classMethodDefinition.DeclaringType.GetInterfaces() .First(i => i.TypeEquals(interfaceMethodSpecialization.DeclaringType)); var @interfaceMethodDefinition = @interfaceDefinition.GetMethods(flags) .First(m => m.IsGenericMethodDefinition && m.IsMatchingOverride(interfaceMethodSpecialization)); var classMethodSpecialization = classMethodDefinition.ToSpecialization( MetadataGenericContext.CreateCustomMap(@interfaceMethodDefinition, interfaceMethodSpecialization, classMethodDefinition)); readingTypesContext.GenericMethodSpecializations.Add(classMethodSpecialization); // rediscover generic methods again classMethodSpecialization.DiscoverRequiredTypesAndMethodsInMethodBody( readingTypesContext.GenericTypeSpecializations, readingTypesContext.GenericMethodSpecializations, null, readingTypesContext.AdditionalTypesToProcess, new Queue <IMethod>()); } } }