internal void GenerateSupportedTypes(Type[] types) { _writer.Write("public override "); _writer.Write(typeof(bool).FullName); _writer.Write(" CanSerialize("); _writer.Write(typeof(Type).FullName); _writer.WriteLine(" type) {"); _writer.Indent++; Hashtable uniqueTypes = new Hashtable(); for (int i = 0; i < types.Length; i++) { Type type = types[i]; if (type == null) { continue; } TypeInfo info = type.GetTypeInfo(); if (!info.IsPublic && !info.IsNestedPublic) { continue; } if (uniqueTypes[type] != null) { continue; } if (DynamicAssemblies.IsTypeDynamic(type)) { continue; } if (info.IsGenericType || info.ContainsGenericParameters && DynamicAssemblies.IsTypeDynamic(type.GetGenericArguments())) { continue; } uniqueTypes[type] = type; _writer.Write("if (type == typeof("); _writer.Write(CodeIdentifier.GetCSharpName(type)); _writer.WriteLine(")) return true;"); } _writer.WriteLine("return false;"); _writer.Indent--; _writer.WriteLine("}"); }
internal string GenerateBaseSerializer(string baseSerializer, string readerClass, string writerClass, CodeIdentifiers classes) { baseSerializer = CodeIdentifier.MakeValid(baseSerializer); baseSerializer = classes.AddUnique(baseSerializer, baseSerializer); TypeBuilder baseSerializerTypeBuilder = CodeGenerator.CreateTypeBuilder( _moduleBuilder, CodeIdentifier.GetCSharpName(baseSerializer), TypeAttributes.Public | TypeAttributes.Abstract | TypeAttributes.BeforeFieldInit, typeof(XmlSerializer), CodeGenerator.EmptyTypeArray); ConstructorInfo readerCtor = CreatedTypes[readerClass].GetConstructor(CodeGenerator.EmptyTypeArray); ilg = new CodeGenerator(baseSerializerTypeBuilder); ilg.BeginMethod(typeof(XmlSerializationReader), "CreateReader", CodeGenerator.EmptyTypeArray, CodeGenerator.EmptyStringArray, CodeGenerator.ProtectedOverrideMethodAttributes); ilg.New(readerCtor); ilg.EndMethod(); ConstructorInfo writerCtor = CreatedTypes[writerClass].GetConstructor(CodeGenerator.EmptyTypeArray); ilg.BeginMethod(typeof(XmlSerializationWriter), "CreateWriter", CodeGenerator.EmptyTypeArray, CodeGenerator.EmptyStringArray, CodeGenerator.ProtectedOverrideMethodAttributes); ilg.New(writerCtor); ilg.EndMethod(); baseSerializerTypeBuilder.DefineDefaultConstructor( MethodAttributes.Family | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName); Type baseSerializerType = baseSerializerTypeBuilder.CreateTypeInfo().AsType(); CreatedTypes.Add(baseSerializerType.Name, baseSerializerType); return(baseSerializer); }
internal string GenerateTypedSerializer(string readMethod, string writeMethod, XmlMapping mapping, CodeIdentifiers classes, string baseSerializer, string readerClass, string writerClass) { string serializerName = CodeIdentifier.MakeValid(Accessor.UnescapeName(mapping.Accessor.Mapping.TypeDesc.Name)); serializerName = classes.AddUnique(serializerName + "Serializer", mapping); TypeBuilder typedSerializerTypeBuilder = CodeGenerator.CreateTypeBuilder( _moduleBuilder, CodeIdentifier.GetCSharpName(serializerName), TypeAttributes.Public | TypeAttributes.Sealed | TypeAttributes.BeforeFieldInit, CreatedTypes[baseSerializer], CodeGenerator.EmptyTypeArray ); ilg = new CodeGenerator(typedSerializerTypeBuilder); ilg.BeginMethod( typeof(Boolean), "CanDeserialize", new Type[] { typeof(XmlReader) }, new string[] { "xmlReader" }, CodeGenerator.PublicOverrideMethodAttributes ); if (mapping.Accessor.Any) { ilg.Ldc(true); ilg.Stloc(ilg.ReturnLocal); ilg.Br(ilg.ReturnLabel); } else { MethodInfo XmlReader_IsStartElement = typeof(XmlReader).GetMethod( "IsStartElement", CodeGenerator.InstanceBindingFlags, null, new Type[] { typeof(String), typeof(String) }, null ); ilg.Ldarg(ilg.GetArg("xmlReader")); ilg.Ldstr(mapping.Accessor.Name); ilg.Ldstr(mapping.Accessor.Namespace); ilg.Call(XmlReader_IsStartElement); ilg.Stloc(ilg.ReturnLocal); ilg.Br(ilg.ReturnLabel); } ilg.MarkLabel(ilg.ReturnLabel); ilg.Ldloc(ilg.ReturnLocal); ilg.EndMethod(); if (writeMethod != null) { ilg = new CodeGenerator(typedSerializerTypeBuilder); ilg.BeginMethod( typeof(void), "Serialize", new Type[] { typeof(object), typeof(XmlSerializationWriter) }, new string[] { "objectToSerialize", "writer" }, CodeGenerator.ProtectedOverrideMethodAttributes); MethodInfo writerType_writeMethod = CreatedTypes[writerClass].GetMethod( writeMethod, CodeGenerator.InstanceBindingFlags, null, new Type[] { (mapping is XmlMembersMapping) ? typeof(object[]) : typeof(object) }, null ); ilg.Ldarg("writer"); ilg.Castclass(CreatedTypes[writerClass]); ilg.Ldarg("objectToSerialize"); if (mapping is XmlMembersMapping) { ilg.ConvertValue(typeof(object), typeof(object[])); } ilg.Call(writerType_writeMethod); ilg.EndMethod(); } if (readMethod != null) { ilg = new CodeGenerator(typedSerializerTypeBuilder); ilg.BeginMethod( typeof(object), "Deserialize", new Type[] { typeof(XmlSerializationReader) }, new string[] { "reader" }, CodeGenerator.ProtectedOverrideMethodAttributes); MethodInfo readerType_readMethod = CreatedTypes[readerClass].GetMethod( readMethod, CodeGenerator.InstanceBindingFlags, null, CodeGenerator.EmptyTypeArray, null ); ilg.Ldarg("reader"); ilg.Castclass(CreatedTypes[readerClass]); ilg.Call(readerType_readMethod); ilg.EndMethod(); } typedSerializerTypeBuilder.DefineDefaultConstructor(CodeGenerator.PublicMethodAttributes); Type typedSerializerType = typedSerializerTypeBuilder.CreateTypeInfo().AsType(); CreatedTypes.Add(typedSerializerType.Name, typedSerializerType); return(typedSerializerType.Name); }
private void InternalLoad(Type elementType, bool asAddress = false) { Match match = s_regex.Match(Arg); if (match.Success) { object varA = ILG.GetVariable(match.Groups["a"].Value); Type varType = ILG.GetVariableType(varA); object varIA = ILG.GetVariable(match.Groups["ia"].Value); if (varType.IsArray) { ILG.Load(varA); ILG.Load(varIA); Type eType = varType.GetElementType(); if (CodeGenerator.IsNullableGenericType(eType)) { ILG.Ldelema(eType); ConvertNullableValue(eType, elementType); } else { if (eType.GetTypeInfo().IsValueType) { ILG.Ldelema(eType); if (!asAddress) { ILG.Ldobj(eType); } } else { ILG.Ldelem(eType); } if (elementType != null) { ILG.ConvertValue(eType, elementType); } } } else { ILG.Load(varA); ILG.Load(varIA); MethodInfo get_Item = varType.GetMethod( "get_Item", CodeGenerator.InstanceBindingFlags, null, new Type[] { typeof(Int32) }, null ); if (get_Item == null && typeof(IList).IsAssignableFrom(varType)) { get_Item = s_iListGetItemMethod.Value; } Debug.Assert(get_Item != null); ILG.Call(get_Item); Type eType = get_Item.ReturnType; if (CodeGenerator.IsNullableGenericType(eType)) { LocalBuilder localTmp = ILG.GetTempLocal(eType); ILG.Stloc(localTmp); ILG.Ldloca(localTmp); ConvertNullableValue(eType, elementType); } else if ((elementType != null) && !(eType.IsAssignableFrom(elementType) || elementType.IsAssignableFrom(eType))) { throw new CodeGeneratorConversionException(eType, elementType, asAddress, "IsNotAssignableFrom"); } else { Convert(eType, elementType, asAddress); } } } else if (Source == "null") { ILG.Load(null); } else { object var; Type varType; if (Arg.StartsWith("o.@", StringComparison.Ordinal) || MemberInfo != null) { var = ILG.GetVariable(Arg.StartsWith("o.@", StringComparison.Ordinal) ? "o" : Arg); varType = ILG.GetVariableType(var); if (varType.GetTypeInfo().IsValueType) { ILG.LoadAddress(var); } else { ILG.Load(var); } } else { var = ILG.GetVariable(Arg); varType = ILG.GetVariableType(var); if (CodeGenerator.IsNullableGenericType(varType) && varType.GetGenericArguments()[0] == elementType) { ILG.LoadAddress(var); ConvertNullableValue(varType, elementType); } else { if (asAddress) { ILG.LoadAddress(var); } else { ILG.Load(var); } } } if (MemberInfo != null) { Type memberType = (MemberInfo is FieldInfo) ? ((FieldInfo)MemberInfo).FieldType : ((PropertyInfo)MemberInfo).PropertyType; if (CodeGenerator.IsNullableGenericType(memberType)) { ILG.LoadMemberAddress(MemberInfo); ConvertNullableValue(memberType, elementType); } else { ILG.LoadMember(MemberInfo); Convert(memberType, elementType, asAddress); } } else { match = s_regex2.Match(Source); if (match.Success) { Debug.Assert(match.Groups["arg"].Value == Arg); Debug.Assert(match.Groups["cast"].Value == CodeIdentifier.GetCSharpName(Type)); if (asAddress) { ILG.ConvertAddress(varType, Type); } else { ILG.ConvertValue(varType, Type); } varType = Type; } Convert(varType, elementType, asAddress); } } }