Example #1
0
        internal IEnumerable <ITypeModelDifference> FindDifferences(TypeDescription otherType)
        {
            if (SerializationType != otherType.SerializationType)
            {
                return new[]
                       { new SerializationTypeChanged(otherType.AssemblyQualifiedName, SerializationType, otherType.SerializationType) }
            }
            ;

            switch (SerializationType)
            {
            case SerializationType.ByReference:
                return(FindByReferenceDifferences(otherType));

            case SerializationType.ByValue:
                return(FindByValueDifferences(otherType));

            case SerializationType.Singleton:
                return(FindSingletonDifferences(otherType));

            default:
                throw new NotImplementedException();
            }
        }
Example #2
0
 private IEnumerable <ITypeModelDifference> FindSingletonDifferences(TypeDescription otherType)
 {
     throw new NotImplementedException();
 }
Example #3
0
        /// <summary>
        ///     Creates a new description for the given type.
        /// </summary>
        /// <param name="type"></param>
        /// <param name="typesByAssemblyQualifiedName"></param>
        /// <param name="assumeByReference"></param>
        /// <returns></returns>
        public static TypeDescription Create(Type type,
                                             IDictionary <string, TypeDescription> typesByAssemblyQualifiedName,
                                             bool assumeByReference = false)
        {
            if (type == null)
            {
                throw new ArgumentNullException(nameof(type));
            }

            var assemblyQualifiedName = type.AssemblyQualifiedName;

            if (assemblyQualifiedName == null)
            {
                throw new ArgumentException("Type.AssemblyQualifiedName should not be null");
            }

            bool       builtIn, isEnumerable;
            MethodInfo singletonAccessor;
            Type       byReferenceInterface;
            var        serializerType = GetSerializationType(type,
                                                             assumeByReference,
                                                             out builtIn,
                                                             out isEnumerable,
                                                             out singletonAccessor,
                                                             out byReferenceInterface);

            var description = new TypeDescription(type, byReferenceInterface)
            {
                AssemblyQualifiedName = assemblyQualifiedName,
                SerializationType     = serializerType
            };

            typesByAssemblyQualifiedName.Add(assemblyQualifiedName, description);

            var serializationCallbacks = GetSerializationCallbacks(type, typesByAssemblyQualifiedName);

            switch (description.SerializationType)
            {
            case SerializationType.ByValue:
                description.Fields = type.GetFields(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly)
                                     .Where(x => x.GetCustomAttribute <DataMemberAttribute>() != null)
                                     .Select(x => FieldDescription.Create(x, typesByAssemblyQualifiedName)).ToArray();
                description.Properties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly)
                                         .Where(x => x.GetCustomAttribute <DataMemberAttribute>() != null)
                                         .Select(x => PropertyDescription.Create(description, x, typesByAssemblyQualifiedName)).ToArray();
                description.Methods = serializationCallbacks;
                break;

            case SerializationType.ByReference:
                if (serializationCallbacks.Any())
                {
                    throw new ArgumentException(
                              string.Format(
                                  "The type '{0}.{1}' is marked with the [ByReference] attribute and thus may not contain serialization callback methods",
                                  type.Namespace, type.Name));
                }

                description.Fields     = new FieldDescription[0];
                description.Properties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance)
                                         .Select(x => PropertyDescription.Create(description, x, typesByAssemblyQualifiedName)).ToArray();
                description.Methods = type.GetMethods(BindingFlags.Public | BindingFlags.Instance)
                                      .Where(x => !x.IsSpecialName)
                                      .Select(x => MethodDescription.Create(x, typesByAssemblyQualifiedName)).ToArray();
                break;

            case SerializationType.Singleton:
                if (serializationCallbacks.Any())
                {
                    throw new ArgumentException(
                              string.Format(
                                  "The type '{0}.{1}' is a singleton and thus may not contain any serialization callbacks",
                                  type.Namespace, type.Name));
                }

                description.Fields     = new FieldDescription[0];
                description.Properties = new PropertyDescription[0];
                description.Methods    = new[] { MethodDescription.Create(singletonAccessor, typesByAssemblyQualifiedName) };
                break;

            case SerializationType.Unknown:
                description.Fields     = new FieldDescription[0];
                description.Properties = new PropertyDescription[0];
                description.Methods    = new MethodDescription[0];
                break;

            case SerializationType.NotSerializable:
                // TODO: Throw proper exception with proper error message
                throw new NotImplementedException();

            default:
                throw new NotImplementedException();
            }

            if (IsInterestingBaseType(type.BaseType))
            {
                description.BaseType = GetOrCreate(type.BaseType, typesByAssemblyQualifiedName);
            }
            description.IsBuiltIn     = builtIn;
            description.IsValueType   = type.IsValueType;
            description.IsClass       = type.IsClass;
            description.IsInterface   = type.IsInterface;
            description.IsEnum        = type.IsEnum;
            description.IsEnumerable  = isEnumerable;
            description.IsSealed      = type.IsSealed;
            description.IsGenericType = type.IsGenericType;

            if (type.IsGenericType)
            {
                var genericArguments = type.GetGenericArguments();
                var types            = new TypeDescription[genericArguments.Length];
                for (int i = 0; i < genericArguments.Length; ++i)
                {
                    types[i] = GetOrCreate(genericArguments[i], typesByAssemblyQualifiedName);
                }

                description.GenericArguments = types;
            }
            else if (type.IsArray)
            {
                description.GenericArguments = new[]
                {
                    GetOrCreate(type.GetElementType(), typesByAssemblyQualifiedName)
                };
            }
            else
            {
                description.GenericArguments = new TypeDescription[0];
            }

            if (type.IsEnum)
            {
                var storageType = Enum.GetUnderlyingType(type);
                description.StorageType = GetOrCreate(storageType, typesByAssemblyQualifiedName);

                var values       = Enum.GetValues(type).OfType <object>().ToArray();
                var names        = Enum.GetNames(type);
                var descriptions = new EnumValueDescription[values.Length];
                for (int i = 0; i < names.Length; ++i)
                {
                    descriptions[i] = EnumValueDescription.Create(storageType, values[i], names[i]);
                }

                description.EnumValues = descriptions;
            }

            return(description);
        }