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; }
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); }