Merge pull request #495 from nicolas-raoul/fix-for-issue2907-with-no-formatting-changes
[mono.git] / mcs / class / corlib / System.Reflection / MonoGenericClass.cs
1 //
2 // System.Reflection.MonoGenericClass
3 //
4 // Sean MacIsaac (macisaac@ximian.com)
5 // Paolo Molaro (lupus@ximian.com)
6 // Patrik Torstensson (patrik.torstensson@labs2.com)
7 //
8 // (C) 2001 Ximian, Inc.
9 //
10
11 //
12 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
13 //
14 // Permission is hereby granted, free of charge, to any person obtaining
15 // a copy of this software and associated documentation files (the
16 // "Software"), to deal in the Software without restriction, including
17 // without limitation the rights to use, copy, modify, merge, publish,
18 // distribute, sublicense, and/or sell copies of the Software, and to
19 // permit persons to whom the Software is furnished to do so, subject to
20 // the following conditions:
21 // 
22 // The above copyright notice and this permission notice shall be
23 // included in all copies or substantial portions of the Software.
24 // 
25 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
29 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 //
33
34 #if !FULL_AOT_RUNTIME
35 using System.Reflection;
36 using System.Reflection.Emit;
37 using System.Collections;
38 using System.Runtime.CompilerServices;
39 using System.Globalization;
40 using System.Runtime.Serialization;
41 using System.Text;
42 using System.Runtime.InteropServices;
43
44 namespace System.Reflection
45 {
46         /*
47          * MonoGenericClass represents an instantiation of a generic TypeBuilder. MS
48          * calls this class TypeBuilderInstantiation (a much better name). MS returns 
49          * NotImplementedException for many of the methods but we can't do that as gmcs
50          * depends on them.
51          */
52         [StructLayout (LayoutKind.Sequential)]
53         internal class MonoGenericClass : Type
54         {
55                 #region Keep in sync with object-internals.h
56 #pragma warning disable 649
57                 internal Type generic_type;
58                 Type[] type_arguments;
59                 bool initialized;
60 #pragma warning restore 649
61                 #endregion
62
63                 Hashtable fields, ctors, methods;
64
65                 internal MonoGenericClass ()
66                 {
67                         // this should not be used
68                         throw new InvalidOperationException ();
69                 }
70
71                 internal MonoGenericClass (Type tb, Type[] args)
72                 {
73                         this.generic_type = tb;
74                         this.type_arguments = args;
75                         /*
76                         This is a temporary hack until we can fix the rest of the runtime
77                         to properly handle this class to be a complete UT.
78
79                         We must not regisrer this with the runtime after the type is created
80                         otherwise created_type.MakeGenericType will return an instance of MonoGenericClass,
81                         which is very very broken.
82                         */
83                         if (tb is TypeBuilder && !(tb as TypeBuilder).is_created)
84                                 register_with_runtime (this);
85                         
86                 }
87
88                 internal override Type InternalResolve ()
89                 {
90                         Type gtd = generic_type.InternalResolve ();
91                         Type[] args = new Type [type_arguments.Length];
92                         for (int i = 0; i < type_arguments.Length; ++i)
93                                 args [i] = type_arguments [i].InternalResolve ();
94                         return gtd.MakeGenericType (args);
95                 }
96
97                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
98                 extern void initialize (FieldInfo[] fields);
99
100                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
101                 internal static extern void register_with_runtime (Type type);
102
103                 internal bool IsCreated {
104                         get {
105                                 TypeBuilder tb = generic_type as TypeBuilder;
106                                 return tb != null ? tb.is_created : true;
107                         }
108                 }
109
110                 private const BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic |
111                 BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly;
112
113                 void initialize ()
114                 {
115                         if (initialized)
116                                 return;
117
118                         MonoGenericClass parent = GetParentType () as MonoGenericClass;
119                         if (parent != null)
120                                 parent.initialize ();
121                                 
122                         initialize (generic_type.GetFields (flags));
123
124                         initialized = true;
125                 }
126
127                 Type GetParentType ()
128                 {
129                         return InflateType (generic_type.BaseType);             
130                 }
131
132                 internal Type InflateType (Type type)
133                 {
134                         return InflateType (type, type_arguments, null);
135                 }
136
137                 internal Type InflateType (Type type, Type[] method_args)
138                 {
139                         return InflateType (type, type_arguments, method_args);
140                 }
141
142                 internal static Type InflateType (Type type, Type[] type_args, Type[] method_args)
143                 {
144                         if (type == null)
145                                 return null;
146                         if (!type.IsGenericParameter && !type.ContainsGenericParameters)
147                                 return type;
148                         if (type.IsGenericParameter) {
149                                 if (type.DeclaringMethod == null)
150                                         return type_args == null ? type : type_args [type.GenericParameterPosition];
151                                 return method_args == null ? type : method_args [type.GenericParameterPosition];
152                         }
153                         if (type.IsPointer)
154                                 return InflateType (type.GetElementType (), type_args, method_args).MakePointerType ();
155                         if (type.IsByRef)
156                                 return InflateType (type.GetElementType (), type_args, method_args).MakeByRefType ();
157                         if (type.IsArray) {
158                                 if (type.GetArrayRank () > 1)
159                                         return InflateType (type.GetElementType (), type_args, method_args).MakeArrayType (type.GetArrayRank ());
160                                 
161                                 if (type.ToString ().EndsWith ("[*]", StringComparison.Ordinal)) /*FIXME, the reflection API doesn't offer a way around this*/
162                                         return InflateType (type.GetElementType (), type_args, method_args).MakeArrayType (1);
163                                 return InflateType (type.GetElementType (), type_args, method_args).MakeArrayType ();
164                         }
165
166                         Type[] args = type.GetGenericArguments ();
167                         for (int i = 0; i < args.Length; ++i)
168                                 args [i] = InflateType (args [i], type_args, method_args);
169
170                         Type gtd = type.IsGenericTypeDefinition ? type : type.GetGenericTypeDefinition ();
171                         return gtd.MakeGenericType (args);
172                 }
173                 
174                 public override Type BaseType {
175                         get { return generic_type.BaseType; }
176                 }
177
178                 public override Type[] GetInterfaces ()
179                 {
180                         throw new NotSupportedException ();
181                 }
182
183                 protected override bool IsValueTypeImpl ()
184                 {
185                         return generic_type.IsValueType;
186                 }
187
188                 internal override MethodInfo GetMethod (MethodInfo fromNoninstanciated)
189                 {
190                         initialize ();
191
192                         if (methods == null)
193                                 methods = new Hashtable ();
194                         if (!methods.ContainsKey (fromNoninstanciated))
195                                 methods [fromNoninstanciated] = new MethodOnTypeBuilderInst (this, fromNoninstanciated);
196                         return (MethodInfo)methods [fromNoninstanciated];
197                 }
198
199                 internal override ConstructorInfo GetConstructor (ConstructorInfo fromNoninstanciated)
200                 {
201                         initialize ();
202
203                         if (ctors == null)
204                                 ctors = new Hashtable ();
205                         if (!ctors.ContainsKey (fromNoninstanciated))
206                                 ctors [fromNoninstanciated] = new ConstructorOnTypeBuilderInst (this, fromNoninstanciated);
207                         return (ConstructorInfo)ctors [fromNoninstanciated];
208                 }
209
210                 internal override FieldInfo GetField (FieldInfo fromNoninstanciated)
211                 {
212                         initialize ();
213                         if (fields == null)
214                                 fields = new Hashtable ();
215                         if (!fields.ContainsKey (fromNoninstanciated))
216                                 fields [fromNoninstanciated] = new FieldOnTypeBuilderInst (this, fromNoninstanciated);
217                         return (FieldInfo)fields [fromNoninstanciated];
218                 }
219                 
220                 public override MethodInfo[] GetMethods (BindingFlags bf)
221                 {
222                         throw new NotSupportedException ();
223                 }
224
225                 public override ConstructorInfo[] GetConstructors (BindingFlags bf)
226                 {
227                         throw new NotSupportedException ();
228                 }
229
230                 public override FieldInfo[] GetFields (BindingFlags bf)
231                 {
232                         throw new NotSupportedException ();
233                 }
234
235                 public override PropertyInfo[] GetProperties (BindingFlags bf)
236                 {
237                         throw new NotSupportedException ();
238                 }
239
240                 public override EventInfo[] GetEvents (BindingFlags bf)
241                 {
242                         throw new NotSupportedException ();
243                 }
244
245                 public override Type[] GetNestedTypes (BindingFlags bf)
246                 {
247                         throw new NotSupportedException ();
248                 }
249
250                 public override bool IsAssignableFrom (Type c)
251                 {
252                         throw new NotSupportedException ();
253                 }
254
255                 public override Type UnderlyingSystemType {
256                         get { return this; }
257                 }
258
259                 public override Assembly Assembly {
260                         get { return generic_type.Assembly; }
261                 }
262
263                 public override Module Module {
264                         get { return generic_type.Module; }
265                 }
266
267                 public override string Name {
268                         get { return generic_type.Name; }
269                 }
270
271                 public override string Namespace {
272                         get { return generic_type.Namespace; }
273                 }
274
275                 public override string FullName {
276                         get { return format_name (true, false); }
277                 }
278
279                 public override string AssemblyQualifiedName {
280                         get { return format_name (true, true); }
281                 }
282
283                 public override Guid GUID {
284                         get { throw new NotSupportedException (); }
285                 }
286
287                 string format_name (bool full_name, bool assembly_qualified)
288                 {
289                         StringBuilder sb = new StringBuilder (generic_type.FullName);
290
291                         sb.Append ("[");
292                         for (int i = 0; i < type_arguments.Length; ++i) {
293                                 if (i > 0)
294                                         sb.Append (",");
295                                 
296                                 string name;
297                                 if (full_name) {
298                                         string assemblyName = type_arguments [i].Assembly.FullName;
299                                         name = type_arguments [i].FullName;
300                                         if (name != null && assemblyName != null)
301                                                 name = name + ", " + assemblyName;
302                                 } else {
303                                         name = type_arguments [i].ToString ();
304                                 }
305                                 if (name == null) {
306                                         return null;
307                                 }
308                                 if (full_name)
309                                         sb.Append ("[");
310                                 sb.Append (name);
311                                 if (full_name)
312                                         sb.Append ("]");
313                         }
314                         sb.Append ("]");
315                         if (assembly_qualified) {
316                                 sb.Append (", ");
317                                 sb.Append (generic_type.Assembly.FullName);
318                         }
319                         return sb.ToString ();
320                 }
321
322                 public override string ToString ()
323                 {
324                         return format_name (false, false);
325                 }
326
327                 public override Type GetGenericTypeDefinition ()
328                 {
329                         return generic_type;
330                 }
331
332                 public override Type[] GetGenericArguments ()
333                 {
334                         Type[] ret = new Type [type_arguments.Length];
335                         type_arguments.CopyTo (ret, 0);
336                         return ret;
337                 }
338
339                 public override bool ContainsGenericParameters {
340                         get {
341                                 foreach (Type t in type_arguments) {
342                                         if (t.ContainsGenericParameters)
343                                                 return true;
344                                 }
345                                 return false;
346                         }
347                 }
348
349                 public override bool IsGenericTypeDefinition {
350                         get { return false; }
351                 }
352
353                 public override bool IsGenericType {
354                         get { return true; }
355                 }
356
357                 public override Type DeclaringType {
358                         get { return generic_type.DeclaringType; }
359                 }
360
361                 public override RuntimeTypeHandle TypeHandle {
362                         get {
363                                 throw new NotSupportedException ();
364                         }
365                 }
366
367                 public override Type MakeArrayType ()
368                 {
369                         return new ArrayType (this, 0);
370                 }
371
372                 public override Type MakeArrayType (int rank)
373                 {
374                         if (rank < 1)
375                                 throw new IndexOutOfRangeException ();
376                         return new ArrayType (this, rank);
377                 }
378
379                 public override Type MakeByRefType ()
380                 {
381                         return new ByRefType (this);
382                 }
383
384                 public override Type MakePointerType ()
385                 {
386                         return new PointerType (this);
387                 }
388
389                 public override Type GetElementType ()
390                 {
391                         throw new NotSupportedException ();
392                 }
393
394                 protected override bool HasElementTypeImpl ()
395                 {
396                         return false;
397                 }
398
399                 protected override bool IsCOMObjectImpl ()
400                 {
401                         return false;
402                 }
403
404                 protected override bool IsPrimitiveImpl ()
405                 {
406                         return false;
407                 }
408
409                 protected override bool IsArrayImpl ()
410                 {
411                         return false;
412                 }
413
414                 protected override bool IsByRefImpl ()
415                 {
416                         return false;
417                 }
418
419                 protected override bool IsPointerImpl ()
420                 {
421                         return false;
422                 }
423
424                 protected override TypeAttributes GetAttributeFlagsImpl ()
425                 {
426                         return generic_type.Attributes; 
427                 }
428
429                 //stuff that throws
430                 public override Type GetInterface (string name, bool ignoreCase)
431                 {
432                         throw new NotSupportedException ();
433                 }
434
435                 public override EventInfo GetEvent (string name, BindingFlags bindingAttr)
436                 {
437                         throw new NotSupportedException ();
438                 }
439
440                 public override FieldInfo GetField( string name, BindingFlags bindingAttr)
441                 {
442                         throw new NotSupportedException ();
443                 }
444
445                 public override MemberInfo[] GetMembers (BindingFlags bindingAttr)
446                 {
447                         throw new NotSupportedException ();
448                 }
449
450                 public override Type GetNestedType (string name, BindingFlags bindingAttr)
451                 {
452                         throw new NotSupportedException ();
453                 }
454
455                 public override object InvokeMember (string name, BindingFlags invokeAttr,
456                                                      Binder binder, object target, object[] args,
457                                                      ParameterModifier[] modifiers,
458                                                      CultureInfo culture, string[] namedParameters)
459                 {
460                         throw new NotSupportedException ();
461                 }
462
463                 protected override MethodInfo GetMethodImpl (string name, BindingFlags bindingAttr, Binder binder,
464                                                              CallingConventions callConvention, Type[] types,
465                                                              ParameterModifier[] modifiers)
466                 {
467                         throw new NotSupportedException ();
468                 }
469
470                 protected override PropertyInfo GetPropertyImpl (string name, BindingFlags bindingAttr, Binder binder,
471                                                                  Type returnType, Type[] types, ParameterModifier[] modifiers)
472                 {
473                         throw new NotSupportedException ();
474                 }
475
476                 protected override ConstructorInfo GetConstructorImpl (BindingFlags bindingAttr,
477                                                                        Binder binder,
478                                                                        CallingConventions callConvention,
479                                                                        Type[] types,
480                                                                        ParameterModifier[] modifiers)
481                 {
482                         throw new NotSupportedException ();
483                 }
484
485                 //MemberInfo
486                 public override bool IsDefined (Type attributeType, bool inherit)
487                 {
488                         throw new NotSupportedException ();
489                 }
490
491                 public override object [] GetCustomAttributes (bool inherit)
492                 {
493                         throw new NotSupportedException ();
494                 }
495
496                 public override object [] GetCustomAttributes (Type attributeType, bool inherit)
497                 {
498                         throw new NotSupportedException ();
499                 }
500
501                 internal override bool IsUserType {
502                         get {
503                                 foreach (var t in type_arguments) {
504                                         if (t.IsUserType)
505                                                 return true;
506                                 }
507                                 return false;
508                         }
509                 }
510
511         }
512 }
513
514 #endif