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