de6862e0825f0423b423bdc27616a535a4b2ce56
[mono.git] / mcs / class / corlib / System.Reflection.Emit / TypeBuilder.cs
1 //
2 // System.Reflection.Emit/TypeBuilder.cs
3 //
4 // Author:
5 //   Paolo Molaro (lupus@ximian.com)
6 //
7 // (C) 2001 Ximian, Inc.  http://www.ximian.com
8 //
9
10 using System;
11 using System.Reflection;
12 using System.Reflection.Emit;
13 using System.Runtime.CompilerServices;
14 using System.Runtime.InteropServices;
15 using System.Globalization;
16 using System.Collections;
17 using System.Security;
18 using System.Security.Permissions;
19
20 namespace System.Reflection.Emit {
21         public sealed class TypeBuilder : Type {
22         private string tname;
23         private string nspace;
24         private Type parent;
25         private Type[] interfaces;
26         private MethodBuilder[] methods;
27         private ConstructorBuilder[] ctors;
28         private PropertyBuilder[] properties;
29         private FieldBuilder[] fields;
30         private CustomAttributeBuilder[] cattrs;
31         internal TypeBuilder[] subtypes;
32         private TypeAttributes attrs;
33         private int table_idx;
34         private ModuleBuilder pmodule;
35         private int class_size;
36         private PackingSize packing_size;
37
38         public const int UnspecifiedTypeSize = -1;
39
40                 protected override TypeAttributes GetAttributeFlagsImpl () {
41                         return attrs;
42                 }
43                 
44                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
45                 private extern void setup_internal_class (TypeBuilder tb);
46                 
47                 internal TypeBuilder (ModuleBuilder mb, string name, TypeAttributes attr, Type parent, Type[] interfaces) {
48                         int sep_index;
49                         this.parent = parent;
50                         this.attrs = attr;
51                         packing_size = PackingSize.Unspecified;
52                         sep_index = name.LastIndexOf('.');
53                         if (sep_index != -1) {
54                                 this.tname = name.Substring (sep_index + 1);
55                                 this.nspace = name.Substring (0, sep_index);
56                         } else {
57                                 this.tname = name;
58                                 this.nspace = "";
59                         }
60                         if (interfaces != null) {
61                                 this.interfaces = new Type[interfaces.Length];
62                                 System.Array.Copy (interfaces, this.interfaces, interfaces.Length);
63                         }
64                         pmodule = mb;
65                         // skip .<Module> ?
66                         table_idx = mb.get_next_table_index (0x02, true);
67                         setup_internal_class (this);
68                 }
69
70                 public override Assembly Assembly {
71                         get {return pmodule.Assembly;}
72                 }
73                 public override string AssemblyQualifiedName {get {return null;}}
74                 public override Type BaseType {
75                         get {
76                                 return parent;
77                         }
78                 }
79                 public override Type DeclaringType {get {return null;}}
80                 public override Type UnderlyingSystemType {
81                         get {return null;}
82                 }
83
84                 public override string FullName {
85                         get {
86                                 if ((nspace != null) && (nspace.Length > 0))
87                                         return String.Concat (nspace, ".", tname);
88                                 return tname;
89                         }
90                 }
91         
92                 public override Guid GUID {
93                         get {return Guid.Empty;}
94                 }
95
96                 public override Module Module {
97                         get {return pmodule;}
98                 }
99                 public override string Name {
100                         get {return tname;}
101                 }
102                 public override string Namespace {
103                         get {return nspace;}
104                 }
105                 public PackingSize PackingSize {
106                         get {return packing_size;}
107                 }
108                 public override Type ReflectedType {get {return parent;}}
109                 public override MemberTypes MemberType { 
110                         get {return MemberTypes.TypeInfo;}
111                 }
112
113                 public void AddDeclarativeSecurity( SecurityAction action, PermissionSet pset) {
114                         throw new NotImplementedException ();
115                 }
116
117                 public void AddInterfaceImplementation( Type interfaceType) {
118                         throw new NotImplementedException ();
119                 }
120
121                 protected override ConstructorInfo GetConstructorImpl (BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers) {
122                         throw new NotImplementedException ();
123                 }
124
125                 public override bool IsDefined( Type attributeType, bool inherit) {
126                         return false;
127                 }
128                 public override object[] GetCustomAttributes(bool inherit) {
129                         return null;
130                 }
131                 public override object[] GetCustomAttributes(Type attributeType, bool inherit) {
132                         return null;
133                 }
134
135                 [MonoTODO]
136                 public TypeBuilder DefineNestedType (string name) {
137                         // FIXME: LAMESPEC: what other attributes should we use here as default?
138                         return DefineNestedType (name, TypeAttributes.Public, typeof(object), null);
139                 }
140
141                 public TypeBuilder DefineNestedType (string name, TypeAttributes attr) {
142                         return DefineNestedType (name, attr, typeof(object), null);
143                 }
144
145                 public TypeBuilder DefineNestedType (string name, TypeAttributes attr, Type parent) {
146                         return DefineNestedType (name, attr, parent, null);
147                 }
148
149                 public TypeBuilder DefineNestedType (string name, TypeAttributes attr, Type parent, Type[] interfaces) {
150                         TypeBuilder res = new TypeBuilder (pmodule, name, attr, parent, interfaces);
151                         if (subtypes != null) {
152                                 TypeBuilder[] new_types = new TypeBuilder [subtypes.Length + 1];
153                                 System.Array.Copy (subtypes, new_types, subtypes.Length);
154                                 new_types [subtypes.Length] = res;
155                                 subtypes = new_types;
156                         } else {
157                                 subtypes = new TypeBuilder [1];
158                                 subtypes [0] = res;
159                         }
160                         return res;
161                 }
162
163                 public TypeBuilder DefineNestedType (string name, TypeAttributes attr, Type parent, int typesize) {
164                         return DefineNestedType (name, attr, parent, null);
165                 }
166
167                 public TypeBuilder DefineNestedType (string name, TypeAttributes attr, Type parent, PackingSize packsize) {
168                         return DefineNestedType (name, attr, parent, null);
169                 }
170
171                 public TypeBuilder DefineNestedType (string name, TypeAttributes attr, Type parent, PackingSize packsize, int typesize) {
172                         return DefineNestedType (name, attr, parent, null);
173                 }
174
175                 public ConstructorBuilder DefineConstructor( MethodAttributes attributes, CallingConventions callingConvention, Type[] parameterTypes) {
176                         ConstructorBuilder cb = new ConstructorBuilder (this, attributes, callingConvention, parameterTypes);
177                         if (ctors != null) {
178                                 ConstructorBuilder[] new_ctors = new ConstructorBuilder [ctors.Length+1];
179                                 System.Array.Copy (ctors, new_ctors, ctors.Length);
180                                 new_ctors [ctors.Length] = cb;
181                                 ctors = new_ctors;
182                         } else {
183                                 ctors = new ConstructorBuilder [1];
184                                 ctors [0] = cb;
185                         }
186                         return cb;
187                 }
188
189                 public ConstructorBuilder DefineDefaultConstructor( MethodAttributes attributes) {
190                         return DefineConstructor (attributes, CallingConventions.Standard, null);
191                 }
192
193                 public MethodBuilder DefineMethod( string name, MethodAttributes attributes, Type returnType, Type[] parameterTypes) {
194                         return DefineMethod (name, attributes, CallingConventions.Standard, returnType, parameterTypes);
195                 }
196
197                 private void append_method (MethodBuilder mb) {
198                         if (methods != null) {
199                                 MethodBuilder[] new_methods = new MethodBuilder [methods.Length+1];
200                                 System.Array.Copy (methods, new_methods, methods.Length);
201                                 new_methods [methods.Length] = mb;
202                                 methods = new_methods;
203                         } else {
204                                 methods = new MethodBuilder [1];
205                                 methods [0] = mb;
206                         }
207                 }
208
209                 public MethodBuilder DefineMethod( string name, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] parameterTypes) {
210                         MethodBuilder res = new MethodBuilder (this, name, attributes, callingConvention, returnType, parameterTypes);
211                         append_method (res);
212                         return res;
213                 }
214
215                 public MethodBuilder DefinePInvokeMethod (string name, string dllName, string entryName, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] parameterTypes, CallingConvention nativeCallConv, CharSet nativeCharSet) {
216                         MethodBuilder res = new MethodBuilder (this, name, attributes, callingConvention, returnType, parameterTypes,
217                                 dllName, entryName, nativeCallConv, nativeCharSet);
218                         append_method (res);
219                         return res;
220                 }
221
222                 public MethodBuilder DefinePInvokeMethod (string name, string dllName, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] parameterTypes, CallingConvention nativeCallConv, CharSet nativeCharSet) {
223                         return DefinePInvokeMethod (name, dllName, name, attributes, callingConvention, returnType, parameterTypes,
224                                 nativeCallConv, nativeCharSet);
225                 }
226
227                 public void DefineMethodOverride( MethodInfo methodInfoBody, MethodInfo methodInfoDeclaration) {
228                         if (methodInfoBody is MethodBuilder) {
229                                 MethodBuilder mb = (MethodBuilder)methodInfoBody;
230                                 mb.set_override (methodInfoDeclaration);
231                         }
232                 }
233
234                 public FieldBuilder DefineField( string fieldName, Type type, FieldAttributes attributes) {
235                         FieldBuilder res = new FieldBuilder (this, fieldName, type, attributes);
236                         if (fields != null) {
237                                 FieldBuilder[] new_fields = new FieldBuilder [fields.Length+1];
238                                 System.Array.Copy (fields, new_fields, fields.Length);
239                                 new_fields [fields.Length] = res;
240                                 fields = new_fields;
241                         } else {
242                                 fields = new FieldBuilder [1];
243                                 fields [0] = res;
244                         }
245                         return res;
246                 }
247
248                 public PropertyBuilder DefineProperty( string name, PropertyAttributes attributes, Type returnType, Type[] parameterTypes) {
249                         PropertyBuilder res = new PropertyBuilder (this, name, attributes, returnType, parameterTypes);
250
251                         if (properties != null) {
252                                 PropertyBuilder[] new_properties = new PropertyBuilder [properties.Length+1];
253                                 System.Array.Copy (properties, new_properties, properties.Length);
254                                 new_properties [properties.Length] = res;
255                                 properties = new_properties;
256                         } else {
257                                 properties = new PropertyBuilder [1];
258                                 properties [0] = res;
259                         }
260                         return res;
261                 }
262
263                 public ConstructorBuilder DefineTypeInitializer() {
264                         throw new NotImplementedException ();
265                 }
266
267                 public Type CreateType() {
268                         if (methods != null) {
269                                 foreach (MethodBuilder method in methods) {
270                                         method.fixup ();
271                                 }
272                         }
273                         if (ctors != null) {
274                                 foreach (ConstructorBuilder ctor in ctors) {
275                                         ctor.fixup ();
276                                 }
277                         }
278                         return this;
279                 }
280
281                 public override ConstructorInfo[] GetConstructors (BindingFlags bindingAttr) {
282                         if (ctors == null)
283                                 return new ConstructorInfo [0];
284                         ArrayList l = new ArrayList ();
285                         bool match;
286                         MethodAttributes mattrs;
287                         
288                         foreach (ConstructorBuilder c in ctors) {
289                                 match = false;
290                                 mattrs = c.Attributes;
291                                 if ((mattrs & MethodAttributes.MemberAccessMask) == MethodAttributes.Public) {
292                                         if ((bindingAttr & BindingFlags.Public) != 0)
293                                                 match = true;
294                                 } else {
295                                         if ((bindingAttr & BindingFlags.NonPublic) != 0)
296                                                 match = true;
297                                 }
298                                 if (!match)
299                                         continue;
300                                 match = false;
301                                 if ((mattrs & MethodAttributes.Static) != 0) {
302                                         if ((bindingAttr & BindingFlags.Static) != 0)
303                                                 match = true;
304                                 } else {
305                                         if ((bindingAttr & BindingFlags.Instance) != 0)
306                                                 match = true;
307                                 }
308                                 if (!match)
309                                         continue;
310                                 l.Add (c);
311                         }
312                         ConstructorInfo[] result = new ConstructorInfo [l.Count];
313                         l.CopyTo (result);
314                         return result;
315                 }
316
317                 public override Type GetElementType () { return null; }
318
319                 public override EventInfo GetEvent (string name, BindingFlags bindingAttr) {
320                         throw new NotImplementedException ();
321                 }
322
323                 public override EventInfo[] GetEvents (BindingFlags bindingAttr) {
324                         return new EventInfo [0];
325                 }
326
327                 public override FieldInfo GetField( string name, BindingFlags bindingAttr) {
328                         //FIXME
329                         throw new NotImplementedException ();
330                 }
331
332                 public override FieldInfo[] GetFields (BindingFlags bindingAttr) {
333                         if (fields == null)
334                                 return new FieldInfo [0];
335                         ArrayList l = new ArrayList ();
336                         bool match;
337                         FieldAttributes mattrs;
338                         
339                         foreach (FieldInfo c in fields) {
340                                 match = false;
341                                 mattrs = c.Attributes;
342                                 if ((mattrs & FieldAttributes.FieldAccessMask) == FieldAttributes.Public) {
343                                         if ((bindingAttr & BindingFlags.Public) != 0)
344                                                 match = true;
345                                 } else {
346                                         if ((bindingAttr & BindingFlags.NonPublic) != 0)
347                                                 match = true;
348                                 }
349                                 if (!match)
350                                         continue;
351                                 match = false;
352                                 if ((mattrs & FieldAttributes.Static) != 0) {
353                                         if ((bindingAttr & BindingFlags.Static) != 0)
354                                                 match = true;
355                                 } else {
356                                         if ((bindingAttr & BindingFlags.Instance) != 0)
357                                                 match = true;
358                                 }
359                                 if (!match)
360                                         continue;
361                                 l.Add (c);
362                         }
363                         FieldInfo[] result = new FieldInfo [l.Count];
364                         l.CopyTo (result);
365                         return result;
366                 }
367
368                 public override Type GetInterface (string name, bool ignoreCase) {
369                         throw new NotImplementedException ();
370                 }
371                 
372                 public override Type[] GetInterfaces () {
373                         if (interfaces != null) {
374                                 Type [] pi;
375                                 if (parent != null)
376                                         pi = parent.GetInterfaces ();
377                                 else
378                                         pi = Type.EmptyTypes;
379                                 Type[] ret = new Type [interfaces.Length + pi.Length];
380                                 interfaces.CopyTo (ret, 0);
381                                 pi.CopyTo (ret, interfaces.Length);
382                                 return ret;
383                         } else {
384                                 if (parent != null)
385                                         return parent.GetInterfaces ();
386                                 else
387                                         return Type.EmptyTypes;
388                         }
389                 }
390
391                 public override MemberInfo[] GetMembers( BindingFlags bindingAttr) {
392                         // FIXME
393                         throw new NotImplementedException ();
394                 }
395
396                 public override MethodInfo[] GetMethods (BindingFlags bindingAttr) {
397                         if (methods == null)
398                                 return new MethodInfo [0];
399                         ArrayList l = new ArrayList ();
400                         bool match;
401                         MethodAttributes mattrs;
402
403                         foreach (MethodInfo c in methods) {
404                                 match = false;
405                                 mattrs = c.Attributes;
406                                 if ((mattrs & MethodAttributes.MemberAccessMask) == MethodAttributes.Public) {
407                                         if ((bindingAttr & BindingFlags.Public) != 0)
408                                                 match = true;
409                                 } else {
410                                         if ((bindingAttr & BindingFlags.NonPublic) != 0)
411                                                 match = true;
412                                 }
413                                 if (!match)
414                                         continue;
415                                 match = false;
416                                 if ((mattrs & MethodAttributes.Static) != 0) {
417                                         if ((bindingAttr & BindingFlags.Static) != 0)
418                                                 match = true;
419                                 } else {
420                                         if ((bindingAttr & BindingFlags.Instance) != 0)
421                                                 match = true;
422                                 }
423                                 if (!match)
424                                         continue;
425                                 l.Add (c);
426                         }
427                         MethodInfo[] result = new MethodInfo [l.Count];
428                         l.CopyTo (result);
429                         return result;
430                 }
431
432                 protected override MethodInfo GetMethodImpl( string name, BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers) {
433                         // FIXME
434                         throw new NotImplementedException ();
435                         return null;
436                 }
437                 
438                 public override Type GetNestedType( string name, BindingFlags bindingAttr) {
439                         // FIXME
440                         throw new NotImplementedException ();
441                         return null;
442                 }
443
444                 public override Type[] GetNestedTypes (BindingFlags bindingAttr) {
445                         // FIXME
446                         throw new NotImplementedException ();
447                         return null;
448                 }
449
450                 public override PropertyInfo[] GetProperties( BindingFlags bindingAttr) {
451                         if (properties == null)
452                                 return new PropertyInfo [0];
453                         ArrayList l = new ArrayList ();
454                         bool match;
455                         MethodAttributes mattrs;
456                         MethodInfo accessor;
457                         
458                         foreach (PropertyInfo c in properties) {
459                                 match = false;
460                                 accessor = c.GetGetMethod (true);
461                                 if (accessor == null)
462                                         accessor = c.GetSetMethod (true);
463                                 if (accessor == null)
464                                         continue;
465                                 mattrs = accessor.Attributes;
466                                 if ((mattrs & MethodAttributes.MemberAccessMask) == MethodAttributes.Public) {
467                                         if ((bindingAttr & BindingFlags.Public) != 0)
468                                                 match = true;
469                                 } else {
470                                         if ((bindingAttr & BindingFlags.NonPublic) != 0)
471                                                 match = true;
472                                 }
473                                 if (!match)
474                                         continue;
475                                 match = false;
476                                 if ((mattrs & MethodAttributes.Static) != 0) {
477                                         if ((bindingAttr & BindingFlags.Static) != 0)
478                                                 match = true;
479                                 } else {
480                                         if ((bindingAttr & BindingFlags.Instance) != 0)
481                                                 match = true;
482                                 }
483                                 if (!match)
484                                         continue;
485                                 l.Add (c);
486                         }
487                         PropertyInfo[] result = new PropertyInfo [l.Count];
488                         l.CopyTo (result);
489                         return result;
490                 }
491                 
492                 protected override PropertyInfo GetPropertyImpl( string name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers) {
493                         // FIXME
494                         throw new NotImplementedException ();
495                         return null;
496                 }
497
498                 protected override bool HasElementTypeImpl () {
499                         return IsArrayImpl() || IsByRefImpl() || IsPointerImpl ();
500                 }
501
502                 public override object InvokeMember( string name, BindingFlags invokeAttr, Binder binder, object target, object[] args, ParameterModifier[] modifiers, CultureInfo culture, string[] namedParameters) {
503                         // FIXME
504                         throw new NotImplementedException ();
505                         return null;
506                 }
507
508                 protected override bool IsArrayImpl () {
509                         // FIXME
510                         return false;
511                 }
512                 protected override bool IsByRefImpl () {
513                         // FIXME
514                         return false;
515                 }
516                 protected override bool IsCOMObjectImpl () {
517                         return false;
518                 }
519                 protected override bool IsPointerImpl () {
520                         // FIXME
521                         return false;
522                 }
523                 protected override bool IsPrimitiveImpl () {
524                         // FIXME
525                         return false;
526                 }
527                 protected override bool IsValueTypeImpl () {
528                         // test this one
529                         return type_is_subtype_of (this, typeof (System.ValueType), false);
530                 }
531                 
532                 public override RuntimeTypeHandle TypeHandle { get { return _impl; } }
533
534                 public void SetCustomAttribute( CustomAttributeBuilder customBuilder) {
535                         if (cattrs != null) {
536                                 CustomAttributeBuilder[] new_array = new CustomAttributeBuilder [cattrs.Length + 1];
537                                 cattrs.CopyTo (new_array, 0);
538                                 new_array [cattrs.Length] = customBuilder;
539                                 cattrs = new_array;
540                         } else {
541                                 cattrs = new CustomAttributeBuilder [1];
542                                 cattrs [0] = customBuilder;
543                         }
544                 }
545                 public void SetCustomAttribute( ConstructorInfo con, byte[] binaryAttribute) {
546                         SetCustomAttribute (new CustomAttributeBuilder (con, binaryAttribute));
547                 }
548
549                 public EventBuilder DefineEvent( string name, EventAttributes attributes, Type eventtype) {
550                         throw new NotImplementedException ();
551                 }
552
553                 static int InitializedDataCount = 0;
554                 
555                 public FieldBuilder DefineInitializedData( string name, byte[] data, FieldAttributes attributes) {
556                         TypeBuilder datablobtype = pmodule.DefineType ("$ArrayType$"+InitializedDataCount.ToString(),
557                                 TypeAttributes.Public|TypeAttributes.ExplicitLayout|TypeAttributes.Sealed,
558                                 typeof (System.ValueType), PackingSize.Size1, data.Length);
559                         datablobtype.packing_size = PackingSize.Size1;
560                         datablobtype.class_size = data.Length;
561                         datablobtype.CreateType ();
562                         FieldBuilder res = DefineField (name, datablobtype, attributes|FieldAttributes.Assembly|FieldAttributes.Static|FieldAttributes.HasFieldRVA);
563                         res.SetRVAData (data);
564                         InitializedDataCount++;
565                         return res;
566                 }
567
568                 public FieldBuilder DefineUninitializedData( string name, int size, FieldAttributes attributes) {
569                         throw new NotImplementedException ();
570                         return null;
571                 }
572
573                 public void SetParent (Type parentType) {
574                         parent = parentType;
575                 }
576                 internal int get_next_table_index (int table, bool inc) {
577                         return pmodule.get_next_table_index (table, inc);
578                 }
579
580         }
581 }