2004-01-16 Gonzalo Paniagua Javier <gonzalo@ximian.com>
[mono.git] / mcs / class / corlib / System.Reflection / MonoProperty.cs
1 //
2 // System.Reflection/MonoProperty.cs
3 // The class used to represent Properties from the mono runtime.
4 //
5 // Author:
6 //   Paolo Molaro (lupus@ximian.com)
7 //   Patrik Torstensson (patrik.torstensson@labs2.com)
8 //
9 // (C) 2001 Ximian, Inc.  http://www.ximian.com
10 //
11
12 using System;
13 using System.Globalization;
14 using System.Runtime.CompilerServices;
15 using System.Runtime.InteropServices;
16
17 namespace System.Reflection {
18         
19         internal struct MonoPropertyInfo {
20                 public Type parent;
21                 public String name;
22                 public MethodInfo get_method;
23                 public MethodInfo set_method;
24                 public PropertyAttributes attrs;
25                 
26                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
27                 internal static extern void get_property_info (MonoProperty prop, out MonoPropertyInfo info,
28                                                                PInfo req_info);
29         }
30
31         [Flags]
32         internal enum PInfo {
33                 Attributes = 1,
34                 GetMethod  = 1 << 1,
35                 SetMethod  = 1 << 2,
36                 ReflectedType = 1 << 3,
37                 DeclaringType = 1 << 4,
38                 Name = 1 << 5
39                 
40         }
41         internal class MonoProperty : PropertyInfo {
42                 internal IntPtr klass;
43                 internal IntPtr prop;
44                 
45                 public override PropertyAttributes Attributes {
46                         get {
47                                 MonoPropertyInfo info;
48                                 MonoPropertyInfo.get_property_info (this, out info, PInfo.Attributes);
49                                 return info.attrs;
50                         }
51                 }
52                 
53                 public override bool CanRead {
54                         get {
55                                 MonoPropertyInfo info;
56                                 MonoPropertyInfo.get_property_info (this, out info, PInfo.GetMethod);
57                                 return (info.get_method != null);
58                         }
59                 }
60                 
61                 public override bool CanWrite {
62                         get {
63                                 MonoPropertyInfo info;
64                                 MonoPropertyInfo.get_property_info (this, out info, PInfo.SetMethod);
65                                 return (info.set_method != null);
66                         }
67                 }
68
69                 public override Type PropertyType {
70                         get {
71                                 MonoPropertyInfo info;
72                                 MonoPropertyInfo.get_property_info (this, out info, PInfo.GetMethod | PInfo.SetMethod);
73                                 
74                                 if (info.get_method != null) {
75                                         return info.get_method.ReturnType;
76                                 } else {
77                                         ParameterInfo[] parameters = info.set_method.GetParameters();
78                                         
79                                         return parameters [parameters.Length - 1].ParameterType;
80                                 }
81                         }
82                 }
83
84                 public override Type ReflectedType {
85                         get {
86                                 MonoPropertyInfo info;
87                                 MonoPropertyInfo.get_property_info (this, out info, PInfo.ReflectedType);
88                                 return info.parent;
89                         }
90                 }
91                 
92                 public override Type DeclaringType {
93                         get {
94                                 MonoPropertyInfo info;
95                                 MonoPropertyInfo.get_property_info (this, out info, PInfo.DeclaringType);
96                                 return info.parent;
97                         }
98                 }
99                 
100                 public override string Name {
101                         get {
102                                 MonoPropertyInfo info;
103                                 MonoPropertyInfo.get_property_info (this, out info, PInfo.Name);
104                                 return info.name;
105                         }
106                 }
107
108                 [MonoTODO]
109                 public override MethodInfo[] GetAccessors (bool nonPublic)
110                 {
111                         // FIXME: check nonPublic
112                         MonoPropertyInfo info;
113                         int n = 0;
114                         MonoPropertyInfo.get_property_info (this, out info, PInfo.GetMethod | PInfo.SetMethod);
115                         if (info.set_method != null)
116                                 n++;
117                         if (info.get_method != null)
118                                 n++;
119                         MethodInfo[] res = new MethodInfo [n];
120                         n = 0;
121                         if (info.set_method != null)
122                                 res [n++] = info.set_method;
123                         if (info.get_method != null)
124                                 res [n++] = info.get_method;
125                         return res;
126                 }
127
128                 [MonoTODO]
129                 public override MethodInfo GetGetMethod (bool nonPublic)
130                 {
131                         // FIXME: check nonPublic
132                         MonoPropertyInfo info;
133                         MonoPropertyInfo.get_property_info (this, out info, PInfo.GetMethod);
134                         return info.get_method;
135                 }
136
137                 public override ParameterInfo[] GetIndexParameters()
138                 {
139                         MonoPropertyInfo info;
140                         MonoPropertyInfo.get_property_info (this, out info, PInfo.GetMethod);
141                         if (info.get_method != null)
142                                 return info.get_method.GetParameters ();
143                         return new ParameterInfo [0];
144                 }
145                 
146                 public override MethodInfo GetSetMethod (bool nonPublic)
147                 {
148                         // FIXME: check nonPublic
149                         MonoPropertyInfo info;
150                         MonoPropertyInfo.get_property_info (this, out info, PInfo.SetMethod);
151                         return info.set_method;
152                 }
153                 
154                 public override bool IsDefined (Type attributeType, bool inherit)
155                 {
156                         return MonoCustomAttrs.IsDefined (this, attributeType, inherit);
157                 }
158
159                 public override object[] GetCustomAttributes (bool inherit)
160                 {
161                         return MonoCustomAttrs.GetCustomAttributes (this, inherit);
162                 }
163                 
164                 public override object[] GetCustomAttributes (Type attributeType, bool inherit)
165                 {
166                         return MonoCustomAttrs.GetCustomAttributes (this, attributeType, inherit);
167                 }
168
169                 public override object GetValue (object obj, BindingFlags invokeAttr, Binder binder, object[] index, CultureInfo culture)
170                 {
171                         object ret = null;
172
173                         MethodInfo method = GetGetMethod (false);
174                         if (method == null)
175                                 throw new ArgumentException ("Get Method not found for '" + Name + "'");
176                         
177                         if (index == null || index.Length == 0) 
178                                 ret = method.Invoke (obj, invokeAttr, binder, null, culture);
179                         else
180                                 ret = method.Invoke (obj, invokeAttr, binder, index, culture);
181
182                         return ret;
183                 }
184
185                 public override void SetValue (object obj, object value, BindingFlags invokeAttr, Binder binder, object[] index, CultureInfo culture)
186                 {
187                         MethodInfo method = GetSetMethod (false);
188                         if (method == null)
189                                 throw new ArgumentException ("Set Method not found for '" + Name + "'");
190                         
191                         object [] parms;
192                         if (index == null || index.Length == 0) 
193                                 parms = new object [] {value};
194                         else {
195                                 int ilen = index.Length;
196                                 parms = new object [ilen+ 1];
197                                 index.CopyTo (parms, 0);
198                                 parms [ilen] = value;
199                         }
200
201                         method.Invoke (obj, invokeAttr, binder, parms, culture);
202                 }
203
204                 public override string ToString () {
205                         return PropertyType.ToString () + " " + Name;
206                 }
207         }
208 }
209