Fix null sessions in HttpContextWrapper.Session
[mono.git] / mcs / class / IKVM.Reflection / Emit / TypeBuilder.cs
1 /*
2   Copyright (C) 2008-2011 Jeroen Frijters
3
4   This software is provided 'as-is', without any express or implied
5   warranty.  In no event will the authors be held liable for any damages
6   arising from the use of this software.
7
8   Permission is granted to anyone to use this software for any purpose,
9   including commercial applications, and to alter it and redistribute it
10   freely, subject to the following restrictions:
11
12   1. The origin of this software must not be misrepresented; you must not
13      claim that you wrote the original software. If you use this software
14      in a product, an acknowledgment in the product documentation would be
15      appreciated but is not required.
16   2. Altered source versions must be plainly marked as such, and must not be
17      misrepresented as being the original software.
18   3. This notice may not be removed or altered from any source distribution.
19
20   Jeroen Frijters
21   jeroen@frijters.net
22   
23 */
24 using System;
25 using System.Collections.Generic;
26 using System.Diagnostics;
27 using System.Runtime.InteropServices;
28 using IKVM.Reflection.Impl;
29 using IKVM.Reflection.Metadata;
30 using IKVM.Reflection.Writer;
31
32 namespace IKVM.Reflection.Emit
33 {
34         public sealed class GenericTypeParameterBuilder : TypeInfo
35         {
36                 private readonly string name;
37                 private readonly TypeBuilder type;
38                 private readonly MethodBuilder method;
39                 private readonly int paramPseudoIndex;
40                 private readonly int position;
41                 private int typeToken;
42                 private Type baseType;
43                 private GenericParameterAttributes attr;
44
45                 internal GenericTypeParameterBuilder(string name, TypeBuilder type, MethodBuilder method, int position)
46                 {
47                         this.name = name;
48                         this.type = type;
49                         this.method = method;
50                         this.position = position;
51                         GenericParamTable.Record rec = new GenericParamTable.Record();
52                         rec.Number = (short)position;
53                         rec.Flags = 0;
54                         rec.Owner = type != null ? type.MetadataToken : method.MetadataToken;
55                         rec.Name = this.ModuleBuilder.Strings.Add(name);
56                         this.paramPseudoIndex = this.ModuleBuilder.GenericParam.AddRecord(rec);
57                 }
58
59                 public override string AssemblyQualifiedName
60                 {
61                         get { return null; }
62                 }
63
64                 public override bool IsValueType
65                 {
66                         get { return (this.GenericParameterAttributes & GenericParameterAttributes.NotNullableValueTypeConstraint) != 0; }
67                 }
68
69                 public override Type BaseType
70                 {
71                         get { return baseType; }
72                 }
73
74                 public override Type[] __GetDeclaredInterfaces()
75                 {
76                         throw new NotImplementedException();
77                 }
78
79                 public override TypeAttributes Attributes
80                 {
81                         get { return TypeAttributes.Public; }
82                 }
83
84                 public override string Namespace
85                 {
86                         get { return DeclaringType.Namespace; }
87                 }
88
89                 public override string Name
90                 {
91                         get { return name; }
92                 }
93
94                 public override string FullName
95                 {
96                         get { return null; }
97                 }
98
99                 public override string ToString()
100                 {
101                         return this.Name;
102                 }
103
104                 private ModuleBuilder ModuleBuilder
105                 {
106                         get { return type != null ? type.ModuleBuilder : method.ModuleBuilder; }
107                 }
108
109                 public override Module Module
110                 {
111                         get { return ModuleBuilder; }
112                 }
113
114                 public override bool IsGenericParameter
115                 {
116                         get { return true; }
117                 }
118
119                 public override int GenericParameterPosition
120                 {
121                         get { return position; }
122                 }
123
124                 public override Type DeclaringType
125                 {
126                         get { return type; }
127                 }
128
129                 public override MethodBase DeclaringMethod
130                 {
131                         get { return method; }
132                 }
133
134                 public override Type[] GetGenericParameterConstraints()
135                 {
136                         throw new NotImplementedException();
137                 }
138
139                 public override GenericParameterAttributes GenericParameterAttributes
140                 {
141                         get
142                         {
143                                 CheckBaked();
144                                 return attr;
145                         }
146                 }
147
148                 internal override void CheckBaked()
149                 {
150                         if (type != null)
151                         {
152                                 type.CheckBaked();
153                         }
154                         else
155                         {
156                                 method.CheckBaked();
157                         }
158                 }
159
160                 private void AddConstraint(Type type)
161                 {
162                         GenericParamConstraintTable.Record rec = new GenericParamConstraintTable.Record();
163                         rec.Owner = paramPseudoIndex;
164                         rec.Constraint = this.ModuleBuilder.GetTypeTokenForMemberRef(type);
165                         this.ModuleBuilder.GenericParamConstraint.AddRecord(rec);
166                 }
167
168                 public void SetBaseTypeConstraint(Type baseTypeConstraint)
169                 {
170                         this.baseType = baseTypeConstraint;
171                         AddConstraint(baseTypeConstraint);
172                 }
173
174                 public void SetInterfaceConstraints(params Type[] interfaceConstraints)
175                 {
176                         foreach (Type type in interfaceConstraints)
177                         {
178                                 AddConstraint(type);
179                         }
180                 }
181
182                 public void SetGenericParameterAttributes(GenericParameterAttributes genericParameterAttributes)
183                 {
184                         this.attr = genericParameterAttributes;
185                         // for now we'll back patch the table
186                         this.ModuleBuilder.GenericParam.PatchAttribute(paramPseudoIndex, genericParameterAttributes);
187                 }
188
189                 public void SetCustomAttribute(CustomAttributeBuilder customBuilder)
190                 {
191                         this.ModuleBuilder.SetCustomAttribute((GenericParamTable.Index << 24) | paramPseudoIndex, customBuilder);
192                 }
193
194                 public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute)
195                 {
196                         SetCustomAttribute(new CustomAttributeBuilder(con, binaryAttribute));
197                 }
198
199                 public override int MetadataToken
200                 {
201                         get
202                         {
203                                 CheckBaked();
204                                 return (GenericParamTable.Index << 24) | paramPseudoIndex;
205                         }
206                 }
207
208                 internal override int GetModuleBuilderToken()
209                 {
210                         if (typeToken == 0)
211                         {
212                                 ByteBuffer spec = new ByteBuffer(5);
213                                 Signature.WriteTypeSpec(this.ModuleBuilder, spec, this);
214                                 typeToken = 0x1B000000 | this.ModuleBuilder.TypeSpec.AddRecord(this.ModuleBuilder.Blobs.Add(spec));
215                         }
216                         return typeToken;
217                 }
218
219                 internal override Type BindTypeParameters(IGenericBinder binder)
220                 {
221                         if (type != null)
222                         {
223                                 return binder.BindTypeParameter(this);
224                         }
225                         else
226                         {
227                                 return binder.BindMethodParameter(this);
228                         }
229                 }
230
231                 internal override int GetCurrentToken()
232                 {
233                         if (this.ModuleBuilder.IsSaved)
234                         {
235                                 return (GenericParamTable.Index << 24) | this.Module.GenericParam.GetIndexFixup()[paramPseudoIndex - 1] + 1;
236                         }
237                         else
238                         {
239                                 return (GenericParamTable.Index << 24) | paramPseudoIndex;
240                         }
241                 }
242
243                 internal override bool IsBaked
244                 {
245                         get { return ((MemberInfo)type ?? method).IsBaked; }
246                 }
247         }
248
249         public sealed class TypeBuilder : TypeInfo, ITypeOwner
250         {
251                 public const int UnspecifiedTypeSize = 0;
252                 private readonly ITypeOwner owner;
253                 private readonly int token;
254                 private int extends;
255                 private Type lazyBaseType;              // (lazyBaseType == null && attribs & TypeAttributes.Interface) == 0) => BaseType == System.Object
256                 private readonly int typeName;
257                 private readonly int typeNameSpace;
258                 private readonly string ns;
259                 private readonly string name;
260                 private readonly List<MethodBuilder> methods = new List<MethodBuilder>();
261                 private readonly List<FieldBuilder> fields = new List<FieldBuilder>();
262                 private List<PropertyBuilder> properties;
263                 private List<EventBuilder> events;
264                 private TypeAttributes attribs;
265                 private GenericTypeParameterBuilder[] gtpb;
266                 private List<CustomAttributeBuilder> declarativeSecurity;
267                 private List<Type> interfaces;
268                 private int size;
269                 private short pack;
270                 private bool hasLayout;
271
272                 internal TypeBuilder(ITypeOwner owner, string ns, string name)
273                 {
274                         this.owner = owner;
275                         this.token = this.ModuleBuilder.TypeDef.AllocToken();
276                         this.ns = ns;
277                         this.name = name;
278                         this.typeNameSpace = ns == null ? 0 : this.ModuleBuilder.Strings.Add(ns);
279                         this.typeName = this.ModuleBuilder.Strings.Add(name);
280                         MarkEnumOrValueType(ns, name);
281                 }
282
283                 public ConstructorBuilder DefineDefaultConstructor(MethodAttributes attributes)
284                 {
285                         ConstructorBuilder cb = DefineConstructor(attributes, CallingConventions.Standard, Type.EmptyTypes);
286                         ILGenerator ilgen = cb.GetILGenerator();
287                         ilgen.Emit(OpCodes.Ldarg_0);
288                         ilgen.Emit(OpCodes.Call, BaseType.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null));
289                         ilgen.Emit(OpCodes.Ret);
290                         return cb;
291                 }
292
293                 public ConstructorBuilder DefineConstructor(MethodAttributes attribs, CallingConventions callConv, Type[] parameterTypes)
294                 {
295                         return DefineConstructor(attribs, callConv, parameterTypes, null, null);
296                 }
297
298                 public ConstructorBuilder DefineConstructor(MethodAttributes attribs, CallingConventions callingConvention, Type[] parameterTypes, Type[][] requiredCustomModifiers, Type[][] optionalCustomModifiers)
299                 {
300                         attribs |= MethodAttributes.RTSpecialName | MethodAttributes.SpecialName;
301                         string name = (attribs & MethodAttributes.Static) == 0 ? ConstructorInfo.ConstructorName : ConstructorInfo.TypeConstructorName;
302                         MethodBuilder mb = DefineMethod(name, attribs, callingConvention, null, null, null, parameterTypes, requiredCustomModifiers, optionalCustomModifiers);
303                         return new ConstructorBuilder(mb);
304                 }
305
306                 public ConstructorBuilder DefineTypeInitializer()
307                 {
308                         MethodBuilder mb = DefineMethod(ConstructorInfo.TypeConstructorName, MethodAttributes.Private | MethodAttributes.Static | MethodAttributes.RTSpecialName | MethodAttributes.SpecialName, null, Type.EmptyTypes);
309                         return new ConstructorBuilder(mb);
310                 }
311
312                 private MethodBuilder CreateMethodBuilder(string name, MethodAttributes attributes, CallingConventions callingConvention)
313                 {
314                         this.ModuleBuilder.MethodDef.AddVirtualRecord();
315                         MethodBuilder mb = new MethodBuilder(this, name, attributes, callingConvention);
316                         methods.Add(mb);
317                         return mb;
318                 }
319
320                 public MethodBuilder DefineMethod(string name, MethodAttributes attribs)
321                 {
322                         return DefineMethod(name, attribs, CallingConventions.Standard);
323                 }
324
325                 public MethodBuilder DefineMethod(string name, MethodAttributes attribs, CallingConventions callingConvention)
326                 {
327                         return CreateMethodBuilder(name, attribs, callingConvention);
328                 }
329
330                 public MethodBuilder DefineMethod(string name, MethodAttributes attribs, Type returnType, Type[] parameterTypes)
331                 {
332                         return DefineMethod(name, attribs, CallingConventions.Standard, returnType, null, null, parameterTypes, null, null);
333                 }
334
335                 public MethodBuilder DefineMethod(string name, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] parameterTypes)
336                 {
337                         return DefineMethod(name, attributes, callingConvention, returnType, null, null, parameterTypes, null, null);
338                 }
339
340                 public MethodBuilder DefineMethod(string name, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers, Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers)
341                 {
342                         MethodBuilder mb = CreateMethodBuilder(name, attributes, callingConvention);
343                         mb.SetSignature(returnType, returnTypeRequiredCustomModifiers, returnTypeOptionalCustomModifiers, parameterTypes, parameterTypeRequiredCustomModifiers, parameterTypeOptionalCustomModifiers);
344                         return mb;
345                 }
346
347                 public MethodBuilder DefinePInvokeMethod(string name, string dllName, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] parameterTypes, CallingConvention nativeCallConv, CharSet nativeCharSet)
348                 {
349                         return DefinePInvokeMethod(name, dllName, null, attributes, callingConvention, returnType, null, null, parameterTypes, null, null, nativeCallConv, nativeCharSet);
350                 }
351
352                 public MethodBuilder DefinePInvokeMethod(string name, string dllName, string entryName, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] parameterTypes, CallingConvention nativeCallConv, CharSet nativeCharSet)
353                 {
354                         return DefinePInvokeMethod(name, dllName, entryName, attributes, callingConvention, returnType, null, null, parameterTypes, null, null, nativeCallConv, nativeCharSet);
355                 }
356
357                 public MethodBuilder DefinePInvokeMethod(string name, string dllName, string entryName, MethodAttributes attributes, CallingConventions callingConvention,
358                         Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers,
359                         Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers,
360                         CallingConvention nativeCallConv, CharSet nativeCharSet)
361                 {
362                         MethodBuilder mb = DefineMethod(name, attributes | MethodAttributes.PinvokeImpl, callingConvention,
363                                 returnType, returnTypeRequiredCustomModifiers, returnTypeOptionalCustomModifiers,
364                                 parameterTypes, parameterTypeRequiredCustomModifiers, parameterTypeOptionalCustomModifiers);
365                         mb.SetDllImportPseudoCustomAttribute(dllName, entryName, nativeCallConv, nativeCharSet, null, null, null, null, null);
366                         return mb;
367                 }
368
369                 public void DefineMethodOverride(MethodInfo methodInfoBody, MethodInfo methodInfoDeclaration)
370                 {
371                         MethodImplTable.Record rec = new MethodImplTable.Record();
372                         rec.Class = token;
373                         rec.MethodBody = this.ModuleBuilder.GetMethodToken(methodInfoBody).Token;
374                         rec.MethodDeclaration = this.ModuleBuilder.GetMethodTokenWinRT(methodInfoDeclaration);
375                         this.ModuleBuilder.MethodImpl.AddRecord(rec);
376                 }
377
378                 public FieldBuilder DefineField(string name, Type fieldType, FieldAttributes attribs)
379                 {
380                         return DefineField(name, fieldType, null, null, attribs);
381                 }
382
383                 public FieldBuilder DefineField(string fieldName, Type type, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers, FieldAttributes attributes)
384                 {
385                         return __DefineField(fieldName, type, CustomModifiers.FromReqOpt(requiredCustomModifiers, optionalCustomModifiers), attributes);
386                 }
387
388                 public FieldBuilder __DefineField(string fieldName, Type type, CustomModifiers customModifiers, FieldAttributes attributes)
389                 {
390                         FieldBuilder fb = new FieldBuilder(this, fieldName, type, customModifiers, attributes);
391                         fields.Add(fb);
392                         return fb;
393                 }
394
395                 public PropertyBuilder DefineProperty(string name, PropertyAttributes attributes, Type returnType, Type[] parameterTypes)
396                 {
397                         return DefineProperty(name, attributes, returnType, null, null, parameterTypes, null, null);
398                 }
399
400                 public PropertyBuilder DefineProperty(string name, PropertyAttributes attributes, Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers,
401                         Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers)
402                 {
403                         return DefinePropertyImpl(name, attributes, CallingConventions.Standard, true, returnType, parameterTypes,
404                                 PackedCustomModifiers.CreateFromExternal(returnTypeOptionalCustomModifiers, returnTypeRequiredCustomModifiers, parameterTypeOptionalCustomModifiers, parameterTypeRequiredCustomModifiers, Util.NullSafeLength(parameterTypes)));
405                 }
406
407                 public PropertyBuilder DefineProperty(string name, PropertyAttributes attributes, CallingConventions callingConvention,
408                         Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers,
409                         Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers)
410                 {
411                         return DefinePropertyImpl(name, attributes, callingConvention, false, returnType, parameterTypes,
412                                 PackedCustomModifiers.CreateFromExternal(returnTypeOptionalCustomModifiers, returnTypeRequiredCustomModifiers, parameterTypeOptionalCustomModifiers, parameterTypeRequiredCustomModifiers, Util.NullSafeLength(parameterTypes)));
413                 }
414
415                 public PropertyBuilder __DefineProperty(string name, PropertyAttributes attributes, CallingConventions callingConvention,
416                         Type returnType, CustomModifiers returnTypeCustomModifiers, Type[] parameterTypes, CustomModifiers[] parameterTypeCustomModifiers)
417                 {
418                         return DefinePropertyImpl(name, attributes, callingConvention, false, returnType, parameterTypes,
419                                 PackedCustomModifiers.CreateFromExternal(returnTypeCustomModifiers, parameterTypeCustomModifiers, Util.NullSafeLength(parameterTypes)));
420                 }
421
422                 private PropertyBuilder DefinePropertyImpl(string name, PropertyAttributes attributes, CallingConventions callingConvention, bool patchCallingConvention,
423                         Type returnType, Type[] parameterTypes, PackedCustomModifiers customModifiers)
424                 {
425                         if (properties == null)
426                         {
427                                 properties = new List<PropertyBuilder>();
428                         }
429                         PropertySignature sig = PropertySignature.Create(callingConvention, returnType, parameterTypes, customModifiers);
430                         PropertyBuilder pb = new PropertyBuilder(this, name, attributes, sig, patchCallingConvention);
431                         properties.Add(pb);
432                         return pb;
433                 }
434
435                 public EventBuilder DefineEvent(string name, EventAttributes attributes, Type eventtype)
436                 {
437                         if (events == null)
438                         {
439                                 events = new List<EventBuilder>();
440                         }
441                         EventBuilder eb = new EventBuilder(this, name, attributes, eventtype);
442                         events.Add(eb);
443                         return eb;
444                 }
445
446                 public TypeBuilder DefineNestedType(string name)
447                 {
448                         return DefineNestedType(name, TypeAttributes.Class | TypeAttributes.NestedPrivate);
449                 }
450
451                 public TypeBuilder DefineNestedType(string name, TypeAttributes attribs)
452                 {
453                         return DefineNestedType(name, attribs, null);
454                 }
455
456                 public TypeBuilder DefineNestedType(string name, TypeAttributes attr, Type parent, Type[] interfaces)
457                 {
458                         TypeBuilder tb = DefineNestedType(name, attr, parent);
459                         if (interfaces != null)
460                         {
461                                 foreach (Type iface in interfaces)
462                                 {
463                                         tb.AddInterfaceImplementation(iface);
464                                 }
465                         }
466                         return tb;
467                 }
468
469                 public TypeBuilder DefineNestedType(string name, TypeAttributes attr, Type parent)
470                 {
471                         return DefineNestedType(name, attr, parent, 0);
472                 }
473
474                 public TypeBuilder DefineNestedType(string name, TypeAttributes attr, Type parent, int typeSize)
475                 {
476                         return DefineNestedType(name, attr, parent, PackingSize.Unspecified, typeSize);
477                 }
478
479                 public TypeBuilder DefineNestedType(string name, TypeAttributes attr, Type parent, PackingSize packSize)
480                 {
481                         return DefineNestedType(name, attr, parent, packSize, 0);
482                 }
483
484                 private TypeBuilder DefineNestedType(string name, TypeAttributes attr, Type parent, PackingSize packSize, int typeSize)
485                 {
486                         string ns = null;
487                         int lastdot = name.LastIndexOf('.');
488                         if (lastdot > 0)
489                         {
490                                 ns = name.Substring(0, lastdot);
491                                 name = name.Substring(lastdot + 1);
492                         }
493                         TypeBuilder typeBuilder = __DefineNestedType(ns, name);
494                         typeBuilder.__SetAttributes(attr);
495                         typeBuilder.SetParent(parent);
496                         if (packSize != PackingSize.Unspecified || typeSize != 0)
497                         {
498                                 typeBuilder.__SetLayout((int)packSize, typeSize);
499                         }
500                         return typeBuilder;
501                 }
502
503                 public TypeBuilder __DefineNestedType(string ns, string name)
504                 {
505                         this.typeFlags |= TypeFlags.HasNestedTypes;
506                         TypeBuilder typeBuilder = this.ModuleBuilder.DefineType(this, ns, name);
507                         NestedClassTable.Record rec = new NestedClassTable.Record();
508                         rec.NestedClass = typeBuilder.MetadataToken;
509                         rec.EnclosingClass = this.MetadataToken;
510                         this.ModuleBuilder.NestedClass.AddRecord(rec);
511                         return typeBuilder;
512                 }
513
514                 public void SetParent(Type parent)
515                 {
516                         lazyBaseType = parent;
517                 }
518
519                 public void AddInterfaceImplementation(Type interfaceType)
520                 {
521                         if (interfaces == null)
522                         {
523                                 interfaces = new List<Type>();
524                         }
525                         interfaces.Add(interfaceType);
526                 }
527
528                 public void __SetInterfaceImplementationCustomAttribute(Type interfaceType, CustomAttributeBuilder cab)
529                 {
530                         this.ModuleBuilder.SetInterfaceImplementationCustomAttribute(this, interfaceType, cab);
531                 }
532
533                 public int Size
534                 {
535                         get { return size; }
536                 }
537
538                 public PackingSize PackingSize
539                 {
540                         get { return (PackingSize)pack; }
541                 }
542
543                 public override bool __GetLayout(out int packingSize, out int typeSize)
544                 {
545                         packingSize = this.pack;
546                         typeSize = this.size;
547                         return hasLayout;
548                 }
549
550                 public void __SetLayout(int packingSize, int typesize)
551                 {
552                         this.pack = (short)packingSize;
553                         this.size = typesize;
554                         this.hasLayout = true;
555                 }
556
557                 private void SetStructLayoutPseudoCustomAttribute(CustomAttributeBuilder customBuilder)
558                 {
559                         object val = customBuilder.GetConstructorArgument(0);
560                         LayoutKind layout;
561                         if (val is short)
562                         {
563                                 layout = (LayoutKind)(short)val;
564                         }
565                         else
566                         {
567                                 layout = (LayoutKind)val;
568                         }
569                         StructLayoutAttribute attr = new StructLayoutAttribute(layout);
570                         attr.Pack = (int?)customBuilder.GetFieldValue("Pack") ?? 0;
571                         attr.Size = (int?)customBuilder.GetFieldValue("Size") ?? 0;
572                         attr.CharSet = customBuilder.GetFieldValue<CharSet>("CharSet") ?? CharSet.None;
573                         attribs &= ~TypeAttributes.LayoutMask;
574                         switch (attr.Value)
575                         {
576                                 case LayoutKind.Auto:
577                                         attribs |= TypeAttributes.AutoLayout;
578                                         break;
579                                 case LayoutKind.Explicit:
580                                         attribs |= TypeAttributes.ExplicitLayout;
581                                         break;
582                                 case LayoutKind.Sequential:
583                                         attribs |= TypeAttributes.SequentialLayout;
584                                         break;
585                         }
586                         attribs &= ~TypeAttributes.StringFormatMask;
587                         switch (attr.CharSet)
588                         {
589                                 case CharSet.None:
590                                 case CharSet.Ansi:
591                                         attribs |= TypeAttributes.AnsiClass;
592                                         break;
593                                 case CharSet.Auto:
594                                         attribs |= TypeAttributes.AutoClass;
595                                         break;
596                                 case CharSet.Unicode:
597                                         attribs |= TypeAttributes.UnicodeClass;
598                                         break;
599                         }
600                         pack = (short)attr.Pack;
601                         size = attr.Size;
602                         hasLayout = pack != 0 || size != 0;
603                 }
604
605                 public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute)
606                 {
607                         SetCustomAttribute(new CustomAttributeBuilder(con, binaryAttribute));
608                 }
609
610                 public void SetCustomAttribute(CustomAttributeBuilder customBuilder)
611                 {
612                         Universe u = this.ModuleBuilder.universe;
613                         Type type = customBuilder.Constructor.DeclaringType;
614                         if (type == u.System_Runtime_InteropServices_StructLayoutAttribute)
615                         {
616                                 SetStructLayoutPseudoCustomAttribute(customBuilder.DecodeBlob(this.Assembly));
617                         }
618                         else if (type == u.System_SerializableAttribute)
619                         {
620                                 attribs |= TypeAttributes.Serializable;
621                         }
622                         else if (type == u.System_Runtime_InteropServices_ComImportAttribute)
623                         {
624                                 attribs |= TypeAttributes.Import;
625                         }
626                         else if (type == u.System_Runtime_CompilerServices_SpecialNameAttribute)
627                         {
628                                 attribs |= TypeAttributes.SpecialName;
629                         }
630                         else
631                         {
632                                 if (type == u.System_Security_SuppressUnmanagedCodeSecurityAttribute)
633                                 {
634                                         attribs |= TypeAttributes.HasSecurity;
635                                 }
636                                 this.ModuleBuilder.SetCustomAttribute(token, customBuilder);
637                         }
638                 }
639
640                 public void __AddDeclarativeSecurity(CustomAttributeBuilder customBuilder)
641                 {
642                         attribs |= TypeAttributes.HasSecurity;
643                         if (declarativeSecurity == null)
644                         {
645                                 declarativeSecurity = new List<CustomAttributeBuilder>();
646                         }
647                         declarativeSecurity.Add(customBuilder);
648                 }
649
650                 public void AddDeclarativeSecurity(System.Security.Permissions.SecurityAction securityAction, System.Security.PermissionSet permissionSet)
651                 {
652                         this.ModuleBuilder.AddDeclarativeSecurity(token, securityAction, permissionSet);
653                         this.attribs |= TypeAttributes.HasSecurity;
654                 }
655
656                 public GenericTypeParameterBuilder[] DefineGenericParameters(params string[] names)
657                 {
658                         typeFlags |= TypeFlags.IsGenericTypeDefinition;
659                         gtpb = new GenericTypeParameterBuilder[names.Length];
660                         for (int i = 0; i < names.Length; i++)
661                         {
662                                 gtpb[i] = new GenericTypeParameterBuilder(names[i], this, null, i);
663                         }
664                         return (GenericTypeParameterBuilder[])gtpb.Clone();
665                 }
666
667                 public override Type[] GetGenericArguments()
668                 {
669                         return Util.Copy(gtpb);
670                 }
671
672                 public override CustomModifiers[] __GetGenericArgumentsCustomModifiers()
673                 {
674                         return gtpb == null ? Empty<CustomModifiers>.Array : new CustomModifiers[gtpb.Length];
675                 }
676
677                 internal override Type GetGenericTypeArgument(int index)
678                 {
679                         return gtpb[index];
680                 }
681
682                 public override bool ContainsGenericParameters
683                 {
684                         get { return gtpb != null; }
685                 }
686
687                 public override Type GetGenericTypeDefinition()
688                 {
689                         return this;
690                 }
691
692                 public Type CreateType()
693                 {
694                         if ((typeFlags & TypeFlags.Baked) != 0)
695                         {
696                                 // .NET allows multiple invocations (subsequent invocations return the same baked type)
697                                 throw new NotImplementedException();
698                         }
699                         typeFlags |= TypeFlags.Baked;
700                         if (hasLayout)
701                         {
702                                 ClassLayoutTable.Record rec = new ClassLayoutTable.Record();
703                                 rec.PackingSize = pack;
704                                 rec.ClassSize = size;
705                                 rec.Parent = token;
706                                 this.ModuleBuilder.ClassLayout.AddRecord(rec);
707                         }
708                         bool hasConstructor = false;
709                         foreach (MethodBuilder mb in methods)
710                         {
711                                 hasConstructor |= mb.IsSpecialName && mb.Name == ConstructorInfo.ConstructorName;
712                                 mb.Bake();
713                         }
714                         if (!hasConstructor && !IsModulePseudoType && !IsInterface && !IsValueType && !(IsAbstract && IsSealed))
715                         {
716                                 ((MethodBuilder)DefineDefaultConstructor(MethodAttributes.Public).GetMethodInfo()).Bake();
717                         }
718                         if (declarativeSecurity != null)
719                         {
720                                 this.ModuleBuilder.AddDeclarativeSecurity(token, declarativeSecurity);
721                         }
722                         if (!IsModulePseudoType)
723                         {
724                                 Type baseType = this.BaseType;
725                                 if (baseType != null)
726                                 {
727                                         extends = this.ModuleBuilder.GetTypeToken(baseType).Token;
728                                 }
729                         }
730                         if (interfaces != null)
731                         {
732                                 foreach (Type interfaceType in interfaces)
733                                 {
734                                         InterfaceImplTable.Record rec = new InterfaceImplTable.Record();
735                                         rec.Class = token;
736                                         rec.Interface = this.ModuleBuilder.GetTypeToken(interfaceType).Token;
737                                         this.ModuleBuilder.InterfaceImpl.AddRecord(rec);
738                                 }
739                         }
740                         return new BakedType(this);
741                 }
742
743                 internal void PopulatePropertyAndEventTables()
744                 {
745                         if (properties != null)
746                         {
747                                 PropertyMapTable.Record rec = new PropertyMapTable.Record();
748                                 rec.Parent = token;
749                                 rec.PropertyList = this.ModuleBuilder.Property.RowCount + 1;
750                                 this.ModuleBuilder.PropertyMap.AddRecord(rec);
751                                 foreach (PropertyBuilder pb in properties)
752                                 {
753                                         pb.Bake();
754                                 }
755                         }
756                         if (events != null)
757                         {
758                                 EventMapTable.Record rec = new EventMapTable.Record();
759                                 rec.Parent = token;
760                                 rec.EventList = this.ModuleBuilder.Event.RowCount + 1;
761                                 this.ModuleBuilder.EventMap.AddRecord(rec);
762                                 foreach (EventBuilder eb in events)
763                                 {
764                                         eb.Bake();
765                                 }
766                         }
767                 }
768
769                 public override Type BaseType
770                 {
771                         get
772                         {
773                                 if (lazyBaseType == null && !IsInterface)
774                                 {
775                                         Type obj = Module.universe.System_Object;
776                                         if (this != obj)
777                                         {
778                                                 lazyBaseType = obj;
779                                         }
780                                 }
781                                 return lazyBaseType;
782                         }
783                 }
784
785                 public override string FullName
786                 {
787                         get
788                         {
789                                 if (this.IsNested)
790                                 {
791                                         return this.DeclaringType.FullName + "+" + TypeNameParser.Escape(name);
792                                 }
793                                 if (ns == null)
794                                 {
795                                         return TypeNameParser.Escape(name);
796                                 }
797                                 else
798                                 {
799                                         return TypeNameParser.Escape(ns) + "." + TypeNameParser.Escape(name);
800                                 }
801                         }
802                 }
803
804                 public override string __Name
805                 {
806                         get { return name; }
807                 }
808
809                 public override string __Namespace
810                 {
811                         get { return ns; }
812                 }
813
814                 public override string Name
815                 {
816                         // FXBUG for a TypeBuilder the name is not escaped
817                         get { return name; }
818                 }
819
820                 public override string Namespace
821                 {
822                         get
823                         {
824                                 // for some reason, TypeBuilder doesn't return null (and mcs depends on this)
825                                 // note also that we don't return the declaring type namespace for nested types
826                                 return ns ?? "";
827                         }
828                 }
829
830                 public override TypeAttributes Attributes
831                 {
832                         get { return attribs; }
833                 }
834
835                 public void __SetAttributes(TypeAttributes attributes)
836                 {
837                         this.attribs = attributes;
838                 }
839
840                 public override Type[] __GetDeclaredInterfaces()
841                 {
842                         return Util.ToArray(interfaces, Type.EmptyTypes);
843                 }
844
845                 public override MethodBase[] __GetDeclaredMethods()
846                 {
847                         MethodBase[] methods = new MethodBase[this.methods.Count];
848                         for (int i = 0; i < methods.Length; i++)
849                         {
850                                 MethodBuilder mb = this.methods[i];
851                                 if (mb.IsConstructor)
852                                 {
853                                         methods[i] = new ConstructorInfoImpl(mb);
854                                 }
855                                 else
856                                 {
857                                         methods[i] = mb;
858                                 }
859                         }
860                         return methods;
861                 }
862
863                 public override StructLayoutAttribute StructLayoutAttribute
864                 {
865                         get
866                         {
867                                 LayoutKind layout;
868                                 switch (attribs & TypeAttributes.LayoutMask)
869                                 {
870                                         case TypeAttributes.ExplicitLayout:
871                                                 layout = LayoutKind.Explicit;
872                                                 break;
873                                         case TypeAttributes.SequentialLayout:
874                                                 layout = LayoutKind.Sequential;
875                                                 break;
876                                         default:
877                                                 layout = LayoutKind.Auto;
878                                                 break;
879                                 }
880                                 StructLayoutAttribute attr = new StructLayoutAttribute(layout);
881                                 attr.Pack = (ushort)pack;
882                                 attr.Size = size;
883                                 switch (attribs & TypeAttributes.StringFormatMask)
884                                 {
885                                         case TypeAttributes.AutoClass:
886                                                 attr.CharSet = CharSet.Auto;
887                                                 break;
888                                         case TypeAttributes.UnicodeClass:
889                                                 attr.CharSet = CharSet.Unicode;
890                                                 break;
891                                         case TypeAttributes.AnsiClass:
892                                                 attr.CharSet = CharSet.Ansi;
893                                                 break;
894                                         default:
895                                                 attr.CharSet = CharSet.None;
896                                                 break;
897                                 }
898                                 return attr;
899                         }
900                 }
901
902                 public override Type DeclaringType
903                 {
904                         get { return owner as TypeBuilder; }
905                 }
906
907                 public override bool IsGenericType
908                 {
909                         get { return IsGenericTypeDefinition; }
910                 }
911
912                 public override bool IsGenericTypeDefinition
913                 {
914                         get { return (typeFlags & TypeFlags.IsGenericTypeDefinition) != 0; }
915                 }
916
917                 public override int MetadataToken
918                 {
919                         get { return token; }
920                 }
921
922                 public FieldBuilder DefineUninitializedData(string name, int size, FieldAttributes attributes)
923                 {
924                         return DefineInitializedData(name, new byte[size], attributes);
925                 }
926
927                 public FieldBuilder DefineInitializedData(string name, byte[] data, FieldAttributes attributes)
928                 {
929                         Type fieldType = this.ModuleBuilder.GetType("$ArrayType$" + data.Length);
930                         if (fieldType == null)
931                         {
932                                 TypeBuilder tb = this.ModuleBuilder.DefineType("$ArrayType$" + data.Length, TypeAttributes.Public | TypeAttributes.Sealed | TypeAttributes.ExplicitLayout, this.Module.universe.System_ValueType, PackingSize.Size1, data.Length);
933                                 tb.CreateType();
934                                 fieldType = tb;
935                         }
936                         FieldBuilder fb = DefineField(name, fieldType, attributes | FieldAttributes.Static);
937                         fb.__SetDataAndRVA(data);
938                         return fb;
939                 }
940
941                 public static MethodInfo GetMethod(Type type, MethodInfo method)
942                 {
943                         return new GenericMethodInstance(type, method, null);
944                 }
945
946                 public static ConstructorInfo GetConstructor(Type type, ConstructorInfo constructor)
947                 {
948                         return new ConstructorInfoImpl(GetMethod(type, constructor.GetMethodInfo()));
949                 }
950
951                 public static FieldInfo GetField(Type type, FieldInfo field)
952                 {
953                         return new GenericFieldInstance(type, field);
954                 }
955
956                 public override Module Module
957                 {
958                         get { return owner.ModuleBuilder; }
959                 }
960
961                 public TypeToken TypeToken
962                 {
963                         get { return new TypeToken(token); }
964                 }
965
966                 internal void WriteTypeDefRecord(MetadataWriter mw, ref int fieldList, ref int methodList)
967                 {
968                         mw.Write((int)attribs);
969                         mw.WriteStringIndex(typeName);
970                         mw.WriteStringIndex(typeNameSpace);
971                         mw.WriteTypeDefOrRef(extends);
972                         mw.WriteField(fieldList);
973                         mw.WriteMethodDef(methodList);
974                         methodList += methods.Count;
975                         fieldList += fields.Count;
976                 }
977
978                 internal void WriteMethodDefRecords(int baseRVA, MetadataWriter mw, ref int paramList)
979                 {
980                         foreach (MethodBuilder mb in methods)
981                         {
982                                 mb.WriteMethodDefRecord(baseRVA, mw, ref paramList);
983                         }
984                 }
985
986                 internal void ResolveMethodAndFieldTokens(ref int methodToken, ref int fieldToken, ref int parameterToken)
987                 {
988                         foreach (MethodBuilder method in methods)
989                         {
990                                 method.FixupToken(methodToken++, ref parameterToken);
991                         }
992                         foreach (FieldBuilder field in fields)
993                         {
994                                 field.FixupToken(fieldToken++);
995                         }
996                 }
997
998                 internal void WriteParamRecords(MetadataWriter mw)
999                 {
1000                         foreach (MethodBuilder mb in methods)
1001                         {
1002                                 mb.WriteParamRecords(mw);
1003                         }
1004                 }
1005
1006                 internal void WriteFieldRecords(MetadataWriter mw)
1007                 {
1008                         foreach (FieldBuilder fb in fields)
1009                         {
1010                                 fb.WriteFieldRecords(mw);
1011                         }
1012                 }
1013
1014                 internal ModuleBuilder ModuleBuilder
1015                 {
1016                         get { return owner.ModuleBuilder; }
1017                 }
1018
1019                 ModuleBuilder ITypeOwner.ModuleBuilder
1020                 {
1021                         get { return owner.ModuleBuilder; }
1022                 }
1023
1024                 internal override int GetModuleBuilderToken()
1025                 {
1026                         return token;
1027                 }
1028
1029                 internal bool HasNestedTypes
1030                 {
1031                         get { return (typeFlags & TypeFlags.HasNestedTypes) != 0; }
1032                 }
1033
1034                 // helper for ModuleBuilder.ResolveMethod()
1035                 internal MethodBase LookupMethod(int token)
1036                 {
1037                         foreach (MethodBuilder method in methods)
1038                         {
1039                                 if (method.MetadataToken == token)
1040                                 {
1041                                         return method;
1042                                 }
1043                         }
1044                         return null;
1045                 }
1046
1047                 public bool IsCreated()
1048                 {
1049                         return (typeFlags & TypeFlags.Baked) != 0;
1050                 }
1051
1052                 internal override void CheckBaked()
1053                 {
1054                         if ((typeFlags & TypeFlags.Baked) == 0)
1055                         {
1056                                 throw new NotSupportedException();
1057                         }
1058                 }
1059
1060                 public override Type[] __GetDeclaredTypes()
1061                 {
1062                         if (this.HasNestedTypes)
1063                         {
1064                                 List<Type> types = new List<Type>();
1065                                 List<int> classes = this.ModuleBuilder.NestedClass.GetNestedClasses(token);
1066                                 foreach (int nestedClass in classes)
1067                                 {
1068                                         types.Add(this.ModuleBuilder.ResolveType(nestedClass));
1069                                 }
1070                                 return types.ToArray();
1071                         }
1072                         else
1073                         {
1074                                 return Type.EmptyTypes;
1075                         }
1076                 }
1077
1078                 public override FieldInfo[] __GetDeclaredFields()
1079                 {
1080                         return Util.ToArray(fields, Empty<FieldInfo>.Array);
1081                 }
1082
1083                 public override EventInfo[] __GetDeclaredEvents()
1084                 {
1085                         return Util.ToArray(events, Empty<EventInfo>.Array);
1086                 }
1087
1088                 public override PropertyInfo[] __GetDeclaredProperties()
1089                 {
1090                         return Util.ToArray(properties, Empty<PropertyInfo>.Array);
1091                 }
1092
1093                 internal override bool IsModulePseudoType
1094                 {
1095                         get { return token == 0x02000001; }
1096                 }
1097
1098                 internal override bool IsBaked
1099                 {
1100                         get { return IsCreated(); }
1101                 }
1102         }
1103
1104         sealed class BakedType : TypeInfo
1105         {
1106                 internal BakedType(TypeBuilder typeBuilder)
1107                         : base(typeBuilder)
1108                 {
1109                 }
1110
1111                 public override string AssemblyQualifiedName
1112                 {
1113                         get { return underlyingType.AssemblyQualifiedName; }
1114                 }
1115
1116                 public override Type BaseType
1117                 {
1118                         get { return underlyingType.BaseType; }
1119                 }
1120
1121                 public override string __Name
1122                 {
1123                         get { return underlyingType.__Name; }
1124                 }
1125
1126                 public override string __Namespace
1127                 {
1128                         get { return underlyingType.__Namespace; }
1129                 }
1130
1131                 public override string Name
1132                 {
1133                         // we need to escape here, because TypeBuilder.Name does not escape
1134                         get { return TypeNameParser.Escape(underlyingType.__Name); }
1135                 }
1136
1137                 public override string FullName
1138                 {
1139                         get { return GetFullName(); }
1140                 }
1141
1142                 public override TypeAttributes Attributes
1143                 {
1144                         get { return underlyingType.Attributes; }
1145                 }
1146
1147                 public override Type[] __GetDeclaredInterfaces()
1148                 {
1149                         return underlyingType.__GetDeclaredInterfaces();
1150                 }
1151
1152                 public override MethodBase[] __GetDeclaredMethods()
1153                 {
1154                         return underlyingType.__GetDeclaredMethods();
1155                 }
1156
1157                 public override __MethodImplMap __GetMethodImplMap()
1158                 {
1159                         return underlyingType.__GetMethodImplMap();
1160                 }
1161
1162                 public override FieldInfo[] __GetDeclaredFields()
1163                 {
1164                         return underlyingType.__GetDeclaredFields();
1165                 }
1166
1167                 public override EventInfo[] __GetDeclaredEvents()
1168                 {
1169                         return underlyingType.__GetDeclaredEvents();
1170                 }
1171
1172                 public override PropertyInfo[] __GetDeclaredProperties()
1173                 {
1174                         return underlyingType.__GetDeclaredProperties();
1175                 }
1176
1177                 public override Type[] __GetDeclaredTypes()
1178                 {
1179                         return underlyingType.__GetDeclaredTypes();
1180                 }
1181
1182                 public override Type DeclaringType
1183                 {
1184                         get { return underlyingType.DeclaringType; }
1185                 }
1186
1187                 public override StructLayoutAttribute StructLayoutAttribute
1188                 {
1189                         get { return underlyingType.StructLayoutAttribute; }
1190                 }
1191
1192                 public override Type[] GetGenericArguments()
1193                 {
1194                         return underlyingType.GetGenericArguments();
1195                 }
1196
1197                 internal override Type GetGenericTypeArgument(int index)
1198                 {
1199                         return underlyingType.GetGenericTypeArgument(index);
1200                 }
1201
1202                 public override CustomModifiers[] __GetGenericArgumentsCustomModifiers()
1203                 {
1204                         return underlyingType.__GetGenericArgumentsCustomModifiers();
1205                 }
1206
1207                 public override bool IsGenericType
1208                 {
1209                         get { return underlyingType.IsGenericType; }
1210                 }
1211
1212                 public override bool IsGenericTypeDefinition
1213                 {
1214                         get { return underlyingType.IsGenericTypeDefinition; }
1215                 }
1216
1217                 public override bool ContainsGenericParameters
1218                 {
1219                         get { return underlyingType.ContainsGenericParameters; }
1220                 }
1221
1222                 public override int MetadataToken
1223                 {
1224                         get { return underlyingType.MetadataToken; }
1225                 }
1226
1227                 public override Module Module
1228                 {
1229                         get { return underlyingType.Module; }
1230                 }
1231
1232                 internal override int GetModuleBuilderToken()
1233                 {
1234                         return underlyingType.GetModuleBuilderToken();
1235                 }
1236
1237                 internal override bool IsBaked
1238                 {
1239                         get { return true; }
1240                 }
1241         }
1242 }