Пример #1
0
        public static PrimitiveTypeCode GetEnumUnderlyingPrimitiveTypeCode(this Type enumType, TypeLoader loader)
        {
            Type      type      = enumType.GetEnumUnderlyingType();
            CoreTypes coreTypes = loader.GetAllFoundCoreTypes();

            // Be careful how you compare - one or more elements of "coreTypes" can be null!
            if (type == coreTypes[CoreType.Boolean])
            {
                return(PrimitiveTypeCode.Boolean);
            }
            if (type == coreTypes[CoreType.Char])
            {
                return(PrimitiveTypeCode.Char);
            }
            if (type == coreTypes[CoreType.Byte])
            {
                return(PrimitiveTypeCode.Byte);
            }
            if (type == coreTypes[CoreType.Int16])
            {
                return(PrimitiveTypeCode.Int16);
            }
            if (type == coreTypes[CoreType.Int32])
            {
                return(PrimitiveTypeCode.Int32);
            }
            if (type == coreTypes[CoreType.Int64])
            {
                return(PrimitiveTypeCode.Int64);
            }
            if (type == coreTypes[CoreType.IntPtr])
            {
                return(PrimitiveTypeCode.IntPtr);
            }
            if (type == coreTypes[CoreType.SByte])
            {
                return(PrimitiveTypeCode.SByte);
            }
            if (type == coreTypes[CoreType.UInt16])
            {
                return(PrimitiveTypeCode.UInt16);
            }
            if (type == coreTypes[CoreType.UInt32])
            {
                return(PrimitiveTypeCode.UInt32);
            }
            if (type == coreTypes[CoreType.UInt64])
            {
                return(PrimitiveTypeCode.UInt64);
            }
            if (type == coreTypes[CoreType.UIntPtr])
            {
                return(PrimitiveTypeCode.UIntPtr);
            }

            throw new BadImageFormatException(SR.Format(SR.UnexpectedUnderlyingEnumType, enumType, type));
        }
        /// <summary>
        /// Convert MarshalAsAttribute data into CustomAttributeData form. Returns null if the core assembly cannot be loaded or if the necessary
        /// types aren't in the core assembly.
        /// </summary>
        public static CustomAttributeData TryComputeMarshalAsCustomAttributeData(Func <MarshalAsAttribute> marshalAsAttributeComputer, TypeLoader loader)
        {
            // Make sure all the necessary framework types exist in this TypeLoader's core assembly. If one doesn't, skip.
            CoreTypes ct = loader.GetAllFoundCoreTypes();

            if (ct[CoreType.String] == null ||
                ct[CoreType.Boolean] == null ||
                ct[CoreType.UnmanagedType] == null ||
                ct[CoreType.VarEnum] == null ||
                ct[CoreType.Type] == null ||
                ct[CoreType.Int16] == null ||
                ct[CoreType.Int32] == null)
            {
                return(null);
            }
            ConstructorInfo ci = loader.TryGetMarshalAsCtor();

            if (ci == null)
            {
                return(null);
            }

            Func <CustomAttributeArguments> argumentsPromise =
                () =>
            {
                // The expensive work goes in here. It will not execute unless someone invokes the Constructor/NamedArguments properties on
                // the CustomAttributeData.

                MarshalAsAttribute ma = marshalAsAttributeComputer();

                Type attributeType = ci.DeclaringType;

                CustomAttributeTypedArgument[]      cats = { new CustomAttributeTypedArgument(ct[CoreType.UnmanagedType], (int)(ma.Value)) };
                List <CustomAttributeNamedArgument> cans = new List <CustomAttributeNamedArgument>();
                cans.AddRange(new CustomAttributeNamedArgument[]
                {
                    attributeType.ToCustomAttributeNamedArgument(nameof(MarshalAsAttribute.ArraySubType), ct[CoreType.UnmanagedType], (int)ma.ArraySubType),
                    attributeType.ToCustomAttributeNamedArgument(nameof(MarshalAsAttribute.IidParameterIndex), ct[CoreType.Int32], ma.IidParameterIndex),
                    attributeType.ToCustomAttributeNamedArgument(nameof(MarshalAsAttribute.SafeArraySubType), ct[CoreType.VarEnum], (int)ma.SafeArraySubType),
                    attributeType.ToCustomAttributeNamedArgument(nameof(MarshalAsAttribute.SizeConst), ct[CoreType.Int32], ma.SizeConst),
                    attributeType.ToCustomAttributeNamedArgument(nameof(MarshalAsAttribute.SizeParamIndex), ct[CoreType.Int16], ma.SizeParamIndex),
                });

                if (ma.SafeArrayUserDefinedSubType != null)
                {
                    cans.Add(attributeType.ToCustomAttributeNamedArgument(nameof(MarshalAsAttribute.SafeArrayUserDefinedSubType), ct[CoreType.Type], ma.SafeArrayUserDefinedSubType));
                }

                if (ma.MarshalType != null)
                {
                    cans.Add(attributeType.ToCustomAttributeNamedArgument(nameof(MarshalAsAttribute.MarshalType), ct[CoreType.String], ma.MarshalType));
                }

                if (ma.MarshalTypeRef != null)
                {
                    cans.Add(attributeType.ToCustomAttributeNamedArgument(nameof(MarshalAsAttribute.MarshalTypeRef), ct[CoreType.Type], ma.MarshalTypeRef));
                }

                if (ma.MarshalCookie != null)
                {
                    cans.Add(attributeType.ToCustomAttributeNamedArgument(nameof(MarshalAsAttribute.MarshalCookie), ct[CoreType.String], ma.MarshalCookie));
                }

                return(new CustomAttributeArguments(cats, cans));
            };

            return(new RoPseudoCustomAttributeData(ci, argumentsPromise));
        }