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