public ReflectedParameterTypeInfo BuildType(Type type)
        {
            if (type == null)
            {
                return(null);
            }
            var typeInfo = new ReflectedParameterTypeInfo();

            if (type.IsGenericParameter)
            {
                typeInfo.IsGenericParameter = true;
                typeInfo.GenericParameter   = _genericParameterProvider.GetGenericParameter(type.Name);
                return(typeInfo);
            }
            typeInfo.Type = _getType(type);
            if (!type.IsGenericType)
            {
                return(typeInfo);
            }
            typeInfo.IsGenericType = true;
            typeInfo.Parameters    = (from parameter in type.GetGenericArguments() select BuildType(parameter)).ToList();
            return(typeInfo);
        }
Beispiel #2
0
        public static TypeReference Relink(this TypeReference type, Relinker relinker,
                                           IGenericParameterProvider context)
        {
            if (type == null)
            {
                return(null);
            }

            if (type is TypeSpecification ts)
            {
                var relinkedElem = ts.ElementType.Relink(relinker, context);

                if (type.IsSentinel)
                {
                    return(new SentinelType(relinkedElem));
                }

                if (type.IsByReference)
                {
                    return(new ByReferenceType(relinkedElem));
                }

                if (type.IsPointer)
                {
                    return(new PointerType(relinkedElem));
                }

                if (type.IsPinned)
                {
                    return(new PinnedType(relinkedElem));
                }

                if (type.IsArray)
                {
                    var at = new ArrayType(relinkedElem, ((ArrayType)type).Rank);
                    for (var i = 0; i < at.Rank; i++)
                    {
                        // It's a struct.
                        at.Dimensions[i] = ((ArrayType)type).Dimensions[i];
                    }
                    return(at);
                }

                if (type.IsRequiredModifier)
                {
                    return(new RequiredModifierType(
                               ((RequiredModifierType)type).ModifierType.Relink(relinker, context), relinkedElem));
                }

                if (type.IsOptionalModifier)
                {
                    return(new OptionalModifierType(
                               ((OptionalModifierType)type).ModifierType.Relink(relinker, context), relinkedElem));
                }

                if (type.IsGenericInstance)
                {
                    var git = new GenericInstanceType(relinkedElem);
                    foreach (var genArg in ((GenericInstanceType)type).GenericArguments)
                    {
                        git.GenericArguments.Add(genArg?.Relink(relinker, context));
                    }
                    return(git);
                }

                if (!type.IsFunctionPointer)
                {
                    throw new NotSupportedException(
                              $"MonoMod can't handle TypeSpecification: {type.FullName} ({type.GetType()})");
                }
                var fp = (FunctionPointerType)type;
                fp.ReturnType = fp.ReturnType.Relink(relinker, context);
                foreach (var t in fp.Parameters)
                {
                    t.ParameterType = t.ParameterType.Relink(relinker, context);
                }

                return(fp);
            }

            if (type.IsGenericParameter)
            {
                var genParam = context.GetGenericParameter((GenericParameter)type);
                if (genParam == null)
                {
                    throw new RelinkTargetNotFoundException(
                              $"{RelinkTargetNotFoundException.DefaultMessage} {type.FullName} (context: {context})", type,
                              context);
                }
                for (var i = 0; i < genParam.Constraints.Count; i++)
                {
                    if (!genParam.Constraints[i].IsGenericInstance
                        ) // That is somehow possible and causes a stack overflow.
                    {
                        genParam.Constraints[i] = genParam.Constraints[i].Relink(relinker, context);
                    }
                }
                return(genParam);
            }

            return((TypeReference)relinker(type, context));
        }
Beispiel #3
0
        public static TypeReference Relink(this TypeReference type, Relinker relinker, IGenericParameterProvider context)
        {
            if (type == null)
            {
                return(null);
            }

            if (type is TypeSpecification)
            {
                TypeSpecification ts           = (TypeSpecification)type;
                TypeReference     relinkedElem = ts.ElementType.Relink(relinker, context);

                if (type.IsByReference)
                {
                    return(new ByReferenceType(relinkedElem));
                }

                if (type.IsPointer)
                {
                    return(new PointerType(relinkedElem));
                }

                if (type.IsPinned)
                {
                    return(new PinnedType(relinkedElem));
                }

                if (type.IsArray)
                {
                    return(new ArrayType(relinkedElem, ((ArrayType)type).Dimensions.Count));
                }

                if (type.IsRequiredModifier)
                {
                    return(new RequiredModifierType(((RequiredModifierType)type).ModifierType.Relink(relinker, context), relinkedElem));
                }

                if (type.IsOptionalModifier)
                {
                    return(new OptionalModifierType(((OptionalModifierType)type).ModifierType.Relink(relinker, context), relinkedElem));
                }

                if (type.IsGenericInstance)
                {
                    GenericInstanceType git = new GenericInstanceType(relinkedElem);
                    foreach (TypeReference genArg in ((GenericInstanceType)type).GenericArguments)
                    {
                        git.GenericArguments.Add(genArg?.Relink(relinker, context));
                    }
                    return(git);
                }

                if (type.IsFunctionPointer)
                {
                    FunctionPointerType fp = (FunctionPointerType)type;
                    fp.ReturnType = fp.ReturnType.Relink(relinker, context);
                    for (int i = 0; i < fp.Parameters.Count; i++)
                    {
                        fp.Parameters[i].ParameterType = fp.Parameters[i].ParameterType.Relink(relinker, context);
                    }
                    return(fp);
                }

                throw new InvalidOperationException($"MonoMod can't handle TypeSpecification: {type.FullName} ({type.GetType()})");
            }

            if (type.IsGenericParameter)
            {
                GenericParameter genParam = context.GetGenericParameter(((GenericParameter)type).Name);
                for (int i = 0; i < genParam.Constraints.Count; i++)
                {
                    if (!genParam.Constraints[i].IsGenericInstance) // That is somehow possible and causes a stack overflow.
                    {
                        genParam.Constraints[i] = genParam.Constraints[i].Relink(relinker, context);
                    }
                }
                return(genParam);
            }

            return((TypeReference)relinker(type, context));
        }