public static GenericInstanceMethod InflateMethod(GenericContext context, GenericInstanceMethod genericInstanceMethod) { GenericInstanceType declaringType = genericInstanceMethod.DeclaringType as GenericInstanceType; TypeReference reference = (declaringType == null) ? InflateType(context, genericInstanceMethod.DeclaringType) : InflateType(context, declaringType); return(ConstructGenericMethod(context, reference, genericInstanceMethod.Resolve(), genericInstanceMethod.GenericArguments)); }
public static TypeReference ResolveGenericParameters(this TypeReference type, GenericInstanceMethod?methodInstance, GenericInstanceType?typeInstance) { if (type is GenericParameter genericParameter) { switch (genericParameter.Owner) { case MethodReference ownerMethod: { if (ownerMethod.Resolve() != methodInstance?.Resolve()) { throw new NotSupportedException($"Generic parameter {type} comes from method {ownerMethod} which is different from provided {methodInstance}."); } return(methodInstance.GenericArguments[genericParameter.Position].ResolveGenericParameters(methodInstance, typeInstance)); } case TypeReference ownerType: { if (ownerType.Resolve() != typeInstance?.Resolve()) { throw new NotSupportedException($"Generic parameter {type} comes from type {ownerType} which is different from provided {typeInstance}."); } return(typeInstance.GenericArguments[genericParameter.Position].ResolveGenericParameters(methodInstance, typeInstance)); } default: throw new NotSupportedException($"Unsupported generic parameter owner: {genericParameter.Owner}."); } } if (type is GenericInstanceType generic) { var changed = (GenericInstanceType?)null; for (var i = 0; i < generic.GenericArguments.Count; i++) { var argument = generic.GenericArguments[i]; var resolved = argument.ResolveGenericParameters(methodInstance, typeInstance); if (resolved != argument) { changed = changed ?? Clone(generic); changed.GenericArguments[i] = resolved; } } return(changed ?? type); } if (type is ByReferenceType reference) { var resolved = reference.ElementType.ResolveGenericParameters(methodInstance, typeInstance); if (resolved == reference.ElementType) { return(type); } return(new ByReferenceType(resolved)); } return(type); }
private GenericBindingContext(GenericInstanceMethod method) { var definition = method.Resolve(); for (int i = 0; i < definition.GenericParameters.Count; ++i) { var parameter = definition.GenericParameters[i]; var binding = method.GenericArguments[i]; _methodEntries.Add(new Entry(parameter.FullName, binding)); } }
public static IReadOnlyDictionary<string, TypeReference> GetGenericResolvedTypeNames(this GenericInstanceMethod method) { var genericArgumentNames = method.Resolve().GenericParameters.Select(x => x.FullName).ToArray(); var genericArgumentsOfCurrentType = method.GenericArguments.ToArray(); var result = new Dictionary<string, TypeReference>(); var genericType = method as GenericInstanceMethod; genericArgumentNames = genericType.Resolve().GenericParameters.Select(x => x.FullName).ToArray(); genericArgumentsOfCurrentType = genericType.GenericArguments.ToArray(); for (int i = 0; i < genericArgumentNames.Length; i++) { if (!result.ContainsKey(genericArgumentNames[i])) result.Add(genericArgumentNames[i], genericArgumentsOfCurrentType[i]); } return new ReadOnlyDictionary<string, TypeReference>(result); }
private TypeReference this[TypeReference type, GenericInstanceMethod method] { get { if (type.IsByReference) { return(new ByReferenceType(this[(type as ByReferenceType).ElementType, method])); } if (this.m_Dictionary.TryGetValue(type, out var _type)) { return(_type); } if (type is GenericInstanceType) { return(this.m_Module.Import(type.Resolve()).MakeGenericType((type as GenericInstanceType).GenericArguments.Select(_Type => this[_Type, method]))); } if (type.Name.StartsWith("!!")) { return(method.Resolve().GenericParameters[int.Parse(type.Name.Substring(2))]); } return(type); } }
public override TypeReference Visit(GenericParameter type) { if (type.Type == GenericParameterType.Method) { if (genericContextMethod != null && type.Position < genericContextMethod.GenericArguments.Count) { // Look for generic parameter in both resolved and element method var genericContext1 = genericContextMethod.ElementMethod; var genericContext2 = genericContextMethod.Resolve(); var genericParameter1 = genericContext1.GenericParameters[type.Position]; var genericParameter2 = genericContext2.GenericParameters[type.Position]; if (resolveOnlyReferences) { if (genericParameter1.Name == type.Name) { return(genericParameter2); } } else { if (genericParameter1.Name == type.Name) { return(genericContextMethod.GenericArguments[type.Position]); } if (genericParameter2.Name == type.Name) { return(genericContextMethod.GenericArguments[type.Position]); } } } } else { if (genericContextType != null && type.Position < genericContextType.GenericArguments.Count) { // Look for generic parameter in both resolved and element method var genericContext1 = genericContextType.ElementType; var genericContext2 = genericContextType.Resolve(); var genericParameter1 = genericContext1.GenericParameters[type.Position]; var genericParameter2 = genericContext2.GenericParameters[type.Position]; if (resolveOnlyReferences) { if (genericParameter1.Name == type.Name) { return(genericParameter2); } } else { if (genericParameter1.Name == type.Name) { return(genericContextType.GenericArguments[type.Position]); } if (genericParameter2.Name == type.Name) { return(genericContextType.GenericArguments[type.Position]); } } } } return(base.Visit(type)); }