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