public static void EmitNullableExpression(this CompilationContext context, LocalBuilder local, Action <CompilationContext> nonNullExpression, Action <CompilationContext> nullExpression) { var label = context.DefineLabel(); if (local.LocalType.IsNullable()) { var variableType = local.LocalType.GetTypeInfo(); context.Emit(OpCodes.Ldloca, local); context.EmitCall(variableType.GetProperty("HasValue").GetGetMethod()); context.Emit(OpCodes.Brfalse, label); context.Emit(OpCodes.Ldloca, local); context.EmitCall(variableType.GetProperty("Value").GetGetMethod()); context.CurrentType = variableType.GetGenericArguments()[0]; } else { context.Emit(OpCodes.Ldloc, local); context.Emit(OpCodes.Ldnull); context.EmitCall(_referenceEqualsMethod); context.Emit(OpCodes.Brtrue, label); context.Emit(OpCodes.Ldloc, local); context.CurrentType = local.LocalType; } nonNullExpression(context); var labelEnd = context.DefineLabel(); context.Emit(OpCodes.Br, labelEnd); context.MakeLabel(label); nullExpression(context); context.MakeLabel(labelEnd); }
public void Emit(CompilationContext context) { context.EmitCall(_invokeMethod); context.CurrentType = typeof(IEnumerable <TTarget>); }
public void Emit(CompilationContext context) { context.EmitCall(_invokeMethod); }
public void Emit(CompilationContext context) { context.EmitCall(_invokeMethod); context.CurrentType = null; }
public void Emit(CompilationContext context) { context.EmitCall(_invokeMethod); context.CurrentType = typeof(TResult); }
public static void EmitDefault(this CompilationContext context, Type targetType) { var originalType = targetType; if (targetType.IsNullable()) { var local = context.DeclareLocal(targetType); context.Emit(OpCodes.Ldloca, local); context.Emit(OpCodes.Initobj, targetType); context.Emit(OpCodes.Ldloc, local); context.CurrentType = originalType; return; } if (!targetType.GetTypeInfo().IsValueType) { context.Emit(OpCodes.Ldnull); context.CurrentType = originalType; return; } if (targetType.GetTypeInfo().IsEnum) { targetType = Enum.GetUnderlyingType(targetType); } if (targetType == typeof(int) || targetType == typeof(uint) || targetType == typeof(short) || targetType == typeof(ushort) || targetType == typeof(byte) || targetType == typeof(sbyte) || targetType == typeof(char) || targetType == typeof(bool)) { context.Emit(OpCodes.Ldc_I4_0); context.CurrentType = originalType; return; } if (targetType == typeof(long) || targetType == typeof(ulong)) { context.Emit(OpCodes.Ldc_I4_0); context.Emit(OpCodes.Conv_I8); context.CurrentType = originalType; return; } if (targetType == typeof(float)) { context.Emit(OpCodes.Ldc_I4_0); context.Emit(OpCodes.Conv_R4); context.CurrentType = originalType; return; } if (targetType == typeof(double)) { context.Emit(OpCodes.Ldc_I4_0); context.Emit(OpCodes.Conv_R8); context.CurrentType = originalType; return; } Func <MethodInfo, bool> coverterPredicate = method => { if (method.Name == "op_Implicit") { var parameters = method.GetParameters(); return(parameters.Length == 1 && parameters[0].ParameterType == typeof(int)); } return(false); }; var reflectingType = targetType.GetTypeInfo(); if (targetType == typeof(decimal)) { context.Emit(OpCodes.Ldc_I4_0); context.EmitCall(reflectingType.GetMethods(BindingFlags.Static | BindingFlags.Public).FirstOrDefault(coverterPredicate)); context.CurrentType = originalType; return; } var field = reflectingType.GetField("Empty", BindingFlags.Public | BindingFlags.Static) ?? reflectingType.GetField("Zero", BindingFlags.Public | BindingFlags.Static) ?? reflectingType.GetField("MinValue", BindingFlags.Public | BindingFlags.Static); if (field != null) { context.Emit(OpCodes.Ldsfld, field); context.CurrentType = field.FieldType; context.EmitCast(originalType); return; } var property = reflectingType.GetProperty("Empty", BindingFlags.Public | BindingFlags.Static) ?? reflectingType.GetProperty("Zero", BindingFlags.Public | BindingFlags.Static) ?? reflectingType.GetProperty("MinValue", BindingFlags.Public | BindingFlags.Static); var getMethod = property?.GetGetMethod(); if (getMethod != null) { context.EmitCall(getMethod); context.CurrentType = getMethod.ReturnType; context.EmitCast(originalType); return; } var targetLocal = context.DeclareLocal(targetType); context.Emit(OpCodes.Ldloca, targetLocal); context.Emit(OpCodes.Initobj, targetType); context.Emit(OpCodes.Ldloc, targetLocal); context.CurrentType = originalType; }