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 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 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); }
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(); } }
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(); } }
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); } }