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