Beispiel #1
0
        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));
        }
Beispiel #2
0
        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));
            }
        }
Beispiel #4
0
        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);
     }
 }
Beispiel #6
0
        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));
        }