private void WriteNotApplicableResult(ILWriter writer, ValidationKind kind) { var notApplicable = KnownMetadata.Methods.ValidationResult_NotApplicable; writer.LoadInt32((int)kind); writer.StaticMethodCall(notApplicable); }
public static void Emit(RootNamespace root, SourceCodeBody body, string path) { var pgms = Lookup.AllPrograms(body); var nss = Lookup.AllNamespaces(body); var entrypoint = Lookup.AllFunctionBodies(pgms).FindFirst(x => x.Name == "main"); var structs = Lookup.AllStructBodies(pgms).Concat(Lookup.AllStructBodies(root)); var externs = Lookup.AllExternFunctions(nss); var embedded = Lookup.AllEmbeddedFunctions(nss); var extern_structs = Lookup.AllExternStructs(Lookup.GetRootNamespace(body)); var extern_asms = externs.Map(x => x.Assembly) .Concat(extern_structs.Map(x => x.Assembly)) .By <Assembly>().Unique().ToArray(); using var il = new ILWriter(path); AssemblyExternEmit(il, extern_asms); AssemblyNameEmit(il, path); var fss = new List <FunctionSpecialization>() { new FunctionSpecialization(entrypoint, new GenericsMapper()) }; structs.Each(x => AssemblyStructEmit(il, x, fss)); AssemblyFunctionEmit(il, fss); }
private void WriteTryCatchBlockBody(ILWriter writer, IImmutableQueue <Type> exceptionTypes) { var currentExecutionAttempt = writer.DeclareLocal <int>(); var shouldRetry = writer.DeclareLocal <bool>(); var retryLabel = writer.DefineLabel(); writer.MarkLabel(retryLabel); writer.WriteIncrement(currentExecutionAttempt, 1); writer.TryCatch( endOfTryCatch => { writer.LoadFalse(); writer.SetLocal(shouldRetry); var method = KnownMetadata.Methods.IExceptionAwareAction_Do; writer.LoadFirstParameter(); writer.InstanceMethodCall(method); }, WriteUnrolledCatchBlocks(writer, exceptionTypes, shouldRetry, currentExecutionAttempt) ); writer.LoadLocal(shouldRetry); var shouldNotRetry = writer.IfTrueThen(); writer.GoTo(retryLabel); writer.MarkLabel(shouldNotRetry); writer.Return(); }
private void WriteCustomValidation(ILWriter writer, PropertyInfo property, CustomValidationAttribute customValidationAttribute) { var validationKind = ValidationKind.Custom; var validatorType = typeof(ICustomValidator <>).MakeGenericType(property.PropertyType); if (!customValidationAttribute.ValidatorType.CanBe(validatorType)) { var message = CommonErrors.CustomValidatorMustBeOfType.WithValues(property.ReflectedType.Name, property.Name, property.PropertyType.Name); throw new IncorrectValidationAttributeException(typeof(CustomValidationAttribute), message); } var localValidator = writer.DeclareLocal(validatorType); writer.New(customValidationAttribute.ValidatorType); writer.SetLocal(localValidator); var validate = KnownMetadata.Methods.ICustomValidator_OfType(property.PropertyType); writer.LoadLocal(localValidator); writer.LoadFirstParameter(); writer.GetPropertyValue(property); writer.InstanceMethodCall(validate); var end = writer.IfFalseThen(); WriteFailureResult(writer, validationKind, CommonResults.CustomValidationDidNotSucceed.WithValues(property.ReflectedType.Name, property.Name)); writer.Return(); writer.MarkLabel(end); }
private void WriteStringLength(ILWriter writer, PropertyInfo property, StringLengthAttribute attribute) { var local = writer.DeclareLocal <string>(); if (property.PropertyType == typeof(string)) { writer.LoadFirstParameter(); writer.GetPropertyValue(property); writer.SetLocal(local); writer.LoadLocal(local); writer.LoadNull(); var notNullBlock = writer.IfEqualThen(); var isNullMessage = CommonResults.PropertyCannotBeNull.WithValues(property.ReflectedType.Name, property.Name); WriteFailureResult(writer, ValidationKind.StringLength, isNullMessage); writer.Return(); writer.MarkLabel(notNullBlock); var lengthValue = writer.DeclareLocal <int>(); var length = KnownMetadata.Properties.String_Length; writer.LoadLocal(local); writer.GetPropertyValue(length); writer.SetLocal(lengthValue); var minValue = attribute.Minimum; writer.LoadLocal(lengthValue); writer.LoadInt32((int)minValue); var longerThanMinBlock = writer.IfLessThan(); var tooShortMessage = CommonResults.StringPropertyIsTooShort.WithValues(property.ReflectedType.Name, property.Name, minValue); WriteFailureResult(writer, ValidationKind.StringLength, tooShortMessage); writer.Return(); writer.MarkLabel(longerThanMinBlock); var maxValue = attribute.Maximum; //The maximum value might not be set, if so then just ignore it if (maxValue > 0) { writer.LoadLocal(lengthValue); writer.LoadInt32((int)maxValue); var shorterThanMaxBlock = writer.IfGreaterThan(); var tooLongMessage = CommonResults.StringPropertyIsTooLong.WithValues(property.ReflectedType.Name, property.Name, maxValue); WriteFailureResult(writer, ValidationKind.StringLength, tooLongMessage); writer.Return(); writer.MarkLabel(shorterThanMaxBlock); } } else { WriteNotApplicableResult(writer, ValidationKind.StringLength); writer.Return(); } }
private void WriteFailureResult(ILWriter writer, ValidationKind kind, string message) { var failure = KnownMetadata.Methods.ValidationResult_Failure; writer.LoadInt32((int)kind); writer.LoadString(message); writer.StaticMethodCall(failure); }
public void DeclareLocalOverloadDoesNotUnbalanceTheStack() { var method = new DynamicMethod(String.Empty, typeof(void), Type.EmptyTypes); var generator = method.GetILGenerator(); var il = new ILWriter(generator); var localBuilder = il.DeclareLocal<object>(); il.VerifyStack(); }
public void DeclareLocalOverloadDoesNotUnbalanceTheStack() { var method = new DynamicMethod(String.Empty, typeof(void), Type.EmptyTypes); var generator = method.GetILGenerator(); var il = new ILWriter(generator); var localBuilder = il.DeclareLocal <object>(); il.VerifyStack(); }
public void CatchBlockOverloadDoesNotUnbalanceTheStack() { var method = new DynamicMethod(String.Empty, typeof(void), Type.EmptyTypes); var generator = method.GetILGenerator(); var il = new ILWriter(generator); var exceptionBlock = generator.BeginExceptionBlock(); generator.Emit(OpCodes.Leave, exceptionBlock); il.CatchBlock<Exception>(exceptionBlock, () => { }); il.VerifyStack(); }
public void CatchBlockOverloadDoesNotUnbalanceTheStack() { var method = new DynamicMethod(String.Empty, typeof(void), Type.EmptyTypes); var generator = method.GetILGenerator(); var il = new ILWriter(generator); var exceptionBlock = generator.BeginExceptionBlock(); generator.Emit(OpCodes.Leave, exceptionBlock); il.CatchBlock <Exception>(exceptionBlock, () => { }); il.VerifyStack(); }
public static void AssemblyStructEmit(ILWriter il, StructBody body, List <FunctionSpecialization> fss) { var cache = new HashSet <string>(); body.SpecializationMapper.Each(sp => { var g = sp.Key; var mapper = sp.Value; var name = GetStructName(body.Name, body, g); if (cache.Contains(name)) { return; } cache.Add(name); il.WriteLine($".class public {name}"); il.WriteLine("{"); il.Indent++; body.Members.Each(x => il.WriteLine($".field public {GetTypeName(mapper, x.Value, g)} {EscapeILName(x.Key)}")); il.WriteLine(""); il.WriteLine($".method public void .ctor()"); il.WriteLine("{"); il.Indent++; var local_vals = mapper.Values.Where(x => x.Type == VariableType.LocalVariable && !(x.Struct is NamespaceBody)).Sort((a, b) => a.Index - b.Index).ToList(); local_vals.Each((x, i) => x.Index = i); if (local_vals.Count > 0) { il.WriteLine(".locals("); il.Indent++; il.WriteLine(local_vals.Map(x => $"[{x.Index}] {GetTypeName(x, g)} {x.Name}").Join(",\n")); il.Indent--; il.WriteLine(")"); } var labels = Lookup.AllLabels(body.Body).Zip(Lists.Sequence(1)).ToDictionary(x => x.First, x => $"_{x.First.Name}{x.Second}"); body.Body.Each(x => { if (x is Call call) { CallToAddEmitFunctionList(mapper, call, fss); } AssemblyOperandEmit(il, x, body.Namespace, mapper, labels, g); }); il.WriteLine("ret"); il.Indent--; il.WriteLine("}"); il.Indent--; il.WriteLine("}"); }); }
/// <summary> /// The core method for creating a new proxy type /// </summary> /// <param name="interfaceType"> The interface type. </param> /// <param name="implementationTypeName"> The implementation type name. </param> /// <returns> The created type </returns> private static Type CreateProxyCore(Type interfaceType, string implementationTypeName) { TypeBuilder classBuilder = CreateImplementationType(moduleBuilder, interfaceType, implementationTypeName); ILWriter.CreateConstructor(classBuilder, typeof(ServiceClient)); foreach (MethodInfo method in interfaceType.GetMethods()) { GenerateMethod(classBuilder, method); } return(classBuilder.CreateType()); }
public static void AssemblyFunctionEmit(ILWriter il, List <FunctionSpecialization> fss) { for (var i = 0; i < fss.Count; i++) { var f = fss[i].Body.Cast <IFunctionBody>(); var g = fss[i].GenericsMapper; var mapper = Lookup.GetTypemapper(f.SpecializationMapper, g); il.WriteLine($".method public static {GetTypeName(mapper, f.Return, g)} {EscapeILName(f.Name)}({f.Arguments.Map(a => GetTypeName(mapper[a.Name], g)).Join(", ")})"); il.WriteLine("{"); il.Indent++; if (i == 0) { il.WriteLine(".entrypoint"); } il.WriteLine(".maxstack 8"); var local_vals = mapper.Values.Where(x => x.Type == VariableType.LocalVariable && !(x.Struct is NamespaceBody)).Sort((a, b) => a.Index - b.Index).ToList(); local_vals.Each((x, i) => x.Index = i); if (local_vals.Count > 0) { il.WriteLine(".locals("); il.Indent++; local_vals.Map(x => x.Struct).By <AnonymousFunctionBody>().Each(x => CallToAddEmitFunctionList(mapper, x, fss)); il.WriteLine(local_vals.Map(x => $"[{x.Index}] {GetTypeName(x, g)} {x.Name}").Join(",\n")); il.Indent--; il.WriteLine(")"); } var labels = Lookup.AllLabels(f.Body).Zip(Lists.Sequence(1)).ToDictionary(x => x.First, x => $"_{x.First.Name}{x.Second}"); f.Body.Each(x => { if (x is Call call) { CallToAddEmitFunctionList(mapper, call, fss); } AssemblyOperandEmit(il, x, f, mapper, labels, g); }); il.WriteLine("ret"); il.Indent--; il.WriteLine("}"); } }
private void WriteIsMatch(ILWriter writer, PropertyInfo property, IsMatchForAttribute isMatchAttribute) { var validationKind = ValidationKind.RegularExpressionMatch; var local = writer.DeclareLocal <string>(); if (property.PropertyType == typeof(string)) { writer.LoadFirstParameter(); writer.GetPropertyValue(property); writer.SetLocal(local); } else { var temp = writer.DeclareLocal(property.PropertyType); writer.LoadFirstParameter(); writer.GetPropertyValue(property); writer.SetLocal(temp); writer.LoadLocal(temp); var notNull = writer.IsNotNull(); WriteFailureResult(writer, validationKind, CommonResults.CannotValidateNullProperty.WithValues(property.ReflectedType.Name, property.Name)); writer.Return(); writer.MarkLabel(notNull); writer.LoadLocal(temp); writer.InstanceMethodCall(KnownMetadata.Methods.Object_ToString); writer.SetLocal(local); } writer.LoadLocal(local); writer.LoadString(isMatchAttribute.RegularExpression); writer.StaticMethodCall(KnownMetadata.Methods.Regex_IsMatch); var end = writer.IfFalseThen(); WriteFailureResult(writer, validationKind, CommonResults.RegularExpressionWasNotMatch.WithValues(property.ReflectedType.Name, property.Name)); writer.Return(); writer.MarkLabel(end); }
/// <summary> /// Populates the high level metadata properties /// </summary> /// <param name="il">The IL Generator</param> /// <param name="metadataLocal"> The metadata local. </param> /// <param name="interfaceMethod"> The interface method. </param> private static void PopulateMetadata(ILGenerator il, LocalBuilder metadataLocal, MethodInfo interfaceMethod) { HttpVerb verb = ReflectionUtils.DetermineHttpVerb(interfaceMethod); string consumeMediaType = ReflectionUtils.DetermineConsumesMediaType(interfaceMethod, MediaType.TextXml); string producesMediaType = ReflectionUtils.DetermineProducesMediaType(interfaceMethod, MediaType.TextXml); PathAttribute methodPathAttr = ReflectionUtils.GetAttribute <PathAttribute>(interfaceMethod); PathAttribute servicePathAttr = ReflectionUtils.GetAttribute <PathAttribute>(interfaceMethod.DeclaringType); string methodPath = methodPathAttr == null ? "/" : methodPathAttr.Path; string servicePath = servicePathAttr == null ? string.Empty : servicePathAttr.Path; Type methodMetaType = typeof(MethodMetadata); ILWriter.WritePropertyString(il, metadataLocal, methodMetaType, "ServicePath", servicePath); ILWriter.WritePropertyString(il, metadataLocal, methodMetaType, "MethodPath", methodPath); ILWriter.WritePropertyString(il, metadataLocal, methodMetaType, "Consumes", consumeMediaType); ILWriter.WritePropertyString(il, metadataLocal, methodMetaType, "Produces", producesMediaType); ILWriter.WritePropertyInt(il, metadataLocal, methodMetaType, "Verb", (int)verb); }
private IEnumerable <Action <Label> > WriteUnrolledCatchBlocks(ILWriter writer, IImmutableQueue <Type> exceptionTypes, LocalBuilder shouldRetry, LocalBuilder currentExecutionAttempt) { var handleException = KnownMetadata.Methods.IExceptionAwareAction_HandleException; foreach (var exceptionType in exceptionTypes) { yield return(endOfTryCatch => { var handleSpecificException = handleException.MakeGenericMethod(exceptionType); Action catchBlockBody = () => { var endOfCatch = writer.DefineLabel(); var localException = writer.DeclareLocal(exceptionType); writer.SetLocal(localException); writer.LoadFirstParameter(); //Exception-aware instance writer.LoadLocal(localException); writer.LoadLocal(currentExecutionAttempt); writer.InstanceMethodCall(handleSpecificException); //The handler refusing to handle it indicates that we should perform a retry. var wasHandled = writer.IfFalseThen(); writer.LoadTrue(); writer.SetLocal(shouldRetry); writer.GoTo(endOfCatch); writer.MarkLabel(wasHandled); writer.LoadFalse(); writer.SetLocal(shouldRetry); writer.MarkLabel(endOfCatch); }; writer.CatchBlock(exceptionType, endOfTryCatch, catchBlockBody); }); } }
private void WriteRequireNotNull(ILWriter writer, PropertyInfo property, NotNullAttribute notNullAttribute) { if (property.PropertyType.IsClass || property.PropertyType.IsInterface) { writer.LoadFirstParameter(); writer.GetPropertyValue(property); writer.LoadNull(); var elseLabel = writer.IfEqualThen(); var message = CommonResults.PropertyCannotBeNull.WithValues(property.ReflectedType.Name, property.Name); WriteFailureResult(writer, ValidationKind.RequireNotNull, message); writer.Return(); writer.MarkLabel(elseLabel); } else { //Value types, pointers, everything that can't be null is here WriteNotApplicableResult(writer, ValidationKind.RequireNotNull); writer.Return(); } }
private void WritePropertyValidation <T>(ILWriter writer) { var properties = typeof(T).GetProperties(); foreach (var property in properties) { var validationAttributes = property.GetAttributesOf <IValidationAttribute>(); foreach (var attribute in validationAttributes) { if (attribute.CanBe <NotNullAttribute>()) { WriteRequireNotNull(writer, property, (NotNullAttribute)attribute); } else if (attribute.CanBe <StringLengthAttribute>()) { WriteStringLength(writer, property, (StringLengthAttribute)attribute); } else if (attribute.CanBe <IntegerRangeAttribute>()) { WriteIntegerRange(writer, property, (IntegerRangeAttribute)attribute); } else if (attribute.CanBe <IsMatchForAttribute>()) { WriteIsMatch(writer, property, (IsMatchForAttribute)attribute); } else if (attribute.CanBe <CustomValidationAttribute>()) { WriteCustomValidation(writer, property, (CustomValidationAttribute)attribute); } else { Debug.Fail("Encountered unhandled validation attribute"); } } } }
void WriteValidatorBody <T>(ILWriter writer) { if (typeof(T).IsValueType) { WritePropertyValidation <T>(writer); WriteSuccessResult(writer); writer.Return(); } else { writer.LoadFirstParameter(); //Load the parameter we're validating var isNull = writer.IsNotNull(); WritePropertyValidation <T>(writer); writer.MarkLabel(isNull); //Ending mark for initial parameter null check WriteSuccessResult(writer); writer.Return(); } }
/// <summary> /// The populate metadata. /// </summary> /// <param name="il">The IL Generator</param> /// <param name="metadataLocal"> The metadata local. </param> /// <param name="interfaceMethod"> The interface method. </param> private static void PopulateMetadataParameters(ILGenerator il, LocalBuilder metadataLocal, MethodInfo interfaceMethod) { ParameterInfo[] parameters = interfaceMethod.GetParameters(); Type methodMetaType = typeof(MethodMetadata); foreach (ParameterInfo parameter in parameters) { if (parameter.IsOut) { throw new NotSupportedException(Resources.OutAndOptionalParamsNotSupported); } bool attributeFound = false; HeaderParamAttribute headerAttribute = ReflectionUtils.GetAttribute <HeaderParamAttribute>(parameter); if (headerAttribute != null) { attributeFound = true; ILWriter.AddParameter( il, "AddHeaderParameter", metadataLocal, methodMetaType, headerAttribute.HeaderName, parameter); } QueryParamAttribute queryAttribute = ReflectionUtils.GetAttribute <QueryParamAttribute>(parameter); if (queryAttribute != null) { attributeFound = true; ILWriter.AddParameter( il, "AddQueryParameter", metadataLocal, methodMetaType, queryAttribute.ParameterName, parameter); } FormParamAttribute formAttribute = ReflectionUtils.GetAttribute <FormParamAttribute>(parameter); if (formAttribute != null) { attributeFound = true; ILWriter.AddParameter( il, "AddFormParameter", metadataLocal, methodMetaType, formAttribute.ParameterName, parameter); } PathParamAttribute pathAttribute = ReflectionUtils.GetAttribute <PathParamAttribute>(parameter); if (pathAttribute != null) { attributeFound = true; ILWriter.AddParameter( il, "AddPathParameter", metadataLocal, methodMetaType, pathAttribute.ParameterName, parameter); } if (!attributeFound) { MethodInfo bodySetter = methodMetaType.GetProperty("RequestBody").GetSetMethod(); il.Emit(OpCodes.Ldloc, metadataLocal); il.Emit(OpCodes.Ldarg, parameter.Position + 1); if (parameter.ParameterType.IsValueType) { il.Emit(OpCodes.Box, parameter.ParameterType); } il.Emit(OpCodes.Call, bodySetter); } } }
void WriteTranslatorBody <TFrom, TTo>(ILWriter writer) { var sourceProperties = typeof(TFrom).GetPublicPropertiesWithGetter(); var targetProperties = typeof(TTo).GetPublicPropertiesWithSetter().ToDictionary(p => p.Name); var targetedSourceProperties = sourceProperties.GetTranslatableProperties <TTo>(); if (targetProperties.Count == 0) { writer.ReturnNull(); return; } var localTargetInstance = writer.DeclareLocal <TTo>(); writer.New <TTo>(); writer.SetLocal(localTargetInstance); foreach (var sourceProperty in sourceProperties) { var explicitMapping = GetExplicitMappingIfPresent <TTo>(sourceProperty); var targetName = (explicitMapping == null) ? sourceProperty.Name : explicitMapping.PropertyName; if (!targetProperties.ContainsKey(targetName)) { if (this.shouldThrowExceptions) { throw new PropertyIsMissingException(); } continue; } var targetProperty = targetProperties[targetName]; var propertiesAreSameType = sourceProperty.PropertyType == targetProperty.PropertyType; if (!propertiesAreSameType && !sourceProperty.PropertyType.HasConversionTo(targetProperty.PropertyType)) { if (this.shouldThrowExceptions) { throw new PropertyTypeMismatchException(); } continue; } var localSourceValue = writer.DeclareLocal(sourceProperty.PropertyType); writer.LoadFirstParameter(); writer.GetPropertyValue(sourceProperty); writer.SetLocal(localSourceValue); writer.LoadLocal(localTargetInstance); writer.LoadLocal(localSourceValue); if (!propertiesAreSameType) { writer.Cast(sourceProperty.PropertyType, targetProperty.PropertyType); } writer.SetPropertyValue(targetProperty); } writer.LoadLocal(localTargetInstance); writer.Return(); writer.VerifyStack(); }
private void WriteLogBody(ILWriter writer, Type type, MemberInfo[] loggableMembers) { var localTypedInstance = writer.DeclareLocal(type); writer.LoadFirstParameter(); writer.Cast(typeof(object), type); writer.SetLocal(localTypedInstance); //TODO: Recurse into loggable members foreach (var member in loggableMembers) { var logAttributes = member.GetCustomAttributes <LogAttribute>().ToArray(); if (logAttributes.Length == 0) { continue; } //TODO: Support multiple attributes per member var attribute = logAttributes[0]; if (attribute.Ignore) { continue; } if (CanWriteToLog(attribute.Visibility)) { LocalBuilder localValue; LocalBuilder localLogItem = writer.DeclareLocal <CustomLoggableMember>(); switch (member.MemberType) { case MemberTypes.Field: var field = (FieldInfo)member; localValue = writer.DeclareLocal(field.FieldType); writer.LoadLocal(localTypedInstance); writer.LoadField(field); writer.SetLocal(localValue); break; case MemberTypes.Property: var property = (PropertyInfo)member; localValue = writer.DeclareLocal(property.PropertyType); writer.LoadLocal(localTypedInstance); writer.GetPropertyValue(property); writer.SetLocal(localValue); break; default: var message = String.Format("Encountered loggable member '{0}' that was not supported in IL generation", member.Name); System.Diagnostics.Debug.Fail(message); throw new ILGenerationException(message); } writer.New <CustomLoggableMember>(); writer.SetLocal(localLogItem); writer.LoadLocal(localLogItem); writer.LoadInt32((int)attribute.Visibility); writer.SetPropertyValue(typeof(CustomLoggableMember).GetProperty("MemberVisibility")); writer.LoadLocal(localLogItem); writer.TypeOf(type); writer.Cast(localValue.LocalType, typeof(Type)); writer.SetPropertyValue(KnownMetadata.Properties.CustomLoggableMember_OwningType); writer.LoadLocal(localLogItem); writer.LoadString(member.Name); writer.SetPropertyValue(KnownMetadata.Properties.CustomLoggableMember_MemberName); writer.LoadLocal(localLogItem); writer.TypeOf(localValue.LocalType); writer.Cast(localValue.LocalType, typeof(Type)); writer.SetPropertyValue(KnownMetadata.Properties.CustomLoggableMember_MemberType); writer.LoadLocal(localLogItem); writer.LoadLocal(localValue); writer.SetPropertyValue(KnownMetadata.Properties.CustomLoggableMember_MemberValue); writer.LoadSecondParameter(); writer.LoadLocal(localLogItem); writer.ActionDelegateMethodCall <CustomLoggableMember>(); } } writer.Return(); }
private void WriteSuccessResult(ILWriter writer) { var success = KnownMetadata.Methods.ValidationResult_Success; writer.StaticMethodCall(success); }
public static void AssemblyNameEmit(ILWriter il, string path) => il.WriteLine($".assembly {Path.GetFileNameWithoutExtension(path)} {{}}");
public static void AssemblyOperandEmit(ILWriter il, IOperand op, INamespace ns, TypeMapper m, Dictionary <LabelCode, string> labels, GenericsMapper g) { il.WriteLine(); if (op is IReturnBind prop && prop.Return is { } && m[prop.Return].Type == VariableType.Property)
public static void AssemblyExternEmit(ILWriter il, Assembly[] extern_asms) => extern_asms.Each(x => il.WriteLine($".assembly extern {x.GetName().Name} {{}}"));
private void WriteIntegerRange(ILWriter writer, PropertyInfo property, IntegerRangeAttribute integerRangeAttribute) { var validationKind = ValidationKind.IntegerRange; var signedSet = new HashSet <Type>() { typeof(sbyte), typeof(short), typeof(int), typeof(long) }; var unsignedSet = new HashSet <Type>() { typeof(byte), typeof(ushort), typeof(uint), typeof(ulong) }; LocalBuilder local; if (signedSet.Contains(property.PropertyType)) { local = writer.DeclareLocal <long>(); } else if (unsignedSet.Contains(property.PropertyType)) { local = writer.DeclareLocal <ulong>(); } else { WriteNotApplicableResult(writer, validationKind); writer.Return(); return; } writer.LoadFirstParameter(); writer.GetPropertyValue(property); writer.Cast(property.PropertyType, local.LocalType); writer.SetLocal(local); if (integerRangeAttribute.HasMinimum && integerRangeAttribute.HasMaximum) { if (integerRangeAttribute.Minimum > integerRangeAttribute.Maximum) { var message = CommonErrors.IntegerRangeValidationHasMinGreaterThanMax.WithValues(property.ReflectedType.Name, property.Name); throw new IncorrectValidationAttributeException(typeof(IntegerRangeAttribute), message); } } if (integerRangeAttribute.HasMinimum) { writer.LoadLocal(local); writer.LoadInt64(integerRangeAttribute.Minimum); var isGreaterThanOrEqual = writer.IfLessThan(); WriteFailureResult(writer, validationKind, CommonResults.IntegerPropertyIsTooLow.WithValues(property.ReflectedType.Name, property.Name, integerRangeAttribute.Minimum)); writer.Return(); writer.MarkLabel(isGreaterThanOrEqual); } if (integerRangeAttribute.HasMaximum) { writer.LoadLocal(local); writer.LoadInt64(integerRangeAttribute.Maximum); var isLessThanOrEqual = writer.IfGreaterThan(); WriteFailureResult(writer, validationKind, CommonResults.IntegerPropertyIsTooHigh.WithValues(property.ReflectedType.Name, property.Name, integerRangeAttribute.Maximum)); writer.Return(); writer.MarkLabel(isLessThanOrEqual); } }