Merge pull request #409 from Alkarex/patch-1
[mono.git] / mcs / class / corlib / System.Reflection / ParameterInfo.cs
1 // System.Reflection.ParameterInfo
2 //
3 // Sean MacIsaac (macisaac@ximian.com)
4 //
5 // (C) 2001 Ximian, Inc.
6 // Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
7 //
8 // Permission is hereby granted, free of charge, to any person obtaining
9 // a copy of this software and associated documentation files (the
10 // "Software"), to deal in the Software without restriction, including
11 // without limitation the rights to use, copy, modify, merge, publish,
12 // distribute, sublicense, and/or sell copies of the Software, and to
13 // permit persons to whom the Software is furnished to do so, subject to
14 // the following conditions:
15 // 
16 // The above copyright notice and this permission notice shall be
17 // included in all copies or substantial portions of the Software.
18 // 
19 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
23 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
24 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
25 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 //
27
28 #if !FULL_AOT_RUNTIME
29 using System.Reflection.Emit;
30 #endif
31 using System.Runtime.CompilerServices;
32 using System.Runtime.InteropServices;
33 using System.Collections.Generic;
34
35 namespace System.Reflection
36 {
37         [ComVisible (true)]
38         [ComDefaultInterfaceAttribute (typeof (_ParameterInfo))]
39         [Serializable]
40         [ClassInterfaceAttribute (ClassInterfaceType.None)]
41         [StructLayout (LayoutKind.Sequential)]
42         public class ParameterInfo : ICustomAttributeProvider, _ParameterInfo {
43
44                 protected Type ClassImpl;
45                 protected object DefaultValueImpl;
46                 protected MemberInfo MemberImpl;
47                 protected string NameImpl;
48                 protected int PositionImpl;
49                 protected ParameterAttributes AttrsImpl;
50                 private MarshalAsAttribute marshalAs;
51
52                 protected ParameterInfo () {
53                 }
54
55 #if !FULL_AOT_RUNTIME
56                 internal ParameterInfo (ParameterBuilder pb, Type type, MemberInfo member, int position) {
57                         this.ClassImpl = type;
58                         this.MemberImpl = member;
59                         if (pb != null) {
60                                 this.NameImpl = pb.Name;
61                                 this.PositionImpl = pb.Position - 1;    // ParameterInfo.Position is zero-based
62                                 this.AttrsImpl = (ParameterAttributes) pb.Attributes;
63                         } else {
64                                 this.NameImpl = null;
65                                 this.PositionImpl = position - 1;
66                                 this.AttrsImpl = ParameterAttributes.None;
67                         }
68                 }
69 #endif
70
71                 /*FIXME this constructor looks very broken in the position parameter*/
72                 internal ParameterInfo (ParameterInfo pinfo, Type type, MemberInfo member, int position) {
73                         this.ClassImpl = type;
74                         this.MemberImpl = member;
75                         if (pinfo != null) {
76                                 this.NameImpl = pinfo.Name;
77                                 this.PositionImpl = pinfo.Position - 1; // ParameterInfo.Position is zero-based
78                                 this.AttrsImpl = (ParameterAttributes) pinfo.Attributes;
79                         } else {
80                                 this.NameImpl = null;
81                                 this.PositionImpl = position - 1;
82                                 this.AttrsImpl = ParameterAttributes.None;
83                         }
84                 }
85
86                 internal ParameterInfo (ParameterInfo pinfo, MemberInfo member) {
87                         this.ClassImpl = pinfo.ParameterType;
88                         this.MemberImpl = member;
89                         this.NameImpl = pinfo.Name;
90                         this.PositionImpl = pinfo.Position;
91                         this.AttrsImpl = pinfo.Attributes;
92                         //this.parent = pinfo;
93                 }
94
95                 /* to build a ParameterInfo for the return type of a method */
96                 internal ParameterInfo (Type type, MemberInfo member, MarshalAsAttribute marshalAs) {
97                         this.ClassImpl = type;
98                         this.MemberImpl = member;
99                         this.NameImpl = "";
100                         this.PositionImpl = -1; // since parameter positions are zero-based, return type pos is -1
101                         this.AttrsImpl = ParameterAttributes.Retval;
102                         this.marshalAs = marshalAs;
103                 }
104
105                 public override string ToString() {
106                         Type elementType = ClassImpl;
107                         while (elementType.HasElementType) {
108                                         elementType = elementType.GetElementType();
109                         }
110                         bool useShort = elementType.IsPrimitive || ClassImpl == typeof(void)
111                                 || ClassImpl.Namespace == MemberImpl.DeclaringType.Namespace;
112                         string result = useShort
113                                 ? ClassImpl.Name
114                                 : ClassImpl.FullName;
115                         // MS.NET seems to skip this check and produce an extra space for return types
116                         if (!IsRetval) {
117                                 result += ' ';
118                                 result += NameImpl;
119                         }
120                         return result;
121                 }
122
123                 public virtual Type ParameterType {
124                         get {return ClassImpl;}
125                 }
126                 public virtual ParameterAttributes Attributes {
127                         get {return AttrsImpl;}
128                 }
129                 public virtual object DefaultValue {
130                         get {
131                                 if (ClassImpl == typeof (Decimal)) {
132                                         /* default values for decimals are encoded using a custom attribute */
133                                         DecimalConstantAttribute[] attrs = (DecimalConstantAttribute[])GetCustomAttributes (typeof (DecimalConstantAttribute), false);
134                                         if (attrs.Length > 0)
135                                                 return attrs [0].Value;
136                                 } else if (ClassImpl == typeof (DateTime)) {
137                                         /* default values for DateTime are encoded using a custom attribute */
138                                         DateTimeConstantAttribute[] attrs = (DateTimeConstantAttribute[])GetCustomAttributes (typeof (DateTimeConstantAttribute), false);
139                                         if (attrs.Length > 0)
140                                                 return new DateTime (attrs [0].Ticks);
141                                 }
142                                 return DefaultValueImpl;
143                         }
144                 }
145
146                 public bool IsIn {
147                         get {
148                                 return (Attributes & ParameterAttributes.In) != 0;
149                         }
150                 }
151
152                 public bool IsLcid {
153                         get {
154                                 return (Attributes & ParameterAttributes.Lcid) != 0;
155                         }
156                 }
157
158                 public bool IsOptional {
159                         get {
160                                 return (Attributes & ParameterAttributes.Optional) != 0;
161                         }
162                 }
163
164                 public bool IsOut {
165                         get {
166                                 return (Attributes & ParameterAttributes.Out) != 0;
167                         }
168                 }
169
170                 public bool IsRetval {
171                         get {
172                                 return (Attributes & ParameterAttributes.Retval) != 0;
173                         }
174                 }
175
176                 public virtual MemberInfo Member {
177                         get {return MemberImpl;}
178                 }
179
180                 public virtual string Name {
181                         get {return NameImpl;}
182                 }
183
184                 public virtual int Position {
185                         get {return PositionImpl;}
186                 }
187
188                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
189                 extern int GetMetadataToken ();
190
191                 public
192 #if NET_4_0 || MOONLIGHT
193                 virtual
194 #endif
195                 int MetadataToken {
196                         get {
197                                 if (MemberImpl is PropertyInfo) {
198                                         PropertyInfo prop = (PropertyInfo)MemberImpl;
199                                         MethodInfo mi = prop.GetGetMethod (true);
200                                         if (mi == null)
201                                                 mi = prop.GetSetMethod (true);
202                                         /*TODO expose and use a GetParametersNoCopy()*/
203                                         return mi.GetParameters () [PositionImpl].MetadataToken;
204                                 } else if (MemberImpl is MethodBase) {
205                                         return GetMetadataToken ();
206                                 }
207                                 throw new ArgumentException ("Can't produce MetadataToken for member of type " + MemberImpl.GetType ());
208                         }
209                 }
210
211                 public virtual object[] GetCustomAttributes (bool inherit)
212                 {
213                         return MonoCustomAttrs.GetCustomAttributes (this, inherit);
214                 }
215
216                 public virtual object[] GetCustomAttributes (Type attributeType, bool inherit)
217                 {
218                         return MonoCustomAttrs.GetCustomAttributes (this, attributeType, inherit);
219                 }
220
221                 public virtual bool IsDefined( Type attributeType, bool inherit) {
222                         return MonoCustomAttrs.IsDefined (this, attributeType, inherit);
223                 }
224
225                 internal object[] GetPseudoCustomAttributes () {
226                         int count = 0;
227
228                         if (IsIn)
229                                 count ++;
230                         if (IsOut)
231                                 count ++;
232                         if (IsOptional)
233                                 count ++;
234                         if (marshalAs != null)
235                                 count ++;
236
237                         if (count == 0)
238                                 return null;
239                         object[] attrs = new object [count];
240                         count = 0;
241
242                         if (IsIn)
243                                 attrs [count ++] = new InAttribute ();
244                         if (IsOptional)
245                                 attrs [count ++] = new OptionalAttribute ();
246                         if (IsOut)
247                                 attrs [count ++] = new OutAttribute ();
248
249                         if (marshalAs != null)
250                                 attrs [count ++] = marshalAs.Copy ();
251
252                         return attrs;
253                 }                       
254
255                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
256                 extern Type[] GetTypeModifiers (bool optional);
257
258                 public virtual Type[] GetOptionalCustomModifiers () {
259                         Type[] types = GetTypeModifiers (true);
260                         if (types == null)
261                                 return Type.EmptyTypes;
262                         return types;
263                 }
264
265                 public virtual Type[] GetRequiredCustomModifiers () {
266                         Type[] types = GetTypeModifiers (false);
267                         if (types == null)
268                                 return Type.EmptyTypes;
269                         return types;
270                 }
271
272                 public virtual object RawDefaultValue {
273                         get {
274                                 /*FIXME right now DefaultValue doesn't throw for reflection-only assemblies. Change this once the former is fixed.*/
275                                 return DefaultValue;
276                         }
277                 }
278
279 #if NET_4_0
280                 public virtual IList<CustomAttributeData> GetCustomAttributesData () {
281                         return CustomAttributeData.GetCustomAttributes (this);
282                 }
283 #endif
284
285                 void _ParameterInfo.GetIDsOfNames ([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
286                 {
287                         throw new NotImplementedException ();
288                 }
289
290                 void _ParameterInfo.GetTypeInfo (uint iTInfo, uint lcid, IntPtr ppTInfo)
291                 {
292                         throw new NotImplementedException ();
293                 }
294
295                 void _ParameterInfo.GetTypeInfoCount (out uint pcTInfo)
296                 {
297                         throw new NotImplementedException ();
298                 }
299
300                 void _ParameterInfo.Invoke (uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams,
301                         IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
302                 {
303                         throw new NotImplementedException ();
304                 }
305         }
306 }