Merge pull request #3686 from lambdageek/dev-format-printf
[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 #if !FULL_AOT_RUNTIME
31 using System;
32 using System.Globalization;
33 using System.Reflection;
34 using System.Text;
35 using System.Runtime.InteropServices;
36
37
38 namespace System.Reflection.Emit
39 {
40         /*
41          * This class represents a method of an instantiation of a generic type builder.
42          */
43         [StructLayout (LayoutKind.Sequential)]
44         internal class MethodOnTypeBuilderInst : MethodInfo
45         {
46                 #region Keep in sync with object-internals.h
47                 Type instantiation;
48                 MethodInfo base_method; /*This is the base method definition, it must be non-inflated and belong to a non-inflated type.*/
49                 Type[] method_arguments;
50                 #endregion
51                 MethodInfo generic_method_definition;
52
53                 public MethodOnTypeBuilderInst (TypeBuilderInstantiation instantiation, MethodInfo base_method)
54                 {
55                         this.instantiation = instantiation;
56                         this.base_method = base_method;
57                 }
58
59                 internal MethodOnTypeBuilderInst (MethodOnTypeBuilderInst gmd, Type[] typeArguments)
60                 {
61                         this.instantiation = gmd.instantiation;
62                         this.base_method = gmd.base_method;
63                         this.method_arguments = new Type [typeArguments.Length];
64                         typeArguments.CopyTo (this.method_arguments, 0);
65                         this.generic_method_definition = gmd;
66                 }
67
68                 internal MethodOnTypeBuilderInst (MethodInfo method, Type[] typeArguments)
69                 {
70                         this.instantiation = method.DeclaringType;
71                         this.base_method = ExtractBaseMethod (method);
72                         this.method_arguments = new Type [typeArguments.Length];
73                         typeArguments.CopyTo (this.method_arguments, 0);
74                         if (base_method != method)
75                                 this.generic_method_definition = method;
76                 }
77
78                 static MethodInfo ExtractBaseMethod (MethodInfo info)
79                 {
80                         if (info is MethodBuilder)
81                                 return info;
82                         if (info is MethodOnTypeBuilderInst)
83                                 return ((MethodOnTypeBuilderInst)info).base_method;
84
85                         if (info.IsGenericMethod)
86                                 info = info.GetGenericMethodDefinition ();
87
88                         Type t = info.DeclaringType;
89                         if (!t.IsGenericType || t.IsGenericTypeDefinition)
90                                 return info;
91
92                         return (MethodInfo)t.Module.ResolveMethod (info.MetadataToken);
93                 }
94
95                 internal Type[] GetTypeArgs ()
96                 {
97                         if (!instantiation.IsGenericType || instantiation.IsGenericParameter)
98                                 return null;                            
99
100                         return instantiation.GetGenericArguments ();
101                 }
102
103                 // Called from the runtime to return the corresponding finished MethodInfo object
104                 internal MethodInfo RuntimeResolve () {
105                         var type = instantiation.InternalResolve ();
106                         var m = type.GetMethod (base_method);
107                         if (method_arguments != null) {
108                                 var args = new Type [method_arguments.Length];
109                                 for (int i = 0; i < method_arguments.Length; ++i)
110                                         args [i] = method_arguments [i].InternalResolve ();
111                                 m = m.MakeGenericMethod (args);
112                         }
113                         return m;
114                 }
115
116                 //
117                 // MemberInfo members
118                 //
119                 
120                 public override Type DeclaringType {
121                         get {
122                                 return instantiation;
123                         }
124                 }
125
126                 public override string Name {
127                         get {
128                                 return base_method.Name;
129                         }
130                 }
131
132                 public override Type ReflectedType {
133                         get {
134                                 return instantiation;
135                         }
136                 }
137
138                 public override Type ReturnType {
139                         get { 
140                                 return base_method.ReturnType;
141                         }
142                 }
143
144                 public override Module Module {
145                         get {
146                                 return base_method.Module;
147                         }
148                 }
149
150                 public override bool IsDefined (Type attributeType, bool inherit)
151                 {
152                         throw new NotSupportedException ();
153                 }
154
155                 public override object [] GetCustomAttributes (bool inherit)
156                 {
157                         throw new NotSupportedException ();
158                 }
159
160                 public override object [] GetCustomAttributes (Type attributeType, bool inherit)
161                 {
162                         throw new NotSupportedException ();
163                 }
164
165                 public override string ToString ()
166                 {
167                          //IEnumerable`1 get_Item(TKey)
168                          StringBuilder sb = new StringBuilder (ReturnType.ToString ());
169                          sb.Append (" ");
170                          sb.Append (base_method.Name);
171                          sb.Append ("(");
172                          sb.Append (")");
173                          return sb.ToString ();
174                 }
175                 //
176                 // MethodBase members
177                 //
178
179                 public override MethodImplAttributes GetMethodImplementationFlags ()
180                 {
181                         return base_method.GetMethodImplementationFlags ();
182                 }
183
184                 public override ParameterInfo [] GetParameters ()
185                 {
186                         return GetParametersInternal ();
187                 }
188
189                 internal override ParameterInfo [] GetParametersInternal ()
190                 {
191                         throw new NotSupportedException ();
192                 }
193
194                 public override int MetadataToken {
195                         get {
196                                 return base.MetadataToken;
197                         }
198                 }
199
200                 internal override int GetParametersCount ()
201                 {
202                         return base_method.GetParametersCount ();
203                 }
204
205                 public override Object Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
206                 {
207                         throw new NotSupportedException ();
208                 }
209
210                 public override RuntimeMethodHandle MethodHandle {
211                         get {
212                                 throw new NotSupportedException ();
213                         }
214                 }
215
216                 public override MethodAttributes Attributes {
217                         get {
218                                 return base_method.Attributes;
219                         }
220                 }
221
222                 public override CallingConventions CallingConvention {
223                         get {
224                                 return base_method.CallingConvention;
225                         }
226                 }
227
228                 public override MethodInfo MakeGenericMethod (params Type [] methodInstantiation)
229                 {
230                         if (!base_method.IsGenericMethodDefinition || (method_arguments != null))
231                                 throw new InvalidOperationException ("Method is not a generic method definition");
232
233                         if (methodInstantiation == null)
234                                 throw new ArgumentNullException ("methodInstantiation");
235
236                         if (base_method.GetGenericArguments ().Length != methodInstantiation.Length)
237                                 throw new ArgumentException ("Incorrect length", "methodInstantiation");
238
239                         foreach (Type type in methodInstantiation) {
240                                 if (type == null)
241                                         throw new ArgumentNullException ("methodInstantiation");
242                         }
243
244                         return new MethodOnTypeBuilderInst (this, methodInstantiation);
245                 }
246
247                 public override Type [] GetGenericArguments ()
248                 {
249                         if (!base_method.IsGenericMethodDefinition)
250                                 return null;
251                         Type[] source = method_arguments ?? base_method.GetGenericArguments ();
252                         Type[] result = new Type [source.Length];
253                         source.CopyTo (result, 0);
254                         return result;
255                 }
256
257                 public override MethodInfo GetGenericMethodDefinition ()
258                 {
259                         return generic_method_definition ?? base_method;
260                 }
261
262                 public override bool ContainsGenericParameters {
263                         get {
264                                 if (base_method.ContainsGenericParameters)
265                                         return true;
266                                 if (!base_method.IsGenericMethodDefinition)
267                                         throw new NotSupportedException ();
268                                 if (method_arguments == null)
269                                         return true;
270                                 foreach (Type t in method_arguments) {
271                                         if (t.ContainsGenericParameters)
272                                                 return true;
273                                 }
274                                 return false;
275                         }
276                 }
277
278                 public override bool IsGenericMethodDefinition {
279                         get {
280                                 return base_method.IsGenericMethodDefinition && method_arguments == null;
281                         }
282                 }
283
284                 public override bool IsGenericMethod {
285                         get {
286                                 return base_method.IsGenericMethodDefinition;
287                         }
288                 }
289
290                 //
291                 // MethodInfo members
292                 //
293
294                 public override MethodInfo GetBaseDefinition ()
295                 {
296                         throw new NotSupportedException ();
297                 }
298
299                 public override ParameterInfo ReturnParameter {
300                         get {
301                                 throw new NotSupportedException();
302                         }
303                 }
304
305                 public override ICustomAttributeProvider ReturnTypeCustomAttributes {
306                         get {
307                                 throw new NotSupportedException ();
308                         }
309                 }
310         }
311 }
312
313 #endif