/// <summary>
        /// Gets the row number in the C# 4.0 spec operator precedence table.
        /// </summary>
        static int GetPrecedence(Expression expr)
        {
            // Note: the operator precedence table on MSDN is incorrect
            if (expr is QueryExpression)
            {
                // Not part of the table in the C# spec, but we need to ensure that queries within
                // primary expressions get parenthesized.
                return(QueryOrLambda);
            }
            UnaryOperatorExpression uoe = expr as UnaryOperatorExpression;

            if (uoe != null)
            {
                if (uoe.Operator == UnaryOperatorType.PostDecrement || uoe.Operator == UnaryOperatorType.PostIncrement)
                {
                    return(Primary);
                }
                else
                {
                    return(Unary);
                }
            }
            if (expr is CastExpression)
            {
                return(Unary);
            }
            BinaryOperatorExpression boe = expr as BinaryOperatorExpression;

            if (boe != null)
            {
                switch (boe.Operator)
                {
                case BinaryOperatorType.Multiply:
                case BinaryOperatorType.Divide:
                case BinaryOperatorType.Modulus:
                    return(13);                            // multiplicative

                case BinaryOperatorType.Add:
                case BinaryOperatorType.Subtract:
                    return(12);                            // additive

                case BinaryOperatorType.ShiftLeft:
                case BinaryOperatorType.ShiftRight:
                    return(11);

                case BinaryOperatorType.GreaterThan:
                case BinaryOperatorType.GreaterThanOrEqual:
                case BinaryOperatorType.LessThan:
                case BinaryOperatorType.LessThanOrEqual:
                    return(RelationalAndTypeTesting);

                case BinaryOperatorType.Equality:
                case BinaryOperatorType.InEquality:
                    return(Equality);

                case BinaryOperatorType.BitwiseAnd:
                    return(8);

                case BinaryOperatorType.ExclusiveOr:
                    return(7);

                case BinaryOperatorType.BitwiseOr:
                    return(6);

                case BinaryOperatorType.ConditionalAnd:
                    return(5);

                case BinaryOperatorType.ConditionalOr:
                    return(4);

                case BinaryOperatorType.NullCoalescing:
                    return(3);

                default:
                    throw new NotSupportedException("Invalid value for BinaryOperatorType");
                }
            }
            if (expr is IsExpression || expr is AsExpression)
            {
                return(RelationalAndTypeTesting);
            }
            if (expr is ConditionalExpression)
            {
                return(Conditional);
            }
            if (expr is AssignmentExpression || expr is LambdaExpression)
            {
                return(Assignment);
            }
            // anything else: primary expression
            return(Primary);
        }
Ejemplo n.º 2
0
 void IAstVisitor.VisitUnaryOperatorExpression(UnaryOperatorExpression unaryOperatorExpression)
 {
     Visit(EnterUnaryOperatorExpression, LeaveUnaryOperatorExpression, unaryOperatorExpression);
 }
        public override void VisitCastExpression(CastExpression castExpression)
        {
            ParenthesizeIfRequired(castExpression.Expression, InsertParenthesesForReadability ? Primary : Unary);
            // There's a nasty issue in the C# grammar: cast expressions including certain operators are ambiguous in some cases
            // "(int)-1" is fine, but "(A)-b" is not a cast.
            UnaryOperatorExpression uoe = castExpression.Expression as UnaryOperatorExpression;

            if (uoe != null && !(uoe.Operator == UnaryOperatorType.BitNot || uoe.Operator == UnaryOperatorType.Not))
            {
                if (TypeCanBeMisinterpretedAsExpression(castExpression.Type))
                {
                    Parenthesize(castExpression.Expression);
                }
            }
            // The above issue can also happen with PrimitiveExpressions representing negative values:
            PrimitiveExpression pe = castExpression.Expression as PrimitiveExpression;

            if (pe != null && pe.Value != null && TypeCanBeMisinterpretedAsExpression(castExpression.Type))
            {
                TypeCode typeCode = Type.GetTypeCode(pe.Value.GetType());
                switch (typeCode)
                {
                case TypeCode.SByte:
                    if ((sbyte)pe.Value < 0)
                    {
                        Parenthesize(castExpression.Expression);
                    }
                    break;

                case TypeCode.Int16:
                    if ((short)pe.Value < 0)
                    {
                        Parenthesize(castExpression.Expression);
                    }
                    break;

                case TypeCode.Int32:
                    if ((int)pe.Value < 0)
                    {
                        Parenthesize(castExpression.Expression);
                    }
                    break;

                case TypeCode.Int64:
                    if ((long)pe.Value < 0)
                    {
                        Parenthesize(castExpression.Expression);
                    }
                    break;

                case TypeCode.Single:
                    if ((float)pe.Value < 0)
                    {
                        Parenthesize(castExpression.Expression);
                    }
                    break;

                case TypeCode.Double:
                    if ((double)pe.Value < 0)
                    {
                        Parenthesize(castExpression.Expression);
                    }
                    break;

                case TypeCode.Decimal:
                    if ((decimal)pe.Value < 0)
                    {
                        Parenthesize(castExpression.Expression);
                    }
                    break;
                }
            }
            base.VisitCastExpression(castExpression);
        }