Procházet zdrojové kódy

2008-01-18 Jb Evain <[email protected]>

	* Expression[Printer|Visitor].cs: implement UnaryPlus, Not, Negate.


svn path=/trunk/mcs/; revision=93256
Jb Evain před 18 roky
rodič
revize
8f4b736f29

+ 4 - 0
mcs/class/System.Core/System.Linq.Expressions/ChangeLog

@@ -1,3 +1,7 @@
+2008-01-18  Jb Evain  <[email protected]>
+
+	* Expression[Printer|Visitor].cs: implement UnaryPlus, Not, Negate.
+
 2008-01-18  Miguel de Icaza  <[email protected]>
 
 	* BinaryExpression.cs: Add support for emitting code for some

+ 81 - 17
mcs/class/System.Core/System.Linq.Expressions/Expression.cs

@@ -89,6 +89,63 @@ namespace System.Linq.Expressions {
 			return t == typeof (float) || t == typeof (double) || t == typeof (decimal);
 		}
 
+		static MethodInfo GetUnaryOperator (string oper_name, Type on_type, Expression expression)
+		{
+			var methods = on_type.GetMethods (PublicStatic);
+
+			foreach (var method in methods) {
+				if (method.Name != oper_name)
+					continue;
+
+				var parameters = method.GetParameters ();
+				if (parameters.Length != 1)
+					continue;
+
+				if (!parameters [0].ParameterType.IsAssignableFrom (expression.Type))
+					continue;
+
+				return method;
+			}
+
+			return null;
+		}
+
+		static MethodInfo UnaryCoreCheck (string oper_name, Expression expression, MethodInfo method)
+		{
+			if (expression == null)
+				throw new ArgumentNullException ("expression");
+
+			if (method != null) {
+				if (method.ReturnType == typeof (void))
+					throw new ArgumentException ("Specified method must return a value", "method");
+
+				if (!method.IsStatic)
+					throw new ArgumentException ("Method must be static", "method");
+
+				var parameters = method.GetParameters ();
+
+				if (parameters.Length != 1)
+					throw new ArgumentException ("Must have only one parameters", "method");
+
+				if (!parameters [0].ParameterType.IsAssignableFrom (expression.Type))
+					throw new InvalidOperationException ("left-side argument type does not match left expression type");
+
+				return method;
+			} else {
+				if (IsNumber (expression.Type))
+					return null;
+
+				if (oper_name != null) {
+					method = GetUnaryOperator (oper_name, expression.Type, expression);
+					if (method != null)
+						return method;
+				}
+
+				throw new InvalidOperationException (
+					String.Format ("Operation {0} not defined for {1}", oper_name != null ? oper_name.Substring (3) : "is", expression.Type));
+			}
+		}
+
 		static MethodInfo GetBinaryOperator (string oper_name, Type on_type, Expression left, Expression right)
 		{
 			MethodInfo [] methods = on_type.GetMethods (PublicStatic);
@@ -205,6 +262,13 @@ namespace System.Linq.Expressions {
 			return new BinaryExpression (et, result, left, right, method);
 		}
 
+		static UnaryExpression MakeSimpleUnary (ExpressionType et, Expression expression, MethodInfo method)
+		{
+			Type result = method == null ? expression.Type : method.ReturnType;
+
+			return new UnaryExpression (et, expression, result, method);
+		}
+
 		static BinaryExpression MakeBoolBinary (ExpressionType et, Expression left, Expression right, bool liftToNull, MethodInfo method)
 		{
 			Type result = method == null ? typeof (bool) : method.ReturnType;
@@ -263,7 +327,7 @@ namespace System.Linq.Expressions {
 			// The check in BinaryCoreCheck allows a bit more than we do
 			// (byte, sbyte, short, ushort).  Catch that here
 			//
-			
+
 			if (method == null){
 				Type ltype = left.Type;
 
@@ -1050,28 +1114,28 @@ namespace System.Linq.Expressions {
 			throw new NotImplementedException ();
 		}
 
-		[MonoTODO]
 		public static UnaryExpression Negate (Expression expression)
 		{
-			throw new NotImplementedException ();
+			return Negate (expression, null);
 		}
 
-		[MonoTODO]
 		public static UnaryExpression Negate (Expression expression, MethodInfo method)
 		{
-			throw new NotImplementedException ();
+			method = UnaryCoreCheck ("op_UnaryNegation", expression, method);
+
+			return MakeSimpleUnary (ExpressionType.Negate, expression, method);
 		}
 
-		[MonoTODO]
 		public static UnaryExpression NegateChecked (Expression expression)
 		{
-			throw new NotImplementedException ();
+			return NegateChecked (expression, null);
 		}
 
-		[MonoTODO]
 		public static UnaryExpression NegateChecked (Expression expression, MethodInfo method)
 		{
-			throw new NotImplementedException ();
+			method = UnaryCoreCheck ("op_UnaryNegation", expression, method);
+
+			return MakeSimpleUnary (ExpressionType.Negate, expression, method);
 		}
 
 		[MonoTODO]
@@ -1134,16 +1198,16 @@ namespace System.Linq.Expressions {
 			throw new NotImplementedException ();
 		}
 
-		[MonoTODO]
 		public static UnaryExpression Not (Expression expression)
 		{
-			throw new NotImplementedException ();
+			return Not (expression, null);
 		}
 
-		[MonoTODO]
 		public static UnaryExpression Not (Expression expression, MethodInfo method)
 		{
-			throw new NotImplementedException ();
+			method = UnaryCoreCheck ("op_LogicalNot", expression, method);
+
+			return MakeSimpleUnary (ExpressionType.Not, expression, method);
 		}
 
 		public static ParameterExpression Parameter (Type type, string name)
@@ -1208,16 +1272,16 @@ namespace System.Linq.Expressions {
 			return new TypeBinaryExpression (ExpressionType.TypeIs, expression, type, typeof (bool));
 		}
 
-		[MonoTODO]
 		public static UnaryExpression UnaryPlus (Expression expression)
 		{
-			throw new NotImplementedException ();
+			return UnaryPlus (expression, null);
 		}
 
-		[MonoTODO]
 		public static UnaryExpression UnaryPlus (Expression expression, MethodInfo method)
 		{
-			throw new NotImplementedException ();
+			method = UnaryCoreCheck ("op_UnaryPlus", expression, method);
+
+			return MakeSimpleUnary (ExpressionType.UnaryPlus, expression, method);
 		}
 
 		static bool IsNullable (Type type)

+ 13 - 0
mcs/class/System.Core/System.Linq.Expressions/ExpressionPrinter.cs

@@ -95,6 +95,15 @@ namespace System.Linq.Expressions {
 				Visit (unary.Operand);
 				Print (")");
 				return;
+			case ExpressionType.Negate:
+				Print ("-");
+				Visit (unary.Operand);
+				return;
+			case ExpressionType.Not:
+				Print ("Not(");
+				Visit (unary.Operand);
+				Print (")");
+				return;
 			case ExpressionType.Quote:
 				Visit (unary.Operand);
 				return;
@@ -103,6 +112,10 @@ namespace System.Linq.Expressions {
 				Visit (unary.Operand);
 				Print (" As {0})", unary.Type.Name);
 				return;
+			case ExpressionType.UnaryPlus:
+				Print ("+");
+				Visit (unary.Operand);
+				return;
 			}
 
 			throw new NotImplementedException ();

+ 1 - 0
mcs/class/System.Core/System.Linq.Expressions/ExpressionVisitor.cs

@@ -51,6 +51,7 @@ namespace System.Linq.Expressions {
 			case ExpressionType.ArrayLength:
 			case ExpressionType.Quote:
 			case ExpressionType.TypeAs:
+			case ExpressionType.UnaryPlus:
 				VisitUnary ((UnaryExpression) expression);
 				break;
 			case ExpressionType.Add: