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