public void ProcessSerializers(CecilSerializerContext context) { // Iterate over each static member of type PropertyKey<> or ParameterKey<> foreach (var type in context.Assembly.EnumerateTypes()) { foreach (var member in type.Fields) { if (!member.IsStatic || member.IsPrivate) { continue; } if (member.FieldType.Name == "PropertyKey`1" || member.FieldType.Name == "ParameterKey`1" || member.FieldType.Name == "ValueParameterKey`1" || member.FieldType.Name == "ObjectParameterKey`1" || member.FieldType.Name == "PermutationParameterKey`1") { context.GenerateSerializer(member.FieldType); var genericType = (GenericInstanceType)member.FieldType; // Also generate serializer for embedded type context.GenerateSerializer(genericType.GenericArguments[0]); } } } }
public void ProcessSerializers(CecilSerializerContext context) { // Iterate over each static member of type PropertyKey<> or ParameterKey<> foreach (var type in context.Assembly.EnumerateTypes()) { foreach (var member in type.Fields) { if (!member.IsStatic || member.IsPrivate) continue; if (member.FieldType.Name == "PropertyKey`1" || member.FieldType.Name == "ParameterKey`1" || member.FieldType.Name == "ValueParameterKey`1" || member.FieldType.Name == "ObjectParameterKey`1" || member.FieldType.Name == "PermutationParameterKey`1") { context.GenerateSerializer(member.FieldType); var genericType = (GenericInstanceType)member.FieldType; // Also generate serializer for embedded type context.GenerateSerializer(genericType.GenericArguments[0]); } } } }
public void ProcessSerializers(CecilSerializerContext context) { var defaultProfile = context.SerializableTypes; foreach (var profile in context.SerializableTypesProfiles) { // Skip default profile if (profile.Value == defaultProfile) continue; defaultProfile.IsFrozen = true; // For each profile, try to instantiate all types existing in default profile foreach (var type in defaultProfile.SerializableTypes) { context.GenerateSerializer(type.Key, false, profile.Key); } } }
private void ProcessDataSerializerGlobalAttributes(CecilSerializerContext context, AssemblyDefinition assembly, bool local) { // Already processed? if (!processedAssemblies.Add(assembly)) { return; } // TODO: Add a flag for ComplexSerializer and transmit it properly (it needs different kind of analysis) // Let's recurse over referenced assemblies foreach (var referencedAssemblyName in assembly.MainModule.AssemblyReferences) { // Avoid processing system assemblies // TODO: Scan what is actually in framework folders if (referencedAssemblyName.Name == "mscorlib" || referencedAssemblyName.Name.StartsWith("System") || referencedAssemblyName.FullName.Contains("PublicKeyToken=31bf3856ad364e35")) // Signed with Microsoft public key (likely part of system libraries) { continue; } var referencedAssembly = context.Assembly.MainModule.AssemblyResolver.Resolve(referencedAssemblyName); ProcessDataSerializerGlobalAttributes(context, referencedAssembly, false); } // Find DataSerializer attribute on assembly and/or types foreach (var dataSerializerAttribute in assembly.CustomAttributes.Concat(assembly.MainModule.Types.SelectMany(x => x.CustomAttributes)).Where( x => x.AttributeType.FullName == "SiliconStudio.Core.Serialization.DataSerializerGlobalAttribute") .OrderBy(x => x.ConstructorArguments[0].Value != null ? -1 : 1)) // Order so that we first have the ones which don't require us to go through GenerateSerializer { var dataSerializerType = (TypeReference)dataSerializerAttribute.ConstructorArguments[0].Value; var dataType = (TypeReference)dataSerializerAttribute.ConstructorArguments[1].Value; var mode = (DataSerializerGenericMode)dataSerializerAttribute.ConstructorArguments[2].Value; var inherited = (bool)dataSerializerAttribute.ConstructorArguments[3].Value; var complexSerializer = (bool)dataSerializerAttribute.ConstructorArguments[4].Value; var profile = dataSerializerAttribute.Properties.Where(x => x.Name == "Profile").Select(x => (string)x.Argument.Value).FirstOrDefault() ?? "Default"; if (dataType == null) { if (mode == DataSerializerGenericMode.None) { dataType = FindSerializerDataType(dataSerializerType); } else { throw new InvalidOperationException("Can't deduce data serializer type for generic types."); } } CecilSerializerContext.SerializableTypeInfo serializableTypeInfo; if (dataSerializerType == null) { // TODO: We should avoid calling GenerateSerializer now just to have the dataSerializerType (we should do so only in a second step) serializableTypeInfo = context.GenerateSerializer(dataType, profile: profile); if (serializableTypeInfo == null) { throw new InvalidOperationException(string.Format("Can't find serializer for type {0}", dataType)); } serializableTypeInfo.Local = local; serializableTypeInfo.ExistingLocal = local; dataSerializerType = serializableTypeInfo.SerializerType; } else { // Add it to list of serializable types serializableTypeInfo = new CecilSerializerContext.SerializableTypeInfo(dataSerializerType, local, mode) { ExistingLocal = local, Inherited = inherited, ComplexSerializer = complexSerializer }; context.AddSerializableType(dataType, serializableTypeInfo, profile); } } }
private void ProcessDataSerializerGlobalAttributes(CecilSerializerContext context, AssemblyDefinition assembly, bool local) { // Already processed? if (!processedAssemblies.Add(assembly)) return; // TODO: Add a flag for ComplexSerializer and transmit it properly (it needs different kind of analysis) // Let's recurse over referenced assemblies foreach (var referencedAssemblyName in assembly.MainModule.AssemblyReferences.ToArray()) { // Avoid processing system assemblies // TODO: Scan what is actually in framework folders if (referencedAssemblyName.Name == "mscorlib" || referencedAssemblyName.Name.StartsWith("System") || referencedAssemblyName.FullName.Contains("PublicKeyToken=31bf3856ad364e35") // Signed with Microsoft public key (likely part of system libraries) || referencedAssemblyName.Name.StartsWith("SharpDX")) continue; try { var referencedAssembly = context.Assembly.MainModule.AssemblyResolver.Resolve(referencedAssemblyName); ProcessDataSerializerGlobalAttributes(context, referencedAssembly, false); } catch (AssemblyResolutionException) { continue; } } // Find DataSerializer attribute on assembly and/or types foreach (var dataSerializerAttribute in assembly.CustomAttributes.Concat(assembly.MainModule.Types.SelectMany(x => x.CustomAttributes)).Where( x => x.AttributeType.FullName == "SiliconStudio.Core.Serialization.DataSerializerGlobalAttribute") .OrderBy(x => x.ConstructorArguments[0].Value != null ? -1 : 1)) // Order so that we first have the ones which don't require us to go through GenerateSerializer { var dataSerializerType = (TypeReference)dataSerializerAttribute.ConstructorArguments[0].Value; var dataType = (TypeReference)dataSerializerAttribute.ConstructorArguments[1].Value; var mode = (DataSerializerGenericMode)dataSerializerAttribute.ConstructorArguments[2].Value; var inherited = (bool)dataSerializerAttribute.ConstructorArguments[3].Value; var complexSerializer = (bool)dataSerializerAttribute.ConstructorArguments[4].Value; var profile = dataSerializerAttribute.Properties.Where(x => x.Name == "Profile").Select(x => (string)x.Argument.Value).FirstOrDefault() ?? "Default"; if (dataType == null) { if (mode == DataSerializerGenericMode.None) dataType = FindSerializerDataType(dataSerializerType); else throw new InvalidOperationException("Can't deduce data serializer type for generic types."); } CecilSerializerContext.SerializableTypeInfo serializableTypeInfo; if (dataSerializerType == null) { // TODO: We should avoid calling GenerateSerializer now just to have the dataSerializerType (we should do so only in a second step) serializableTypeInfo = context.GenerateSerializer(dataType, profile: profile); if (serializableTypeInfo == null) throw new InvalidOperationException(string.Format("Can't find serializer for type {0}", dataType)); serializableTypeInfo.Local = local; serializableTypeInfo.ExistingLocal = local; dataSerializerType = serializableTypeInfo.SerializerType; } else { // Add it to list of serializable types serializableTypeInfo = new CecilSerializerContext.SerializableTypeInfo(dataSerializerType, local, mode) { ExistingLocal = local, Inherited = inherited, ComplexSerializer = complexSerializer }; context.AddSerializableType(dataType, serializableTypeInfo, profile); } } }