/// <summary> /// Transform open generic types to closed instantiation using context information. /// As an example, if B{T} inherits from A{T}, running it with B{C} as context and A{B.T} as type, ti will return A{C}. /// </summary> public static TypeReference Process(TypeReference context, TypeReference type) { if (type == null) { return(null); } var genericInstanceTypeContext = context as GenericInstanceType; if (genericInstanceTypeContext == null) { return(type); } // Build dictionary that will map generic type to their real implementation type var resolvedType = genericInstanceTypeContext.ElementType; var genericTypeMapping = new Dictionary <TypeReference, TypeReference>(); for (int i = 0; i < resolvedType.GenericParameters.Count; ++i) { var genericParameter = genericInstanceTypeContext.ElementType.GenericParameters[i]; genericTypeMapping.Add(genericParameter, genericInstanceTypeContext.GenericArguments[i]); } var visitor = new ResolveGenericsVisitor(genericTypeMapping); var result = visitor.VisitDynamic(type); // Make sure type is closed now if (result.ContainsGenericParameter()) { throw new InvalidOperationException("Unsupported generic resolution."); } return(result); }
public static void MethodSignatureMangledName(this MethodReference method, StringBuilder builder) { builder.Append("("); if (method.HasParameters) { var parameters = method.Parameters; for (int i = 0; i < parameters.Count; i++) { ParameterDefinition parameter = parameters[i]; if (i > 0) { builder.Append(","); } if (parameter.ParameterType.IsSentinel) { builder.Append("...,"); } // We are replacing GenericInstance of type !0 with their real definitions (T, U, etc...) var parameterType = ResolveGenericsVisitor.Process(method, parameter.ParameterType, true); builder.Append(parameterType.MangledName()); } } builder.Append(")"); }
public static TypeReference Process(MethodReference context, TypeReference type, bool resolveOnlyReferences = false) { if (type == null) { return(null); } if (context == null) { return(type); } // Visit recursively and replace generic parameters with generic arguments from context var genericInstanceTypeContext = context.DeclaringType as GenericInstanceType; var genericInstanceMethodContext = context as GenericInstanceMethod; if (genericInstanceMethodContext == null && genericInstanceTypeContext == null) { return(type); } var visitor = new ResolveGenericsVisitor(context, resolveOnlyReferences); var result = visitor.VisitDynamic(type); return(result); }
/// <summary> /// Transform open generic types to closed instantiation using context information. /// As an example, if B{T} inherits from A{T}, running it with B{C} as context and A{B.T} as type, ti will return A{C}. /// </summary> public static TypeReference Process(TypeReference context, TypeReference type) { if (type == null) { return(null); } var genericInstanceTypeContext = context as GenericInstanceType; if (genericInstanceTypeContext == null) { return(type); } // Visit recursively and replace generic parameters with generic arguments from context var visitor = new ResolveGenericsVisitor(context); var result = visitor.VisitDynamic(type); // Make sure type is closed now if (result.ContainsGenericParameter) { throw new InvalidOperationException("Unsupported generic resolution."); } return(result); }
public static TypeReference Process(MethodReference context, TypeReference type) { if (type == null) { return(null); } if (context == null) { return(type); } var genericInstanceTypeContext = context.DeclaringType as GenericInstanceType; var genericInstanceMethodContext = context as GenericInstanceMethod; if (genericInstanceMethodContext == null && genericInstanceTypeContext == null) { return(type); } // Build dictionary that will map generic type to their real implementation type var genericTypeMapping = new Dictionary <TypeReference, TypeReference>(TypeReferenceComparer.Default); if (genericInstanceTypeContext != null) { var resolvedType = genericInstanceTypeContext.ElementType; for (int i = 0; i < resolvedType.GenericParameters.Count; ++i) { var genericParameter = genericInstanceTypeContext.ElementType.GenericParameters[i]; genericTypeMapping.Add(genericParameter, genericInstanceTypeContext.GenericArguments[i]); } } if (genericInstanceMethodContext != null) { var elementMethod = genericInstanceMethodContext.ElementMethod; var resolvedMethod = genericInstanceMethodContext.Resolve(); for (int i = 0; i < elementMethod.GenericParameters.Count; ++i) { var genericParameter = elementMethod.GenericParameters[i]; genericTypeMapping.Add(genericParameter, genericInstanceMethodContext.GenericArguments[i]); var genericParameter2 = resolvedMethod.GenericParameters[i]; if (genericParameter != genericParameter2) { genericTypeMapping.Add(genericParameter2, genericInstanceMethodContext.GenericArguments[i]); } } } var visitor = new ResolveGenericsVisitor(genericTypeMapping); var result = visitor.VisitDynamic(type); // Make sure type is closed now //if (result.ContainsGenericParameter()) // throw new InvalidOperationException("Unsupported generic resolution."); return(result); }
static bool MethodMatch(MethodReference candidate, MethodReference method) { var candidateResolved = candidate.Resolve(); // Check overrides if (candidateResolved.HasOverrides) { foreach (var @override in candidateResolved.Overrides) { var resolvedOverride = ResolveGenericsVisitor.Process(candidate, @override); if (resolvedOverride.FullName == method.FullName) { return(true); } } } if (!candidateResolved.IsVirtual) { return(false); } if (candidate.Name != method.Name) { return(false); } if (!TypeMatch(ResolveGenericsVisitor.Process(candidate, candidate.ReturnType), ResolveGenericsVisitor.Process(method, method.ReturnType))) { return(false); } if (candidate.Parameters.Count != method.Parameters.Count) { return(false); } for (int i = 0; i < candidate.Parameters.Count; i++) { if (!TypeMatch(ResolveGenericsVisitor.Process(candidate, candidate.Parameters[i].ParameterType), ResolveGenericsVisitor.Process(method, method.Parameters[i].ParameterType))) { return(false); } } return(true); }
public static string MangledName(this MethodReference method) { var builder = new StringBuilder(); if (method.DeclaringType != null) { builder.Append(method.DeclaringType.MangledName()).Append("::"); } builder.Append(method.Name); // Append generic arguments var genericInstanceMethod = method as GenericInstanceMethod; if (genericInstanceMethod != null) { foreach (var genericArgument in genericInstanceMethod.GenericArguments) { builder.Append('_'); builder.Append(genericArgument.MangledName()); } } if (method.Name == "op_Implicit" || method.Name == "op_Explicit") { // If it's op_Implicit or op_Explicit, we might want to use return type instead of first parameter (depending on which way the conversion is) builder.Append("_"); if (MemberEqualityComparer.Default.Equals(method.Parameters[0].ParameterType, method.DeclaringType)) { builder.Append("ret_"); builder.Append(method.ReturnType.MangledName()); } else { builder.Append(ResolveGenericsVisitor.Process(method, method.Parameters[0].ParameterType).MangledName()); } } else { // Method signature MethodSignatureMangledName(method, builder); } return(builder.ToString()); }
public static TypeReference Process(MethodReference context, TypeReference type, bool resolveOnlyReferences = false) { if (type == null) return null; if (context == null) return type; // Visit recursively and replace generic parameters with generic arguments from context var genericInstanceTypeContext = context.DeclaringType as GenericInstanceType; var genericInstanceMethodContext = context as GenericInstanceMethod; if (genericInstanceMethodContext == null && genericInstanceTypeContext == null) return type; var visitor = new ResolveGenericsVisitor(context, resolveOnlyReferences); var result = visitor.VisitDynamic(type); return result; }
/// <summary> /// Transform open generic types to closed instantiation using context information. /// As an example, if B{T} inherits from A{T}, running it with B{C} as context and A{B.T} as type, ti will return A{C}. /// </summary> public static TypeReference Process(TypeReference context, TypeReference type) { if (type == null) return null; var genericInstanceTypeContext = context as GenericInstanceType; if (genericInstanceTypeContext == null) return type; // Visit recursively and replace generic parameters with generic arguments from context var visitor = new ResolveGenericsVisitor(context); var result = visitor.VisitDynamic(type); // Make sure type is closed now if (result.ContainsGenericParameter) throw new InvalidOperationException("Unsupported generic resolution."); return result; }