2008-01-24 Jb Evain <jbevain@novell.com>
authorJb Evain <jbevain@gmail.com>
Thu, 24 Jan 2008 17:55:41 +0000 (17:55 -0000)
committerJb Evain <jbevain@gmail.com>
Thu, 24 Jan 2008 17:55:41 +0000 (17:55 -0000)
* Expression.cs, MemberExpression.cs, ExpressionPrinter.cs:
implement Field and Property.

svn path=/trunk/mcs/; revision=93821

mcs/class/System.Core/System.Linq.Expressions/ChangeLog
mcs/class/System.Core/System.Linq.Expressions/Expression.cs
mcs/class/System.Core/System.Linq.Expressions/ExpressionPrinter.cs
mcs/class/System.Core/System.Linq.Expressions/MemberExpression.cs

index a0a537127b251c959dd5f3f6d54cbd48c835ed4d..246cd8d69506ebfa731ceb3028ae837685b66bc1 100644 (file)
@@ -1,3 +1,8 @@
+2008-01-24  Jb Evain  <jbevain@novell.com>
+
+       * Expression.cs, MemberExpression.cs, ExpressionPrinter.cs:
+       implement Field and Property.
+
 2008-01-22  Miguel de Icaza  <miguel@novell.com>
 
        * BinaryExpression.cs: Unleash the power of cut and paste.
index 7db3b01d0e9d5955b7fc70ec1b70dc6d6d150934..b7931599001f3d921044173b42e951139f79e1fa 100644 (file)
@@ -42,6 +42,9 @@ namespace System.Linq.Expressions {
 
                static BindingFlags PublicInstance = BindingFlags.Public | BindingFlags.Instance;
                static BindingFlags PublicStatic = BindingFlags.Public | BindingFlags.Static;
+               static BindingFlags AllInstance = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
+               static BindingFlags AllStatic = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static;
+               static BindingFlags All = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance;
 
                public ExpressionType NodeType {
                        get { return node_type; }
@@ -994,16 +997,30 @@ namespace System.Linq.Expressions {
                        throw new NotImplementedException ();
                }
 
-               [MonoTODO]
                public static MemberExpression Field (Expression expression, FieldInfo field)
                {
-                       throw new NotImplementedException ();
+                       if (field == null)
+                               throw new ArgumentNullException ("field");
+                       if (!field.IsStatic) {
+                               if (expression == null)
+                                       throw new ArgumentNullException ("expression");
+                               if (!field.DeclaringType.IsAssignableFrom (expression.Type))
+                                       throw new ArgumentException ("field");
+                       }
+
+                       return new MemberExpression (expression, field, field.FieldType);
                }
 
-               [MonoTODO]
                public static MemberExpression Field (Expression expression, string fieldName)
                {
-                       throw new NotImplementedException ();
+                       if (expression == null)
+                               throw new ArgumentNullException ("expression");
+
+                       var field = expression.Type.GetField (fieldName, AllInstance);
+                       if (field == null)
+                               throw new ArgumentException (string.Format ("No field named {0} on {1}", fieldName, expression.Type));
+
+                       return new MemberExpression (expression, field, field.FieldType);
                }
 
                public static Type GetActionType (params Type [] typeArgs)
@@ -1385,22 +1402,64 @@ namespace System.Linq.Expressions {
                        return new ParameterExpression (type, name);
                }
 
-               [MonoTODO]
                public static MemberExpression Property (Expression expression, MethodInfo propertyAccessor)
                {
-                       throw new NotImplementedException ();
+                       if (propertyAccessor == null)
+                               throw new ArgumentNullException ("propertyAccessor");
+
+                       if (!propertyAccessor.IsStatic) {
+                               if (expression == null)
+                                       throw new ArgumentNullException ("expression");
+                               if (!propertyAccessor.DeclaringType.IsAssignableFrom (expression.Type))
+                                       throw new ArgumentException ("expression");
+                       }
+
+                       var prop = GetAssociatedProperty (propertyAccessor);
+                       if (prop == null)
+                               throw new ArgumentException (string.Format ("Method {0} has no associated property", propertyAccessor));
+
+                       return new MemberExpression (expression, prop, prop.PropertyType);
+               }
+
+               static PropertyInfo GetAssociatedProperty (MethodInfo method)
+               {
+                       foreach (var prop in method.DeclaringType.GetProperties (All)) {
+                               if (prop.GetGetMethod (true) == method)
+                                       return prop;
+                       }
+
+                       return null;
                }
 
-               [MonoTODO]
                public static MemberExpression Property (Expression expression, PropertyInfo property)
                {
-                       throw new NotImplementedException ();
+                       if (property == null)
+                               throw new ArgumentNullException ("property");
+
+                       var getter = property.GetGetMethod (true);
+                       if (getter == null)
+                               throw new ArgumentException ("getter");
+
+                       if (!getter.IsStatic) {
+                               if (expression == null)
+                                       throw new ArgumentNullException ("expression");
+                               if (!property.DeclaringType.IsAssignableFrom (expression.Type))
+                                       throw new ArgumentException ("expression");
+                       }
+
+                       return new MemberExpression (expression, property, property.PropertyType);
                }
 
-               [MonoTODO]
                public static MemberExpression Property (Expression expression, string propertyName)
                {
-                       throw new NotImplementedException ();
+                       if (expression == null)
+                               throw new ArgumentNullException ("expression");
+
+                       var prop = expression.Type.GetProperty (propertyName, AllInstance);
+                       if (prop == null)
+                               throw new ArgumentException (string.Format ("No property named {0} on {1}", propertyName, expression.Type));
+
+                       return new MemberExpression (expression, prop, prop.PropertyType);
                }
 
                [MonoTODO]
index afc6beeabb6be0f68aec350d44e16cf8ca3ddd68..dcde208d0240c76fd36f6e201b062e75540cd4b7 100644 (file)
@@ -246,9 +246,14 @@ namespace System.Linq.Expressions {
                        Print (parameter.Name ?? "<param>");
                }
 
-               protected override void VisitMemberAccess (MemberExpression member)
+               protected override void VisitMemberAccess (MemberExpression access)
                {
-                       throw new NotImplementedException ();
+                       if (access.Expression == null)
+                               Print (access.Member.DeclaringType.Name);
+                       else
+                               Visit (access.Expression);
+
+                       Print (".{0}", access.Member.Name);
                }
 
                protected override void VisitMethodCall (MethodCallExpression call)
index ffdca501747375ed14109e1045d8359f029f6c0c..cbeaa24dbea8adfe885215ac5cd589ae8ae5ce97 100644 (file)
@@ -45,6 +45,13 @@ namespace System.Linq.Expressions {
                        get { return member; }
                }
 
+               internal MemberExpression (Expression expression, MemberInfo member, Type type)
+                       : base (ExpressionType.MemberAccess, type)
+               {
+                       this.expression = expression;
+                       this.member = member;
+               }
+
                internal override void Emit (EmitContext ec)
                {
                        throw new NotImplementedException ();