예제 #1
0
        /// <summary>
        /// Initializes a new instance of the <see cref="CilGenericType"/> class.
        /// </summary>
        /// <param name="typeModule">The type module.</param>
        /// <param name="token">The token.</param>
        /// <param name="baseGenericType">Type of the base generic.</param>
        /// <param name="genericTypeInstanceSignature">The generic type instance signature.</param>
        public CilGenericType(ITypeModule typeModule, Token token, RuntimeType baseGenericType, GenericInstSigType genericTypeInstanceSignature)
            : base(baseGenericType.Module, token, baseGenericType.BaseType)
        {
            Debug.Assert(baseGenericType is CilRuntimeType);

            this.signature = genericTypeInstanceSignature;
            this.baseGenericType = baseGenericType as CilRuntimeType;
            this.InstantiationModule = typeModule;
            base.Attributes = baseGenericType.Attributes;
            base.Namespace = baseGenericType.Namespace;

            if (this.baseGenericType.IsNested)
            {
                // TODO: find generic type

                ;
            }

            // TODO: if this is a nested types, add enclosing type(s) into genericArguments first
            this.genericArguments = signature.GenericArguments;

            base.Name = GetName(typeModule);

            ResolveMethods();
            ResolveFields();

            this.containsOpenGenericArguments = CheckContainsOpenGenericParameters();
        }
예제 #2
0
        /// <summary>
        /// Patches the field.
        /// </summary>
        /// <param name="typeModule">The type module.</param>
        /// <param name="enclosingType">Type of the closed.</param>
        /// <param name="openField">The open field.</param>
        /// <returns></returns>
        RuntimeField IGenericTypePatcher.PatchField(ITypeModule typeModule, CilGenericType enclosingType, RuntimeField openField)
        {
            var openType = openField.DeclaringType as CilGenericType;
            var genericArguments = CloseGenericArguments(enclosingType, openType);
            var patchedType = GetType(openType, genericArguments);

            if (patchedType == null)
            {
                var typeToken = new Token(0xFE000000 | ++typeTokenCounter);
                var signatureToken = new Token(0xFD000000 | ++signatureTokenCounter);
                var sigtype = new TypeSigType(signatureToken, CilElementType.Var);
                var signature = new GenericInstSigType(sigtype, genericArguments);

                // FIXME: There has got to be a better way to do this...
                try
                {
                    patchedType = new CilGenericType(enclosingType.Module, typeToken, openType.BaseGenericType, signature);
                }
                catch (Exception)
                {
                    foreach (var module in typeModule.TypeSystem.TypeModules)
                    {
                        try
                        {
                            patchedType = new CilGenericType(module, typeToken, openType.BaseGenericType, signature);
                            break;
                        }
                        catch (Exception)
                        {
                            ;
                        }
                    }
                }

                AddType(patchedType, genericArguments);
            }

            foreach (var field in patchedType.Fields)
            {
                if (field.Name == openField.Name)
                {
                    return field;
                }
            }

            throw new MissingFieldException();
        }
예제 #3
0
 /// <summary>
 /// Closes the generic arguments.
 /// </summary>
 /// <param name="enclosingType">Type of the enclosing.</param>
 /// <param name="openType">Type of the open.</param>
 /// <returns></returns>
 private SigType[] CloseGenericArguments(CilGenericType enclosingType, GenericInstSigType openType)
 {
     return CloseGenericArguments(enclosingType.GenericArguments, openType.GenericArguments);
 }
예제 #4
0
        /// <summary>
        /// Patches the type.
        /// </summary>
        /// <param name="typeModule">The type module.</param>
        /// <param name="enclosingType">Type of the enclosing.</param>
        /// <param name="openType">Type of the open.</param>
        /// <returns></returns>
        RuntimeType IGenericTypePatcher.PatchType(ITypeModule typeModule, CilGenericType enclosingType, CilGenericType openType)
        {
            var genericArguments = CloseGenericArguments(enclosingType, openType);
            var patchedType = GetType(openType, genericArguments);

            if (patchedType == null)
            {
                var typeToken = new Token(0xFE000000 | ++typeTokenCounter);
                var signatureToken = new Token(0xFD000000 | ++signatureTokenCounter);
                var sigtype = new TypeSigType(signatureToken, CilElementType.Var);
                var signature = new GenericInstSigType(sigtype, genericArguments);

                patchedType = new CilGenericType(enclosingType.InstantiationModule, typeToken, openType.BaseGenericType, signature);
                AddType(patchedType, genericArguments);
            }

            return patchedType;
        }
예제 #5
0
        /// <summary>
        /// Patches the method.
        /// </summary>
        /// <param name="typeModule">The type module.</param>
        /// <param name="enclosingType">Type of the enclosing.</param>
        /// <param name="openMethod">The open method.</param>
        /// <returns></returns>
        RuntimeMethod IGenericTypePatcher.PatchMethod(ITypeModule typeModule, CilGenericType enclosingType, RuntimeMethod openMethod)
        {
            var openType = openMethod.DeclaringType as CilGenericType;
            var genericArguments = CloseGenericArguments(enclosingType, openType);

            var patchedType = GetType(openType, genericArguments);
            if (patchedType == null)
            {
                var typeToken = new Token(0xFE000000 | ++typeTokenCounter);
                var signatureToken = new Token(0xFD000000 | ++signatureTokenCounter);
                var sigtype = new TypeSigType(signatureToken, CilElementType.Var);
                var signature = new GenericInstSigType(sigtype, genericArguments);

                patchedType = new CilGenericType(enclosingType.InstantiationModule, typeToken, openType.BaseGenericType, signature);
                AddType(patchedType, genericArguments);
            }

            var methodIndex = GetMethodIndex(openMethod);
            return patchedType.Methods[methodIndex];
        }
예제 #6
0
        /// <summary>
        /// Patches the field.
        /// </summary>
        /// <param name="typeModule">The type module.</param>
        /// <param name="enclosingType">Type of the closed.</param>
        /// <param name="openField">The open field.</param>
        /// <returns></returns>
        RuntimeField IGenericTypePatcher.PatchField(ITypeModule typeModule, CilGenericType enclosingType, RuntimeField openField)
        {
            var openType = openField.DeclaringType as CilGenericType;
            var genericArguments = CloseGenericArguments(enclosingType, openType);

            var patchedType = GetPatchedType(openType, genericArguments);
            if (patchedType == null)
            {
                var typeToken = new Token(0xFE000000 | ++typeTokenCounter);
                var signatureToken = new Token(0xFD000000 | ++signatureTokenCounter);
                var sigtype = new TypeSigType(signatureToken, CilElementType.Var);
                var signature = new GenericInstSigType(sigtype, genericArguments);

                patchedType = new CilGenericType(enclosingType.InstantiationModule, typeToken, openType.BaseGenericType, signature);

                AddPatchedType(openType, genericArguments, patchedType);
            }

            foreach (var field in patchedType.Fields)
            {
                if (field.Name == openField.Name)
                {
                    return field;
                }
            }

            throw new MissingFieldException();
        }