CheckNeedConstructor() private method

private CheckNeedConstructor ( ) : void
return void
Exemplo n.º 1
0
        private TypeDesc ImportTypeDesc(Type type, MemberInfo memberInfo, bool directReference)
        {
            TypeDesc typeDesc = null;
            TypeKind kind;
            Type arrayElementType = null;
            Type baseType = null;
            TypeFlags flags = 0;
            Exception exception = null;

            if (!type.GetTypeInfo().IsVisible)
            {
                flags |= TypeFlags.Unsupported;
                exception = new InvalidOperationException(SR.Format(SR.XmlTypeInaccessible, type.FullName));
            }
            else if (directReference && (type.GetTypeInfo().IsAbstract && type.GetTypeInfo().IsSealed))
            {
                flags |= TypeFlags.Unsupported;
                exception = new InvalidOperationException(SR.Format(SR.XmlTypeStatic, type.FullName));
            }

            if (!type.GetTypeInfo().IsValueType)
                flags |= TypeFlags.Reference;

            if (type == typeof(object))
            {
                kind = TypeKind.Root;
                flags |= TypeFlags.HasDefaultConstructor;
            }
            else if (type == typeof(ValueType))
            {
                kind = TypeKind.Enum;
                flags |= TypeFlags.Unsupported;
                if (exception == null)
                {
                    exception = new NotSupportedException(SR.Format(SR.XmlSerializerUnsupportedType, type.FullName));
                }
            }
            else if (type == typeof(void))
            {
                kind = TypeKind.Void;
            }
            else if (typeof(IXmlSerializable).IsAssignableFrom(type))
            {
                kind = TypeKind.Serializable;
                flags |= TypeFlags.Special | TypeFlags.CanBeElementValue;
                flags |= GetConstructorFlags(type, ref exception);
            }
            else if (type.IsArray)
            {
                kind = TypeKind.Array;
                if (type.GetArrayRank() > 1)
                {
                    flags |= TypeFlags.Unsupported;
                    if (exception == null)
                    {
                        exception = new NotSupportedException(SR.Format(SR.XmlUnsupportedRank, type.FullName));
                    }
                }
                arrayElementType = type.GetElementType();
                flags |= TypeFlags.HasDefaultConstructor;
            }
            else if (typeof(ICollection).IsAssignableFrom(type))
            {
                kind = TypeKind.Collection;
                arrayElementType = GetCollectionElementType(type, memberInfo == null ? null : memberInfo.DeclaringType.FullName + "." + memberInfo.Name);
                flags |= GetConstructorFlags(type, ref exception);
            }
            else if (type == typeof(XmlQualifiedName))
            {
                kind = TypeKind.Primitive;
            }
            else if (type.GetTypeInfo().IsPrimitive)
            {
                kind = TypeKind.Primitive;
                flags |= TypeFlags.Unsupported;
                if (exception == null)
                {
                    exception = new NotSupportedException(SR.Format(SR.XmlSerializerUnsupportedType, type.FullName));
                }
            }
            else if (type.GetTypeInfo().IsEnum)
            {
                kind = TypeKind.Enum;
            }
            else if (type.GetTypeInfo().IsValueType)
            {
                kind = TypeKind.Struct;
                if (IsOptionalValue(type))
                {
                    baseType = type.GetGenericArguments()[0];
                    flags |= TypeFlags.OptionalValue;
                }
                else
                {
                    baseType = type.GetTypeInfo().BaseType;
                }
                if (type.GetTypeInfo().IsAbstract) flags |= TypeFlags.Abstract;
            }
            else if (type.GetTypeInfo().IsClass)
            {
                if (type == typeof(XmlAttribute))
                {
                    kind = TypeKind.Attribute;
                    flags |= TypeFlags.Special | TypeFlags.CanBeAttributeValue;
                }
                else if (typeof(XmlNode).IsAssignableFrom(type))
                {
                    kind = TypeKind.Node;
                    baseType = type.GetTypeInfo().BaseType;
                    flags |= TypeFlags.Special | TypeFlags.CanBeElementValue | TypeFlags.CanBeTextValue;
                    if (typeof(XmlText).IsAssignableFrom(type))
                        flags &= ~TypeFlags.CanBeElementValue;
                    else if (typeof(XmlElement).IsAssignableFrom(type))
                        flags &= ~TypeFlags.CanBeTextValue;
                    else if (type.IsAssignableFrom(typeof(XmlAttribute)))
                        flags |= TypeFlags.CanBeAttributeValue;
                }
                else
                {
                    kind = TypeKind.Class;
                    baseType = type.GetTypeInfo().BaseType;
                    if (type.GetTypeInfo().IsAbstract)
                        flags |= TypeFlags.Abstract;
                }
            }
            else if (type.GetTypeInfo().IsInterface)
            {
                kind = TypeKind.Void;
                flags |= TypeFlags.Unsupported;
                if (exception == null)
                {
                    if (memberInfo == null)
                    {
                        exception = new NotSupportedException(SR.Format(SR.XmlUnsupportedInterface, type.FullName));
                    }
                    else
                    {
                        exception = new NotSupportedException(SR.Format(SR.XmlUnsupportedInterfaceDetails, memberInfo.DeclaringType.FullName + "." + memberInfo.Name, type.FullName));
                    }
                }
            }
            else
            {
                kind = TypeKind.Void;
                flags |= TypeFlags.Unsupported;
                if (exception == null)
                {
                    exception = new NotSupportedException(SR.Format(SR.XmlSerializerUnsupportedType, type.FullName));
                }
            }

            // check to see if the type has public default constructor for classes
            if (kind == TypeKind.Class && !type.GetTypeInfo().IsAbstract)
            {
                flags |= GetConstructorFlags(type, ref exception);
            }
            // check if a struct-like type is enumerable
            if (kind == TypeKind.Struct || kind == TypeKind.Class)
            {
                if (typeof(IEnumerable).IsAssignableFrom(type))
                {
                    arrayElementType = GetEnumeratorElementType(type, ref flags);
                    kind = TypeKind.Enumerable;

                    // GetEnumeratorElementType checks for the security attributes on the GetEnumerator(), Add() methods and Current property, 
                    // we need to check the MoveNext() and ctor methods for the security attribues
                    flags |= GetConstructorFlags(type, ref exception);
                }
            }
            typeDesc = new TypeDesc(type, CodeIdentifier.MakeValid(TypeName(type)), type.ToString(), kind, null, flags, null);
            typeDesc.Exception = exception;

            if (directReference && (typeDesc.IsClass || kind == TypeKind.Serializable))
                typeDesc.CheckNeedConstructor();

            if (typeDesc.IsUnsupported)
            {
                // return right away, do not check anything else
                return typeDesc;
            }
            _typeDescs.Add(type, typeDesc);

            if (arrayElementType != null)
            {
                TypeDesc td = GetTypeDesc(arrayElementType, memberInfo, true, false);
                // explicitly disallow read-only elements, even if they are collections
                if (directReference && (td.IsCollection || td.IsEnumerable) && !td.IsPrimitive)
                {
                    td.CheckNeedConstructor();
                }
                typeDesc.ArrayElementTypeDesc = td;
            }
            if (baseType != null && baseType != typeof(object) && baseType != typeof(ValueType))
            {
                typeDesc.BaseTypeDesc = GetTypeDesc(baseType, memberInfo, false, false);
            }
            return typeDesc;
        }
