//private static void DeclareInstance(MethodGenerator g, TypeSerializationInfo typeInfo) //{ // if (typeInfo.ClassType.IsValueType) // { // var instance = g.Declare(typeInfo.ClassType, SerializationArgs.InstanceName); // //g.LoadVariable(instance, LoadOptions.ValueAsAddress); // //g.InitValue(); // } // else // { // var instance = g.Declare(typeInfo.ClassType, SerializationArgs.InstanceName); // g.Assign(instance, () => // { // g.NewObject(typeInfo.ClassType); // }); // } //} private static void ReadMembers(MethodGenerator g, TypeSerializationInfo typeInfo) { if (typeInfo.ClassAttribute.Mode == DTOSerializableMode.General) { foreach (var member in typeInfo.MemberInfos) { //只有可以写入并且不是抽象的成员才能从dto中赋值 if (member.CanWrite && !member.IsAbstract) { g.BeginScope(); member.GenerateDeserializeIL(g); g.EndScope(); } } } else { //在函数模式,只有标记了Parameter的成员才会被反序列化到对象实例中 foreach (var member in typeInfo.MemberInfos) { if (member.MemberAttribute.Type == DTOMemberType.Parameter && member.CanWrite && !member.IsAbstract) { g.BeginScope(); member.GenerateDeserializeIL(g); g.EndScope(); } } } }
private static void WriteMembers(MethodGenerator g, TypeSerializationInfo typeInfo) { if (typeInfo.ClassAttribute.Mode == DTOSerializableMode.General) { foreach (var member in typeInfo.MemberInfos) { if (member.CanRead) { g.BeginScope(); member.GenerateSerializeIL(g); g.EndScope(); } } } else { //在函数模式,只有标记了ReturnValue的成员才会被写入到dto中 foreach (var member in typeInfo.MemberInfos) { if (member.MemberAttribute.Type == DTOMemberType.ReturnValue && member.CanRead) { g.BeginScope(); member.GenerateSerializeIL(g); g.EndScope(); } } } }
private void GenerateAssertPartsAreEqual(MethodGenerator g) { var expected = g.GetParameter(0); var actual = g.GetParameter(1); var assertAgs = g.GetParameter(2); foreach (var part in _def.Parts) { g.BeginScope(); { var e = g.CreateExpression(expected); var a = g.CreateExpression(actual); if (part.Member == null) { e.MakeReadOnly(); a.MakeReadOnly(); } else { e.AddMember(part.Member); a.AddMember(part.Member); } var context = new GenAssertAreEqualContext(g, part, e, a, g.CreateExpression(assertAgs)); part.GetCurrentBuilder() .GenerateAssertAreEqualPart(context); } g.EndScope(); } }
public void GenerateFill(ICilWriter msilWriter) { var g = new MethodGenerator(msilWriter); var instance = g.GetParameter(0); g.If(() => { g.Load(instance); return(BinaryOperator.IsNull); }); { if (_def.Type.IsAbstract) { g.BeginCall(typeof(BarfErrors).ResolveMethod("RaiseAbstractConstructionError", typeof(Type))); g.Load(_def.Type); g.EndCall(); } else { g.BeginAssign(instance); { g.NewObject(_def.Type); } g.EndAssign(); } } g.EndIf(); foreach (var part in _def.Parts) { g.BeginScope(); { var member = g.CreateExpression(instance); if (part.Member == null) { member.MakeReadOnly(); } else { member.AddMember(part.Member); } var context = new GenFillContext(g, member, part); var builder = PartResolver.Current.GetPartBuilder(part.Type, part, true); builder.GenerateFillPart(context); } g.EndScope(); } g.Return(); }
/// <summary> /// Generates the body of the serialize method. /// </summary> /// <param name="msilWriter">The MSIL writer to write to.</param> public void GenerateSerializeMethod(ICilWriter msilWriter) { var g = new MethodGenerator(msilWriter); var instance = g.GetParameter(0); var args = g.GetParameter(1); if (!_def.Type.IsValueType) { g.If(() => { g.Load(instance); return(BinaryOperator.IsNull); }); { g.Load(args); // todo - call through MemberResolver g.Call(typeof(BarfSerializationArgs).GetMethod("WriteNullObject")); g.Return(); } g.EndIf(); } IVariable typeContext; MethodInfo beginMethod; MethodInfo endMethod; if (_def.IsForwardCompatible) { typeContext = g.DeclareLocal(typeof(BarfSerializationArgs.TypeContext)); beginMethod = typeof(BarfSerializationArgs).GetMethods(BindingFlags.Instance | BindingFlags.Public) .Where <MethodInfo>(m => m.Name == "BeginObject") .Where <MethodInfo>(m => { var ps = m.GetParameters(); return(ps.Length == 1 && ps[0].ParameterType.IsGenericParameter); }) .FirstOrDefault <MethodInfo>() .MakeGenericMethod(_def.Type); endMethod = typeof(BarfSerializationArgs).ResolveMethod("EndObject", typeof(BarfSerializationArgs.TypeContext)); } else { typeContext = g.DeclareLocal(typeof(long)); beginMethod = typeof(BarfSerializationArgs) .ResolveMethod("BeginObject", Type.EmptyTypes) .MakeGenericMethod(_def.Type); endMethod = typeof(BarfSerializationArgs).ResolveMethod("EndObject", typeof(long)); } g.Load(args); g.BeginCall(beginMethod); if (_def.IsForwardCompatible) { g.Load(instance); } g.EndCall(); g.Store(typeContext); foreach (var part in _def.Parts) { Trace.WriteLine("\tBuilding Serialize Part - " + part.FullName); g.BeginScope(); { var context = new GenSerializeContext(g, part, g.CreateExpression(instance)); part.GetCurrentBuilder() .GenerateSerializePart(context); } g.EndScope(); } g.Load(args); g.BeginCall(endMethod); { g.Load(typeContext); } g.EndCall(); g.Return(); }
public void GenerateInnerDeserializeMethod(ICilWriter msilWriter) { var g = new MethodGenerator(msilWriter); var instance = g.CreateExpression(g.GetParameter(0)); var args = g.CreateExpression(g.GetParameter(1)); var header = g.DeclareLocal(typeof(BarfObjectHeader)); g.BeginAssign(header); { g.Load(args); g.Call(typeof(BarfDeserializationArgs) .ResolveMethod("BeginObject") .MakeGenericMethod(_def.Type)); } g.EndAssign(); var version = g.CreateExpression(header).AddMember("Version"); g.If(() => { g.Load(header); g.LoadMember("IsNull"); return(BinaryOperator.IsTrue); }); { g.BeginAssign(instance); g.LoadNull(); g.EndAssign(); } g.Else(); { g.If(() => { g.Load(instance); return(BinaryOperator.IsNull); }); { if (_def.Type.IsAbstract) { g.BeginCall(typeof(BarfErrors).ResolveMethod("RaiseAbstractConstructionError", typeof(Type))); g.Load(_def.Type); g.EndCall(); } else { g.BeginAssign(instance); g.NewObject(instance.Type); g.EndAssign(); } } g.EndIf(); var partsByVersion = _def.Parts .GroupBy <PartDefinition, int>(part => part.Version) .OrderBy <IGrouping <int, PartDefinition>, int>(group => group.Key); int count = 0; foreach (var versionGroup in partsByVersion) { g.If(() => { g.Load(version); g.Load(versionGroup.Key); return(BinaryOperator.GreaterThanOrEqualTo); }); { foreach (var part in versionGroup) { Trace.WriteLine("\tBuilding Deserialize Part - " + part.FullName); g.BeginScope(); var context = new GenDeserializeContext(g, part, instance, args, header); part.GetCurrentBuilder() .GenerateDeserializePart(context); g.EndScope(); } } count++; } for (; count > 0; --count) { g.EndIf(); } if (_def.IsForwardCompatible) { g.If(() => { g.Load(header).LoadMember("Version"); g.Load(_def.CurrentVersion); return(BinaryOperator.GreaterThan); }); { g.Load(args); g.BeginCall(typeof(BarfDeserializationArgs) .ResolveMethod( "CaptureFutureData", new[] { _def.Type }, typeof(BarfObjectHeader), new GenericParameter(0).MakeByRefType())); { g.Load(header); g.Load(instance, LoadOptions.AnyAsAddress); } g.EndCall(); } g.EndIf(); } } g.EndIf(); g.Load(args).BeginCall(typeof(BarfDeserializationArgs) .ResolveMethod("EndObject", new[] { _def.Type }, typeof(BarfObjectHeader))); { g.Load(header); } g.EndCall(); g.Return(); }