示例#1
0
        /// <summary>
        /// Replace generic parameters with actual arguments
        /// </summary>
        private MonoTypeContext ResolveGenericParameter()
        {
            switch (Type.etype)
            {
            case ElementType.Var:
            case ElementType.MVar:
            {
                GenericParameter parameter    = (GenericParameter)Type;
                TypeReference    resolvedType = Arguments[parameter];
                return(new MonoTypeContext(resolvedType));
            }

            case ElementType.Array:
            {
                ArrayType       array           = (ArrayType)Type;
                MonoTypeContext arrayContext    = new MonoTypeContext(array.ElementType, Arguments);
                MonoTypeContext resolvedContext = arrayContext.ResolveGenericParameter();
                ArrayType       newArray        = new ArrayType(resolvedContext.Type, array.Rank);
                if (array.Rank > 1)
                {
                    for (int i = 0; i < array.Rank; i++)
                    {
                        newArray.Dimensions[i] = array.Dimensions[i];
                    }
                }
                return(new MonoTypeContext(newArray, Arguments));
            }

            case ElementType.GenericInst:
            {
                GenericInstanceType genericInstance = (GenericInstanceType)Type;
                GenericInstanceType newInstance     = new GenericInstanceType(genericInstance.ElementType);
                foreach (TypeReference argument in genericInstance.GenericArguments)
                {
                    MonoTypeContext argumentContext  = new MonoTypeContext(argument, Arguments);
                    MonoTypeContext resolvedArgument = argumentContext.Resolve();
                    newInstance.GenericArguments.Add(resolvedArgument.Type);
                }
                return(new MonoTypeContext(newInstance, Arguments));
            }

            case ElementType.ByRef:
            {
                ByReferenceType reference       = (ByReferenceType)Type;
                MonoTypeContext refContext      = new MonoTypeContext(reference.ElementType, Arguments);
                MonoTypeContext resolvedContext = refContext.ResolveGenericParameter();
                ByReferenceType newReference    = new ByReferenceType(resolvedContext.Type);
                return(new MonoTypeContext(newReference, Arguments));
            }

            case ElementType.Ptr:
            {
                PointerType     pointer         = (PointerType)Type;
                MonoTypeContext ptrContext      = new MonoTypeContext(pointer.ElementType, Arguments);
                MonoTypeContext resolvedContext = ptrContext.ResolveGenericParameter();
                PointerType     newPointer      = new PointerType(resolvedContext.Type);
                return(new MonoTypeContext(newPointer, Arguments));
            }

            case ElementType.Pinned:
            {
                PinnedType      pinned          = (PinnedType)Type;
                MonoTypeContext pinContext      = new MonoTypeContext(pinned.ElementType, Arguments);
                MonoTypeContext resolvedContext = pinContext.ResolveGenericParameter();
                PinnedType      newPinned       = new PinnedType(resolvedContext.Type);
                return(new MonoTypeContext(newPinned, Arguments));
            }

            case ElementType.FnPtr:
            {
                FunctionPointerType funcPtr    = (FunctionPointerType)Type;
                FunctionPointerType newFuncPtr = new FunctionPointerType();
                newFuncPtr.HasThis           = funcPtr.HasThis;
                newFuncPtr.ExplicitThis      = funcPtr.ExplicitThis;
                newFuncPtr.CallingConvention = funcPtr.CallingConvention;
                MonoTypeContext returnContext  = new MonoTypeContext(funcPtr.ReturnType, Arguments);
                MonoTypeContext resolvedReturn = returnContext.Resolve();
                newFuncPtr.ReturnType = resolvedReturn.Type;
                foreach (ParameterDefinition param in funcPtr.Parameters)
                {
                    MonoTypeContext     paramContext  = new MonoTypeContext(param.ParameterType, Arguments);
                    MonoTypeContext     resolvedParam = paramContext.Resolve();
                    ParameterDefinition newParameter  = new ParameterDefinition(param.Name, param.Attributes, resolvedParam.Type);
                    newFuncPtr.Parameters.Add(newParameter);
                }
                return(new MonoTypeContext(newFuncPtr, Arguments));
            }

            default:
                throw new Exception($"Unknown generic parameter container {Type}");
            }
        }