Exemplo n.º 2
0
        private TypeDesc ImportTypeDesc(Type type, MemberInfo memberInfo, bool directReference)
        {
            TypeDesc  typeDesc = null;
            TypeKind  kind;
            Type      arrayElementType = null;
            Type      baseType         = null;
            TypeFlags flags            = 0;
            Exception exception        = null;

            if (!type.GetTypeInfo().IsVisible)
            {
                flags    |= TypeFlags.Unsupported;
                exception = new InvalidOperationException(SR.Format(SR.XmlTypeInaccessible, type.FullName));
            }
            else if (directReference && (type.GetTypeInfo().IsAbstract&& type.GetTypeInfo().IsSealed))
            {
                flags    |= TypeFlags.Unsupported;
                exception = new InvalidOperationException(SR.Format(SR.XmlTypeStatic, type.FullName));
            }

            if (!type.GetTypeInfo().IsValueType)
            {
                flags |= TypeFlags.Reference;
            }

            if (type == typeof(object))
            {
                kind   = TypeKind.Root;
                flags |= TypeFlags.HasDefaultConstructor;
            }
            else if (type == typeof(ValueType))
            {
                kind   = TypeKind.Enum;
                flags |= TypeFlags.Unsupported;
                if (exception == null)
                {
                    exception = new NotSupportedException(SR.Format(SR.XmlSerializerUnsupportedType, type.FullName));
                }
            }
            else if (type == typeof(void))
            {
                kind = TypeKind.Void;
            }
            else if (typeof(IXmlSerializable).IsAssignableFrom(type))
            {
                kind   = TypeKind.Serializable;
                flags |= TypeFlags.Special | TypeFlags.CanBeElementValue;
                flags |= GetConstructorFlags(type, ref exception);
            }
            else if (type.IsArray)
            {
                kind = TypeKind.Array;
                if (type.GetArrayRank() > 1)
                {
                    flags |= TypeFlags.Unsupported;
                    if (exception == null)
                    {
                        exception = new NotSupportedException(SR.Format(SR.XmlUnsupportedRank, type.FullName));
                    }
                }
                arrayElementType = type.GetElementType();
                flags           |= TypeFlags.HasDefaultConstructor;
            }
            else if (typeof(ICollection).IsAssignableFrom(type))
            {
                kind             = TypeKind.Collection;
                arrayElementType = GetCollectionElementType(type, memberInfo == null ? null : memberInfo.DeclaringType.FullName + "." + memberInfo.Name);
                flags           |= GetConstructorFlags(type, ref exception);
            }
            else if (type == typeof(XmlQualifiedName))
            {
                kind = TypeKind.Primitive;
            }
            else if (type.GetTypeInfo().IsPrimitive)
            {
                kind   = TypeKind.Primitive;
                flags |= TypeFlags.Unsupported;
                if (exception == null)
                {
                    exception = new NotSupportedException(SR.Format(SR.XmlSerializerUnsupportedType, type.FullName));
                }
            }
            else if (type.GetTypeInfo().IsEnum)
            {
                kind = TypeKind.Enum;
            }
            else if (type.GetTypeInfo().IsValueType)
            {
                kind = TypeKind.Struct;
                if (IsOptionalValue(type))
                {
                    baseType = type.GetGenericArguments()[0];
                    flags   |= TypeFlags.OptionalValue;
                }
                else
                {
                    baseType = type.GetTypeInfo().BaseType;
                }
                if (type.GetTypeInfo().IsAbstract)
                {
                    flags |= TypeFlags.Abstract;
                }
            }
            else if (type.GetTypeInfo().IsClass)
            {
                {
                    kind     = TypeKind.Class;
                    baseType = type.GetTypeInfo().BaseType;
                    if (type.GetTypeInfo().IsAbstract)
                    {
                        flags |= TypeFlags.Abstract;
                    }
                }
            }
            else if (type.GetTypeInfo().IsInterface)
            {
                kind   = TypeKind.Void;
                flags |= TypeFlags.Unsupported;
                if (exception == null)
                {
                    if (memberInfo == null)
                    {
                        exception = new NotSupportedException(SR.Format(SR.XmlUnsupportedInterface, type.FullName));
                    }
                    else
                    {
                        exception = new NotSupportedException(SR.Format(SR.XmlUnsupportedInterfaceDetails, memberInfo.DeclaringType.FullName + "." + memberInfo.Name, type.FullName));
                    }
                }
            }
            else
            {
                kind   = TypeKind.Void;
                flags |= TypeFlags.Unsupported;
                if (exception == null)
                {
                    exception = new NotSupportedException(SR.Format(SR.XmlSerializerUnsupportedType, type.FullName));
                }
            }

            // check to see if the type has public default constructor for classes
            if (kind == TypeKind.Class && !type.GetTypeInfo().IsAbstract)
            {
                flags |= GetConstructorFlags(type, ref exception);
            }
            // check if a struct-like type is enumerable
            if (kind == TypeKind.Struct || kind == TypeKind.Class)
            {
                if (typeof(IEnumerable).IsAssignableFrom(type))
                {
                    arrayElementType = GetEnumeratorElementType(type, ref flags);
                    kind             = TypeKind.Enumerable;

                    // GetEnumeratorElementType checks for the security attributes on the GetEnumerator(), Add() methods and Current property,
                    // we need to check the MoveNext() and ctor methods for the security attribues
                    flags |= GetConstructorFlags(type, ref exception);
                }
            }
            typeDesc           = new TypeDesc(type, CodeIdentifier.MakeValid(TypeName(type)), type.ToString(), kind, null, flags, null);
            typeDesc.Exception = exception;

            if (directReference && (typeDesc.IsClass || kind == TypeKind.Serializable))
            {
                typeDesc.CheckNeedConstructor();
            }

            if (typeDesc.IsUnsupported)
            {
                // return right away, do not check anything else
                return(typeDesc);
            }
            _typeDescs.Add(type, typeDesc);

            if (arrayElementType != null)
            {
                TypeDesc td = GetTypeDesc(arrayElementType, memberInfo, true, false);
                // explicitly disallow read-only elements, even if they are collections
                if (directReference && (td.IsCollection || td.IsEnumerable) && !td.IsPrimitive)
                {
                    td.CheckNeedConstructor();
                }
                typeDesc.ArrayElementTypeDesc = td;
            }
            if (baseType != null && baseType != typeof(object) && baseType != typeof(ValueType))
            {
                typeDesc.BaseTypeDesc = GetTypeDesc(baseType, memberInfo, false, false);
            }
            return(typeDesc);
        }
 private TypeDesc ImportTypeDesc(Type type, MemberInfo memberInfo, bool directReference)
 {
     TypeDesc desc = null;
     TypeKind root;
     Type elementType = null;
     Type baseType = null;
     TypeFlags none = TypeFlags.None;
     Exception exception = null;
     if (!type.IsPublic && !type.IsNestedPublic)
     {
         none |= TypeFlags.Unsupported;
         exception = new InvalidOperationException(Res.GetString("XmlTypeInaccessible", new object[] { type.FullName }));
     }
     else if (type.IsAbstract && type.IsSealed)
     {
         none |= TypeFlags.Unsupported;
         exception = new InvalidOperationException(Res.GetString("XmlTypeStatic", new object[] { type.FullName }));
     }
     if (DynamicAssemblies.IsTypeDynamic(type))
     {
         none |= TypeFlags.UseReflection;
     }
     if (!type.IsValueType)
     {
         none |= TypeFlags.Reference;
     }
     if (type == typeof(object))
     {
         root = TypeKind.Root;
         none |= TypeFlags.HasDefaultConstructor;
     }
     else if (type == typeof(ValueType))
     {
         root = TypeKind.Enum;
         none |= TypeFlags.Unsupported;
         if (exception == null)
         {
             exception = new NotSupportedException(Res.GetString("XmlSerializerUnsupportedType", new object[] { type.FullName }));
         }
     }
     else if (type == typeof(void))
     {
         root = TypeKind.Void;
     }
     else if (typeof(IXmlSerializable).IsAssignableFrom(type))
     {
         root = TypeKind.Serializable;
         none |= TypeFlags.CanBeElementValue | TypeFlags.Special;
         none |= GetConstructorFlags(type, ref exception);
     }
     else if (type.IsArray)
     {
         root = TypeKind.Array;
         if (type.GetArrayRank() > 1)
         {
             none |= TypeFlags.Unsupported;
             if (exception == null)
             {
                 exception = new NotSupportedException(Res.GetString("XmlUnsupportedRank", new object[] { type.FullName }));
             }
         }
         elementType = type.GetElementType();
         none |= TypeFlags.HasDefaultConstructor;
     }
     else if (typeof(ICollection).IsAssignableFrom(type))
     {
         root = TypeKind.Collection;
         elementType = GetCollectionElementType(type, (memberInfo == null) ? null : (memberInfo.DeclaringType.FullName + "." + memberInfo.Name));
         none |= GetConstructorFlags(type, ref exception);
     }
     else if (type == typeof(XmlQualifiedName))
     {
         root = TypeKind.Primitive;
     }
     else if (type.IsPrimitive)
     {
         root = TypeKind.Primitive;
         none |= TypeFlags.Unsupported;
         if (exception == null)
         {
             exception = new NotSupportedException(Res.GetString("XmlSerializerUnsupportedType", new object[] { type.FullName }));
         }
     }
     else if (type.IsEnum)
     {
         root = TypeKind.Enum;
     }
     else if (type.IsValueType)
     {
         root = TypeKind.Struct;
         if (IsOptionalValue(type))
         {
             baseType = type.GetGenericArguments()[0];
             none |= TypeFlags.OptionalValue;
         }
         else
         {
             baseType = type.BaseType;
         }
         if (type.IsAbstract)
         {
             none |= TypeFlags.Abstract;
         }
     }
     else if (type.IsClass)
     {
         if (type == typeof(XmlAttribute))
         {
             root = TypeKind.Attribute;
             none |= TypeFlags.CanBeAttributeValue | TypeFlags.Special;
         }
         else if (typeof(XmlNode).IsAssignableFrom(type))
         {
             root = TypeKind.Node;
             baseType = type.BaseType;
             none |= TypeFlags.CanBeElementValue | TypeFlags.CanBeTextValue | TypeFlags.Special;
             if (typeof(XmlText).IsAssignableFrom(type))
             {
                 none &= ~TypeFlags.CanBeElementValue;
             }
             else if (typeof(XmlElement).IsAssignableFrom(type))
             {
                 none &= ~TypeFlags.CanBeTextValue;
             }
             else if (type.IsAssignableFrom(typeof(XmlAttribute)))
             {
                 none |= TypeFlags.CanBeAttributeValue;
             }
         }
         else
         {
             root = TypeKind.Class;
             baseType = type.BaseType;
             if (type.IsAbstract)
             {
                 none |= TypeFlags.Abstract;
             }
         }
     }
     else if (type.IsInterface)
     {
         root = TypeKind.Void;
         none |= TypeFlags.Unsupported;
         if (exception == null)
         {
             if (memberInfo == null)
             {
                 exception = new NotSupportedException(Res.GetString("XmlUnsupportedInterface", new object[] { type.FullName }));
             }
             else
             {
                 exception = new NotSupportedException(Res.GetString("XmlUnsupportedInterfaceDetails", new object[] { memberInfo.DeclaringType.FullName + "." + memberInfo.Name, type.FullName }));
             }
         }
     }
     else
     {
         root = TypeKind.Void;
         none |= TypeFlags.Unsupported;
         if (exception == null)
         {
             exception = new NotSupportedException(Res.GetString("XmlSerializerUnsupportedType", new object[] { type.FullName }));
         }
     }
     if ((root == TypeKind.Class) && !type.IsAbstract)
     {
         none |= GetConstructorFlags(type, ref exception);
     }
     if (((root == TypeKind.Struct) || (root == TypeKind.Class)) && typeof(IEnumerable).IsAssignableFrom(type))
     {
         elementType = GetEnumeratorElementType(type, ref none);
         root = TypeKind.Enumerable;
         none |= GetConstructorFlags(type, ref exception);
     }
     desc = new TypeDesc(type, CodeIdentifier.MakeValid(TypeName(type)), type.ToString(), root, null, none, null) {
         Exception = exception
     };
     if (directReference && (desc.IsClass || (root == TypeKind.Serializable)))
     {
         desc.CheckNeedConstructor();
     }
     if (!desc.IsUnsupported)
     {
         this.typeDescs.Add(type, desc);
         if (elementType != null)
         {
             TypeDesc desc2 = this.GetTypeDesc(elementType, memberInfo, true, false);
             if ((directReference && (desc2.IsCollection || desc2.IsEnumerable)) && !desc2.IsPrimitive)
             {
                 desc2.CheckNeedConstructor();
             }
             desc.ArrayElementTypeDesc = desc2;
         }
         if (((baseType != null) && (baseType != typeof(object))) && (baseType != typeof(ValueType)))
         {
             desc.BaseTypeDesc = this.GetTypeDesc(baseType, memberInfo, false, false);
         }
         if (type.IsNestedPublic)
         {
             for (Type type4 = type.DeclaringType; (type4 != null) && !type4.ContainsGenericParameters; type4 = type4.DeclaringType)
             {
                 this.GetTypeDesc(type4, null, false);
             }
         }
     }
     return desc;
 }
        private TypeDesc ImportTypeDesc(Type type, MemberInfo memberInfo, bool directReference)
        {
            TypeDesc  desc = null;
            TypeKind  root;
            Type      elementType = null;
            Type      baseType    = null;
            TypeFlags none        = TypeFlags.None;
            Exception exception   = null;

            if (!type.IsPublic && !type.IsNestedPublic)
            {
                none     |= TypeFlags.Unsupported;
                exception = new InvalidOperationException(Res.GetString("XmlTypeInaccessible", new object[] { type.FullName }));
            }
            else if (type.IsAbstract && type.IsSealed)
            {
                none     |= TypeFlags.Unsupported;
                exception = new InvalidOperationException(Res.GetString("XmlTypeStatic", new object[] { type.FullName }));
            }
            if (DynamicAssemblies.IsTypeDynamic(type))
            {
                none |= TypeFlags.UseReflection;
            }
            if (!type.IsValueType)
            {
                none |= TypeFlags.Reference;
            }
            if (type == typeof(object))
            {
                root  = TypeKind.Root;
                none |= TypeFlags.HasDefaultConstructor;
            }
            else if (type == typeof(ValueType))
            {
                root  = TypeKind.Enum;
                none |= TypeFlags.Unsupported;
                if (exception == null)
                {
                    exception = new NotSupportedException(Res.GetString("XmlSerializerUnsupportedType", new object[] { type.FullName }));
                }
            }
            else if (type == typeof(void))
            {
                root = TypeKind.Void;
            }
            else if (typeof(IXmlSerializable).IsAssignableFrom(type))
            {
                root  = TypeKind.Serializable;
                none |= TypeFlags.CanBeElementValue | TypeFlags.Special;
                none |= GetConstructorFlags(type, ref exception);
            }
            else if (type.IsArray)
            {
                root = TypeKind.Array;
                if (type.GetArrayRank() > 1)
                {
                    none |= TypeFlags.Unsupported;
                    if (exception == null)
                    {
                        exception = new NotSupportedException(Res.GetString("XmlUnsupportedRank", new object[] { type.FullName }));
                    }
                }
                elementType = type.GetElementType();
                none       |= TypeFlags.HasDefaultConstructor;
            }
            else if (typeof(ICollection).IsAssignableFrom(type))
            {
                root        = TypeKind.Collection;
                elementType = GetCollectionElementType(type, (memberInfo == null) ? null : (memberInfo.DeclaringType.FullName + "." + memberInfo.Name));
                none       |= GetConstructorFlags(type, ref exception);
            }
            else if (type == typeof(XmlQualifiedName))
            {
                root = TypeKind.Primitive;
            }
            else if (type.IsPrimitive)
            {
                root  = TypeKind.Primitive;
                none |= TypeFlags.Unsupported;
                if (exception == null)
                {
                    exception = new NotSupportedException(Res.GetString("XmlSerializerUnsupportedType", new object[] { type.FullName }));
                }
            }
            else if (type.IsEnum)
            {
                root = TypeKind.Enum;
            }
            else if (type.IsValueType)
            {
                root = TypeKind.Struct;
                if (IsOptionalValue(type))
                {
                    baseType = type.GetGenericArguments()[0];
                    none    |= TypeFlags.OptionalValue;
                }
                else
                {
                    baseType = type.BaseType;
                }
                if (type.IsAbstract)
                {
                    none |= TypeFlags.Abstract;
                }
            }
            else if (type.IsClass)
            {
                if (type == typeof(XmlAttribute))
                {
                    root  = TypeKind.Attribute;
                    none |= TypeFlags.CanBeAttributeValue | TypeFlags.Special;
                }
                else if (typeof(XmlNode).IsAssignableFrom(type))
                {
                    root     = TypeKind.Node;
                    baseType = type.BaseType;
                    none    |= TypeFlags.CanBeElementValue | TypeFlags.CanBeTextValue | TypeFlags.Special;
                    if (typeof(XmlText).IsAssignableFrom(type))
                    {
                        none &= ~TypeFlags.CanBeElementValue;
                    }
                    else if (typeof(XmlElement).IsAssignableFrom(type))
                    {
                        none &= ~TypeFlags.CanBeTextValue;
                    }
                    else if (type.IsAssignableFrom(typeof(XmlAttribute)))
                    {
                        none |= TypeFlags.CanBeAttributeValue;
                    }
                }
                else
                {
                    root     = TypeKind.Class;
                    baseType = type.BaseType;
                    if (type.IsAbstract)
                    {
                        none |= TypeFlags.Abstract;
                    }
                }
            }
            else if (type.IsInterface)
            {
                root  = TypeKind.Void;
                none |= TypeFlags.Unsupported;
                if (exception == null)
                {
                    if (memberInfo == null)
                    {
                        exception = new NotSupportedException(Res.GetString("XmlUnsupportedInterface", new object[] { type.FullName }));
                    }
                    else
                    {
                        exception = new NotSupportedException(Res.GetString("XmlUnsupportedInterfaceDetails", new object[] { memberInfo.DeclaringType.FullName + "." + memberInfo.Name, type.FullName }));
                    }
                }
            }
            else
            {
                root  = TypeKind.Void;
                none |= TypeFlags.Unsupported;
                if (exception == null)
                {
                    exception = new NotSupportedException(Res.GetString("XmlSerializerUnsupportedType", new object[] { type.FullName }));
                }
            }
            if ((root == TypeKind.Class) && !type.IsAbstract)
            {
                none |= GetConstructorFlags(type, ref exception);
            }
            if (((root == TypeKind.Struct) || (root == TypeKind.Class)) && typeof(IEnumerable).IsAssignableFrom(type))
            {
                elementType = GetEnumeratorElementType(type, ref none);
                root        = TypeKind.Enumerable;
                none       |= GetConstructorFlags(type, ref exception);
            }
            desc = new TypeDesc(type, CodeIdentifier.MakeValid(TypeName(type)), type.ToString(), root, null, none, null)
            {
                Exception = exception
            };
            if (directReference && (desc.IsClass || (root == TypeKind.Serializable)))
            {
                desc.CheckNeedConstructor();
            }
            if (!desc.IsUnsupported)
            {
                this.typeDescs.Add(type, desc);
                if (elementType != null)
                {
                    TypeDesc desc2 = this.GetTypeDesc(elementType, memberInfo, true, false);
                    if ((directReference && (desc2.IsCollection || desc2.IsEnumerable)) && !desc2.IsPrimitive)
                    {
                        desc2.CheckNeedConstructor();
                    }
                    desc.ArrayElementTypeDesc = desc2;
                }
                if (((baseType != null) && (baseType != typeof(object))) && (baseType != typeof(ValueType)))
                {
                    desc.BaseTypeDesc = this.GetTypeDesc(baseType, memberInfo, false, false);
                }
                if (type.IsNestedPublic)
                {
                    for (Type type4 = type.DeclaringType; (type4 != null) && !type4.ContainsGenericParameters; type4 = type4.DeclaringType)
                    {
                        this.GetTypeDesc(type4, null, false);
                    }
                }
            }
            return(desc);
        }