2003-12-17 Zoltan Varga <vargaz@freemail.hu>
[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         }
29
30         internal class MonoProperty : PropertyInfo {
31                 internal IntPtr klass;
32                 internal IntPtr prop;
33                 
34                 public override PropertyAttributes Attributes {
35                         get {
36                                 MonoPropertyInfo info;
37                                 MonoPropertyInfo.get_property_info (this, out info);
38                                 return info.attrs;
39                         }
40                 }
41                 
42                 public override bool CanRead {
43                         get {
44                                 MonoPropertyInfo info;
45                                 MonoPropertyInfo.get_property_info (this, out info);
46                                 return (info.get_method != null);
47                         }
48                 }
49                 
50                 public override bool CanWrite {
51                         get {
52                                 MonoPropertyInfo info;
53                                 MonoPropertyInfo.get_property_info (this, out info);
54                                 return (info.set_method != null);
55                         }
56                 }
57
58                 public override Type PropertyType {
59                         get {
60                                 MonoPropertyInfo info;
61                                 MonoPropertyInfo.get_property_info (this, out info);
62                                 
63                                 if (info.get_method != null) {
64                                         return info.get_method.ReturnType;
65                                 } else {
66                                         ParameterInfo[] parameters = info.set_method.GetParameters();
67                                         
68                                         return parameters [parameters.Length - 1].ParameterType;
69                                 }
70                         }
71                 }
72
73                 public override Type ReflectedType {
74                         get {
75                                 MonoPropertyInfo info;
76                                 MonoPropertyInfo.get_property_info (this, out info);
77                                 return info.parent;
78                         }
79                 }
80                 
81                 public override Type DeclaringType {
82                         get {
83                                 MonoPropertyInfo info;
84                                 MonoPropertyInfo.get_property_info (this, out info);
85                                 return info.parent;
86                         }
87                 }
88                 
89                 public override string Name {
90                         get {
91                                 MonoPropertyInfo info;
92                                 MonoPropertyInfo.get_property_info (this, out info);
93                                 return info.name;
94                         }
95                 }
96
97                 [MonoTODO]
98                 public override MethodInfo[] GetAccessors (bool nonPublic)
99                 {
100                         // FIXME: check nonPublic
101                         MonoPropertyInfo info;
102                         int n = 0;
103                         MonoPropertyInfo.get_property_info (this, out info);
104                         if (info.set_method != null)
105                                 n++;
106                         if (info.get_method != null)
107                                 n++;
108                         MethodInfo[] res = new MethodInfo [n];
109                         n = 0;
110                         if (info.set_method != null)
111                                 res [n++] = info.set_method;
112                         if (info.get_method != null)
113                                 res [n++] = info.get_method;
114                         return res;
115                 }
116
117                 [MonoTODO]
118                 public override MethodInfo GetGetMethod (bool nonPublic)
119                 {
120                         // FIXME: check nonPublic
121                         MonoPropertyInfo info;
122                         MonoPropertyInfo.get_property_info (this, out info);
123                         return info.get_method;
124                 }
125
126                 public override ParameterInfo[] GetIndexParameters()
127                 {
128                         MonoPropertyInfo info;
129                         MonoPropertyInfo.get_property_info (this, out info);
130                         if (info.get_method != null)
131                                 return info.get_method.GetParameters ();
132                         return new ParameterInfo [0];
133                 }
134                 
135                 public override MethodInfo GetSetMethod (bool nonPublic)
136                 {
137                         // FIXME: check nonPublic
138                         MonoPropertyInfo info;
139                         MonoPropertyInfo.get_property_info (this, out info);
140                         return info.set_method;
141                 }
142                 
143                 public override bool IsDefined (Type attributeType, bool inherit)
144                 {
145                         return MonoCustomAttrs.IsDefined (this, attributeType, inherit);
146                 }
147
148                 public override object[] GetCustomAttributes (bool inherit)
149                 {
150                         return MonoCustomAttrs.GetCustomAttributes (this, inherit);
151                 }
152                 
153                 public override object[] GetCustomAttributes (Type attributeType, bool inherit)
154                 {
155                         return MonoCustomAttrs.GetCustomAttributes (this, attributeType, inherit);
156                 }
157
158                 public override object GetValue (object obj, BindingFlags invokeAttr, Binder binder, object[] index, CultureInfo culture)
159                 {
160                         object ret = null;
161
162                         MethodInfo method = GetGetMethod (false);
163                         if (method == null)
164                                 throw new ArgumentException ("Get Method not found for '" + Name + "'");
165                         
166                         if (index == null || index.Length == 0) 
167                                 ret = method.Invoke (obj, invokeAttr, binder, null, culture);
168                         else
169                                 ret = method.Invoke (obj, invokeAttr, binder, index, culture);
170
171                         return ret;
172                 }
173
174                 public override void SetValue (object obj, object value, BindingFlags invokeAttr, Binder binder, object[] index, CultureInfo culture)
175                 {
176                         MethodInfo method = GetSetMethod (false);
177                         if (method == null)
178                                 throw new ArgumentException ("Set Method not found for '" + Name + "'");
179                         
180                         object [] parms;
181                         if (index == null || index.Length == 0) 
182                                 parms = new object [] {value};
183                         else {
184                                 int ilen = index.Length;
185                                 parms = new object [ilen+ 1];
186                                 index.CopyTo (parms, 0);
187                                 parms [ilen] = value;
188                         }
189
190                         method.Invoke (obj, invokeAttr, binder, parms, culture);
191                 }
192
193                 public override string ToString () {
194                         return PropertyType.ToString () + " " + Name;
195                 }
196         }
197 }
198