internal override RuleExpressionInfo Validate(CodeExpression expression, RuleValidation validation, bool isWritten)
        {
            Type targetType = null;
            RuleMethodInvokeExpressionInfo methodInvokeInfo = null;
            string message;
            ValidationError error = null;
            BindingFlags bindingFlags = BindingFlags.Public;

            CodeMethodInvokeExpression invokeExpr = (CodeMethodInvokeExpression)expression;

            if (isWritten)
            {
                message = string.Format(CultureInfo.CurrentCulture, Messages.CannotWriteToExpression, typeof(CodeMethodInvokeExpression).ToString());
                error = new ValidationError(message, ErrorNumbers.Error_InvalidAssignTarget);
                error.UserData[RuleUserDataKeys.ErrorObject] = invokeExpr;
                validation.Errors.Add(error);
                return null;
            }

            if ((invokeExpr.Method == null) || (invokeExpr.Method.TargetObject == null))
            {
                message = string.Format(CultureInfo.CurrentCulture, Messages.NullMethodTarget, invokeExpr.Method.MethodName);
                error = new ValidationError(message, ErrorNumbers.Error_ParameterNotSet);
                error.UserData[RuleUserDataKeys.ErrorObject] = invokeExpr;
                validation.Errors.Add(error);
                return null; // Fatal error; discontinue validation of this object.
            }

            if ((invokeExpr.Method.TypeArguments != null) && (invokeExpr.Method.TypeArguments.Count > 0))
            {
                error = new ValidationError(Messages.GenericMethodsNotSupported, ErrorNumbers.Error_CodeExpressionNotHandled);
                error.UserData[RuleUserDataKeys.ErrorObject] = invokeExpr;
                validation.Errors.Add(error);
                return null;
            }

            try
            {
                // Early exit from this if a cycle is detected.
                if (!validation.PushParentExpression(invokeExpr))
                    return null;

                RuleExpressionInfo targetExprInfo = RuleExpressionWalker.Validate(validation, invokeExpr.Method.TargetObject, false);
                if (targetExprInfo == null)     // error occurred, so simply return
                    return null;

                targetType = targetExprInfo.ExpressionType;
                if (targetType == null)
                    return null;

                // if an error occurred (targetType == null), continue on to validate the arguments
                if (targetType == typeof(NullLiteral))
                {
                    message = string.Format(CultureInfo.CurrentCulture, Messages.NullMethodTarget, invokeExpr.Method.MethodName);
                    error = new ValidationError(message, ErrorNumbers.Error_BindingTypeMissing);
                    error.UserData[RuleUserDataKeys.ErrorObject] = invokeExpr;
                    validation.Errors.Add(error);
                    targetType = null; // force exit after validating the arguments
                }

                List<CodeExpression> argExprs = new List<CodeExpression>();

                bool hasInvalidArgument = false;
                if (invokeExpr.Parameters != null)
                {
                    for (int i = 0; i < invokeExpr.Parameters.Count; ++i)
                    {
                        CodeExpression argExpr = invokeExpr.Parameters[i];
                        if (argExpr == null)
                        {
                            message = string.Format(CultureInfo.CurrentCulture, Messages.NullMethodParameter, i.ToString(CultureInfo.CurrentCulture), invokeExpr.Method.MethodName);
                            error = new ValidationError(message, ErrorNumbers.Error_ParameterNotSet);
                            error.UserData[RuleUserDataKeys.ErrorObject] = invokeExpr;
                            validation.Errors.Add(error);
                            targetType = null; // force exit after validating the rest of the arguments
                        }
                        else
                        {
                            if (argExpr is CodeTypeReferenceExpression)
                            {
                                message = string.Format(CultureInfo.CurrentCulture, Messages.CodeExpressionNotHandled, argExpr.GetType().FullName);
                                error = new ValidationError(message, ErrorNumbers.Error_CodeExpressionNotHandled);
                                error.UserData[RuleUserDataKeys.ErrorObject] = argExpr;
                                validation.AddError(error);

                                hasInvalidArgument = true;
                            }

                            // Validate the argument.
                            RuleExpressionInfo argExprInfo = RuleExpressionWalker.Validate(validation, argExpr, false);
                            if (argExprInfo == null)
                                hasInvalidArgument = true;
                            argExprs.Add(argExpr);
                        }
                    }
                }

                // Stop further validation if there was a problem with the target expression.
                if (targetType == null)
                    return null;

                // Stop further validation if there was a problem with any of the arguments.
                if (hasInvalidArgument)
                    return null;

                if (invokeExpr.Method.TargetObject is CodeTypeReferenceExpression)
                    bindingFlags |= BindingFlags.Static | BindingFlags.FlattenHierarchy;
                else
                    bindingFlags |= BindingFlags.Instance;
                if (validation.AllowInternalMembers(targetType))
                    bindingFlags |= BindingFlags.NonPublic;

                // Everything okay so far, try to resolve the method.
                methodInvokeInfo = validation.ResolveMethod(targetType, invokeExpr.Method.MethodName, bindingFlags, argExprs, out error);
                if ((methodInvokeInfo == null) && (invokeExpr.UserData.Contains(RuleUserDataKeys.QualifiedName)))
                {
                    // failed to resolve the method, but a fully qualified type name is around
                    // load the type, add it to the assemblies, and try again
                    string qualifiedName = invokeExpr.UserData[RuleUserDataKeys.QualifiedName] as string;
                    Type containingClassType = validation.ResolveType(qualifiedName);
                    if (containingClassType != null)
                    {
                        validation.DetermineExtensionMethods(containingClassType.Assembly);
                        methodInvokeInfo = validation.ResolveMethod(targetType, invokeExpr.Method.MethodName, bindingFlags, argExprs, out error);
                    }
                }
                if (methodInvokeInfo == null)
                {
                    error.UserData[RuleUserDataKeys.ErrorObject] = invokeExpr;
                    validation.Errors.Add(error);
                    return null;
                }
            }
            finally
            {
                validation.PopParentExpression();
            }


            MethodInfo mi = methodInvokeInfo.MethodInfo;

            if (mi.ReturnType == null)
            {
                // This can only happen with a design-time type.
                message = string.Format(CultureInfo.CurrentCulture, Messages.CouldNotDetermineMemberType, invokeExpr.Method.MethodName);
                error = new ValidationError(message, ErrorNumbers.Error_CouldNotDetermineMemberType);
                error.UserData[RuleUserDataKeys.ErrorObject] = invokeExpr;
                validation.Errors.Add(error);
                return null;
            }

            if (!validation.ValidateMemberAccess(invokeExpr.Method.TargetObject, targetType, mi, invokeExpr.Method.MethodName, invokeExpr))
                return null;

            // Validate any RuleAttributes, if present.
            object[] attrs = mi.GetCustomAttributes(typeof(RuleAttribute), true);
            if (attrs != null && attrs.Length > 0)
            {
                Stack<MemberInfo> methodStack = new Stack<MemberInfo>();
                methodStack.Push(mi);

                bool allAttributesValid = true;
                foreach (RuleAttribute ruleAttr in attrs)
                {
                    if (!ruleAttr.Validate(validation, mi, targetType, mi.GetParameters()))
                        allAttributesValid = false;
                }

                methodStack.Pop();

                if (!allAttributesValid)
                    return null;
            }

            // if this is an extension method, save the type information
            if (mi is ExtensionMethodInfo)
            {
                invokeExpr.UserData[RuleUserDataKeys.QualifiedName] = mi.DeclaringType.AssemblyQualifiedName;
            }

            return methodInvokeInfo;
        }
