Переглянути джерело

2008-02-08 Jb Evain <[email protected]>

	* Expression.cs, InvocationExpression.cs, ExpressionPrinter.cs
		add support for Invoke.


svn path=/trunk/mcs/; revision=95257
Jb Evain 18 роки тому
батько
коміт
6b052d2092

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

@@ -1,3 +1,8 @@
+2008-02-08  Jb Evain  <[email protected]>
+
+	* Expression.cs, InvocationExpression.cs, ExpressionPrinter.cs
+		add support for Invoke.
+
 2008-02-04  Jb Evain  <[email protected]>
 2008-02-04  Jb Evain  <[email protected]>
 
 
 	* ExpressionPrinter.cs: fix printing of MemberListBinding.
 	* ExpressionPrinter.cs: fix printing of MemberListBinding.

+ 39 - 3
mcs/class/System.Core/System.Linq.Expressions/Expression.cs

@@ -1158,16 +1158,52 @@ namespace System.Linq.Expressions {
 			return func.MakeGenericType (typeArgs);
 			return func.MakeGenericType (typeArgs);
 		}
 		}
 
 
-		[MonoTODO]
 		public static InvocationExpression Invoke (Expression expression, params Expression [] arguments)
 		public static InvocationExpression Invoke (Expression expression, params Expression [] arguments)
 		{
 		{
 			return Invoke (expression, arguments as IEnumerable<Expression>);
 			return Invoke (expression, arguments as IEnumerable<Expression>);
 		}
 		}
 
 
-		[MonoTODO]
+		static Type GetInvokableType (Type t)
+		{
+			if (typeof (Delegate).IsAssignableFrom (t))
+				return t;
+
+			return GetGenericType (t, typeof (Expression<>));
+		}
+
+		static Type GetGenericType (Type t, Type def)
+		{
+			if (t == null)
+				return null;
+
+			if (t.IsGenericType && t.GetGenericTypeDefinition () == def)
+				return t;
+
+			return GetGenericType (t.BaseType, def);
+		}
+
 		public static InvocationExpression Invoke (Expression expression, IEnumerable<Expression> arguments)
 		public static InvocationExpression Invoke (Expression expression, IEnumerable<Expression> arguments)
 		{
 		{
-			throw new NotImplementedException ();
+			if (expression == null)
+				throw new ArgumentNullException ("expression");
+
+			var type = GetInvokableType (expression.Type);
+			if (type == null)
+				throw new ArgumentException ("The type of the expression is not invokable");
+
+			var args = arguments.ToReadOnlyCollection ();
+			CheckForNull (args, "arguments");
+
+			var invoke = type.GetMethod ("Invoke");
+			if (invoke == null)
+				throw new ArgumentException ("expression");
+
+			if (invoke.GetParameters ().Length != args.Count)
+				throw new InvalidOperationException ("Arguments count doesn't match parameters length");
+
+			CheckMethodArguments (invoke, args);
+
+			return new InvocationExpression (expression, invoke.ReturnType, args);
 		}
 		}
 
 
 		public static Expression<TDelegate> Lambda<TDelegate> (Expression body, params ParameterExpression [] parameters)
 		public static Expression<TDelegate> Lambda<TDelegate> (Expression body, params ParameterExpression [] parameters)

+ 12 - 2
mcs/class/System.Core/System.Linq.Expressions/ExpressionPrinter.cs

@@ -37,6 +37,8 @@ namespace System.Linq.Expressions {
 
 
 		StringBuilder builder;
 		StringBuilder builder;
 
 
+		const string ListSeparator = ", ";
+
 		ExpressionPrinter (StringBuilder builder)
 		ExpressionPrinter (StringBuilder builder)
 		{
 		{
 			this.builder = builder;
 			this.builder = builder;
@@ -296,7 +298,7 @@ namespace System.Linq.Expressions {
 		{
 		{
 			for (int i = 0; i < list.Count; i++) {
 			for (int i = 0; i < list.Count; i++) {
 				if (i > 0)
 				if (i > 0)
-					Print (", ");
+					Print (ListSeparator);
 
 
 				visitor (list [i]);
 				visitor (list [i]);
 			}
 			}
@@ -356,7 +358,15 @@ namespace System.Linq.Expressions {
 
 
 		protected override void VisitInvocation (InvocationExpression invocation)
 		protected override void VisitInvocation (InvocationExpression invocation)
 		{
 		{
-			throw new NotImplementedException ();
+			Print ("Invoke(");
+			Visit (invocation.Expression);
+
+			if (invocation.Arguments.Count != 0) {
+				Print (ListSeparator);
+				VisitExpressionList (invocation.Arguments);
+			}
+
+			Print (")");
 		}
 		}
 	}
 	}
 }
 }

+ 7 - 8
mcs/class/System.Core/System.Linq.Expressions/InvocationExpression.cs

@@ -35,28 +35,27 @@ namespace System.Linq.Expressions {
 
 
 	public sealed class InvocationExpression : Expression {
 	public sealed class InvocationExpression : Expression {
 
 
-		Expression lambda;
+		Expression expression;
 		ReadOnlyCollection<Expression> arguments;
 		ReadOnlyCollection<Expression> arguments;
 
 
 		public Expression Expression {
 		public Expression Expression {
-			get { return lambda; }
+			get { return expression; }
 		}
 		}
 
 
 		public ReadOnlyCollection<Expression> Arguments {
 		public ReadOnlyCollection<Expression> Arguments {
 			get { return arguments; }
 			get { return arguments; }
 		}
 		}
-		
-		internal InvocationExpression (Expression lambda, ReadOnlyCollection<Expression> arguments)
-			: base (ExpressionType.Invoke, lambda.Type)
+
+		internal InvocationExpression (Expression expression, Type type, ReadOnlyCollection<Expression> arguments)
+			: base (ExpressionType.Invoke, type)
 		{
 		{
-			this.lambda = lambda;
+			this.expression = expression;
 			this.arguments = arguments;
 			this.arguments = arguments;
 		}
 		}
-		
+
 		internal override void Emit (EmitContext ec)
 		internal override void Emit (EmitContext ec)
 		{
 		{
 			throw new NotImplementedException ();
 			throw new NotImplementedException ();
 		}
 		}
-		
 	}
 	}
 }
 }