* MonoProperty.cs: Property.GetGetMethod() does not return the method if it
[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                 public override MethodInfo[] GetAccessors (bool nonPublic)
109                 {
110                         MonoPropertyInfo info;
111                         int nget = 0;
112                         int nset = 0;
113                         
114                         MonoPropertyInfo.get_property_info (this, out info, PInfo.GetMethod | PInfo.SetMethod);
115                         if (info.set_method != null && (nonPublic || info.set_method.IsPublic))
116                                 nget = 1;
117                         if (info.get_method != null && (nonPublic || info.get_method.IsPublic))
118                                 nset = 1;
119
120                         MethodInfo[] res = new MethodInfo [nget + nset];
121                         int n = 0;
122                         if (nset != 0)
123                                 res [n++] = info.set_method;
124                         if (nget != 0)
125                                 res [n++] = info.get_method;
126                         return res;
127                 }
128
129                 public override MethodInfo GetGetMethod (bool nonPublic)
130                 {
131                         MonoPropertyInfo info;
132                         MonoPropertyInfo.get_property_info (this, out info, PInfo.GetMethod);
133                         if (info.get_method != null && (nonPublic || info.get_method.IsPublic))
134                                 return info.get_method;
135                         else
136                                 return null;
137                 }
138
139                 public override ParameterInfo[] GetIndexParameters()
140                 {
141                         MonoPropertyInfo info;
142                         MonoPropertyInfo.get_property_info (this, out info, PInfo.GetMethod);
143                         if (info.get_method != null)
144                                 return info.get_method.GetParameters ();
145                         return new ParameterInfo [0];
146                 }
147                 
148                 public override MethodInfo GetSetMethod (bool nonPublic)
149                 {
150                         MonoPropertyInfo info;
151                         MonoPropertyInfo.get_property_info (this, out info, PInfo.SetMethod);
152                         if (info.set_method != null && (nonPublic || info.set_method.IsPublic))
153                                 return info.set_method;
154                         else
155                                 return null;
156                 }
157                 
158                 public override bool IsDefined (Type attributeType, bool inherit)
159                 {
160                         return MonoCustomAttrs.IsDefined (this, attributeType, inherit);
161                 }
162
163                 public override object[] GetCustomAttributes (bool inherit)
164                 {
165                         return MonoCustomAttrs.GetCustomAttributes (this, inherit);
166                 }
167                 
168                 public override object[] GetCustomAttributes (Type attributeType, bool inherit)
169                 {
170                         return MonoCustomAttrs.GetCustomAttributes (this, attributeType, inherit);
171                 }
172
173                 public override object GetValue (object obj, BindingFlags invokeAttr, Binder binder, object[] index, CultureInfo culture)
174                 {
175                         object ret = null;
176
177                         MethodInfo method = GetGetMethod (true);
178                         if (method == null)
179                                 throw new ArgumentException ("Get Method not found for '" + Name + "'");
180                         
181                         if (index == null || index.Length == 0) 
182                                 ret = method.Invoke (obj, invokeAttr, binder, null, culture);
183                         else
184                                 ret = method.Invoke (obj, invokeAttr, binder, index, culture);
185
186                         return ret;
187                 }
188
189                 public override void SetValue (object obj, object value, BindingFlags invokeAttr, Binder binder, object[] index, CultureInfo culture)
190                 {
191                         MethodInfo method = GetSetMethod (true);
192                         if (method == null)
193                                 throw new ArgumentException ("Set Method not found for '" + Name + "'");
194                         
195                         object [] parms;
196                         if (index == null || index.Length == 0) 
197                                 parms = new object [] {value};
198                         else {
199                                 int ilen = index.Length;
200                                 parms = new object [ilen+ 1];
201                                 index.CopyTo (parms, 0);
202                                 parms [ilen] = value;
203                         }
204
205                         method.Invoke (obj, invokeAttr, binder, parms, culture);
206                 }
207
208                 public override string ToString () {
209                         return PropertyType.ToString () + " " + Name;
210                 }
211         }
212 }
213