private void EmitMap(CompilationContext context) { if (_beforeMapBuilder != null) { context.LoadSource(LoadPurpose.Parameter); context.LoadTarget(LoadPurpose.Parameter); _beforeMapBuilder.Emit(context); } if (_customInvokerBuilder != null) { context.LoadSource(LoadPurpose.Parameter); context.LoadTarget(LoadPurpose.Parameter); _customInvokerBuilder.Emit(context); } else { foreach (var mapper in _memberMappers) { mapper.Emit(context); } } if (_afterMapBuilder != null) { context.LoadSource(LoadPurpose.Parameter); context.LoadTarget(LoadPurpose.Parameter); _afterMapBuilder.Emit(context); } }
public Func <TSource, TTarget> CreateConverter(ModuleBuilder builder) { Initialize(); var typeBuilder = builder.DefineStaticType(); var methodBuilder = typeBuilder.DefineStaticMethod("Map"); methodBuilder.SetReturnType(typeof(TTarget)); methodBuilder.SetParameters(typeof(TSource)); #if NetCore var reflectingTargetType = typeof(TTarget).GetTypeInfo(); var reflectingSourceType = typeof(TSource).GetTypeInfo(); #else var reflectingTargetType = typeof(TTarget); var reflectingSourceType = typeof(TSource); #endif var il = methodBuilder.GetILGenerator(); var context = new CompilationContext(il); if (reflectingSourceType.IsValueType) { context.SetSource(purpose => { if (purpose == LoadPurpose.MemberAccess) { il.Emit(OpCodes.Ldarga_S, 0); } else { il.Emit(OpCodes.Ldarg_0); } }); } else { context.SetSource(purpose => il.Emit(OpCodes.Ldarg_0)); } var targetLocal = il.DeclareLocal(typeof(TTarget)); _creator.Emit(context); il.Emit(OpCodes.Stloc, targetLocal); if (reflectingTargetType.IsValueType) { context.SetTarget( purpose => il.Emit(purpose == LoadPurpose.MemberAccess ? OpCodes.Ldloca_S : OpCodes.Ldloc, targetLocal)); } else { context.SetTarget(purpose => il.Emit(OpCodes.Ldloc, targetLocal)); } EmitMap(context); context.LoadTarget(LoadPurpose.ReturnValue); context.Emit(OpCodes.Ret); #if NetCore return((Func <TSource, TTarget>)typeBuilder.CreateTypeInfo().GetMethod("Map", BindingFlags.Static | BindingFlags.Public).CreateDelegate(typeof(Func <TSource, TTarget>))); #else return((Func <TSource, TTarget>)Delegate.CreateDelegate(typeof(Func <TSource, TTarget>), typeBuilder.CreateType(), "Map")); #endif }
public override void Emit(Type sourceType, Type targetType, CompilationContext context) { context.LoadSource(LoadPurpose.Parameter); context.CurrentType = sourceType; context.EmitCast(typeof(IEnumerable <>).MakeGenericType(_sourceElementType)); context.LoadTarget(LoadPurpose.Parameter); context.CurrentType = targetType; context.EmitCast(typeof(IEnumerable <>).MakeGenericType(_targetElementType)); _invokerBuilder.Emit(context); }
internal override void EmitSetter(CompilationContext context) { var local = context.DeclareLocal(context.CurrentType); context.Emit(OpCodes.Stloc, local); context.LoadTarget(LoadPurpose.MemberAccess); context.Emit(OpCodes.Ldloc, local); if (MemberType != context.CurrentType) { context.EmitCast(MemberType); } context.Emit(OpCodes.Stfld, _field); context.CurrentType = null; }
internal override void EmitSetter(CompilationContext context) { var local = context.DeclareLocal(context.CurrentType); context.Emit(OpCodes.Stloc, local); var setMethod = _property.GetSetMethod(true); context.LoadTarget(LoadPurpose.MemberAccess); context.Emit(OpCodes.Ldloc, local); if (MemberType != context.CurrentType) { context.EmitCast(MemberType); } context.EmitCall(setMethod); context.CurrentType = null; }