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); } }
/// <summary> /// Create the template output /// </summary> public virtual string TransformText() { this.Write("\r\n"); #line 7 "C:\DEV\paradox\sources\common\core\SiliconStudio.AssemblyProcessor.Common\ComplexClassSerializerGenerator.tt" var className = SerializerTypeName(type, true, true); var parentType = hasParentSerializer ? ResolveGenericsVisitor.Process(type, type.BaseType) : null; #line default #line hidden this.Write("\r\nnamespace SiliconStudio.DataSerializers\r\n{\r\n\t"); #line 14 "C:\DEV\paradox\sources\common\core\SiliconStudio.AssemblyProcessor.Common\ComplexClassSerializerGenerator.tt" if (type.HasGenericParameters) { #line default #line hidden this.Write("public "); #line 14 "C:\DEV\paradox\sources\common\core\SiliconStudio.AssemblyProcessor.Common\ComplexClassSerializerGenerator.tt" } #line default #line hidden this.Write("sealed class "); #line 14 "C:\DEV\paradox\sources\common\core\SiliconStudio.AssemblyProcessor.Common\ComplexClassSerializerGenerator.tt" this.Write(this.ToStringHelper.ToStringWithCulture(className)); #line default #line hidden this.Write(" : "); #line 14 "C:\DEV\paradox\sources\common\core\SiliconStudio.AssemblyProcessor.Common\ComplexClassSerializerGenerator.tt" this.Write(this.ToStringHelper.ToStringWithCulture(type.IsClass && !type.IsValueType && !type.IsAbstract && HasEmptyConstructor(type) ? "Class" : string.Empty)); #line default #line hidden this.Write("DataSerializer<"); #line 14 "C:\DEV\paradox\sources\common\core\SiliconStudio.AssemblyProcessor.Common\ComplexClassSerializerGenerator.tt" this.Write(this.ToStringHelper.ToStringWithCulture(type.ConvertCSharp())); #line default #line hidden this.Write(">, IDataSerializerInitializer"); #line 14 "C:\DEV\paradox\sources\common\core\SiliconStudio.AssemblyProcessor.Common\ComplexClassSerializerGenerator.tt" this.Write(this.ToStringHelper.ToStringWithCulture(GenerateGenericConstraints(type))); #line default #line hidden this.Write("\r\n\t{\r\n"); #line 16 "C:\DEV\paradox\sources\common\core\SiliconStudio.AssemblyProcessor.Common\ComplexClassSerializerGenerator.tt" if (hasParentSerializer) { #line default #line hidden this.Write("\t\tprivate DataSerializer<"); #line 17 "C:\DEV\paradox\sources\common\core\SiliconStudio.AssemblyProcessor.Common\ComplexClassSerializerGenerator.tt" this.Write(this.ToStringHelper.ToStringWithCulture(parentType.ConvertCSharp())); #line default #line hidden this.Write("> parentSerializer;\r\n"); #line 18 "C:\DEV\paradox\sources\common\core\SiliconStudio.AssemblyProcessor.Common\ComplexClassSerializerGenerator.tt" } var serializableItems = GetSerializableItems(type, true).ToArray(); #line default #line hidden #line 21 "C:\DEV\paradox\sources\common\core\SiliconStudio.AssemblyProcessor.Common\ComplexClassSerializerGenerator.tt" foreach (var serializableItem in serializableItems) { #line default #line hidden this.Write("\t\tprivate DataSerializer<"); #line 22 "C:\DEV\paradox\sources\common\core\SiliconStudio.AssemblyProcessor.Common\ComplexClassSerializerGenerator.tt" this.Write(this.ToStringHelper.ToStringWithCulture(serializableItem.Type.ConvertCSharp())); #line default #line hidden this.Write("> "); #line 22 "C:\DEV\paradox\sources\common\core\SiliconStudio.AssemblyProcessor.Common\ComplexClassSerializerGenerator.tt" this.Write(this.ToStringHelper.ToStringWithCulture(serializableItem.MemberInfo.Name)); #line default #line hidden this.Write("Serializer;\r\n"); #line 23 "C:\DEV\paradox\sources\common\core\SiliconStudio.AssemblyProcessor.Common\ComplexClassSerializerGenerator.tt" } #line default #line hidden this.Write("\r\n\t\tpublic void Initialize(SerializerSelector serializerSelector)\r\n\t\t{\r\n"); #line 27 "C:\DEV\paradox\sources\common\core\SiliconStudio.AssemblyProcessor.Common\ComplexClassSerializerGenerator.tt" if (hasParentSerializer) { #line default #line hidden this.Write("\t\t\t// Get parent serializer\r\n\t\t\tparentSerializer = serializerSelector.GetSerializ" + "er<"); #line 29 "C:\DEV\paradox\sources\common\core\SiliconStudio.AssemblyProcessor.Common\ComplexClassSerializerGenerator.tt" this.Write(this.ToStringHelper.ToStringWithCulture(parentType.ConvertCSharp())); #line default #line hidden this.Write(">();\r\n\t\t\tif (parentSerializer == null)\r\n\t\t\t\tthrow new InvalidOperationException(s" + "tring.Format(\"Could not find parent serializer for type {0}\", @\""); #line 31 "C:\DEV\paradox\sources\common\core\SiliconStudio.AssemblyProcessor.Common\ComplexClassSerializerGenerator.tt" this.Write(this.ToStringHelper.ToStringWithCulture(parentType.ConvertCSharp())); #line default #line hidden this.Write("\"));\r\n"); #line 32 "C:\DEV\paradox\sources\common\core\SiliconStudio.AssemblyProcessor.Common\ComplexClassSerializerGenerator.tt" } #line default #line hidden this.Write("\t\t\t// Cache member serializers\r\n"); #line 34 "C:\DEV\paradox\sources\common\core\SiliconStudio.AssemblyProcessor.Common\ComplexClassSerializerGenerator.tt" foreach (var serializableItem in serializableItems) { #line default #line hidden this.Write("\t\t\t"); #line 35 "C:\DEV\paradox\sources\common\core\SiliconStudio.AssemblyProcessor.Common\ComplexClassSerializerGenerator.tt" this.Write(this.ToStringHelper.ToStringWithCulture(serializableItem.MemberInfo.Name)); #line default #line hidden this.Write("Serializer = MemberSerializer<"); #line 35 "C:\DEV\paradox\sources\common\core\SiliconStudio.AssemblyProcessor.Common\ComplexClassSerializerGenerator.tt" this.Write(this.ToStringHelper.ToStringWithCulture(serializableItem.Type.ConvertCSharp())); #line default #line hidden this.Write(">.Create(serializerSelector);\r\n"); #line 36 "C:\DEV\paradox\sources\common\core\SiliconStudio.AssemblyProcessor.Common\ComplexClassSerializerGenerator.tt" } #line default #line hidden this.Write("\t\t}\r\n\r\n\t\tpublic override void Serialize(ref "); #line 39 "C:\DEV\paradox\sources\common\core\SiliconStudio.AssemblyProcessor.Common\ComplexClassSerializerGenerator.tt" this.Write(this.ToStringHelper.ToStringWithCulture(type.ConvertCSharp())); #line default #line hidden this.Write(" obj, ArchiveMode mode, SerializationStream stream)\r\n\t\t{\r\n"); #line 41 "C:\DEV\paradox\sources\common\core\SiliconStudio.AssemblyProcessor.Common\ComplexClassSerializerGenerator.tt" if (hasParentSerializer) { #line default #line hidden this.Write("\t\t\t// Serialize parent (for now we don\'t copy reference back because it shouldn\'t" + " change)\r\n\t\t\t"); #line 43 "C:\DEV\paradox\sources\common\core\SiliconStudio.AssemblyProcessor.Common\ComplexClassSerializerGenerator.tt" this.Write(this.ToStringHelper.ToStringWithCulture(parentType.ConvertCSharp())); #line default #line hidden this.Write(" parentObj = obj;\r\n\t\t\tparentSerializer.Serialize(ref parentObj, mode, stream);\r\n\t" + "\t\tobj = ("); #line 45 "C:\DEV\paradox\sources\common\core\SiliconStudio.AssemblyProcessor.Common\ComplexClassSerializerGenerator.tt" this.Write(this.ToStringHelper.ToStringWithCulture(type.ConvertCSharp())); #line default #line hidden this.Write(")parentObj;\r\n\r\n"); #line 47 "C:\DEV\paradox\sources\common\core\SiliconStudio.AssemblyProcessor.Common\ComplexClassSerializerGenerator.tt" } foreach (var serializableItem in serializableItems) { var memberType = serializableItem.Type; var memberTypeName = serializableItem.Type.ConvertCSharp(); var memberName = serializableItem.MemberInfo.Name; var memberAssignBack = serializableItem.AssignBack; var memberVariableName = (serializableItem.MemberInfo is PropertyDefinition || !memberAssignBack) ? CreateMemberVariableName(serializableItem.MemberInfo) : null; var memberAccessName = memberVariableName != null ? memberVariableName : "obj." + memberName; if (serializableItem.HasFixedAttribute) { #line default #line hidden this.Write("\t\tthrow new NotImplementedException(\"FixedBuffer attribute is not supported.\");\r\n" + ""); #line 59 "C:\DEV\paradox\sources\common\core\SiliconStudio.AssemblyProcessor.Common\ComplexClassSerializerGenerator.tt" } else { if (memberVariableName != null) { #line default #line hidden this.Write(" "); #line 64 "C:\DEV\paradox\sources\common\core\SiliconStudio.AssemblyProcessor.Common\ComplexClassSerializerGenerator.tt" this.Write(this.ToStringHelper.ToStringWithCulture(memberTypeName)); #line default #line hidden this.Write(" "); #line 64 "C:\DEV\paradox\sources\common\core\SiliconStudio.AssemblyProcessor.Common\ComplexClassSerializerGenerator.tt" this.Write(this.ToStringHelper.ToStringWithCulture(memberVariableName)); #line default #line hidden this.Write(" = "); #line 64 "C:\DEV\paradox\sources\common\core\SiliconStudio.AssemblyProcessor.Common\ComplexClassSerializerGenerator.tt" if (memberAssignBack) { #line default #line hidden this.Write("mode == ArchiveMode.Serialize ? obj."); #line 64 "C:\DEV\paradox\sources\common\core\SiliconStudio.AssemblyProcessor.Common\ComplexClassSerializerGenerator.tt" this.Write(this.ToStringHelper.ToStringWithCulture(memberName)); #line default #line hidden this.Write(" : default("); #line 64 "C:\DEV\paradox\sources\common\core\SiliconStudio.AssemblyProcessor.Common\ComplexClassSerializerGenerator.tt" this.Write(this.ToStringHelper.ToStringWithCulture(memberTypeName)); #line default #line hidden this.Write(")"); #line 64 "C:\DEV\paradox\sources\common\core\SiliconStudio.AssemblyProcessor.Common\ComplexClassSerializerGenerator.tt" } else { #line default #line hidden this.Write("obj."); #line 64 "C:\DEV\paradox\sources\common\core\SiliconStudio.AssemblyProcessor.Common\ComplexClassSerializerGenerator.tt" this.Write(this.ToStringHelper.ToStringWithCulture(memberName)); #line default #line hidden #line 64 "C:\DEV\paradox\sources\common\core\SiliconStudio.AssemblyProcessor.Common\ComplexClassSerializerGenerator.tt" } #line default #line hidden this.Write(";\r\n"); #line 65 "C:\DEV\paradox\sources\common\core\SiliconStudio.AssemblyProcessor.Common\ComplexClassSerializerGenerator.tt" } #line default #line hidden this.Write(" "); #line 66 "C:\DEV\paradox\sources\common\core\SiliconStudio.AssemblyProcessor.Common\ComplexClassSerializerGenerator.tt" this.Write(this.ToStringHelper.ToStringWithCulture(serializableItem.MemberInfo.Name)); #line default #line hidden this.Write("Serializer.Serialize(ref "); #line 66 "C:\DEV\paradox\sources\common\core\SiliconStudio.AssemblyProcessor.Common\ComplexClassSerializerGenerator.tt" this.Write(this.ToStringHelper.ToStringWithCulture(memberAccessName)); #line default #line hidden this.Write(", mode, stream);\r\n"); #line 67 "C:\DEV\paradox\sources\common\core\SiliconStudio.AssemblyProcessor.Common\ComplexClassSerializerGenerator.tt" if (memberVariableName != null && memberAssignBack) { #line default #line hidden this.Write(" obj."); #line 69 "C:\DEV\paradox\sources\common\core\SiliconStudio.AssemblyProcessor.Common\ComplexClassSerializerGenerator.tt" this.Write(this.ToStringHelper.ToStringWithCulture(memberName)); #line default #line hidden this.Write(" = "); #line 69 "C:\DEV\paradox\sources\common\core\SiliconStudio.AssemblyProcessor.Common\ComplexClassSerializerGenerator.tt" this.Write(this.ToStringHelper.ToStringWithCulture(memberVariableName)); #line default #line hidden this.Write(";\r\n"); #line 70 "C:\DEV\paradox\sources\common\core\SiliconStudio.AssemblyProcessor.Common\ComplexClassSerializerGenerator.tt" } } } #line default #line hidden this.Write("\t\t}\r\n\r\n\t\tinternal static void ForceGenericInstantiation()\r\n\t\t{\r\n"); #line 77 "C:\DEV\paradox\sources\common\core\SiliconStudio.AssemblyProcessor.Common\ComplexClassSerializerGenerator.tt" foreach (var memberSerializerType in EnumerateSerializerTypes(serializableItems.Select(x => x.Type))) { #line default #line hidden this.Write("\t\t\ttypeof("); #line 79 "C:\DEV\paradox\sources\common\core\SiliconStudio.AssemblyProcessor.Common\ComplexClassSerializerGenerator.tt" this.Write(this.ToStringHelper.ToStringWithCulture(memberSerializerType.ConvertCSharp())); #line default #line hidden this.Write(").ToString();\r\n"); #line 80 "C:\DEV\paradox\sources\common\core\SiliconStudio.AssemblyProcessor.Common\ComplexClassSerializerGenerator.tt" } #line default #line hidden this.Write("\t\t}\r\n\t}\r\n}"); return(this.GenerationEnvironment.ToString()); }
public void ProcessSerializers(CecilSerializerContext context) { var references = new HashSet <AssemblyDefinition>(); EnumerateReferences(references, context.Assembly); var coreAssembly = CecilExtensions.FindCorlibAssembly(context.Assembly); // Only process assemblies depending on Xenko.Engine if (!references.Any(x => x.Name.Name == "SiliconStudio.Xenko.Engine")) { // Make sure Xenko.Engine.Serializers can access everything internally var internalsVisibleToAttribute = coreAssembly.MainModule.GetTypeResolved(typeof(InternalsVisibleToAttribute).FullName); var serializationAssemblyName = "SiliconStudio.Xenko.Engine.Serializers"; // Add [InteralsVisibleTo] attribute var internalsVisibleToAttributeCtor = context.Assembly.MainModule.ImportReference(internalsVisibleToAttribute.GetConstructors().Single()); var internalsVisibleAttribute = new CustomAttribute(internalsVisibleToAttributeCtor) { ConstructorArguments = { new CustomAttributeArgument(context.Assembly.MainModule.ImportReference(context.Assembly.MainModule.TypeSystem.String), serializationAssemblyName) } }; context.Assembly.CustomAttributes.Add(internalsVisibleAttribute); return; } // Get or create method var updateEngineType = GetOrCreateUpdateType(context.Assembly, true); var mainPrepareMethod = new MethodDefinition("UpdateMain", MethodAttributes.HideBySig | MethodAttributes.Assembly | MethodAttributes.Static, context.Assembly.MainModule.TypeSystem.Void); updateEngineType.Methods.Add(mainPrepareMethod); // Get some useful Cecil objects from SiliconStudio.Core var siliconStudioCoreAssembly = context.Assembly.Name.Name == "SiliconStudio.Core" ? context.Assembly : context.Assembly.MainModule.AssemblyResolver.Resolve("SiliconStudio.Core"); var siliconStudioCoreModule = siliconStudioCoreAssembly.MainModule; var siliconStudioXenkoEngineAssembly = context.Assembly.Name.Name == "SiliconStudio.Xenko.Engine" ? context.Assembly : context.Assembly.MainModule.AssemblyResolver.Resolve("SiliconStudio.Xenko.Engine"); var siliconStudioXenkoEngineModule = siliconStudioXenkoEngineAssembly.MainModule; // Generate IL for SiliconStudio.Core if (context.Assembly.Name.Name == "SiliconStudio.Xenko.Engine") { ProcessXenkoEngineAssembly(context); } else { #if true || SILICONSTUDIO_XENKO_XAMARIN_CALLI_BUG // We still process UpdatableProperty<T> since we had to revert it back when writing back Xenko.Engine (otherwise it crashes at AOT on iOS) new UpdatablePropertyCodeGenerator(siliconStudioXenkoEngineAssembly).GenerateUpdatablePropertyCode(); #endif } animationDataType = siliconStudioXenkoEngineModule.GetType("SiliconStudio.Xenko.Animations.AnimationData`1"); var updatableFieldGenericType = siliconStudioXenkoEngineModule.GetType("SiliconStudio.Xenko.Updater.UpdatableField`1"); updatableFieldGenericCtor = updatableFieldGenericType.Methods.First(x => x.IsConstructor && !x.IsStatic); updatablePropertyGenericType = siliconStudioXenkoEngineModule.GetType("SiliconStudio.Xenko.Updater.UpdatableProperty`1"); updatablePropertyGenericCtor = updatablePropertyGenericType.Methods.First(x => x.IsConstructor && !x.IsStatic); var updatablePropertyObjectGenericType = siliconStudioXenkoEngineModule.GetType("SiliconStudio.Xenko.Updater.UpdatablePropertyObject`1"); updatablePropertyObjectGenericCtor = updatablePropertyObjectGenericType.Methods.First(x => x.IsConstructor && !x.IsStatic); var updatableListUpdateResolverGenericType = siliconStudioXenkoEngineModule.GetType("SiliconStudio.Xenko.Updater.ListUpdateResolver`1"); updatableListUpdateResolverGenericCtor = updatableListUpdateResolverGenericType.Methods.First(x => x.IsConstructor && !x.IsStatic); var updatableArrayUpdateResolverGenericType = siliconStudioXenkoEngineModule.GetType("SiliconStudio.Xenko.Updater.ArrayUpdateResolver`1"); updatableArrayUpdateResolverGenericCtor = updatableArrayUpdateResolverGenericType.Methods.First(x => x.IsConstructor && !x.IsStatic); var registerMemberMethod = siliconStudioXenkoEngineModule.GetType("SiliconStudio.Xenko.Updater.UpdateEngine").Methods.First(x => x.Name == "RegisterMember"); var pclVisitor = new PclFixupTypeVisitor(coreAssembly); pclVisitor.VisitMethod(registerMemberMethod); updateEngineRegisterMemberMethod = context.Assembly.MainModule.ImportReference(registerMemberMethod); var registerMemberResolverMethod = siliconStudioXenkoEngineModule.GetType("SiliconStudio.Xenko.Updater.UpdateEngine").Methods.First(x => x.Name == "RegisterMemberResolver"); pclVisitor.VisitMethod(registerMemberResolverMethod); updateEngineRegisterMemberResolverMethod = context.Assembly.MainModule.ImportReference(registerMemberResolverMethod); var typeType = coreAssembly.MainModule.GetTypeResolved(typeof(Type).FullName); getTypeFromHandleMethod = context.Assembly.MainModule.ImportReference(typeType.Methods.First(x => x.Name == "GetTypeFromHandle")); // Make sure it is called at module startup var moduleInitializerAttribute = siliconStudioCoreModule.GetType("SiliconStudio.Core.ModuleInitializerAttribute"); var ctorMethod = moduleInitializerAttribute.GetConstructors().Single(x => !x.IsStatic && !x.HasParameters); pclVisitor.VisitMethod(ctorMethod); mainPrepareMethod.CustomAttributes.Add(new CustomAttribute(context.Assembly.MainModule.ImportReference(ctorMethod))); // Emit serialization code for all the types we care about var processedTypes = new HashSet <TypeDefinition>(TypeReferenceEqualityComparer.Default); foreach (var serializableType in context.SerializableTypesProfiles.SelectMany(x => x.Value.SerializableTypes)) { // Special case: when processing Xenko.Engine assembly, we automatically add dependent assemblies types too if (!serializableType.Value.Local && siliconStudioXenkoEngineAssembly != context.Assembly) { continue; } var typeDefinition = serializableType.Key as TypeDefinition; if (typeDefinition == null) { continue; } // Ignore already processed types if (!processedTypes.Add(typeDefinition)) { continue; } try { ProcessType(context, typeDefinition, mainPrepareMethod); } catch (Exception e) { throw new InvalidOperationException(string.Format("Error when generating update engine code for {0}", typeDefinition), e); } } // Force generic instantiations var il = mainPrepareMethod.Body.GetILProcessor(); foreach (var serializableType in context.SerializableTypesProfiles.SelectMany(x => x.Value.SerializableTypes).ToArray()) { // Special case: when processing Xenko.Engine assembly, we automatically add dependent assemblies types too if (!serializableType.Value.Local && siliconStudioXenkoEngineAssembly != context.Assembly) { continue; } // Make sure AnimationData<T> is serializable //if (serializableType.Value.Mode == DataSerializerGenericMode.None) // context.GenerateSerializer(context.Assembly.MainModule.ImportReference(animationDataType).MakeGenericType(context.Assembly.MainModule.ImportReference(serializableType.Key))); // Try to find if original method definition was generated var typeDefinition = serializableType.Key.Resolve(); // If using List<T>, register this type in UpdateEngine var listInterfaceType = typeDefinition.Interfaces.OfType <GenericInstanceType>().FirstOrDefault(x => x.ElementType.FullName == typeof(IList <>).FullName); if (listInterfaceType != null) { //call Updater.UpdateEngine.RegisterMemberResolver(new Updater.ListUpdateResolver<T>()); var elementType = ResolveGenericsVisitor.Process(serializableType.Key, listInterfaceType.GenericArguments[0]); il.Emit(OpCodes.Newobj, context.Assembly.MainModule.ImportReference(updatableListUpdateResolverGenericCtor).MakeGeneric(context.Assembly.MainModule.ImportReference(elementType).FixupValueType())); il.Emit(OpCodes.Call, updateEngineRegisterMemberResolverMethod); } // Same for arrays var arrayType = serializableType.Key as ArrayType; if (arrayType != null) { //call Updater.UpdateEngine.RegisterMemberResolver(new Updater.ArrayUpdateResolver<T>()); var elementType = ResolveGenericsVisitor.Process(serializableType.Key, arrayType.ElementType); il.Emit(OpCodes.Newobj, context.Assembly.MainModule.ImportReference(updatableArrayUpdateResolverGenericCtor).MakeGeneric(context.Assembly.MainModule.ImportReference(elementType).FixupValueType())); il.Emit(OpCodes.Call, updateEngineRegisterMemberResolverMethod); } var genericInstanceType = serializableType.Key as GenericInstanceType; if (genericInstanceType != null) { var expectedUpdateMethodName = ComputeUpdateMethodName(typeDefinition); var updateMethod = GetOrCreateUpdateType(typeDefinition.Module.Assembly, false)?.Methods.FirstOrDefault(x => x.Name == expectedUpdateMethodName && x.HasGenericParameters && x.GenericParameters.Count == genericInstanceType.GenericParameters.Count); // If nothing was found in main assembly, also look in SiliconStudio.Xenko.Engine assembly, just in case (it might defines some shared/corlib types -- currently not the case) if (updateMethod == null) { updateMethod = GetOrCreateUpdateType(siliconStudioXenkoEngineAssembly, false)?.Methods.FirstOrDefault(x => x.Name == expectedUpdateMethodName && x.HasGenericParameters && x.GenericParameters.Count == genericInstanceType.GenericParameters.Count); } if (updateMethod != null) { // Emit call to update engine setup method with generic arguments of current type il.Emit(OpCodes.Call, context.Assembly.MainModule.ImportReference(updateMethod) .MakeGenericMethod(genericInstanceType.GenericArguments .Select(context.Assembly.MainModule.ImportReference) .Select(CecilExtensions.FixupValueType).ToArray())); } } } il.Emit(OpCodes.Ret); #if true || SILICONSTUDIO_XENKO_XAMARIN_CALLI_BUG // Due to Xamarin iOS AOT limitation, we can't keep this type around because it fails compilation if (context.Assembly.Name.Name == "SiliconStudio.Xenko.Engine") { NotImplementedBody(updatablePropertyGenericType.Methods.First(x => x.Name == "GetStructAndUnbox")); NotImplementedBody(updatablePropertyGenericType.Methods.First(x => x.Name == "GetBlittable")); NotImplementedBody(updatablePropertyGenericType.Methods.First(x => x.Name == "SetStruct")); NotImplementedBody(updatablePropertyGenericType.Methods.First(x => x.Name == "SetBlittable")); } #endif }