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