Exemplo n.º 1
0
        internal static bool IsMemberIgnored(ICollection <CustomAttribute> customAttributes, ComplexTypeSerializerFlags flags, DataMemberMode dataMemberMode)
        {
            // Check for DataMemberIgnore
            if (customAttributes.Any(x => x.AttributeType.FullName == "Stride.Core.DataMemberIgnoreAttribute"))
            {
                // Still allow members with DataMemberUpdatable if we are running UpdateEngineProcessor
                if (!((flags & ComplexTypeSerializerFlags.Updatable) != 0 &&
                      customAttributes.Any(x => x.AttributeType.FullName == "Stride.Updater.DataMemberUpdatableAttribute")))
                {
                    return(true);
                }
            }
            var dataMemberAttribute = customAttributes.FirstOrDefault(x => x.AttributeType.FullName == "Stride.Core.DataMemberAttribute");

            if (dataMemberAttribute != null)
            {
                var dataMemberModeArg = dataMemberAttribute.ConstructorArguments.FirstOrDefault(x => x.Type.Name == nameof(DataMemberMode));
                if (dataMemberModeArg.Value != null)
                {
                    dataMemberMode = (DataMemberMode)(int)dataMemberModeArg.Value;
                }
                else
                {
                    // Default value if not specified in .ctor
                    dataMemberMode = DataMemberMode.Default;
                }
            }

            // Ignored?
            if (dataMemberMode == DataMemberMode.Never)
            {
                return(true);
            }

            return(false);
        }
 private static bool IsMemberIgnored(ICollection<CustomAttribute> customAttributes, ComplexTypeSerializerFlags flags)
 {
     // Check for DataMemberIgnore
     if (customAttributes.Any(x => x.AttributeType.FullName == "SiliconStudio.Core.DataMemberIgnoreAttribute"))
     {
         // Still allow members with DataMemberUpdatable if we are running UpdateEngineProcessor
         if (!((flags & ComplexTypeSerializerFlags.Updatable) != 0
               && customAttributes.Any(x => x.AttributeType.FullName == "SiliconStudio.Xenko.Updater.DataMemberUpdatableAttribute")))
             return true;
     }
     return false;
 }
        public static IEnumerable<SerializableItem> GetSerializableItems(TypeReference type, bool serializeFields, ComplexTypeSerializerFlags? flagsOverride = null)
        {
            foreach (var serializableItemOriginal in GetSerializableItems(type.Resolve(), serializeFields, flagsOverride))
            {
                var serializableItem = serializableItemOriginal;

                // Try to resolve open generic types with context to have closed types.
                if (serializableItem.Type.ContainsGenericParameter())
                {
                    serializableItem.Type = ResolveGenericsVisitor.Process(type, serializableItem.Type);
                }

                yield return serializableItem;
            }
        }
        public static IEnumerable<SerializableItem> GetSerializableItems(TypeDefinition type, bool serializeFields, ComplexTypeSerializerFlags? flagsOverride = null)
        {
            ComplexTypeSerializerFlags flags;

            var fields = new List<FieldDefinition>();
            var properties = new List<PropertyDefinition>();

            var fieldEnum = type.Fields.Where(x => (x.IsPublic || (x.IsAssembly && x.CustomAttributes.Any(a => a.AttributeType.FullName == "SiliconStudio.Core.DataMemberAttribute"))) && !x.IsStatic && !ignoredMembers.Contains(x));

            // If there is a explicit or sequential layout, use offset, otherwise use name
            // (not sure if Cecil follow declaration order, in which case it could be OK to not sort;
            // sorting has the advantage of being more resistant to type upgrade, when field is added/remove, as long as field name is saved)
            if (type.IsSequentialLayout || type.IsExplicitLayout)
                fieldEnum = fieldEnum.OrderBy(x => x.Offset);
            else
                fieldEnum = fieldEnum.OrderBy(x => x.Name);

            foreach (var field in fieldEnum)
            {
                fields.Add(field);
            }

            foreach (var property in type.Properties.OrderBy(x => x.Name))
            {
                // Need a non-static public get method
                if (property.GetMethod == null || !property.GetMethod.IsPublic || property.GetMethod.IsStatic)
                    continue;

                // If it's a struct (!IsValueType), we need a public set method as well
                if (property.PropertyType.IsValueType && (property.SetMethod == null || !(property.SetMethod.IsAssembly || property.SetMethod.IsPublic)))
                    continue;

                // Only take virtual properties (override ones will be handled by parent serializers)
                if (property.GetMethod.IsVirtual && !property.GetMethod.IsNewSlot)
                {
                    // Exception: if this one has a DataMember, let's assume parent one was Ignore and we explicitly want to serialize this one
                    if (!property.CustomAttributes.Any(x => x.AttributeType.FullName == "SiliconStudio.Core.DataMemberAttribute"))
                        continue;
                }

                // Ignore blacklisted properties
                if (ignoredMembers.Contains(property))
                    continue;

                properties.Add(property);
            }

            if (flagsOverride.HasValue)
                flags = flagsOverride.Value;
            else if (type.IsClass && !type.IsValueType)
                flags = ComplexTypeSerializerFlags.SerializePublicFields | ComplexTypeSerializerFlags.SerializePublicProperties;
            else if (type.Fields.Any(x => x.IsPublic && !x.IsStatic))
                flags = ComplexTypeSerializerFlags.SerializePublicFields;
            else
                flags = ComplexTypeSerializerFlags.SerializePublicProperties;

            if ((flags & ComplexTypeSerializerFlags.SerializePublicFields) != 0)
            {
                foreach (var field in fields)
                {
                    if (IsMemberIgnored(field.CustomAttributes, flags)) continue;
                    var attributes = field.CustomAttributes;
                    var fixedAttribute = field.CustomAttributes.FirstOrDefault(x => x.AttributeType.FullName == typeof(FixedBufferAttribute).FullName);
                    var assignBack = !field.IsInitOnly;

                    // If not assigned back, check that type is serializable in place
                    if (!assignBack && !IsReadOnlyTypeSerializable(field.FieldType))
                        continue;

                    yield return new SerializableItem { MemberInfo = field, Type = field.FieldType, Name = field.Name, Attributes = attributes, AssignBack = assignBack, NeedReference = false, HasFixedAttribute = fixedAttribute != null };
                }
            }
            if ((flags & ComplexTypeSerializerFlags.SerializePublicProperties) != 0)
            {
                // Only process properties with public get and set methods
                foreach (var property in properties)
                {
                    // Ignore properties with indexer
                    if (property.GetMethod.Parameters.Count > 0)
                        continue;
                    if (IsMemberIgnored(property.CustomAttributes, flags)) continue;
                    var attributes = property.CustomAttributes;
                    var assignBack = property.SetMethod != null && (property.SetMethod.IsPublic || property.SetMethod.IsAssembly);

                    // If not assigned back, check that type is serializable in place
                    if (!assignBack && !IsReadOnlyTypeSerializable(property.PropertyType))
                        continue;

                    yield return new SerializableItem { MemberInfo = property, Type = property.PropertyType, Name = property.Name, Attributes = attributes, AssignBack = assignBack, NeedReference = !type.IsClass || type.IsValueType };
                }
            }
        }
 private static bool IsMemberIgnored(ICollection <CustomAttribute> customAttributes, ComplexTypeSerializerFlags flags)
 {
     // Check for DataMemberIgnore
     if (customAttributes.Any(x => x.AttributeType.FullName == "SiliconStudio.Core.DataMemberIgnoreAttribute"))
     {
         // Still allow members with DataMemberUpdatable if we are running UpdateEngineProcessor
         if (!((flags & ComplexTypeSerializerFlags.Updatable) != 0 &&
               customAttributes.Any(x => x.AttributeType.FullName == "SiliconStudio.Xenko.Updater.DataMemberUpdatableAttribute")))
         {
             return(true);
         }
     }
     return(false);
 }