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