/// <summary> /// This is a helper method that makes it simple to run an AOT compilation on the given type. /// </summary> /// <param name="config">The configuration to use when running AOT compilation.</param> /// <param name="type">The type to perform the AOT compilation on.</param> /// <param name="aotCompiledClassInCSharp">The AOT class. Add this C# code to your project.</param> /// <returns>True if AOT compilation was successful.</returns> public static bool TryToPerformAotCompilation(fsConfig config, Type type, out string aotCompiledClassInCSharp) { if (fsMetaType.Get(config, type).EmitAotData()) { aotCompiledClassInCSharp = AvailableAotCompilations[type]; return true; } aotCompiledClassInCSharp = default(string); return false; }
private fsMetaType(fsConfig config, Type reflectedType) { ReflectedType = reflectedType; List<fsMetaProperty> properties = new List<fsMetaProperty>(); CollectProperties(config, properties, reflectedType); Properties = properties.ToArray(); #if UNITY_EDITOR || UNITY_STANDALONE try { if (!ReflectedType.Resolve().IsValueType && ReflectedType.GetDeclaredConstructor(fsPortableReflection.EmptyTypes) != null ){ Generator = Expression.Lambda<Func<object>>(Expression.New(reflectedType)).Compile(); } } catch{Generator = null;} #endif }
private static void CollectProperties(fsConfig config, List <fsMetaProperty> properties, Type reflectedType) { // do we require a [SerializeField] or [fsProperty] attribute? bool requireOptIn = config.DefaultMemberSerialization == fsMemberSerialization.OptIn; bool requireOptOut = config.DefaultMemberSerialization == fsMemberSerialization.OptOut; fsObjectAttribute attr = fsPortableReflection.GetAttribute <fsObjectAttribute>(reflectedType); if (attr != null) { requireOptIn = attr.MemberSerialization == fsMemberSerialization.OptIn; requireOptOut = attr.MemberSerialization == fsMemberSerialization.OptOut; } MemberInfo[] members = reflectedType.GetDeclaredMembers(); foreach (var member in members) { // We don't serialize members annotated with any of the ignore serialize attributes if (config.IgnoreSerializeAttributes.Any(t => fsPortableReflection.HasAttribute(member, t))) { continue; } PropertyInfo property = member as PropertyInfo; FieldInfo field = member as FieldInfo; // Early out if it's neither a field or a property, since we don't serialize anything else. if (property == null && field == null) { continue; } // If an opt-in annotation is required, then skip the property if it doesn't have one // of the serialize attributes if (requireOptIn && !config.SerializeAttributes.Any(t => fsPortableReflection.HasAttribute(member, t))) { continue; } // If an opt-out annotation is required, then skip the property *only if* it has one of // the not serialize attributes if (requireOptOut && config.IgnoreSerializeAttributes.Any(t => fsPortableReflection.HasAttribute(member, t))) { continue; } if (property != null) { if (CanSerializeProperty(config, property, members, requireOptOut)) { properties.Add(new fsMetaProperty(config, property)); } } else if (field != null) { if (CanSerializeField(config, field, requireOptOut)) { properties.Add(new fsMetaProperty(config, field)); } } } if (reflectedType.Resolve().BaseType != null) { CollectProperties(config, properties, reflectedType.Resolve().BaseType); } }
public fsSerializer() { _cachedConverterTypeInstances = new Dictionary <Type, fsBaseConverter>(); _cachedConverters = new Dictionary <Type, fsBaseConverter>(); _cachedProcessors = new Dictionary <Type, List <fsObjectProcessor> >(); _references = new fsCyclicReferenceManager(); _lazyReferenceWriter = new fsLazyCycleDefinitionWriter(); // note: The order here is important. Items at the beginning of this // list will be used before converters at the end. Converters // added via AddConverter() are added to the front of the list. _availableConverters = new List <fsConverter> { new fsNullableConverter { Serializer = this }, new fsGuidConverter { Serializer = this }, new fsTypeConverter { Serializer = this }, new fsDateConverter { Serializer = this }, new fsEnumConverter { Serializer = this }, new fsPrimitiveConverter { Serializer = this }, new fsArrayConverter { Serializer = this }, new fsDictionaryConverter { Serializer = this }, new fsIEnumerableConverter { Serializer = this }, new fsKeyValuePairConverter { Serializer = this }, new fsWeakReferenceConverter { Serializer = this }, new fsReflectedConverter { Serializer = this } }; _availableDirectConverters = new Dictionary <Type, fsDirectConverter>(); _processors = new List <fsObjectProcessor>(); /* * _processors = new List<fsObjectProcessor>() { * new fsSerializationCallbackProcessor() * }; * #if !NO_UNITY * _processors.Add(new fsSerializationCallbackReceiverProcessor()); #endif */ Context = new fsContext(); Config = new fsConfig(); // Register the converters from the registrar foreach (var converterType in fsConverterRegistrar.Converters) { AddConverter((fsBaseConverter)Activator.CreateInstance(converterType)); } }
private static void CollectProperties(fsConfig config, List<fsMetaProperty> properties, Type reflectedType) { // do we require a [SerializeField] or [fsProperty] attribute? bool requireOptIn = config.DefaultMemberSerialization == fsMemberSerialization.OptIn; bool requireOptOut = config.DefaultMemberSerialization == fsMemberSerialization.OptOut; fsObjectAttribute attr = fsPortableReflection.GetAttribute<fsObjectAttribute>(reflectedType); if (attr != null) { requireOptIn = attr.MemberSerialization == fsMemberSerialization.OptIn; requireOptOut = attr.MemberSerialization == fsMemberSerialization.OptOut; } MemberInfo[] members = reflectedType.GetDeclaredMembers(); foreach (var member in members) { // We don't serialize members annotated with any of the ignore serialize attributes if (config.IgnoreSerializeAttributes.Any(t => fsPortableReflection.HasAttribute(member, t))) { continue; } PropertyInfo property = member as PropertyInfo; FieldInfo field = member as FieldInfo; // Early out if it's neither a field or a property, since we don't serialize anything else. if (property == null && field == null) { continue; } // If an opt-in annotation is required, then skip the property if it doesn't have one // of the serialize attributes if (requireOptIn && !config.SerializeAttributes.Any(t => fsPortableReflection.HasAttribute(member, t))) { continue; } // If an opt-out annotation is required, then skip the property *only if* it has one of // the not serialize attributes if (requireOptOut && config.IgnoreSerializeAttributes.Any(t => fsPortableReflection.HasAttribute(member, t))) { continue; } if (property != null) { if (CanSerializeProperty(config, property, members, requireOptOut)) { properties.Add(new fsMetaProperty(config, property)); } } else if (field != null) { if (CanSerializeField(config, field, requireOptOut)) { properties.Add(new fsMetaProperty(config, field)); } } } if (reflectedType.Resolve().BaseType != null) { CollectProperties(config, properties, reflectedType.Resolve().BaseType); } }
/// <summary> /// Returns if the given property should be serialized. /// </summary> /// <param name="annotationFreeValue">Should a property without any annotations be serialized?</param> private static bool CanSerializeProperty(fsConfig config, PropertyInfo property, MemberInfo[] members, bool annotationFreeValue) { // We don't serialize delegates if (typeof(Delegate).IsAssignableFrom(property.PropertyType)) { return false; } var publicGetMethod = property.GetGetMethod(/*nonPublic:*/ false); var publicSetMethod = property.GetSetMethod(/*nonPublic:*/ false); // We do not bother to serialize static fields. if ((publicGetMethod != null && publicGetMethod.IsStatic) || (publicSetMethod != null && publicSetMethod.IsStatic)) { return false; } // Never serialize indexers. I can't think of a sane way to serialize/deserialize them, and they're normally wrappers around other fields anyway... if (property.GetIndexParameters().Length > 0) { return false; } // If a property is annotated with one of the serializable attributes, then it should // it should definitely be serialized. // // NOTE: We place this override check *after* the static check, because we *never* // allow statics to be serialized. if (config.SerializeAttributes.Any(t => fsPortableReflection.HasAttribute(property, t))) { return true; } // If the property cannot be both read and written to, we are not going to serialize it // regardless of the default serialization mode if (property.CanRead == false || property.CanWrite == false) { return false; } // Depending on the configuration options, check whether the property is automatic // and if it has a public setter to determine whether it should be serialized if ((config.SerializeNonAutoProperties || IsAutoProperty(property, members)) && (publicGetMethod != null && (config.SerializeNonPublicSetProperties || publicSetMethod != null))) { return true; } // Otherwise, we don't bother with serialization return annotationFreeValue; }
private static bool CanSerializeField(fsConfig config, FieldInfo field, bool annotationFreeValue) { // We don't serialize delegates if (typeof(Delegate).IsAssignableFrom(field.FieldType)) { return false; } // We don't serialize compiler generated fields. if (field.IsDefined(typeof(CompilerGeneratedAttribute), false)) { return false; } // We don't serialize static fields if (field.IsStatic) { return false; } // We want to serialize any fields annotated with one of the serialize attributes. // // NOTE: This occurs *after* the static check, because we *never* want to serialize // static fields. if (config.SerializeAttributes.Any(t => fsPortableReflection.HasAttribute(field, t))) { return true; } // We use !IsPublic because that also checks for internal, protected, and private. if (!annotationFreeValue && !field.IsPublic) { return false; } return true; }
public static fsMetaType Get(fsConfig config, Type type) { Dictionary<Type, fsMetaType> metaTypes; if (_configMetaTypes.TryGetValue(config, out metaTypes) == false) metaTypes = _configMetaTypes[config] = new Dictionary<Type, fsMetaType>(); fsMetaType metaType; if (metaTypes.TryGetValue(type, out metaType) == false) { metaType = new fsMetaType(config, type); metaTypes[type] = metaType; } return metaType; }