Example #1
0
        public static DataType BuildDataType(Type type, Func<Type, MemberInfo, int> membersOrder = null)
        {
            if (DataType.IsPrimitiveType(type) || type.IsEnum || type == typeof(Guid) || type.IsKeyValuePair() || type.IsArray || type.IsList() || type.IsDictionary() || type.IsNullable())
                return BuildDataType(type, membersOrder, new HashSet<Type>());

            List<DataType> slots = new List<DataType>();
            foreach (var member in GetPublicMembers(type, membersOrder))
                slots.Add(BuildDataType(member.GetPropertyOrFieldType(), membersOrder, new HashSet<Type>()));

            return DataType.Slots(slots.ToArray());
        }
        private static bool CheckIfIsImmutable(Type type, List<Type> checkedTypes)
        {
            bool result;
            if (ImmutableCheckedTypes.TryGetValue(type, out result))
            {
                return result;
            }

            if (type.IsNullable())
            {
                var underlyingType = Nullable.GetUnderlyingType(type);
                result = CheckIfIsImmutable(underlyingType, checkedTypes);
            }
            else if (type == typeof(bool))
            {
                result = true;
            }
            else if (type.IsEnum)
            {
                result = true;
            }
            else if (type.IsArray)
            {
                result = false;
            }
            else if (type.IsDelegate())
            {
                result = true;
            }
            else if (type.IsImmutableList() ||
                     type.IsImmutableArray() ||
                     type.IsImmutableHashSet())
            {
                var itemType = type.GetItemType();
                result = CheckIfIsImmutable(itemType, checkedTypes);
            }
            else if (type.IsKeyValuePair())
            {
                var genericArguments = type.GetGenericArguments();
                result = CheckIfIsImmutable(genericArguments[0], checkedTypes)
                         && CheckIfIsImmutable(genericArguments[1], checkedTypes);
            }
            else if (CanBeImmutable(type))
            {
                result = HasImmutableMembers(type, checkedTypes);
            }
            else
            {
                result = false;
            }

            ImmutableCheckedTypes.TryAdd(type, result);
            return result;
        }
Example #3
0
        public static bool IsAllPrimitive(Type type, Func<Type, MemberInfo, int> membersOrder = null)
        {
            if (DataType.IsPrimitiveType(type))
                return true;

            if (type.IsArray || type.IsList() || type.IsDictionary() || type.IsKeyValuePair() || type.IsNullable() || type == typeof(Guid))
                return false;

            foreach (var member in GetPublicMembers(type, membersOrder))
            {
                if (!DataType.IsPrimitiveType(member.GetPropertyOrFieldType()))
                    return false;
            }

            return true;
        }
Example #4
0
        private static DataType BuildDataType(Type type, Func<Type, MemberInfo, int> membersOrder, HashSet<Type> cycleCheck)
        {
            if (DataType.IsPrimitiveType(type))
                return DataType.FromPrimitiveType(type);

            if (type.IsEnum)
                return DataType.FromPrimitiveType(type.GetEnumUnderlyingType());

            if (type == typeof(Guid))
                return DataType.ByteArray;

            if (type.IsKeyValuePair())
            {
                return DataType.Slots(
                    BuildDataType(type.GetGenericArguments()[0], membersOrder, cycleCheck),
                    BuildDataType(type.GetGenericArguments()[1], membersOrder, cycleCheck));
            }

            if (type.IsArray)
                return DataType.Array(BuildDataType(type.GetElementType(), membersOrder, cycleCheck));

            if (type.IsList())
                return DataType.List(BuildDataType(type.GetGenericArguments()[0], membersOrder, cycleCheck));

            if (type.IsDictionary())
            {
                return DataType.Dictionary(
                    BuildDataType(type.GetGenericArguments()[0], membersOrder, cycleCheck),
                    BuildDataType(type.GetGenericArguments()[1], membersOrder, cycleCheck));
            }

            if (type.IsNullable())
                return DataType.Slots(BuildDataType(type.GetGenericArguments()[0], membersOrder, cycleCheck));

            List<DataType> slots = new List<DataType>();
            foreach (var member in GetPublicMembers(type, membersOrder))
            {
                var memberType = member.GetPropertyOrFieldType();

                if (cycleCheck.Contains(memberType))
                    throw new NotSupportedException(String.Format("Type {0} has cycle declaration.", memberType));

                cycleCheck.Add(memberType);
                DataType slot = BuildDataType(memberType, membersOrder, cycleCheck);
                cycleCheck.Remove(memberType);
                slots.Add(slot);
            }

            if (slots.Count == 0)
                throw new NotSupportedException(String.Format("{0} do not contains public read/writer properties and fields", type));

            return DataType.Slots(slots.ToArray());
        }
