private GenSerializeContext( GenSerializeContext parent, IExpression instance, IExpression member) : base(parent.Generator) { Writer = parent.Writer; Instance = instance; Member = member; }
/// <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(); }