/// <summary> /// Constructs the implementations for all normal methods. /// </summary> /// <param name="pipeline">The implementation pipeline that consumes the methods.</param> /// <param name="classType">The base class of the type to generate methods for.</param> /// <param name="interfaceTypes">The interfaces where the methods originate.</param> private void ConstructMethods ( [NotNull] ImplementationPipeline pipeline, [NotNull] Type classType, [NotNull] params Type[] interfaceTypes ) { var symbolTransformer = SymbolTransformer.Default; var methods = new List <PipelineWorkUnit <IntrospectiveMethodInfo> >(); foreach (var interfaceType in interfaceTypes) { foreach (var method in interfaceType.GetIntrospectiveMethods(true)) { var targetMethod = method; // Skip any property accessor methods if (method.IsSpecialName && (method.Name.StartsWith("get_") || method.Name.StartsWith("set_"))) { continue; } // Skip methods with a managed implementation in the base class var baseClassMethod = classType.GetIntrospectiveMethod ( method.Name, method.ParameterTypes.ToArray() ); if (!(baseClassMethod is null)) { if (!baseClassMethod.IsAbstract) { continue; } targetMethod = baseClassMethod; } var definition = pipeline.GenerateDefinitionFromSignature(targetMethod); methods.Add ( new PipelineWorkUnit <IntrospectiveMethodInfo> ( definition, symbolTransformer.GetTransformedSymbol(interfaceType, definition), Options ) ); } } pipeline.ConsumeMethodDefinitions(methods); }
/// <summary> /// Constructs the implementations for all normal methods. /// </summary> /// <param name="pipeline">The implementation pipeline that consumes the methods.</param> /// <param name="classType">The base class of the type to generate methods for.</param> /// <param name="interfaceTypes">The interfaces where the methods originate.</param> private void ConstructMethods ( [NotNull] ImplementationPipeline pipeline, [NotNull] Type classType, [NotNull, ItemNotNull] params Type[] interfaceTypes ) { var constructedMethods = new List <IntrospectiveMethodInfo>(); var symbolTransformer = SymbolTransformer.Default; var methods = new List <PipelineWorkUnit <IntrospectiveMethodInfo> >(); foreach (var interfaceType in interfaceTypes) { foreach (var method in interfaceType.GetIntrospectiveMethods(true)) { var targetMethod = method; // Skip any property accessor methods if (method.IsSpecialName && (method.Name.StartsWith("get_") || method.Name.StartsWith("set_"))) { continue; } // Skip methods that were already constructed - happens with inherited interfaces and multiple // identical definitions var existingMethod = constructedMethods.FirstOrDefault(m => m.HasSameSignatureAs(method)); if (!(existingMethod is null)) { if (existingMethod.HasSameNativeEntrypointAs(targetMethod)) { pipeline.TargetType.DefineMethodOverride ( existingMethod.GetWrappedMember(), targetMethod.GetWrappedMember() ); continue; } } // Skip methods with a managed implementation in the base class var baseClassMethod = classType.GetIntrospectiveMethod ( method.Name, method.ParameterTypes.ToArray() ); if (!(baseClassMethod is null)) { if (!baseClassMethod.IsAbstract) { continue; } } // If we have an existing method at this point, this new method must be created as an explicit // interface implementation. Therefore, we override the method name. IntrospectiveMethodInfo definition; if (!(existingMethod is null)) { definition = pipeline.GenerateDefinitionFromSignature ( targetMethod, baseClassMethod, $"{interfaceType.Name}.{targetMethod.Name}" ); }