internal override RuleExpressionResult Evaluate(CodeExpression expression, RuleExecution execution) { object obj5; CodeBinaryOperatorExpression expression2 = (CodeBinaryOperatorExpression)expression; object operandValue = RuleExpressionWalker.Evaluate(execution, expression2.Left).Value; CodeBinaryOperatorType @operator = expression2.Operator; switch (@operator) { case CodeBinaryOperatorType.BooleanAnd: if ((bool)operandValue) { return(new RuleLiteralResult(RuleExpressionWalker.Evaluate(execution, expression2.Right).Value)); } return(new RuleLiteralResult(false)); case CodeBinaryOperatorType.BooleanOr: if ((bool)operandValue) { return(new RuleLiteralResult(true)); } return(new RuleLiteralResult(RuleExpressionWalker.Evaluate(execution, expression2.Right).Value)); } object obj6 = RuleExpressionWalker.Evaluate(execution, expression2.Right).Value; RuleBinaryExpressionInfo info = execution.Validation.ExpressionInfo(expression2) as RuleBinaryExpressionInfo; if (info == null) { InvalidOperationException exception = new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, Messages.ExpressionNotValidated, new object[0])); exception.Data["ErrorObject"] = expression2; throw exception; } MethodInfo methodInfo = info.MethodInfo; if (methodInfo != null) { if (methodInfo == Literal.ObjectEquality) { obj5 = operandValue == obj6; } else { ParameterInfo[] parameters = methodInfo.GetParameters(); object[] objArray = new object[] { Executor.AdjustType(info.LeftType, operandValue, parameters[0].ParameterType), Executor.AdjustType(info.RightType, obj6, parameters[1].ParameterType) }; obj5 = methodInfo.Invoke(null, objArray); } } else { obj5 = EvaluateBinaryOperation(expression2, info.LeftType, operandValue, @operator, info.RightType, obj6); } return(new RuleLiteralResult(obj5)); }
internal override void AnalyzeUsage(CodeExpression expression, RuleAnalysis analysis, bool isRead, bool isWritten, RulePathQualifier qualifier) { CodeBinaryOperatorExpression expression2 = (CodeBinaryOperatorExpression)expression; RuleBinaryExpressionInfo info = analysis.Validation.ExpressionInfo(expression2) as RuleBinaryExpressionInfo; if (info != null) { MethodInfo methodInfo = info.MethodInfo; if (methodInfo != null) { List <CodeExpression> attributedExprs = new List <CodeExpression>(); CodeExpressionCollection argExprs = new CodeExpressionCollection(); argExprs.Add(expression2.Left); argExprs.Add(expression2.Right); CodeExpression targetExpr = new CodeTypeReferenceExpression(methodInfo.DeclaringType); analysis.AnalyzeRuleAttributes(methodInfo, targetExpr, qualifier, argExprs, methodInfo.GetParameters(), attributedExprs); } } RuleExpressionWalker.AnalyzeUsage(analysis, expression2.Left, true, false, null); RuleExpressionWalker.AnalyzeUsage(analysis, expression2.Right, true, false, null); }
internal override RuleExpressionInfo Validate(CodeExpression expression, RuleValidation validation, bool isWritten) { ValidationError error; CodeBinaryOperatorExpression newParent = (CodeBinaryOperatorExpression)expression; if (!validation.PushParentExpression(newParent)) { return(null); } if (isWritten) { error = new ValidationError(string.Format(CultureInfo.CurrentCulture, Messages.CannotWriteToExpression, new object[] { typeof(CodeBinaryOperatorExpression).ToString() }), 0x17a); error.UserData["ErrorObject"] = newParent; validation.Errors.Add(error); } RuleExpressionInfo info = null; RuleExpressionInfo info2 = null; if (newParent.Left == null) { error = new ValidationError(string.Format(CultureInfo.CurrentCulture, Messages.NullBinaryOpLHS, new object[] { newParent.Operator.ToString() }), 0x541); error.UserData["ErrorObject"] = newParent; validation.Errors.Add(error); } else { if (newParent.Left is CodeTypeReferenceExpression) { error = new ValidationError(string.Format(CultureInfo.CurrentCulture, Messages.CodeExpressionNotHandled, new object[] { newParent.Left.GetType().FullName }), 0x548); error.UserData["ErrorObject"] = newParent.Left; validation.AddError(error); return(null); } info = RuleExpressionWalker.Validate(validation, newParent.Left, false); } if (newParent.Right == null) { error = new ValidationError(string.Format(CultureInfo.CurrentCulture, Messages.NullBinaryOpRHS, new object[] { newParent.Operator.ToString() }), 0x543); error.UserData["ErrorObject"] = newParent; validation.Errors.Add(error); } else { if (newParent.Right is CodeTypeReferenceExpression) { error = new ValidationError(string.Format(CultureInfo.CurrentCulture, Messages.CodeExpressionNotHandled, new object[] { newParent.Right.GetType().FullName }), 0x548); error.UserData["ErrorObject"] = newParent.Right; validation.AddError(error); return(null); } info2 = RuleExpressionWalker.Validate(validation, newParent.Right, false); } validation.PopParentExpression(); RuleBinaryExpressionInfo info3 = null; if ((info != null) && (info2 != null)) { Type expressionType = info.ExpressionType; Type rhs = info2.ExpressionType; switch (newParent.Operator) { case CodeBinaryOperatorType.Add: case CodeBinaryOperatorType.Subtract: case CodeBinaryOperatorType.Multiply: case CodeBinaryOperatorType.Divide: case CodeBinaryOperatorType.Modulus: case CodeBinaryOperatorType.BitwiseOr: case CodeBinaryOperatorType.BitwiseAnd: info3 = ArithmeticLiteral.ResultType(newParent.Operator, expressionType, newParent.Left, rhs, newParent.Right, validation, out error); if (info3 == null) { if ((!(expressionType == typeof(ulong)) || !PromotionPossible(rhs, newParent.Right)) && (!(rhs == typeof(ulong)) || !PromotionPossible(expressionType, newParent.Left))) { error.UserData["ErrorObject"] = newParent; validation.Errors.Add(error); } else { info3 = new RuleBinaryExpressionInfo(expressionType, rhs, typeof(ulong)); } } goto Label_063E; case CodeBinaryOperatorType.IdentityInequality: case CodeBinaryOperatorType.IdentityEquality: info3 = new RuleBinaryExpressionInfo(expressionType, rhs, typeof(bool)); goto Label_063E; case CodeBinaryOperatorType.ValueEquality: info3 = Literal.AllowedComparison(expressionType, newParent.Left, rhs, newParent.Right, newParent.Operator, validation, out error); if (info3 == null) { if ((!(expressionType == typeof(ulong)) || !PromotionPossible(rhs, newParent.Right)) && (!(rhs == typeof(ulong)) || !PromotionPossible(expressionType, newParent.Left))) { error.UserData["ErrorObject"] = newParent; validation.Errors.Add(error); } else { info3 = new RuleBinaryExpressionInfo(expressionType, rhs, typeof(bool)); } } goto Label_063E; case CodeBinaryOperatorType.BooleanOr: case CodeBinaryOperatorType.BooleanAnd: info3 = new RuleBinaryExpressionInfo(expressionType, rhs, typeof(bool)); if (expressionType != typeof(bool)) { error = new ValidationError(string.Format(CultureInfo.CurrentCulture, Messages.LogicalOpBadTypeLHS, new object[] { newParent.Operator.ToString(), (expressionType == typeof(NullLiteral)) ? Messages.NullValue : RuleDecompiler.DecompileType(expressionType) }), 0x542); error.UserData["ErrorObject"] = newParent; validation.Errors.Add(error); info3 = null; } if (rhs != typeof(bool)) { error = new ValidationError(string.Format(CultureInfo.CurrentCulture, Messages.LogicalOpBadTypeRHS, new object[] { newParent.Operator.ToString(), (rhs == typeof(NullLiteral)) ? Messages.NullValue : RuleDecompiler.DecompileType(rhs) }), 0x544); error.UserData["ErrorObject"] = newParent; validation.Errors.Add(error); info3 = null; } goto Label_063E; case CodeBinaryOperatorType.LessThan: case CodeBinaryOperatorType.LessThanOrEqual: case CodeBinaryOperatorType.GreaterThan: case CodeBinaryOperatorType.GreaterThanOrEqual: info3 = Literal.AllowedComparison(expressionType, newParent.Left, rhs, newParent.Right, newParent.Operator, validation, out error); if (info3 == null) { if ((!(expressionType == typeof(ulong)) || !PromotionPossible(rhs, newParent.Right)) && (!(rhs == typeof(ulong)) || !PromotionPossible(expressionType, newParent.Left))) { error.UserData["ErrorObject"] = newParent; validation.Errors.Add(error); } else { info3 = new RuleBinaryExpressionInfo(expressionType, rhs, typeof(bool)); } } goto Label_063E; } error = new ValidationError(string.Format(CultureInfo.CurrentCulture, Messages.BinaryOpNotSupported, new object[] { newParent.Operator.ToString() }), 0x548); error.UserData["ErrorObject"] = newParent; validation.Errors.Add(error); } Label_063E: if (info3 != null) { MethodInfo methodInfo = info3.MethodInfo; if (methodInfo == null) { return(info3); } object[] customAttributes = methodInfo.GetCustomAttributes(typeof(RuleAttribute), true); if ((customAttributes == null) || (customAttributes.Length <= 0)) { return(info3); } Stack <MemberInfo> stack = new Stack <MemberInfo>(); stack.Push(methodInfo); bool flag = true; foreach (RuleAttribute attribute in customAttributes) { if (!attribute.Validate(validation, methodInfo, methodInfo.DeclaringType, methodInfo.GetParameters())) { flag = false; } } stack.Pop(); if (!flag) { return(null); } } return(info3); }
internal override RuleExpressionInfo Validate(CodeExpression expression, RuleValidation validation, bool isWritten) { ValidationError error; CodeBinaryOperatorExpression newParent = (CodeBinaryOperatorExpression) expression; if (!validation.PushParentExpression(newParent)) { return null; } if (isWritten) { error = new ValidationError(string.Format(CultureInfo.CurrentCulture, Messages.CannotWriteToExpression, new object[] { typeof(CodeBinaryOperatorExpression).ToString() }), 0x17a); error.UserData["ErrorObject"] = newParent; validation.Errors.Add(error); } RuleExpressionInfo info = null; RuleExpressionInfo info2 = null; if (newParent.Left == null) { error = new ValidationError(string.Format(CultureInfo.CurrentCulture, Messages.NullBinaryOpLHS, new object[] { newParent.Operator.ToString() }), 0x541); error.UserData["ErrorObject"] = newParent; validation.Errors.Add(error); } else { if (newParent.Left is CodeTypeReferenceExpression) { error = new ValidationError(string.Format(CultureInfo.CurrentCulture, Messages.CodeExpressionNotHandled, new object[] { newParent.Left.GetType().FullName }), 0x548); error.UserData["ErrorObject"] = newParent.Left; validation.AddError(error); return null; } info = RuleExpressionWalker.Validate(validation, newParent.Left, false); } if (newParent.Right == null) { error = new ValidationError(string.Format(CultureInfo.CurrentCulture, Messages.NullBinaryOpRHS, new object[] { newParent.Operator.ToString() }), 0x543); error.UserData["ErrorObject"] = newParent; validation.Errors.Add(error); } else { if (newParent.Right is CodeTypeReferenceExpression) { error = new ValidationError(string.Format(CultureInfo.CurrentCulture, Messages.CodeExpressionNotHandled, new object[] { newParent.Right.GetType().FullName }), 0x548); error.UserData["ErrorObject"] = newParent.Right; validation.AddError(error); return null; } info2 = RuleExpressionWalker.Validate(validation, newParent.Right, false); } validation.PopParentExpression(); RuleBinaryExpressionInfo info3 = null; if ((info != null) && (info2 != null)) { Type expressionType = info.ExpressionType; Type rhs = info2.ExpressionType; switch (newParent.Operator) { case CodeBinaryOperatorType.Add: case CodeBinaryOperatorType.Subtract: case CodeBinaryOperatorType.Multiply: case CodeBinaryOperatorType.Divide: case CodeBinaryOperatorType.Modulus: case CodeBinaryOperatorType.BitwiseOr: case CodeBinaryOperatorType.BitwiseAnd: info3 = ArithmeticLiteral.ResultType(newParent.Operator, expressionType, newParent.Left, rhs, newParent.Right, validation, out error); if (info3 == null) { if ((!(expressionType == typeof(ulong)) || !PromotionPossible(rhs, newParent.Right)) && (!(rhs == typeof(ulong)) || !PromotionPossible(expressionType, newParent.Left))) { error.UserData["ErrorObject"] = newParent; validation.Errors.Add(error); } else { info3 = new RuleBinaryExpressionInfo(expressionType, rhs, typeof(ulong)); } } goto Label_063E; case CodeBinaryOperatorType.IdentityInequality: case CodeBinaryOperatorType.IdentityEquality: info3 = new RuleBinaryExpressionInfo(expressionType, rhs, typeof(bool)); goto Label_063E; case CodeBinaryOperatorType.ValueEquality: info3 = Literal.AllowedComparison(expressionType, newParent.Left, rhs, newParent.Right, newParent.Operator, validation, out error); if (info3 == null) { if ((!(expressionType == typeof(ulong)) || !PromotionPossible(rhs, newParent.Right)) && (!(rhs == typeof(ulong)) || !PromotionPossible(expressionType, newParent.Left))) { error.UserData["ErrorObject"] = newParent; validation.Errors.Add(error); } else { info3 = new RuleBinaryExpressionInfo(expressionType, rhs, typeof(bool)); } } goto Label_063E; case CodeBinaryOperatorType.BooleanOr: case CodeBinaryOperatorType.BooleanAnd: info3 = new RuleBinaryExpressionInfo(expressionType, rhs, typeof(bool)); if (expressionType != typeof(bool)) { error = new ValidationError(string.Format(CultureInfo.CurrentCulture, Messages.LogicalOpBadTypeLHS, new object[] { newParent.Operator.ToString(), (expressionType == typeof(NullLiteral)) ? Messages.NullValue : RuleDecompiler.DecompileType(expressionType) }), 0x542); error.UserData["ErrorObject"] = newParent; validation.Errors.Add(error); info3 = null; } if (rhs != typeof(bool)) { error = new ValidationError(string.Format(CultureInfo.CurrentCulture, Messages.LogicalOpBadTypeRHS, new object[] { newParent.Operator.ToString(), (rhs == typeof(NullLiteral)) ? Messages.NullValue : RuleDecompiler.DecompileType(rhs) }), 0x544); error.UserData["ErrorObject"] = newParent; validation.Errors.Add(error); info3 = null; } goto Label_063E; case CodeBinaryOperatorType.LessThan: case CodeBinaryOperatorType.LessThanOrEqual: case CodeBinaryOperatorType.GreaterThan: case CodeBinaryOperatorType.GreaterThanOrEqual: info3 = Literal.AllowedComparison(expressionType, newParent.Left, rhs, newParent.Right, newParent.Operator, validation, out error); if (info3 == null) { if ((!(expressionType == typeof(ulong)) || !PromotionPossible(rhs, newParent.Right)) && (!(rhs == typeof(ulong)) || !PromotionPossible(expressionType, newParent.Left))) { error.UserData["ErrorObject"] = newParent; validation.Errors.Add(error); } else { info3 = new RuleBinaryExpressionInfo(expressionType, rhs, typeof(bool)); } } goto Label_063E; } error = new ValidationError(string.Format(CultureInfo.CurrentCulture, Messages.BinaryOpNotSupported, new object[] { newParent.Operator.ToString() }), 0x548); error.UserData["ErrorObject"] = newParent; validation.Errors.Add(error); } Label_063E: if (info3 != null) { MethodInfo methodInfo = info3.MethodInfo; if (methodInfo == null) { return info3; } object[] customAttributes = methodInfo.GetCustomAttributes(typeof(RuleAttribute), true); if ((customAttributes == null) || (customAttributes.Length <= 0)) { return info3; } Stack<MemberInfo> stack = new Stack<MemberInfo>(); stack.Push(methodInfo); bool flag = true; foreach (RuleAttribute attribute in customAttributes) { if (!attribute.Validate(validation, methodInfo, methodInfo.DeclaringType, methodInfo.GetParameters())) { flag = false; } } stack.Pop(); if (!flag) { return null; } } return info3; }
internal override RuleExpressionInfo Validate(CodeExpression expression, RuleValidation validation, bool isWritten) { string message; ValidationError error; CodeBinaryOperatorExpression binaryExpr = (CodeBinaryOperatorExpression)expression; // Early exit from this if a cycle is detected. if (!validation.PushParentExpression(binaryExpr)) return null; if (isWritten) { message = string.Format(CultureInfo.CurrentCulture, Messages.CannotWriteToExpression, typeof(CodeBinaryOperatorExpression).ToString()); error = new ValidationError(message, ErrorNumbers.Error_InvalidAssignTarget); error.UserData[RuleUserDataKeys.ErrorObject] = binaryExpr; validation.Errors.Add(error); } RuleExpressionInfo lhsExprInfo = null; RuleExpressionInfo rhsExprInfo = null; if (binaryExpr.Left == null) { message = string.Format(CultureInfo.CurrentCulture, Messages.NullBinaryOpLHS, binaryExpr.Operator.ToString()); error = new ValidationError(message, ErrorNumbers.Error_LeftOperandMissing); error.UserData[RuleUserDataKeys.ErrorObject] = binaryExpr; validation.Errors.Add(error); } else { if (binaryExpr.Left is CodeTypeReferenceExpression) { message = string.Format(CultureInfo.CurrentCulture, Messages.CodeExpressionNotHandled, binaryExpr.Left.GetType().FullName); error = new ValidationError(message, ErrorNumbers.Error_CodeExpressionNotHandled); error.UserData[RuleUserDataKeys.ErrorObject] = binaryExpr.Left; validation.AddError(error); return null; } lhsExprInfo = RuleExpressionWalker.Validate(validation, binaryExpr.Left, false); } if (binaryExpr.Right == null) { message = string.Format(CultureInfo.CurrentCulture, Messages.NullBinaryOpRHS, binaryExpr.Operator.ToString()); error = new ValidationError(message, ErrorNumbers.Error_RightOperandMissing); error.UserData[RuleUserDataKeys.ErrorObject] = binaryExpr; validation.Errors.Add(error); } else { if (binaryExpr.Right is CodeTypeReferenceExpression) { message = string.Format(CultureInfo.CurrentCulture, Messages.CodeExpressionNotHandled, binaryExpr.Right.GetType().FullName); error = new ValidationError(message, ErrorNumbers.Error_CodeExpressionNotHandled); error.UserData[RuleUserDataKeys.ErrorObject] = binaryExpr.Right; validation.AddError(error); return null; } rhsExprInfo = RuleExpressionWalker.Validate(validation, binaryExpr.Right, false); } validation.PopParentExpression(); RuleBinaryExpressionInfo resultExprInfo = null; if (lhsExprInfo != null && rhsExprInfo != null) { Type lhsType = lhsExprInfo.ExpressionType; Type rhsType = rhsExprInfo.ExpressionType; switch (binaryExpr.Operator) { case CodeBinaryOperatorType.Add: case CodeBinaryOperatorType.Subtract: case CodeBinaryOperatorType.Multiply: case CodeBinaryOperatorType.Divide: case CodeBinaryOperatorType.Modulus: case CodeBinaryOperatorType.BitwiseAnd: case CodeBinaryOperatorType.BitwiseOr: resultExprInfo = ArithmeticLiteral.ResultType(binaryExpr.Operator, lhsType, binaryExpr.Left, rhsType, binaryExpr.Right, validation, out error); if (resultExprInfo == null) { // check if constants are used with ulongs, as we should do some extra "conversions" if (((lhsType == typeof(ulong)) && (PromotionPossible(rhsType, binaryExpr.Right))) || ((rhsType == typeof(ulong)) && (PromotionPossible(lhsType, binaryExpr.Left)))) { resultExprInfo = new RuleBinaryExpressionInfo(lhsType, rhsType, typeof(ulong)); } else { error.UserData[RuleUserDataKeys.ErrorObject] = binaryExpr; validation.Errors.Add(error); } } break; case CodeBinaryOperatorType.IdentityEquality: case CodeBinaryOperatorType.IdentityInequality: resultExprInfo = new RuleBinaryExpressionInfo(lhsType, rhsType, typeof(bool)); break; case CodeBinaryOperatorType.ValueEquality: resultExprInfo = Literal.AllowedComparison(lhsType, binaryExpr.Left, rhsType, binaryExpr.Right, binaryExpr.Operator, validation, out error); if (resultExprInfo == null) { // check if constants are used with ulongs, as we should do some extra "conversions" if (((lhsType == typeof(ulong)) && (PromotionPossible(rhsType, binaryExpr.Right))) || ((rhsType == typeof(ulong)) && (PromotionPossible(lhsType, binaryExpr.Left)))) { resultExprInfo = new RuleBinaryExpressionInfo(lhsType, rhsType, typeof(bool)); } else { error.UserData[RuleUserDataKeys.ErrorObject] = binaryExpr; validation.Errors.Add(error); } } break; case CodeBinaryOperatorType.LessThan: case CodeBinaryOperatorType.LessThanOrEqual: case CodeBinaryOperatorType.GreaterThan: case CodeBinaryOperatorType.GreaterThanOrEqual: resultExprInfo = Literal.AllowedComparison(lhsType, binaryExpr.Left, rhsType, binaryExpr.Right, binaryExpr.Operator, validation, out error); if (resultExprInfo == null) { // check if constants are used with ulongs, as we should do some extra "conversions" if (((lhsType == typeof(ulong)) && (PromotionPossible(rhsType, binaryExpr.Right))) || ((rhsType == typeof(ulong)) && (PromotionPossible(lhsType, binaryExpr.Left)))) { resultExprInfo = new RuleBinaryExpressionInfo(lhsType, rhsType, typeof(bool)); } else { error.UserData[RuleUserDataKeys.ErrorObject] = binaryExpr; validation.Errors.Add(error); } } break; case CodeBinaryOperatorType.BooleanAnd: case CodeBinaryOperatorType.BooleanOr: resultExprInfo = new RuleBinaryExpressionInfo(lhsType, rhsType, typeof(bool)); if (lhsType != typeof(bool)) { message = string.Format(CultureInfo.CurrentCulture, Messages.LogicalOpBadTypeLHS, binaryExpr.Operator.ToString(), (lhsType == typeof(NullLiteral)) ? Messages.NullValue : RuleDecompiler.DecompileType(lhsType)); error = new ValidationError(message, ErrorNumbers.Error_LeftOperandInvalidType); error.UserData[RuleUserDataKeys.ErrorObject] = binaryExpr; validation.Errors.Add(error); resultExprInfo = null; } if (rhsType != typeof(bool)) { message = string.Format(CultureInfo.CurrentCulture, Messages.LogicalOpBadTypeRHS, binaryExpr.Operator.ToString(), (rhsType == typeof(NullLiteral)) ? Messages.NullValue : RuleDecompiler.DecompileType(rhsType)); error = new ValidationError(message, ErrorNumbers.Error_RightOperandInvalidType); error.UserData[RuleUserDataKeys.ErrorObject] = binaryExpr; validation.Errors.Add(error); resultExprInfo = null; } break; default: { message = string.Format(CultureInfo.CurrentCulture, Messages.BinaryOpNotSupported, binaryExpr.Operator.ToString()); error = new ValidationError(message, ErrorNumbers.Error_CodeExpressionNotHandled); error.UserData[RuleUserDataKeys.ErrorObject] = binaryExpr; validation.Errors.Add(error); } break; } } // Validate any RuleAttributes, if present. if (resultExprInfo != null) { MethodInfo method = resultExprInfo.MethodInfo; if (method != null) { object[] attrs = method.GetCustomAttributes(typeof(RuleAttribute), true); if (attrs != null && attrs.Length > 0) { Stack<MemberInfo> methodStack = new Stack<MemberInfo>(); methodStack.Push(method); bool allAttributesValid = true; foreach (RuleAttribute ruleAttr in attrs) { if (!ruleAttr.Validate(validation, method, method.DeclaringType, method.GetParameters())) allAttributesValid = false; } methodStack.Pop(); if (!allAttributesValid) return null; } } } return resultExprInfo; }