示例#2
0
        internal override RuleExpressionInfo Validate(CodeExpression expression, RuleValidation validation, bool isWritten)
        {
            Type expressionType = null;
            RuleMethodInvokeExpressionInfo info  = null;
            ValidationError            item      = null;
            BindingFlags               @public   = BindingFlags.Public;
            CodeMethodInvokeExpression newParent = (CodeMethodInvokeExpression)expression;

            if (isWritten)
            {
                item = new ValidationError(string.Format(CultureInfo.CurrentCulture, Messages.CannotWriteToExpression, new object[] { typeof(CodeMethodInvokeExpression).ToString() }), 0x17a);
                item.UserData["ErrorObject"] = newParent;
                validation.Errors.Add(item);
                return(null);
            }
            if ((newParent.Method == null) || (newParent.Method.TargetObject == null))
            {
                item = new ValidationError(string.Format(CultureInfo.CurrentCulture, Messages.NullMethodTarget, new object[] { newParent.Method.MethodName }), 0x53d);
                item.UserData["ErrorObject"] = newParent;
                validation.Errors.Add(item);
                return(null);
            }
            if ((newParent.Method.TypeArguments != null) && (newParent.Method.TypeArguments.Count > 0))
            {
                item = new ValidationError(Messages.GenericMethodsNotSupported, 0x548);
                item.UserData["ErrorObject"] = newParent;
                validation.Errors.Add(item);
                return(null);
            }
            try
            {
                if (!validation.PushParentExpression(newParent))
                {
                    return(null);
                }
                RuleExpressionInfo info2 = RuleExpressionWalker.Validate(validation, newParent.Method.TargetObject, false);
                if (info2 == null)
                {
                    return(null);
                }
                expressionType = info2.ExpressionType;
                if (expressionType == null)
                {
                    return(null);
                }
                if (expressionType == typeof(NullLiteral))
                {
                    item = new ValidationError(string.Format(CultureInfo.CurrentCulture, Messages.NullMethodTarget, new object[] { newParent.Method.MethodName }), 0x546);
                    item.UserData["ErrorObject"] = newParent;
                    validation.Errors.Add(item);
                    expressionType = null;
                }
                List <CodeExpression> argumentExprs = new List <CodeExpression>();
                bool flag = false;
                if (newParent.Parameters != null)
                {
                    for (int i = 0; i < newParent.Parameters.Count; i++)
                    {
                        CodeExpression expression3 = newParent.Parameters[i];
                        if (expression3 == null)
                        {
                            item = new ValidationError(string.Format(CultureInfo.CurrentCulture, Messages.NullMethodParameter, new object[] { i.ToString(CultureInfo.CurrentCulture), newParent.Method.MethodName }), 0x53d);
                            item.UserData["ErrorObject"] = newParent;
                            validation.Errors.Add(item);
                            expressionType = null;
                        }
                        else
                        {
                            if (expression3 is CodeTypeReferenceExpression)
                            {
                                item = new ValidationError(string.Format(CultureInfo.CurrentCulture, Messages.CodeExpressionNotHandled, new object[] { expression3.GetType().FullName }), 0x548);
                                item.UserData["ErrorObject"] = expression3;
                                validation.AddError(item);
                                flag = true;
                            }
                            if (RuleExpressionWalker.Validate(validation, expression3, false) == null)
                            {
                                flag = true;
                            }
                            argumentExprs.Add(expression3);
                        }
                    }
                }
                if (expressionType == null)
                {
                    return(null);
                }
                if (flag)
                {
                    return(null);
                }
                if (newParent.Method.TargetObject is CodeTypeReferenceExpression)
                {
                    @public |= BindingFlags.FlattenHierarchy | BindingFlags.Static;
                }
                else
                {
                    @public |= BindingFlags.Instance;
                }
                if (validation.AllowInternalMembers(expressionType))
                {
                    @public |= BindingFlags.NonPublic;
                }
                info = validation.ResolveMethod(expressionType, newParent.Method.MethodName, @public, argumentExprs, out item);
                if ((info == null) && newParent.UserData.Contains("QualifiedName"))
                {
                    string qualifiedName = newParent.UserData["QualifiedName"] as string;
                    Type   type2         = validation.ResolveType(qualifiedName);
                    if (type2 != null)
                    {
                        validation.DetermineExtensionMethods(type2.Assembly);
                        info = validation.ResolveMethod(expressionType, newParent.Method.MethodName, @public, argumentExprs, out item);
                    }
                }
                if (info == null)
                {
                    item.UserData["ErrorObject"] = newParent;
                    validation.Errors.Add(item);
                    return(null);
                }
            }
            finally
            {
                validation.PopParentExpression();
            }
            MethodInfo methodInfo = info.MethodInfo;

            if (methodInfo.ReturnType == null)
            {
                item = new ValidationError(string.Format(CultureInfo.CurrentCulture, Messages.CouldNotDetermineMemberType, new object[] { newParent.Method.MethodName }), 0x194);
                item.UserData["ErrorObject"] = newParent;
                validation.Errors.Add(item);
                return(null);
            }
            if (!validation.ValidateMemberAccess(newParent.Method.TargetObject, expressionType, methodInfo, newParent.Method.MethodName, newParent))
            {
                return(null);
            }
            object[] customAttributes = methodInfo.GetCustomAttributes(typeof(RuleAttribute), true);
            if ((customAttributes != null) && (customAttributes.Length > 0))
            {
                Stack <MemberInfo> stack = new Stack <MemberInfo>();
                stack.Push(methodInfo);
                bool flag2 = true;
                foreach (RuleAttribute attribute in customAttributes)
                {
                    if (!attribute.Validate(validation, methodInfo, expressionType, methodInfo.GetParameters()))
                    {
                        flag2 = false;
                    }
                }
                stack.Pop();
                if (!flag2)
                {
                    return(null);
                }
            }
            if (methodInfo is ExtensionMethodInfo)
            {
                newParent.UserData["QualifiedName"] = methodInfo.DeclaringType.AssemblyQualifiedName;
            }
            return(info);
        }
 internal override RuleExpressionInfo Validate(CodeExpression expression, RuleValidation validation, bool isWritten)
 {
     Type expressionType = null;
     RuleMethodInvokeExpressionInfo info = null;
     ValidationError item = null;
     BindingFlags @public = BindingFlags.Public;
     CodeMethodInvokeExpression newParent = (CodeMethodInvokeExpression) expression;
     if (isWritten)
     {
         item = new ValidationError(string.Format(CultureInfo.CurrentCulture, Messages.CannotWriteToExpression, new object[] { typeof(CodeMethodInvokeExpression).ToString() }), 0x17a);
         item.UserData["ErrorObject"] = newParent;
         validation.Errors.Add(item);
         return null;
     }
     if ((newParent.Method == null) || (newParent.Method.TargetObject == null))
     {
         item = new ValidationError(string.Format(CultureInfo.CurrentCulture, Messages.NullMethodTarget, new object[] { newParent.Method.MethodName }), 0x53d);
         item.UserData["ErrorObject"] = newParent;
         validation.Errors.Add(item);
         return null;
     }
     if ((newParent.Method.TypeArguments != null) && (newParent.Method.TypeArguments.Count > 0))
     {
         item = new ValidationError(Messages.GenericMethodsNotSupported, 0x548);
         item.UserData["ErrorObject"] = newParent;
         validation.Errors.Add(item);
         return null;
     }
     try
     {
         if (!validation.PushParentExpression(newParent))
         {
             return null;
         }
         RuleExpressionInfo info2 = RuleExpressionWalker.Validate(validation, newParent.Method.TargetObject, false);
         if (info2 == null)
         {
             return null;
         }
         expressionType = info2.ExpressionType;
         if (expressionType == null)
         {
             return null;
         }
         if (expressionType == typeof(NullLiteral))
         {
             item = new ValidationError(string.Format(CultureInfo.CurrentCulture, Messages.NullMethodTarget, new object[] { newParent.Method.MethodName }), 0x546);
             item.UserData["ErrorObject"] = newParent;
             validation.Errors.Add(item);
             expressionType = null;
         }
         List<CodeExpression> argumentExprs = new List<CodeExpression>();
         bool flag = false;
         if (newParent.Parameters != null)
         {
             for (int i = 0; i < newParent.Parameters.Count; i++)
             {
                 CodeExpression expression3 = newParent.Parameters[i];
                 if (expression3 == null)
                 {
                     item = new ValidationError(string.Format(CultureInfo.CurrentCulture, Messages.NullMethodParameter, new object[] { i.ToString(CultureInfo.CurrentCulture), newParent.Method.MethodName }), 0x53d);
                     item.UserData["ErrorObject"] = newParent;
                     validation.Errors.Add(item);
                     expressionType = null;
                 }
                 else
                 {
                     if (expression3 is CodeTypeReferenceExpression)
                     {
                         item = new ValidationError(string.Format(CultureInfo.CurrentCulture, Messages.CodeExpressionNotHandled, new object[] { expression3.GetType().FullName }), 0x548);
                         item.UserData["ErrorObject"] = expression3;
                         validation.AddError(item);
                         flag = true;
                     }
                     if (RuleExpressionWalker.Validate(validation, expression3, false) == null)
                     {
                         flag = true;
                     }
                     argumentExprs.Add(expression3);
                 }
             }
         }
         if (expressionType == null)
         {
             return null;
         }
         if (flag)
         {
             return null;
         }
         if (newParent.Method.TargetObject is CodeTypeReferenceExpression)
         {
             @public |= BindingFlags.FlattenHierarchy | BindingFlags.Static;
         }
         else
         {
             @public |= BindingFlags.Instance;
         }
         if (validation.AllowInternalMembers(expressionType))
         {
             @public |= BindingFlags.NonPublic;
         }
         info = validation.ResolveMethod(expressionType, newParent.Method.MethodName, @public, argumentExprs, out item);
         if ((info == null) && newParent.UserData.Contains("QualifiedName"))
         {
             string qualifiedName = newParent.UserData["QualifiedName"] as string;
             Type type2 = validation.ResolveType(qualifiedName);
             if (type2 != null)
             {
                 validation.DetermineExtensionMethods(type2.Assembly);
                 info = validation.ResolveMethod(expressionType, newParent.Method.MethodName, @public, argumentExprs, out item);
             }
         }
         if (info == null)
         {
             item.UserData["ErrorObject"] = newParent;
             validation.Errors.Add(item);
             return null;
         }
     }
     finally
     {
         validation.PopParentExpression();
     }
     MethodInfo methodInfo = info.MethodInfo;
     if (methodInfo.ReturnType == null)
     {
         item = new ValidationError(string.Format(CultureInfo.CurrentCulture, Messages.CouldNotDetermineMemberType, new object[] { newParent.Method.MethodName }), 0x194);
         item.UserData["ErrorObject"] = newParent;
         validation.Errors.Add(item);
         return null;
     }
     if (!validation.ValidateMemberAccess(newParent.Method.TargetObject, expressionType, methodInfo, newParent.Method.MethodName, newParent))
     {
         return null;
     }
     object[] customAttributes = methodInfo.GetCustomAttributes(typeof(RuleAttribute), true);
     if ((customAttributes != null) && (customAttributes.Length > 0))
     {
         Stack<MemberInfo> stack = new Stack<MemberInfo>();
         stack.Push(methodInfo);
         bool flag2 = true;
         foreach (RuleAttribute attribute in customAttributes)
         {
             if (!attribute.Validate(validation, methodInfo, expressionType, methodInfo.GetParameters()))
             {
                 flag2 = false;
             }
         }
         stack.Pop();
         if (!flag2)
         {
             return null;
         }
     }
     if (methodInfo is ExtensionMethodInfo)
     {
         newParent.UserData["QualifiedName"] = methodInfo.DeclaringType.AssemblyQualifiedName;
     }
     return info;
 }