static MethodReference CreateGenericInstanceCandidate(Inflater.GenericContext context, TypeDefinition candidateType, MethodDefinition interfaceMethod) { var methodReference = new MethodReference(interfaceMethod.Name, interfaceMethod.ReturnType, candidateType) { HasThis = interfaceMethod.HasThis }; foreach (var genericMethodParameter in interfaceMethod.GenericParameters) { methodReference.GenericParameters.Add(new GenericParameter(genericMethodParameter.Name, methodReference)); } if (interfaceMethod.ReturnType.IsGenericParameter || interfaceMethod.ReturnType.IsGenericInstance) { methodReference.ReturnType = Inflater.InflateType(context, interfaceMethod.ReturnType); } foreach (var p in interfaceMethod.Parameters) { var parameterType = p.ParameterType; if (parameterType.IsGenericParameter || parameterType.IsGenericInstance) { parameterType = Inflater.InflateType(context, parameterType); } methodReference.Parameters.Add(new ParameterDefinition(p.Name, p.Attributes, parameterType)); } return(methodReference); }
static MethodDefinition GetBaseInflatedInterfaceMethodInTypeHierarchy(Inflater.GenericContext context, TypeDefinition type, MethodDefinition interfaceMethod) { TypeReference @base = type.GetInflatedBaseType(); while (@base != null) { var candidate = CreateGenericInstanceCandidate(context, @base.Resolve(), interfaceMethod); MethodDefinition base_method = TryMatchMethod(@base, candidate); if (base_method != null) { return(base_method); } @base = @base.GetInflatedBaseType(); } return(null); }
void MapInterfaceMethodsInTypeHierarchy(TypeDefinition type) { if (!type.HasInterfaces) { return; } foreach (var @interface in type.Interfaces) { var interfaceType = @interface.InterfaceType; var iface = interfaceType.Resolve(); if (iface == null || !iface.HasMethods) { continue; } foreach (MethodDefinition interfaceMethod in iface.Methods) { if (TryMatchMethod(type, interfaceMethod) != null) { continue; } var @base = GetBaseMethodInTypeHierarchy(type, interfaceMethod); if (@base != null) { AnnotateMethods(interfaceMethod, @base, @interface); } if (interfaceType is GenericInstanceType genericInterfaceInstance) { var genericContext = new Inflater.GenericContext(genericInterfaceInstance, null); var baseInflated = GetBaseInflatedInterfaceMethodInTypeHierarchy(genericContext, type, interfaceMethod); if (baseInflated != null) { Annotations.AddOverride(interfaceMethod, baseInflated, @interface); } } } } }