Example #5
0
        private static bool InternalIsAnonymousType(Type type, Func<Type, MemberInfo, int> membersOrder = null)
        {
            if (DataType.IsPrimitiveType(type))
                return true;

            if (type.IsEnum || type == typeof(Guid))
                return false;

            if (type.IsNullable())
                return false;

            if (type.IsKeyValuePair())
                return false;

            if (type.IsArray)
                return InternalIsAnonymousType(type.GetElementType(), membersOrder);

            if (type.IsList())
                return InternalIsAnonymousType(type.GetGenericArguments()[0], membersOrder);

            if (type.IsDictionary())
                return InternalIsAnonymousType(type.GetGenericArguments()[0], membersOrder) && InternalIsAnonymousType(type.GetGenericArguments()[1], membersOrder);

            if (type.IsInheritInterface(typeof(ISlots)))
            {
                foreach (var slotType in GetPublicMembers(type, membersOrder))
                {
                    if (!InternalIsAnonymousType(slotType.GetPropertyOrFieldType(), membersOrder))
                        return false;
                }
            }

            if ((type.IsClass || type.IsStruct()) && !type.IsInheritInterface(typeof(ISlots)))
                return false;

            return true;
        }
        /// <summary>
        /// Gets the serialization information about the type members.
        /// This information is used for creation of the corresponding schema nodes.
        /// </summary>
        /// <param name="type">The type, members of which should be serialized.</param>
        /// <returns>
        /// Serialization information about the fields/properties.
        /// </returns>
        /// <exception cref="System.ArgumentNullException">The type argument is null.</exception>
        public override MemberSerializationInfo[] ResolveMembers(Type type)
        {
            if (type == null)
            {
                throw new ArgumentNullException("type");
            }

            if (type.IsKeyValuePair())
            {
                var keyValueProperties = type.GetAllProperties();
                return keyValueProperties
                    .Select(p => new MemberSerializationInfo
                                 {
                                     Name = p.Name,
                                     MemberInfo = p,
                                     Nullable = false
                                 })
                    .ToArray();
            }

            var fields = type.GetAllFields();
            var properties = type.GetAllProperties();

            var dataMemberProperties = properties
                .Where(p => p.GetDataMemberAttribute() != null);

            var serializedProperties = TypeExtensions.RemoveDuplicates(dataMemberProperties);
            TypeExtensions.CheckPropertyGetters(serializedProperties);

            var members = fields
                .Concat<MemberInfo>(serializedProperties)
                .Select(m => new
                {
                    Member = m,
                    Attribute = m.GetCustomAttributes(false).OfType<DataMemberAttribute>().SingleOrDefault(),
                    Nullable = m.GetCustomAttributes(false).OfType<NullableSchemaAttribute>().Any()
                });

            var result = members.Where(m => m.Attribute != null)
                          .Select(m => new MemberSerializationInfo
                          {
                              Name = m.Attribute.Name ?? m.Member.Name,
                              MemberInfo = m.Member,
                              Nullable = m.Nullable
                          });

            if (this.useAlphabeticalOrder)
            {
                result = result.OrderBy(p => p.Name);
            }

            return result.ToArray();
        }
Example #7
0
        internal static TypeErrorsBuilder CheckRequiresReferenceHandling(
            this TypeErrorsBuilder typeErrors,
            Type type,
            MemberSettings settings,
            Func<Type, bool> requiresReferenceHandling)
        {
            if (settings.ReferenceHandling == ReferenceHandling.Throw)
            {
                if (typeof(IEnumerable).IsAssignableFrom(type))
                {
                    if (type.Implements(typeof(IDictionary<,>)))
                    {
                        var arguments = type.GetGenericArguments();
                        if (arguments.Length != 2 ||
                            requiresReferenceHandling(arguments[0]) ||
                            requiresReferenceHandling(arguments[1]))
                        {
                            typeErrors = typeErrors.CreateIfNull(type)
                                                   .Add(RequiresReferenceHandling.Enumerable);
                        }
                    }
                    else if (requiresReferenceHandling(type.GetItemType()))
                    {
                        typeErrors = typeErrors.CreateIfNull(type)
                                               .Add(RequiresReferenceHandling.Enumerable);
                    }
                }
                else if (type.IsKeyValuePair())
                {
                    var arguments = type.GetGenericArguments();
                    if (requiresReferenceHandling(arguments[0]) || requiresReferenceHandling(arguments[1]))
                    {
                        typeErrors = typeErrors.CreateIfNull(type)
                                               .Add(RequiresReferenceHandling.ComplexType);
                    }
                }
                else if (requiresReferenceHandling(type))
                {
                    typeErrors = typeErrors.CreateIfNull(type)
                                           .Add(RequiresReferenceHandling.ComplexType);
                }
            }

            return typeErrors;
        }