Exemplo n.º 1
0
        public override IAstNode UnaryExpression(UnaryExpression unaryExpression)
        {
            if (unaryExpression.Type == ExpressionType.Minus)
            {
                var constant = unaryExpression.Operand as Constant;

                if (constant != null)
                {
                    var unparsedNumber = constant.Value as UnparsedNumber;

                    // We do not parse hex in this manner because int.Parse
                    // doesn't allow hex and sign to be combined.

                    if (
                        unparsedNumber != null &&
                        TypeUtil.IsConvertible(unparsedNumber.Type) &&
                        (unparsedNumber.NumberStyles & NumberStyles.AllowHexSpecifier) == 0
                        )
                    {
                        // Actually parse the constant including the minus sign.

                        unparsedNumber = new UnparsedNumber("-" + unparsedNumber.Value, unparsedNumber.Type, unparsedNumber.NumberStyles | NumberStyles.AllowLeadingSign);

                        return(new Constant(
                                   unparsedNumber.Parse()
                                   ));
                    }
                }
            }

            return(base.UnaryExpression(unaryExpression));
        }
Exemplo n.º 2
0
        public static void EmitConvertToType(ILGenerator il, Type typeFrom, Type typeTo, bool isChecked)
        {
            if (TypeUtil.AreEquivalent(typeFrom, typeTo))
            {
                return;
            }

            if (typeFrom == typeof(void) || typeTo == typeof(void))
            {
                throw new InvalidOperationException();
            }

            bool isTypeFromNullable = TypeUtil.IsNullableType(typeFrom);
            bool isTypeToNullable   = TypeUtil.IsNullableType(typeTo);

            Type nnExprType = TypeUtil.GetNonNullableType(typeFrom);
            Type nnType     = TypeUtil.GetNonNullableType(typeTo);

            if (typeFrom.IsInterface ||       // interface cast
                typeTo.IsInterface ||
                typeFrom == typeof(object) || // boxing cast
                typeTo == typeof(object) ||
                typeFrom == typeof(System.Enum) ||
                typeFrom == typeof(System.ValueType) ||
                TypeUtil.IsLegalExplicitVariantDelegateConversion(typeFrom, typeTo))
            {
                EmitCastToType(il, typeFrom, typeTo);
            }
            else if (isTypeFromNullable || isTypeToNullable)
            {
                EmitNullableConversion(il, typeFrom, typeTo, isChecked);
            }
            else if (!(TypeUtil.IsConvertible(typeFrom) && TypeUtil.IsConvertible(typeTo)) // primitive runtime conversion
                     &&
                     (nnExprType.IsAssignableFrom(nnType) ||                               // down cast
                      nnType.IsAssignableFrom(nnExprType)))                                // up cast
            {
                EmitCastToType(il, typeFrom, typeTo);
            }
            else if (typeFrom.IsArray && typeTo.IsArray)
            {
                // See DevDiv Bugs #94657.
                EmitCastToType(il, typeFrom, typeTo);
            }
            else
            {
                EmitNumericConversion(il, typeFrom, typeTo, isChecked);
            }
        }
Exemplo n.º 3
0
        public override IExpression BinaryExpression(BinaryExpression binaryExpression)
        {
            var left  = binaryExpression.Left.Accept(this);
            var right = binaryExpression.Right.Accept(this);

            if (
                (
                    binaryExpression.ExpressionType == ExpressionType.Add &&
                    (left.Type == typeof(string) || right.Type == typeof(string))
                ) ||
                binaryExpression.ExpressionType == ExpressionType.Concat
                )
            {
                return(_resolver.ResolveMethod(
                           new TypeAccess(typeof(string)),
                           "Concat",
                           FlattenConcatArguments(binaryExpression.Left, binaryExpression.Right)
                           ));
            }
            else if (binaryExpression.ExpressionType == ExpressionType.Power)
            {
                return(_resolver.ResolveMethod(
                           new TypeAccess(typeof(Math)),
                           "Pow",
                           new[] { left, right }
                           ));
            }
            else if (_resolver.DynamicExpression.Language == ExpressionLanguage.VisualBasic)
            {
                // Special handling for Visual Basic.

                string methodName = null;

                switch (binaryExpression.ExpressionType)
                {
                case ExpressionType.Compares: methodName = "CompareObjectEqual"; break;

                case ExpressionType.NotCompares: methodName = "CompareObjectNotEqual"; break;

                case ExpressionType.Greater: methodName = "CompareObjectGreater"; break;

                case ExpressionType.GreaterOrEquals: methodName = "CompareObjectGreaterEqual"; break;

                case ExpressionType.Less: methodName = "CompareObjectLess"; break;

                case ExpressionType.LessOrEquals: methodName = "CompareObjectLessEqual"; break;
                }

                // Is this an operator for which we have a method?

                if (methodName != null)
                {
                    // Should we output a normal comparison anyway?

                    if (TypeUtil.IsConvertible(left.Type) && TypeUtil.IsConvertible(right.Type))
                    {
                        var expressionType = binaryExpression.ExpressionType;

                        // Coerce Compares/NotCompares to Equals/NotEquals.

                        if (expressionType == ExpressionType.Compares)
                        {
                            expressionType = ExpressionType.Equals;
                        }
                        else if (expressionType == ExpressionType.NotCompares)
                        {
                            expressionType = ExpressionType.NotEquals;
                        }

                        if (
                            left == binaryExpression.Left &&
                            right == binaryExpression.Right &&
                            expressionType == binaryExpression.ExpressionType
                            )
                        {
                            return(binaryExpression);
                        }
                        else
                        {
                            return(new BinaryExpression(left, right, expressionType, binaryExpression.Type, binaryExpression.CommonType));
                        }
                    }
                    else
                    {
                        var method = typeof(Operators).GetMethod(methodName);

                        Debug.Assert(method.ReturnType == typeof(object));

                        return(new Cast(
                                   new MethodCall(
                                       new TypeAccess(typeof(Operators)),
                                       method,
                                       new[]
                        {
                            left,
                            right,
                            new Constant(false)
                        }
                                       ),
                                   typeof(bool)
                                   ));
                    }
                }
            }

            if (left == binaryExpression.Left && right == binaryExpression.Right)
            {
                return(binaryExpression);
            }
            else
            {
                return(new BinaryExpression(left, right, binaryExpression.ExpressionType, binaryExpression.Type));
            }
        }