Esempio n. 1
0
        static void VerifyMember(Type resolverType, EmittableMemberInfo info)
        {
            var formatter = typeof(Formatter <,>).MakeGenericType(resolverType, info.MemberType).GetTypeInfo().GetProperty("Default").GetValue(null, null);
            var error     = formatter as IErrorFormatter;

            if (error != null)
            {
                throw error.GetException();
            }

            // OK, Can Serialzie.
        }
Esempio n. 2
0
        public static Tuple <int, EmittableMemberInfo>[] GetMembers(Type resolverType, Type type, bool isClass)
        {
            if (isClass)
            {
                if (!type.GetTypeInfo().IsClass)
                {
                    throw new InvalidOperationException("Type must be class. " + type.Name);
                }
            }
            else
            {
                if (!type.GetTypeInfo().IsValueType)
                {
                    throw new InvalidOperationException("Type must be class. " + type.Name);
                }
            }

            if (type.GetTypeInfo().GetCustomAttributes(typeof(ZeroFormattableAttribute), true).FirstOrDefault() == null)
            {
                throw new InvalidOperationException("Type must be marked with ZeroFormattableAttribute. " + type.Name);
            }

            if (isClass)
            {
                if (!type.GetTypeInfo().GetConstructors().Any(x => x.GetParameters().Length == 0))
                {
                    throw new InvalidOperationException("Type must needs parameterless constructor. " + type.Name);
                }
            }

            var dict = new Dictionary <int, EmittableMemberInfo>();

            foreach (var item in type.GetTypeInfo().GetProperties(BindingFlags.Public | BindingFlags.Instance))
            {
                if (item.GetCustomAttributes(typeof(IgnoreFormatAttribute), true).Any())
                {
                    continue;
                }
                // If base property type marked UnionKey, okay.
                var foundUnionKey = false;
                var propInfo      = item;
                do
                {
                    if (propInfo.GetCustomAttributes(typeof(UnionKeyAttribute), true).Any())
                    {
                        foundUnionKey = true;
                        break;
                    }
                    propInfo = null;

                    var baseType = item.DeclaringType.GetTypeInfo().BaseType;
                    if (baseType != null)
                    {
                        var basePropInfo = baseType.GetTypeInfo().GetProperty(item.Name);
                        if (basePropInfo != null)
                        {
                            propInfo = basePropInfo;
                        }
                    }
                } while (propInfo != null);
                if (foundUnionKey)
                {
                    continue;
                }

                var index = item.GetCustomAttributes(typeof(IndexAttribute), true).Cast <IndexAttribute>().FirstOrDefault();
                if (index == null)
                {
                    throw new InvalidOperationException("Public property must be marked with IndexAttribute or IgnoreFormatAttribute. " + type.Name + "." + item.Name);
                }

                var getMethod = item.GetGetMethod(true);
                var setMethod = item.GetSetMethod(true);

                if (isClass)
                {
                    if (getMethod == null || setMethod == null || getMethod.IsPrivate || setMethod.IsPrivate)
                    {
                        throw new InvalidOperationException("Public property must needs both public/protected get and set accessor." + type.Name + "." + item.Name);
                    }
                }

                if (isClass)
                {
                    if (!getMethod.IsVirtual || !setMethod.IsVirtual)
                    {
                        throw new InvalidOperationException("Public property's accessor must be virtual. " + type.Name + "." + item.Name);
                    }
                }

                if (dict.ContainsKey(index.Index))
                {
                    throw new InvalidOperationException("IndexAttribute is not allow duplicate number. " + type.Name + "." + item.Name + ", Index:" + index.Index);
                }

                var info = new EmittableMemberInfo(item);
                VerifyMember(resolverType, info);
                dict[index.Index] = info;
            }

            foreach (var item in type.GetTypeInfo().GetFields(BindingFlags.Public | BindingFlags.Instance))
            {
                if (item.GetCustomAttributes(typeof(IgnoreFormatAttribute), true).Any())
                {
                    continue;
                }

                var index = item.GetCustomAttributes(typeof(IndexAttribute), true).Cast <IndexAttribute>().FirstOrDefault();
                if (index == null)
                {
                    throw new InvalidOperationException("Public field must mark IndexAttribute or IgnoreFormatAttribute. " + type.Name + "." + item.Name);
                }
                else if (isClass)
                {
                    throw new InvalidOperationException("Class does not allow that field marks IndexAttribute. " + type.Name + "." + item.Name);
                }

                if (dict.ContainsKey(index.Index))
                {
                    throw new InvalidOperationException("IndexAttribute is not allow duplicate number. " + type.Name + "." + item.Name + ", Index:" + index.Index);
                }

                var info = new EmittableMemberInfo(item);
                VerifyMember(resolverType, info);
                dict[index.Index] = info;
            }

            return(dict.OrderBy(x => x.Key).Select(x => Tuple.Create(x.Key, x.Value)).ToArray());
        }