2 // System.Reflection.Emit/TypeBuilder.cs
5 // Paolo Molaro (lupus@ximian.com)
7 // (C) 2001 Ximian, Inc. http://www.ximian.com
11 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
13 // Permission is hereby granted, free of charge, to any person obtaining
14 // a copy of this software and associated documentation files (the
15 // "Software"), to deal in the Software without restriction, including
16 // without limitation the rights to use, copy, modify, merge, publish,
17 // distribute, sublicense, and/or sell copies of the Software, and to
18 // permit persons to whom the Software is furnished to do so, subject to
19 // the following conditions:
21 // The above copyright notice and this permission notice shall be
22 // included in all copies or substantial portions of the Software.
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
35 using System
.Reflection
;
36 using System
.Reflection
.Emit
;
37 using System
.Runtime
.CompilerServices
;
38 using System
.Runtime
.InteropServices
;
39 using System
.Globalization
;
40 using System
.Collections
;
41 using System
.Security
;
42 using System
.Security
.Permissions
;
44 namespace System
.Reflection
.Emit
{
46 public sealed class TypeBuilder
: Type
{
47 #region Sync with reflection.h
49 private string nspace
;
51 private Type nesting_type
;
52 private Type
[] interfaces
;
53 private int num_methods
;
54 private MethodBuilder
[] methods
;
55 private ConstructorBuilder
[] ctors
;
56 private PropertyBuilder
[] properties
;
57 private int num_fields
;
58 private FieldBuilder
[] fields
;
59 private EventBuilder
[] events
;
60 private CustomAttributeBuilder
[] cattrs
;
61 internal TypeBuilder
[] subtypes
;
62 internal TypeAttributes attrs
;
63 private int table_idx
;
64 private ModuleBuilder pmodule
;
65 private int class_size
;
66 private PackingSize packing_size
;
67 private IntPtr generic_container
;
68 #if NET_2_0 || BOOTSTRAP_NET_2_0
69 private GenericTypeParameterBuilder
[] generic_params
;
71 private Object generic_params
; /* so offsets don't change */
73 private RefEmitPermissionSet
[] permissions
;
78 public const int UnspecifiedTypeSize
= 0;
80 protected override TypeAttributes
GetAttributeFlagsImpl () {
84 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
85 private extern void setup_internal_class (TypeBuilder tb
);
87 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
88 private extern void create_internal_class (TypeBuilder tb
);
90 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
91 private extern void setup_generic_class ();
93 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
94 private extern void create_generic_class ();
96 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
97 private extern EventInfo
get_event_info (EventBuilder eb
);
99 internal TypeBuilder (ModuleBuilder mb
, TypeAttributes attr
) {
102 this.class_size
= UnspecifiedTypeSize
;
104 fullname
= this.tname
= "<Module>";
107 setup_internal_class (this);
110 internal TypeBuilder (ModuleBuilder mb
, string name
, TypeAttributes attr
, Type parent
, Type
[] interfaces
, PackingSize packing_size
, int type_size
, Type nesting_type
) {
112 this.parent
= parent
;
114 this.class_size
= type_size
;
115 this.packing_size
= packing_size
;
116 this.nesting_type
= nesting_type
;
117 sep_index
= name
.LastIndexOf('.');
118 if (sep_index
!= -1) {
119 this.tname
= name
.Substring (sep_index
+ 1);
120 this.nspace
= name
.Substring (0, sep_index
);
125 if (interfaces
!= null) {
126 this.interfaces
= new Type
[interfaces
.Length
];
127 System
.Array
.Copy (interfaces
, this.interfaces
, interfaces
.Length
);
131 table_idx
= mb
.get_next_table_index (this, 0x02, true);
132 setup_internal_class (this);
133 fullname
= GetFullName ();
136 public override Assembly Assembly
{
137 get {return pmodule.Assembly;}
140 public override string AssemblyQualifiedName
{
142 return fullname
+ ", " + Assembly
.GetName().FullName
;
145 public override Type BaseType
{
150 public override Type DeclaringType {get {return nesting_type;}}
152 /* public override bool IsSubclassOf (Type c)
169 public override Type UnderlyingSystemType
{
171 // This should return the type itself for non-enum types but
173 if (fields
!= null) {
174 foreach (FieldBuilder f
in fields
) {
175 if ((f
!= null) && (f
.Attributes
& FieldAttributes
.Static
) == 0)
179 throw new InvalidOperationException ("Underlying type information on enumeration is not specified.");
183 string GetFullName () {
184 if (nesting_type
!= null)
185 return String
.Concat (nesting_type
.FullName
, "+", tname
);
186 if ((nspace
!= null) && (nspace
.Length
> 0))
187 return String
.Concat (nspace
, ".", tname
);
191 public override string FullName
{
197 public override Guid GUID
{
204 public override Module Module
{
205 get {return pmodule;}
207 public override string Name
{
210 public override string Namespace
{
213 public PackingSize PackingSize
{
214 get {return packing_size;}
217 get { return class_size; }
219 public override Type ReflectedType {get {return nesting_type;}}
221 public void AddDeclarativeSecurity( SecurityAction action
, PermissionSet pset
) {
223 throw new ArgumentNullException ("pset");
224 if ((action
== SecurityAction
.RequestMinimum
) ||
225 (action
== SecurityAction
.RequestOptional
) ||
226 (action
== SecurityAction
.RequestRefuse
))
227 throw new ArgumentException ("Request* values are not permitted", "action");
229 check_not_created ();
231 if (permissions
!= null) {
232 /* Check duplicate actions */
233 foreach (RefEmitPermissionSet
set in permissions
)
234 if (set.action
== action
)
235 throw new InvalidOperationException ("Multiple permission sets specified with the same SecurityAction.");
237 RefEmitPermissionSet
[] new_array
= new RefEmitPermissionSet
[permissions
.Length
+ 1];
238 permissions
.CopyTo (new_array
, 0);
239 permissions
= new_array
;
242 permissions
= new RefEmitPermissionSet
[1];
244 permissions
[permissions
.Length
- 1] = new RefEmitPermissionSet (action
, pset
.ToXml ().ToString ());
245 attrs
|= TypeAttributes
.HasSecurity
;
248 public void AddInterfaceImplementation( Type interfaceType
) {
249 if (interfaceType
== null)
250 throw new ArgumentNullException ("interfaceType");
251 check_not_created ();
253 if (interfaces
!= null) {
254 // Check for duplicates
255 foreach (Type t
in interfaces
)
256 if (t
== interfaceType
)
259 Type
[] ifnew
= new Type
[interfaces
.Length
+ 1];
260 interfaces
.CopyTo (ifnew
, 0);
261 ifnew
[interfaces
.Length
] = interfaceType
;
264 interfaces
= new Type
[1];
265 interfaces
[0] = interfaceType
;
270 protected override ConstructorInfo
GetConstructorImpl (BindingFlags bindingAttr
, Binder binder
,
271 CallingConventions callConvention
, Type
[] types
,
272 ParameterModifier
[] modifiers
)
277 ConstructorBuilder found
= null;
280 foreach (ConstructorBuilder cb
in ctors
){
281 if (callConvention
!= CallingConventions
.Any
&& cb
.CallingConvention
!= callConvention
)
291 throw new AmbiguousMatchException ();
294 MethodBase
[] match
= new MethodBase
[count
];
299 foreach (ConstructorInfo m
in ctors
) {
300 if (callConvention
!= CallingConventions
.Any
&& m
.CallingConvention
!= callConvention
)
306 binder
= Binder
.DefaultBinder
;
307 return (ConstructorInfo
)binder
.SelectMethod (bindingAttr
, match
, types
, modifiers
);
310 public override bool IsDefined( Type attributeType
, bool inherit
)
313 * MS throws NotSupported here, but we can't because some corlib
314 * classes make calls to IsDefined.
316 return MonoCustomAttrs
.IsDefined (this, attributeType
, inherit
);
319 public override object[] GetCustomAttributes(bool inherit
)
323 return created
.GetCustomAttributes (inherit
);
326 public override object[] GetCustomAttributes(Type attributeType
, bool inherit
)
330 return created
.GetCustomAttributes (attributeType
, inherit
);
333 public TypeBuilder
DefineNestedType (string name
) {
334 return DefineNestedType (name
, TypeAttributes
.NestedPrivate
, pmodule
.assemblyb
.corlib_object_type
, null);
337 public TypeBuilder
DefineNestedType (string name
, TypeAttributes attr
) {
338 return DefineNestedType (name
, attr
, pmodule
.assemblyb
.corlib_object_type
, null);
341 public TypeBuilder
DefineNestedType (string name
, TypeAttributes attr
, Type parent
) {
342 return DefineNestedType (name
, attr
, parent
, null);
345 private TypeBuilder
DefineNestedType (string name
, TypeAttributes attr
, Type parent
, Type
[] interfaces
,
346 PackingSize packsize
, int typesize
)
348 check_name ("name", name
);
349 // Visibility must be NestedXXX
351 if (((attrs & TypeAttributes.VisibilityMask) == TypeAttributes.Public) ||
352 ((attrs & TypeAttributes.VisibilityMask) == TypeAttributes.NotPublic))
353 throw new ArgumentException ("attr", "Bad type flags for nested type.");
355 if (interfaces
!= null)
356 foreach (Type iface
in interfaces
)
358 throw new ArgumentNullException ("interfaces");
360 TypeBuilder res
= new TypeBuilder (pmodule
, name
, attr
, parent
, interfaces
, packsize
, typesize
, this);
361 res
.fullname
= res
.GetFullName ();
362 pmodule
.RegisterTypeName (res
, res
.fullname
);
363 if (subtypes
!= null) {
364 TypeBuilder
[] new_types
= new TypeBuilder
[subtypes
.Length
+ 1];
365 System
.Array
.Copy (subtypes
, new_types
, subtypes
.Length
);
366 new_types
[subtypes
.Length
] = res
;
367 subtypes
= new_types
;
369 subtypes
= new TypeBuilder
[1];
375 public TypeBuilder
DefineNestedType (string name
, TypeAttributes attr
, Type parent
, Type
[] interfaces
) {
376 return DefineNestedType (name
, attr
, parent
, interfaces
, PackingSize
.Unspecified
, UnspecifiedTypeSize
);
379 public TypeBuilder
DefineNestedType (string name
, TypeAttributes attr
, Type parent
, int typesize
) {
380 return DefineNestedType (name
, attr
, parent
, null, PackingSize
.Unspecified
, typesize
);
383 public TypeBuilder
DefineNestedType (string name
, TypeAttributes attr
, Type parent
, PackingSize packsize
) {
384 return DefineNestedType (name
, attr
, parent
, null, packsize
, UnspecifiedTypeSize
);
387 public ConstructorBuilder
DefineConstructor (MethodAttributes attributes
, CallingConventions callingConvention
, Type
[] parameterTypes
) {
388 return DefineConstructor (attributes
, callingConvention
, parameterTypes
, null, null);
391 #if NET_2_0 || BOOTSTRAP_NET_2_0
396 ConstructorBuilder
DefineConstructor (MethodAttributes attributes
, CallingConventions callingConvention
, Type
[] parameterTypes
, Type
[][] requiredCustomModifiers
, Type
[][] optionalCustomModifiers
)
398 check_not_created ();
399 ConstructorBuilder cb
= new ConstructorBuilder (this, attributes
, callingConvention
, parameterTypes
, requiredCustomModifiers
, optionalCustomModifiers
);
401 ConstructorBuilder
[] new_ctors
= new ConstructorBuilder
[ctors
.Length
+1];
402 System
.Array
.Copy (ctors
, new_ctors
, ctors
.Length
);
403 new_ctors
[ctors
.Length
] = cb
;
406 ctors
= new ConstructorBuilder
[1];
412 public ConstructorBuilder
DefineDefaultConstructor (MethodAttributes attributes
)
417 parent_type
= parent
;
419 parent_type
= pmodule
.assemblyb
.corlib_object_type
;
421 ConstructorInfo parent_constructor
=
422 parent_type
.GetConstructor (
423 BindingFlags
.Public
| BindingFlags
.NonPublic
| BindingFlags
.Instance
,
424 null, Type
.EmptyTypes
, null);
425 if (parent_constructor
== null) {
426 throw new NotSupportedException ("Parent does"
427 + " not have a default constructor."
428 + " The default constructor must be"
429 + " explicitly defined.");
432 ConstructorBuilder cb
= DefineConstructor (attributes
,
433 CallingConventions
.Standard
, new Type
[0]);
434 ILGenerator ig
= cb
.GetILGenerator ();
435 ig
.Emit (OpCodes
.Ldarg_0
);
436 ig
.Emit (OpCodes
.Call
, parent_constructor
);
437 ig
.Emit (OpCodes
.Ret
);
441 public MethodBuilder
DefineMethod( string name
, MethodAttributes attributes
, Type returnType
, Type
[] parameterTypes
) {
442 return DefineMethod (name
, attributes
, CallingConventions
.Standard
, returnType
, parameterTypes
);
445 private void append_method (MethodBuilder mb
) {
446 if (methods
!= null) {
447 if (methods
.Length
== num_methods
) {
448 MethodBuilder
[] new_methods
= new MethodBuilder
[methods
.Length
* 2];
449 System
.Array
.Copy (methods
, new_methods
, num_methods
);
450 methods
= new_methods
;
453 methods
= new MethodBuilder
[1];
455 methods
[num_methods
] = mb
;
459 public MethodBuilder
DefineMethod( string name
, MethodAttributes attributes
, CallingConventions callingConvention
, Type returnType
, Type
[] parameterTypes
) {
460 return DefineMethod (name
, attributes
, callingConvention
, returnType
, null, null, parameterTypes
, null, null);
463 #if NET_2_0 || BOOTSTRAP_NET_2_0
468 MethodBuilder
DefineMethod( string name
, MethodAttributes attributes
, CallingConventions callingConvention
, Type returnType
, Type
[] returnTypeRequiredCustomModifiers
, Type
[] returnTypeOptionalCustomModifiers
, Type
[] parameterTypes
, Type
[][] parameterTypeRequiredCustomModifiers
, Type
[][] parameterTypeOptionalCustomModifiers
) {
469 check_name ("name", name
);
470 check_not_created ();
472 !((attributes
& MethodAttributes
.Abstract
) != 0) ||
473 !((attributes
& MethodAttributes
.Virtual
) != 0)))
474 throw new ArgumentException ("attributes", "Interface method must be abstract and virtual.");
476 if (returnType
== null)
477 returnType
= pmodule
.assemblyb
.corlib_void_type
;
478 MethodBuilder res
= new MethodBuilder (this, name
, attributes
, callingConvention
, returnType
, returnTypeRequiredCustomModifiers
, returnTypeOptionalCustomModifiers
, parameterTypes
, parameterTypeRequiredCustomModifiers
, parameterTypeOptionalCustomModifiers
);
483 public MethodBuilder
DefinePInvokeMethod (string name
, string dllName
, string entryName
, MethodAttributes attributes
, CallingConventions callingConvention
, Type returnType
, Type
[] parameterTypes
, CallingConvention nativeCallConv
, CharSet nativeCharSet
) {
484 return DefinePInvokeMethod (name
, dllName
, entryName
, attributes
, callingConvention
, returnType
, null, null, parameterTypes
, null, null, nativeCallConv
, nativeCharSet
);
487 #if NET_2_0 || BOOTSTRAP_NET_2_0
492 MethodBuilder
DefinePInvokeMethod (
495 string entryName
, MethodAttributes attributes
,
496 CallingConventions callingConvention
,
498 Type
[] returnTypeRequiredCustomModifiers
,
499 Type
[] returnTypeOptionalCustomModifiers
,
500 Type
[] parameterTypes
,
501 Type
[][] parameterTypeRequiredCustomModifiers
,
502 Type
[][] parameterTypeOptionalCustomModifiers
,
503 CallingConvention nativeCallConv
,
504 CharSet nativeCharSet
) {
505 check_name ("name", name
);
506 check_name ("dllName", dllName
);
507 check_name ("entryName", entryName
);
508 if ((attributes
& MethodAttributes
.Abstract
) != 0)
509 throw new ArgumentException ("attributes", "PInvoke methods must be static and native and cannot be abstract.");
511 throw new ArgumentException ("PInvoke methods cannot exist on interfaces.");
512 check_not_created ();
515 = new MethodBuilder (
521 returnTypeRequiredCustomModifiers
,
522 returnTypeOptionalCustomModifiers
,
524 parameterTypeRequiredCustomModifiers
,
525 parameterTypeOptionalCustomModifiers
,
534 public MethodBuilder
DefinePInvokeMethod (string name
, string dllName
, MethodAttributes attributes
, CallingConventions callingConvention
, Type returnType
, Type
[] parameterTypes
, CallingConvention nativeCallConv
, CharSet nativeCharSet
) {
535 return DefinePInvokeMethod (name
, dllName
, name
, attributes
, callingConvention
, returnType
, parameterTypes
,
536 nativeCallConv
, nativeCharSet
);
539 public void DefineMethodOverride( MethodInfo methodInfoBody
, MethodInfo methodInfoDeclaration
) {
540 if (methodInfoBody
== null)
541 throw new ArgumentNullException ("methodInfoBody");
542 if (methodInfoDeclaration
== null)
543 throw new ArgumentNullException ("methodInfoDeclaration");
544 check_not_created ();
546 if (methodInfoBody
is MethodBuilder
) {
547 MethodBuilder mb
= (MethodBuilder
)methodInfoBody
;
548 mb
.set_override (methodInfoDeclaration
);
552 public FieldBuilder
DefineField( string fieldName
, Type type
, FieldAttributes attributes
) {
553 return DefineField (fieldName
, type
, null, null, attributes
);
556 #if NET_2_0 || BOOTSTRAP_NET_2_0
561 FieldBuilder
DefineField (string fieldName
, Type type
, Type
[] requiredCustomAttributes
, Type
[] optionalCustomAttributes
, FieldAttributes attributes
) {
562 check_name ("fieldName", fieldName
);
563 if (type
== typeof (void))
564 throw new ArgumentException ("type", "Bad field type in defining field.");
565 check_not_created ();
567 FieldBuilder res
= new FieldBuilder (this, fieldName
, type
, attributes
, requiredCustomAttributes
, optionalCustomAttributes
);
568 if (fields
!= null) {
569 if (fields
.Length
== num_fields
) {
570 FieldBuilder
[] new_fields
= new FieldBuilder
[fields
.Length
* 2];
571 System
.Array
.Copy (fields
, new_fields
, num_fields
);
574 fields
[num_fields
] = res
;
577 fields
= new FieldBuilder
[1];
580 create_internal_class (this);
585 public PropertyBuilder
DefineProperty( string name
, PropertyAttributes attributes
, Type returnType
, Type
[] parameterTypes
) {
586 check_name ("name", name
);
587 if (parameterTypes
!= null)
588 foreach (Type param
in parameterTypes
)
590 throw new ArgumentNullException ("parameterTypes");
591 check_not_created ();
593 PropertyBuilder res
= new PropertyBuilder (this, name
, attributes
, returnType
, parameterTypes
);
595 if (properties
!= null) {
596 PropertyBuilder
[] new_properties
= new PropertyBuilder
[properties
.Length
+1];
597 System
.Array
.Copy (properties
, new_properties
, properties
.Length
);
598 new_properties
[properties
.Length
] = res
;
599 properties
= new_properties
;
601 properties
= new PropertyBuilder
[1];
602 properties
[0] = res
;
607 public ConstructorBuilder
DefineTypeInitializer() {
608 return DefineConstructor (MethodAttributes
.Public
| MethodAttributes
.Static
| MethodAttributes
.SpecialName
| MethodAttributes
.RTSpecialName
, CallingConventions
.Standard
, null);
611 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
612 private extern Type
create_runtime_class (TypeBuilder tb
);
614 private bool is_nested_in (Type t
) {
624 public Type
CreateType() {
625 /* handle nesting_type */
626 check_not_created ();
628 // Fire TypeResolve events for fields whose type is an unfinished
630 if (fields
!= null) {
631 foreach (FieldBuilder fb
in fields
) {
634 Type ft
= fb
.FieldType
;
635 if (!fb
.IsStatic
&& (ft
is TypeBuilder
) && ft
.IsValueType
&& (ft
!= this) && is_nested_in (ft
)) {
636 TypeBuilder tb
= (TypeBuilder
)ft
;
637 if (!tb
.is_created
) {
638 AppDomain
.CurrentDomain
.DoTypeResolve (tb
);
639 if (!tb
.is_created
) {
640 // FIXME: We should throw an exception here,
641 // but mcs expects that the type is created
642 // even if the exception is thrown
643 //throw new TypeLoadException ("Could not load type " + tb);
650 if (methods
!= null) {
651 for (int i
= 0; i
< num_methods
; ++i
)
652 ((MethodBuilder
)(methods
[i
])).fixup ();
656 // On classes, define a default constructor if not provided
658 if (!(IsInterface
|| IsValueType
) && (ctors
== null) && (tname
!= "<Module>") &&
659 (GetAttributeFlagsImpl () & TypeAttributes
.Abstract
| TypeAttributes
.Sealed
) != (TypeAttributes
.Abstract
| TypeAttributes
.Sealed
))
660 DefineDefaultConstructor (MethodAttributes
.Public
);
663 foreach (ConstructorBuilder ctor
in ctors
)
667 created
= create_runtime_class (this);
673 public override ConstructorInfo
[] GetConstructors (BindingFlags bindingAttr
)
676 return new ConstructorInfo
[0];
677 ArrayList l
= new ArrayList ();
679 MethodAttributes mattrs
;
681 foreach (ConstructorBuilder c
in ctors
) {
683 mattrs
= c
.Attributes
;
684 if ((mattrs
& MethodAttributes
.MemberAccessMask
) == MethodAttributes
.Public
) {
685 if ((bindingAttr
& BindingFlags
.Public
) != 0)
688 if ((bindingAttr
& BindingFlags
.NonPublic
) != 0)
694 if ((mattrs
& MethodAttributes
.Static
) != 0) {
695 if ((bindingAttr
& BindingFlags
.Static
) != 0)
698 if ((bindingAttr
& BindingFlags
.Instance
) != 0)
705 ConstructorInfo
[] result
= new ConstructorInfo
[l
.Count
];
710 public override Type
GetElementType () {
712 return created
.GetElementType ();
715 public override EventInfo
GetEvent (string name
, BindingFlags bindingAttr
) {
717 return created
.GetEvent (name
, bindingAttr
);
720 /* Needed to keep signature compatibility with MS.NET */
721 public override EventInfo
[] GetEvents ()
723 return GetEvents (DefaultBindingFlags
);
726 public override EventInfo
[] GetEvents (BindingFlags bindingAttr
) {
727 /* FIXME: mcs calls this
731 return new EventInfo
[0];
733 return created
.GetEvents (bindingAttr
);
736 // This is only used from MonoGenericInst.initialize().
737 internal EventInfo
[] GetEvents_internal (BindingFlags bindingAttr
)
740 return new EventInfo
[0];
741 ArrayList l
= new ArrayList ();
743 MethodAttributes mattrs
;
746 foreach (EventBuilder eb
in events
) {
749 EventInfo c
= get_event_info (eb
);
751 accessor
= c
.GetAddMethod (true);
752 if (accessor
== null)
753 accessor
= c
.GetRemoveMethod (true);
754 if (accessor
== null)
756 mattrs
= accessor
.Attributes
;
757 if ((mattrs
& MethodAttributes
.MemberAccessMask
) == MethodAttributes
.Public
) {
758 if ((bindingAttr
& BindingFlags
.Public
) != 0)
761 if ((bindingAttr
& BindingFlags
.NonPublic
) != 0)
767 if ((mattrs
& MethodAttributes
.Static
) != 0) {
768 if ((bindingAttr
& BindingFlags
.Static
) != 0)
771 if ((bindingAttr
& BindingFlags
.Instance
) != 0)
778 EventInfo
[] result
= new EventInfo
[l
.Count
];
783 public override FieldInfo
GetField( string name
, BindingFlags bindingAttr
) {
788 FieldAttributes mattrs
;
790 foreach (FieldInfo c
in fields
) {
796 mattrs
= c
.Attributes
;
797 if ((mattrs
& FieldAttributes
.FieldAccessMask
) == FieldAttributes
.Public
) {
798 if ((bindingAttr
& BindingFlags
.Public
) != 0)
801 if ((bindingAttr
& BindingFlags
.NonPublic
) != 0)
807 if ((mattrs
& FieldAttributes
.Static
) != 0) {
808 if ((bindingAttr
& BindingFlags
.Static
) != 0)
811 if ((bindingAttr
& BindingFlags
.Instance
) != 0)
821 public override FieldInfo
[] GetFields (BindingFlags bindingAttr
) {
823 return new FieldInfo
[0];
824 ArrayList l
= new ArrayList ();
826 FieldAttributes mattrs
;
828 foreach (FieldInfo c
in fields
) {
832 mattrs
= c
.Attributes
;
833 if ((mattrs
& FieldAttributes
.FieldAccessMask
) == FieldAttributes
.Public
) {
834 if ((bindingAttr
& BindingFlags
.Public
) != 0)
837 if ((bindingAttr
& BindingFlags
.NonPublic
) != 0)
843 if ((mattrs
& FieldAttributes
.Static
) != 0) {
844 if ((bindingAttr
& BindingFlags
.Static
) != 0)
847 if ((bindingAttr
& BindingFlags
.Instance
) != 0)
854 FieldInfo
[] result
= new FieldInfo
[l
.Count
];
859 public override Type
GetInterface (string name
, bool ignoreCase
) {
861 return created
.GetInterface (name
, ignoreCase
);
864 public override Type
[] GetInterfaces () {
865 if (interfaces
!= null) {
866 Type
[] ret
= new Type
[interfaces
.Length
];
867 interfaces
.CopyTo (ret
, 0);
870 return Type
.EmptyTypes
;
874 public override MemberInfo
[] GetMember (string name
, MemberTypes type
,
875 BindingFlags bindingAttr
) {
877 return created
.GetMember (name
, type
, bindingAttr
);
880 public override MemberInfo
[] GetMembers (BindingFlags bindingAttr
) {
882 return created
.GetMembers (bindingAttr
);
885 private MethodInfo
[] GetMethodsByName (string name
, BindingFlags bindingAttr
, bool ignoreCase
, Type reflected_type
) {
886 MethodInfo
[] candidates
;
887 if (((bindingAttr
& BindingFlags
.DeclaredOnly
) == 0) && (parent
!= null)) {
888 MethodInfo
[] parent_methods
= parent
.GetMethods (bindingAttr
);
890 candidates
= parent_methods
;
892 candidates
= new MethodInfo
[methods
.Length
+ parent_methods
.Length
];
893 parent_methods
.CopyTo (candidates
, 0);
894 methods
.CopyTo (candidates
, parent_methods
.Length
);
898 candidates
= methods
;
900 if (candidates
== null)
901 return new MethodInfo
[0];
903 ArrayList l
= new ArrayList ();
905 MethodAttributes mattrs
;
907 foreach (MethodInfo c
in candidates
) {
911 if (String
.Compare (c
.Name
, name
, ignoreCase
) != 0)
915 mattrs
= c
.Attributes
;
916 if ((mattrs
& MethodAttributes
.MemberAccessMask
) == MethodAttributes
.Public
) {
917 if ((bindingAttr
& BindingFlags
.Public
) != 0)
920 if ((bindingAttr
& BindingFlags
.NonPublic
) != 0)
926 if ((mattrs
& MethodAttributes
.Static
) != 0) {
927 if ((bindingAttr
& BindingFlags
.Static
) != 0)
930 if ((bindingAttr
& BindingFlags
.Instance
) != 0)
938 MethodInfo
[] result
= new MethodInfo
[l
.Count
];
943 public override MethodInfo
[] GetMethods (BindingFlags bindingAttr
) {
944 return GetMethodsByName (null, bindingAttr
, false, this);
947 protected override MethodInfo
GetMethodImpl (string name
, BindingFlags bindingAttr
,
949 CallingConventions callConvention
,
950 Type
[] types
, ParameterModifier
[] modifiers
)
954 bool ignoreCase
= ((bindingAttr
& BindingFlags
.IgnoreCase
) != 0);
955 MethodInfo
[] methods
= GetMethodsByName (name
, bindingAttr
, ignoreCase
, this);
956 MethodInfo found
= null;
958 int typesLen
= (types
!= null) ? types
.Length
: 0;
961 foreach (MethodInfo m
in methods
) {
962 // Under MS.NET, Standard|HasThis matches Standard...
963 if (callConvention
!= CallingConventions
.Any
&& ((m
.CallingConvention
& callConvention
) != callConvention
))
972 if (count
== 1 && typesLen
== 0)
975 match
= new MethodBase
[count
];
980 foreach (MethodInfo m
in methods
) {
981 if (callConvention
!= CallingConventions
.Any
&& ((m
.CallingConvention
& callConvention
) != callConvention
))
988 return (MethodInfo
) Binder
.FindMostDerivedMatch (match
);
991 binder
= Binder
.DefaultBinder
;
993 return (MethodInfo
)binder
.SelectMethod (bindingAttr
, match
, types
, modifiers
);
996 public override Type
GetNestedType( string name
, BindingFlags bindingAttr
) {
998 return created
.GetNestedType (name
, bindingAttr
);
1001 public override Type
[] GetNestedTypes (BindingFlags bindingAttr
) {
1003 ArrayList result
= new ArrayList ();
1005 if (subtypes
== null)
1006 return Type
.EmptyTypes
;
1007 foreach (TypeBuilder t
in subtypes
) {
1009 if ((t
.attrs
& TypeAttributes
.VisibilityMask
) == TypeAttributes
.NestedPublic
) {
1010 if ((bindingAttr
& BindingFlags
.Public
) != 0)
1013 if ((bindingAttr
& BindingFlags
.NonPublic
) != 0)
1020 Type
[] r
= new Type
[result
.Count
];
1025 public override PropertyInfo
[] GetProperties( BindingFlags bindingAttr
) {
1026 if (properties
== null)
1027 return new PropertyInfo
[0];
1028 ArrayList l
= new ArrayList ();
1030 MethodAttributes mattrs
;
1031 MethodInfo accessor
;
1033 foreach (PropertyInfo c
in properties
) {
1035 accessor
= c
.GetGetMethod (true);
1036 if (accessor
== null)
1037 accessor
= c
.GetSetMethod (true);
1038 if (accessor
== null)
1040 mattrs
= accessor
.Attributes
;
1041 if ((mattrs
& MethodAttributes
.MemberAccessMask
) == MethodAttributes
.Public
) {
1042 if ((bindingAttr
& BindingFlags
.Public
) != 0)
1045 if ((bindingAttr
& BindingFlags
.NonPublic
) != 0)
1051 if ((mattrs
& MethodAttributes
.Static
) != 0) {
1052 if ((bindingAttr
& BindingFlags
.Static
) != 0)
1055 if ((bindingAttr
& BindingFlags
.Instance
) != 0)
1062 PropertyInfo
[] result
= new PropertyInfo
[l
.Count
];
1067 protected override PropertyInfo
GetPropertyImpl( string name
, BindingFlags bindingAttr
, Binder binder
, Type returnType
, Type
[] types
, ParameterModifier
[] modifiers
) {
1068 throw not_supported ();
1071 protected override bool HasElementTypeImpl () {
1073 return created
.HasElementType
;
1076 public override object InvokeMember( string name
, BindingFlags invokeAttr
, Binder binder
, object target
, object[] args
, ParameterModifier
[] modifiers
, CultureInfo culture
, string[] namedParameters
) {
1078 return created
.InvokeMember (name
, invokeAttr
, binder
, target
, args
, modifiers
, culture
, namedParameters
);
1081 protected override bool IsArrayImpl ()
1083 return Type
.IsArrayImpl (this);
1086 protected override bool IsByRefImpl () {
1090 protected override bool IsCOMObjectImpl () {
1093 protected override bool IsPointerImpl () {
1097 protected override bool IsPrimitiveImpl () {
1101 protected override bool IsValueTypeImpl () {
1102 return ((type_is_subtype_of (this, pmodule
.assemblyb
.corlib_value_type
, false) || type_is_subtype_of (this, typeof(System
.ValueType
), false)) &&
1103 this != pmodule
.assemblyb
.corlib_value_type
&&
1104 this != pmodule
.assemblyb
.corlib_enum_type
);
1107 public override RuntimeTypeHandle TypeHandle
{
1110 return created
.TypeHandle
;
1114 public void SetCustomAttribute( CustomAttributeBuilder customBuilder
) {
1115 if (customBuilder
== null)
1116 throw new ArgumentNullException ("customBuilder");
1118 string attrname
= customBuilder
.Ctor
.ReflectedType
.FullName
;
1119 if (attrname
== "System.Runtime.InteropServices.StructLayoutAttribute") {
1120 byte[] data
= customBuilder
.Data
;
1121 int layout_kind
; /* the (stupid) ctor takes a short or an int ... */
1122 layout_kind
= (int)data
[2];
1123 layout_kind
|= ((int)data
[3]) << 8;
1124 attrs
&= ~TypeAttributes
.LayoutMask
;
1125 switch ((LayoutKind
)layout_kind
) {
1126 case LayoutKind
.Auto
:
1127 attrs
|= TypeAttributes
.AutoLayout
;
1129 case LayoutKind
.Explicit
:
1130 attrs
|= TypeAttributes
.ExplicitLayout
;
1132 case LayoutKind
.Sequential
:
1133 attrs
|= TypeAttributes
.SequentialLayout
;
1136 // we should ignore it since it can be any value anyway...
1137 throw new Exception ("Error in customattr");
1139 string first_type_name
= customBuilder
.Ctor
.GetParameters()[0].ParameterType
.FullName
;
1141 if (first_type_name
== "System.Int16")
1143 int nnamed
= (int)data
[pos
++];
1144 nnamed
|= ((int)data
[pos
++]) << 8;
1145 for (int i
= 0; i
< nnamed
; ++i
) {
1146 byte named_type
= data
[pos
++];
1147 byte type
= data
[pos
++];
1152 len
= CustomAttributeBuilder
.decode_len (data
, pos
, out pos
);
1153 string named_typename
= CustomAttributeBuilder
.string_from_bytes (data
, pos
, len
);
1155 // FIXME: Check that 'named_type' and 'named_typename' match, etc.
1156 // See related code/FIXME in mono/mono/metadata/reflection.c
1159 len
= CustomAttributeBuilder
.decode_len (data
, pos
, out pos
);
1160 named_name
= CustomAttributeBuilder
.string_from_bytes (data
, pos
, len
);
1162 /* all the fields are integers in StructLayout */
1163 int value = (int)data
[pos
++];
1164 value |= ((int)data
[pos
++]) << 8;
1165 value |= ((int)data
[pos
++]) << 16;
1166 value |= ((int)data
[pos
++]) << 24;
1167 switch (named_name
) {
1169 switch ((CharSet
)value) {
1173 case CharSet
.Unicode
:
1174 attrs
|= TypeAttributes
.UnicodeClass
;
1177 attrs
|= TypeAttributes
.AutoClass
;
1180 break; // error out...
1184 packing_size
= (PackingSize
)value;
1190 break; // error out...
1194 } else if (attrname
== "System.SerializableAttribute") {
1195 attrs
|= TypeAttributes
.Serializable
;
1198 if (cattrs
!= null) {
1199 CustomAttributeBuilder
[] new_array
= new CustomAttributeBuilder
[cattrs
.Length
+ 1];
1200 cattrs
.CopyTo (new_array
, 0);
1201 new_array
[cattrs
.Length
] = customBuilder
;
1204 cattrs
= new CustomAttributeBuilder
[1];
1205 cattrs
[0] = customBuilder
;
1208 public void SetCustomAttribute( ConstructorInfo con
, byte[] binaryAttribute
) {
1209 SetCustomAttribute (new CustomAttributeBuilder (con
, binaryAttribute
));
1212 public EventBuilder
DefineEvent( string name
, EventAttributes attributes
, Type eventtype
) {
1213 check_name ("name", name
);
1214 if (eventtype
== null)
1215 throw new ArgumentNullException ("eventtype");
1216 check_not_created ();
1218 EventBuilder res
= new EventBuilder (this, name
, attributes
, eventtype
);
1219 if (events
!= null) {
1220 EventBuilder
[] new_events
= new EventBuilder
[events
.Length
+1];
1221 System
.Array
.Copy (events
, new_events
, events
.Length
);
1222 new_events
[events
.Length
] = res
;
1223 events
= new_events
;
1225 events
= new EventBuilder
[1];
1231 public FieldBuilder
DefineInitializedData( string name
, byte[] data
, FieldAttributes attributes
) {
1233 throw new ArgumentNullException ("data");
1234 if ((data
.Length
== 0) || (data
.Length
> 0x3f0000))
1235 throw new ArgumentException ("data", "Data size must be > 0 and < 0x3f0000");
1237 FieldBuilder res
= DefineUninitializedData (name
, data
.Length
, attributes
);
1238 res
.SetRVAData (data
);
1243 static int UnmanagedDataCount
= 0;
1245 public FieldBuilder
DefineUninitializedData( string name
, int size
, FieldAttributes attributes
) {
1246 check_name ("name", name
);
1247 if ((size
<= 0) || (size
> 0x3f0000))
1248 throw new ArgumentException ("size", "Data size must be > 0 and < 0x3f0000");
1249 check_not_created ();
1251 string s
= "$ArrayType$"+UnmanagedDataCount
.ToString();
1252 UnmanagedDataCount
++;
1253 TypeBuilder datablobtype
= DefineNestedType (s
,
1254 TypeAttributes
.NestedPrivate
|TypeAttributes
.ExplicitLayout
|TypeAttributes
.Sealed
,
1255 pmodule
.assemblyb
.corlib_value_type
, null, PackingSize
.Size1
, size
);
1256 datablobtype
.CreateType ();
1257 return DefineField (name
, datablobtype
, attributes
|FieldAttributes
.Static
|FieldAttributes
.HasFieldRVA
);
1260 public TypeToken TypeToken
{
1262 return new TypeToken (0x02000000 | table_idx
);
1265 public void SetParent (Type parentType
) {
1266 if (parentType
== null)
1267 throw new ArgumentNullException ("parentType");
1268 check_not_created ();
1270 parent
= parentType
;
1271 // will just set the parent-related bits if called a second time
1272 setup_internal_class (this);
1274 internal int get_next_table_index (object obj
, int table
, bool inc
) {
1275 return pmodule
.get_next_table_index (obj
, table
, inc
);
1278 public override InterfaceMapping
GetInterfaceMap (Type interfaceType
)
1280 if (created
== null)
1281 throw new NotSupportedException ("This method is not implemented for incomplete types.");
1283 return created
.GetInterfaceMap (interfaceType
);
1286 internal bool is_created
{
1288 return created
!= null;
1292 private Exception
not_supported ()
1294 return new NotSupportedException ("The invoked member is not supported in a dynamic module.");
1297 private void check_not_created ()
1300 throw new InvalidOperationException ("Unable to change after type has been created.");
1303 private void check_created ()
1306 throw not_supported ();
1309 private void check_name (string argName
, string name
)
1312 throw new ArgumentNullException (argName
);
1314 throw new ArgumentException (argName
, "Empty name is not legal.");
1315 if (name
.IndexOf ((char)0) != -1)
1316 throw new ArgumentException (argName
, "Illegal name.");
1319 public override String
ToString ()
1325 public override bool IsAssignableFrom (Type c
)
1327 return base.IsAssignableFrom (c
);
1331 public override bool IsSubclassOf (Type c
)
1333 return base.IsSubclassOf (c
);
1336 #if NET_2_0 || BOOTSTRAP_NET_2_0
1337 public bool IsCreated () {
1341 public override Type
[] GetGenericArguments ()
1343 if (generic_params
!= null)
1344 return generic_params
;
1346 throw new InvalidOperationException ();
1349 public override Type
GetGenericTypeDefinition ()
1351 create_generic_class ();
1353 return base.GetGenericTypeDefinition ();
1356 public override bool HasGenericArguments
{
1358 throw new NotImplementedException ();
1362 public override bool ContainsGenericParameters
{
1364 return generic_params
!= null;
1368 public extern override bool IsGenericParameter
{
1369 [MethodImplAttribute(MethodImplOptions
.InternalCall
)]
1373 public override int GenericParameterPosition
{
1375 throw new NotImplementedException ();
1379 public override MethodInfo DeclaringMethod
{
1381 throw new NotImplementedException ();
1385 public GenericTypeParameterBuilder
[] DefineGenericParameters (string[] names
)
1387 setup_generic_class ();
1389 generic_params
= new GenericTypeParameterBuilder
[names
.Length
];
1390 for (int i
= 0; i
< names
.Length
; i
++)
1391 generic_params
[i
] = new GenericTypeParameterBuilder (
1392 this, null, names
[i
], i
);
1394 return generic_params
;
1397 public MethodBuilder
DefineGenericMethod (string name
, MethodAttributes attributes
)
1399 return DefineMethod (name
, attributes
, CallingConventions
.Standard
, null, null);