2009-12-08 Rodrigo Kumpera <rkumpera@novell.com>
[mono.git] / mcs / class / corlib / System.Reflection.Emit / MethodOnTypeBuilderInst.cs
1 //
2 // System.Reflection.Emit/MethodOnTypeBuilderInst.cs
3 //
4 // Author:
5 //   Zoltan Varga (vargaz@gmail.com)
6 //
7 //
8 // Copyright (C) 2008 Novell, Inc (http://www.novell.com)
9 //
10 // Permission is hereby granted, free of charge, to any person obtaining
11 // a copy of this software and associated documentation files (the
12 // "Software"), to deal in the Software without restriction, including
13 // without limitation the rights to use, copy, modify, merge, publish,
14 // distribute, sublicense, and/or sell copies of the Software, and to
15 // permit persons to whom the Software is furnished to do so, subject to
16 // the following conditions:
17 // 
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
20 // 
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 //
29
30 using System;
31 using System.Globalization;
32 using System.Reflection;
33 using System.Text;
34
35 namespace System.Reflection.Emit
36 {
37         /*
38          * This class represents a method of an instantiation of a generic type builder.
39          */
40         internal class MethodOnTypeBuilderInst : MethodInfo
41         {
42                 #region Keep in sync with object-internals.h
43                 Type instantiation;
44                 MethodInfo base_method; /*This is the base method definition, it must be non-inflated and belong to a non-inflated type.*/
45                 Type[] method_arguments;
46                 MethodOnTypeBuilderInst generic_method_definition;
47                 #endregion
48
49                 public MethodOnTypeBuilderInst (MonoGenericClass instantiation, MethodBuilder base_method)
50                 {
51                         this.instantiation = instantiation;
52                         this.base_method = base_method;
53                 }
54
55                 internal MethodOnTypeBuilderInst (MethodBuilder base_method, Type[] typeArguments)
56                 {
57                         this.instantiation = base_method.TypeBuilder;
58                         this.base_method = base_method;
59                         this.method_arguments = new Type [typeArguments.Length];
60                         typeArguments.CopyTo (this.method_arguments, 0);
61                 }
62
63                 internal MethodOnTypeBuilderInst (MethodOnTypeBuilderInst gmd, Type[] typeArguments)
64                 {
65                         this.instantiation = gmd.instantiation;
66                         this.base_method = gmd.base_method;
67                         this.method_arguments = new Type [typeArguments.Length];
68                         typeArguments.CopyTo (this.method_arguments, 0);
69                         this.generic_method_definition = gmd;
70                 }
71
72                 internal Type[] GetTypeArgs ()
73                 {
74                         if (!instantiation.IsGenericType || instantiation.IsGenericParameter)
75                                 return null;                            
76
77                         return instantiation.GetGenericArguments ();
78                 }
79
80                 internal bool IsCompilerContext {
81                         get { return instantiation.IsCompilerContext; }
82                 }
83
84                 //
85                 // MemberInfo members
86                 //
87                 
88                 public override Type DeclaringType {
89                         get {
90                                 return instantiation;
91                         }
92                 }
93
94                 public override string Name {
95                         get {
96                                 return base_method.Name;
97                         }
98                 }
99
100                 public override Type ReflectedType {
101                         get {
102                                 return instantiation;
103                         }
104                 }
105
106                 public override Type ReturnType {
107                         get { 
108                                 if (!IsCompilerContext)
109                                         return base_method.ReturnType;
110                                 return MonoGenericClass.InflateType (base_method.ReturnType, GetTypeArgs (), method_arguments);
111                         }
112                 }
113
114                 public override bool IsDefined (Type attributeType, bool inherit)
115                 {
116                         throw new NotSupportedException ();
117                 }
118
119                 public override object [] GetCustomAttributes (bool inherit)
120                 {
121                         throw new NotSupportedException ();
122                 }
123
124                 public override object [] GetCustomAttributes (Type attributeType, bool inherit)
125                 {
126                         throw new NotSupportedException ();
127                 }
128
129                 public override string ToString ()
130                 {
131                          //IEnumerable`1 get_Item(TKey)
132                          StringBuilder sb = new StringBuilder (ReturnType.ToString ());
133                          sb.Append (" ");
134                          sb.Append (base_method.Name);
135                          sb.Append ("(");
136                          if (IsCompilerContext) {
137                                  ParameterInfo [] par = GetParameters ();
138                                  for (int i = 0; i < par.Length; ++i) {
139                                         if (i > 0)
140                                                 sb.Append (", ");
141                                         sb.Append (par [i].ParameterType);
142                                  }
143                         }
144                          sb.Append (")");
145                          return sb.ToString ();
146                 }
147                 //
148                 // MethodBase members
149                 //
150
151                 public override MethodImplAttributes GetMethodImplementationFlags ()
152                 {
153                         return base_method.GetMethodImplementationFlags ();
154                 }
155
156                 public override ParameterInfo [] GetParameters ()
157                 {
158                         ParameterInfo [] res = null;
159                         if (!IsCompilerContext)
160                                 throw new NotSupportedException ();
161
162                         if (base_method is MethodBuilder) {
163                                 MethodBuilder mb = (MethodBuilder)base_method;
164                                 res = new ParameterInfo [mb.parameters.Length];
165                                 for (int i = 0; i < mb.parameters.Length; i++) {
166                                         Type type = MonoGenericClass.InflateType (mb.parameters [i], GetTypeArgs (), method_arguments);
167                                         res [i] = new ParameterInfo (mb.pinfo == null ? null : mb.pinfo [i + 1], type, this, i + 1);
168                                 }
169                         } else {
170                                 ParameterInfo[] base_params = base_method.GetParameters ();
171                                 res = new ParameterInfo [base_params.Length];
172                                 for (int i = 0; i < base_params.Length; i++) {
173                                         Type type = MonoGenericClass.InflateType (base_params [i].ParameterType, GetTypeArgs (), method_arguments);
174                                         res [i] = new ParameterInfo (base_params [i], type, this, i + 1);
175                                 }
176                         }
177                         return res;
178                 }
179
180                 public override int MetadataToken {
181                         get {
182                                 if (!IsCompilerContext)
183                                         return base.MetadataToken;
184                                 return base_method.MetadataToken;
185                         }
186                 }
187
188                 internal override int GetParameterCount ()
189                 {
190                         return base_method.GetParameterCount ();
191                 }
192
193                 public override Object Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
194                 {
195                         throw new NotSupportedException ();
196                 }
197
198                 public override RuntimeMethodHandle MethodHandle {
199                         get {
200                                 throw new NotSupportedException ();
201                         }
202                 }
203
204                 public override MethodAttributes Attributes {
205                         get {
206                                 return base_method.Attributes;
207                         }
208                 }
209
210                 public override CallingConventions CallingConvention {
211                         get {
212                                 return base_method.CallingConvention;
213                         }
214                 }
215
216                 public override MethodInfo MakeGenericMethod (params Type [] methodInstantiation)
217                 {
218                         if (!base_method.IsGenericMethodDefinition || (method_arguments != null && !IsCompilerContext))
219                                 throw new InvalidOperationException ("Method is not a generic method definition");
220
221                         if (methodInstantiation == null)
222                                 throw new ArgumentNullException ("methodInstantiation");
223
224                         if (base_method.GetGenericArguments ().Length != methodInstantiation.Length)
225                                 throw new ArgumentException ("Incorrect length", "methodInstantiation");
226
227                         foreach (Type type in methodInstantiation) {
228                                 if (type == null)
229                                         throw new ArgumentNullException ("methodInstantiation");
230                         }
231
232                         return new MethodOnTypeBuilderInst (this, methodInstantiation);
233                 }
234
235                 public override Type [] GetGenericArguments ()
236                 {
237                         if (!base_method.IsGenericMethodDefinition)
238                                 return null;
239                         Type[] source = method_arguments ?? base_method.GetGenericArguments ();
240                         Type[] result = new Type [source.Length];
241                         source.CopyTo (result, 0);
242                         return result;
243                 }
244
245                 public override MethodInfo GetGenericMethodDefinition ()
246                 {
247                         return (MethodInfo)generic_method_definition ?? base_method;
248                 }
249
250                 public override bool ContainsGenericParameters {
251                         get {
252                                 if (!base_method.IsGenericMethodDefinition)
253                                         throw new NotSupportedException ();
254                                 if (method_arguments == null)
255                                         return true;
256                                 foreach (Type t in method_arguments) {
257                                         if (t.ContainsGenericParameters)
258                                                 return true;
259                                 }
260                                 return false;
261                         }
262                 }
263
264                 public override bool IsGenericMethodDefinition {
265                         get {
266                                 return base_method.IsGenericMethodDefinition && method_arguments == null;
267                         }
268                 }
269
270                 public override bool IsGenericMethod {
271                         get {
272                                 return base_method.IsGenericMethodDefinition;
273                         }
274                 }
275
276                 //
277                 // MethodInfo members
278                 //
279
280                 public override MethodInfo GetBaseDefinition ()
281                 {
282                         throw new NotSupportedException ();
283                 }
284
285                 public override ICustomAttributeProvider ReturnTypeCustomAttributes {
286                         get {
287                                 throw new NotSupportedException ();
288                         }
289                 }
290         }
291 }
292