X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fclass%2Fcorlib%2FSystem.Reflection.Emit%2FTypeBuilder.cs;h=88409ed5fe5ce966c2e3b4a95fa7b411662ec7bd;hb=7d136a86ab14cdc8eb8804171d2b6c8d1a059893;hp=e5eaaad1cb32abab714d73e58a21f4589e420204;hpb=64c394f419b4971075030ecf5d455d08b229ce6e;p=mono.git diff --git a/mcs/class/corlib/System.Reflection.Emit/TypeBuilder.cs b/mcs/class/corlib/System.Reflection.Emit/TypeBuilder.cs index e5eaaad1cb3..88409ed5fe5 100644 --- a/mcs/class/corlib/System.Reflection.Emit/TypeBuilder.cs +++ b/mcs/class/corlib/System.Reflection.Emit/TypeBuilder.cs @@ -1,5 +1,5 @@ // -// System.Reflection.Emit/TypeBuilder.cs +// System.Reflection.Emit.TypeBuilder.cs // // Author: // Paolo Molaro (lupus@ximian.com) @@ -43,47 +43,52 @@ using System.Security; using System.Security.Permissions; using System.Diagnostics.SymbolStore; -namespace System.Reflection.Emit { +namespace System.Reflection.Emit +{ #if NET_2_0 [ComVisible (true)] [ComDefaultInterface (typeof (_TypeBuilder))] #endif [ClassInterface (ClassInterfaceType.None)] - public sealed class TypeBuilder : Type, _TypeBuilder { - #region Sync with reflection.h - private string tname; - private string nspace; - private Type parent; - private Type nesting_type; - private Type[] interfaces; - private int num_methods; - private MethodBuilder[] methods; - private ConstructorBuilder[] ctors; - private PropertyBuilder[] properties; - private int num_fields; - private FieldBuilder[] fields; - private EventBuilder[] events; - private CustomAttributeBuilder[] cattrs; - internal TypeBuilder[] subtypes; - internal TypeAttributes attrs; - private int table_idx; - private ModuleBuilder pmodule; - private int class_size; - private PackingSize packing_size; - private IntPtr generic_container; + public sealed class TypeBuilder : Type, _TypeBuilder + { + #region Sync with reflection.h + private string tname; + private string nspace; + private Type parent; + private Type nesting_type; + private Type[] interfaces; + private int num_methods; + private MethodBuilder[] methods; + private ConstructorBuilder[] ctors; + private PropertyBuilder[] properties; + private int num_fields; + private FieldBuilder[] fields; + private EventBuilder[] events; + private CustomAttributeBuilder[] cattrs; + internal TypeBuilder[] subtypes; + internal TypeAttributes attrs; + private int table_idx; + private ModuleBuilder pmodule; + private int class_size; + private PackingSize packing_size; + private IntPtr generic_container; #if NET_2_0 || BOOTSTRAP_NET_2_0 - private GenericTypeParameterBuilder[] generic_params; + private GenericTypeParameterBuilder[] generic_params; #else - private Object generic_params; /* so offsets don't change */ + private Object generic_params; /* so offsets don't change */ #endif - private RefEmitPermissionSet[] permissions; - private Type created; - #endregion - string fullname; + private RefEmitPermissionSet[] permissions; + private Type created; + #endregion + string fullname; + bool createTypeCalled; + private Type underlying_type; - public const int UnspecifiedTypeSize = 0; + public const int UnspecifiedTypeSize = 0; - protected override TypeAttributes GetAttributeFlagsImpl () { + protected override TypeAttributes GetAttributeFlagsImpl () + { return attrs; } @@ -102,7 +107,8 @@ namespace System.Reflection.Emit { [MethodImplAttribute(MethodImplOptions.InternalCall)] private extern EventInfo get_event_info (EventBuilder eb); - internal TypeBuilder (ModuleBuilder mb, TypeAttributes attr) { + internal TypeBuilder (ModuleBuilder mb, TypeAttributes attr) + { this.parent = null; this.attrs = attr; this.class_size = UnspecifiedTypeSize; @@ -113,13 +119,20 @@ namespace System.Reflection.Emit { setup_internal_class (this); } - internal TypeBuilder (ModuleBuilder mb, string name, TypeAttributes attr, Type parent, Type[] interfaces, PackingSize packing_size, int type_size, Type nesting_type) { + internal TypeBuilder (ModuleBuilder mb, string name, TypeAttributes attr, Type parent, Type[] interfaces, PackingSize packing_size, int type_size, Type nesting_type) + { int sep_index; this.parent = parent; this.attrs = attr; this.class_size = type_size; this.packing_size = packing_size; this.nesting_type = nesting_type; + + check_name ("fullname", name); + + if (parent == null && (attr & TypeAttributes.Interface) != 0 && (attr & TypeAttributes.Abstract) == 0) + throw new InvalidOperationException ("Interface must be declared abstract."); + sep_index = name.LastIndexOf('.'); if (sep_index != -1) { this.tname = name.Substring (sep_index + 1); @@ -133,6 +146,10 @@ namespace System.Reflection.Emit { System.Array.Copy (interfaces, this.interfaces, interfaces.Length); } pmodule = mb; + + if (((attr & TypeAttributes.Interface) == 0) && (parent == null) && !IsCompilerContext) + this.parent = typeof (object); + // skip . ? table_idx = mb.get_next_table_index (this, 0x02, true); setup_internal_class (this); @@ -145,15 +162,19 @@ namespace System.Reflection.Emit { public override string AssemblyQualifiedName { get { - return fullname + ", " + Assembly.GetName().FullName; + return fullname + ", " + Assembly.FullName; } } + public override Type BaseType { get { return parent; } } - public override Type DeclaringType {get {return nesting_type;}} + + public override Type DeclaringType { + get { return nesting_type; } + } /* public override bool IsSubclassOf (Type c) { @@ -173,29 +194,22 @@ namespace System.Reflection.Emit { public override Type UnderlyingSystemType { get { + if (is_created) + return created.UnderlyingSystemType; + + if (IsEnum && !IsCompilerContext) { + if (underlying_type != null) + return underlying_type; + throw new InvalidOperationException ( + "Enumeration type is not defined."); + } - // Return this as requested by Zoltan. - return this; - -#if false - // Dont know what to do with the rest, should be killed: - // See bug: 75008. - // - ////// This should return the type itself for non-enum types but - ////// that breaks mcs. - if (fields != null) { - foreach (FieldBuilder f in fields) { - if ((f != null) && (f.Attributes & FieldAttributes.Static) == 0) - return f.FieldType; - } - } - throw new InvalidOperationException ("Underlying type information on enumeration is not specified."); -#endif } } - string GetFullName () { + string GetFullName () + { if (nesting_type != null) return String.Concat (nesting_type.FullName, "+", tname); if ((nspace != null) && (nspace.Length > 0)) @@ -219,21 +233,29 @@ namespace System.Reflection.Emit { public override Module Module { get {return pmodule;} } + public override string Name { get {return tname;} } + public override string Namespace { get {return nspace;} } + public PackingSize PackingSize { get {return packing_size;} } + public int Size { get { return class_size; } } - public override Type ReflectedType {get {return nesting_type;}} - public void AddDeclarativeSecurity( SecurityAction action, PermissionSet pset) { + public override Type ReflectedType { + get { return nesting_type; } + } + + public void AddDeclarativeSecurity (SecurityAction action, PermissionSet pset) + { if (pset == null) throw new ArgumentNullException ("pset"); if ((action == SecurityAction.RequestMinimum) || @@ -263,7 +285,8 @@ namespace System.Reflection.Emit { #if NET_2_0 [ComVisible (true)] #endif - public void AddInterfaceImplementation( Type interfaceType) { + public void AddInterfaceImplementation (Type interfaceType) + { if (interfaceType == null) throw new ArgumentNullException ("interfaceType"); check_not_created (); @@ -284,50 +307,61 @@ namespace System.Reflection.Emit { } } - [MonoTODO] protected override ConstructorInfo GetConstructorImpl (BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers) { check_created (); - - if (ctors == null) - return null; - ConstructorBuilder found = null; - int count = 0; + if (created == typeof (object)) { + /* + * This happens when building corlib. Calling created.GetConstructor + * would return constructors from the real mscorlib, instead of the + * newly built one. + */ + + if (ctors == null) + return null; + + ConstructorBuilder found = null; + int count = 0; - foreach (ConstructorBuilder cb in ctors){ - if (callConvention != CallingConventions.Any && cb.CallingConvention != callConvention) - continue; - found = cb; - count++; - } - - if (count == 0) - return null; - if (types == null){ - if (count > 1) - throw new AmbiguousMatchException (); - return found; - } - MethodBase[] match = new MethodBase [count]; - if (count == 1) - match [0] = found; - else { - count = 0; - foreach (ConstructorInfo m in ctors) { - if (callConvention != CallingConventions.Any && m.CallingConvention != callConvention) + foreach (ConstructorBuilder cb in ctors) { + if (callConvention != CallingConventions.Any && cb.CallingConvention != callConvention) continue; - match [count++] = m; + found = cb; + count++; + } + + if (count == 0) + return null; + if (types == null) { + if (count > 1) + throw new AmbiguousMatchException (); + return found; + } + MethodBase[] match = new MethodBase [count]; + if (count == 1) + match [0] = found; + else { + count = 0; + foreach (ConstructorInfo m in ctors) { + if (callConvention != CallingConventions.Any && m.CallingConvention != callConvention) + continue; + match [count++] = m; + } } + if (binder == null) + binder = Binder.DefaultBinder; + return (ConstructorInfo) binder.SelectMethod (bindingAttr, match, + types, modifiers); } - if (binder == null) - binder = Binder.DefaultBinder; - return (ConstructorInfo)binder.SelectMethod (bindingAttr, match, types, modifiers); + + return created.GetConstructor (bindingAttr, binder, + callConvention, types, modifiers); } - public override bool IsDefined( Type attributeType, bool inherit) + public override bool IsDefined (Type attributeType, bool inherit) { /* * MS throws NotSupported here, but we can't because some corlib @@ -350,22 +384,25 @@ namespace System.Reflection.Emit { return created.GetCustomAttributes (attributeType, inherit); } - public TypeBuilder DefineNestedType (string name) { - return DefineNestedType (name, TypeAttributes.NestedPrivate, pmodule.assemblyb.corlib_object_type, null); + public TypeBuilder DefineNestedType (string name) + { + return DefineNestedType (name, TypeAttributes.NestedPrivate, + pmodule.assemblyb.corlib_object_type, null); } - public TypeBuilder DefineNestedType (string name, TypeAttributes attr) { + public TypeBuilder DefineNestedType (string name, TypeAttributes attr) + { return DefineNestedType (name, attr, pmodule.assemblyb.corlib_object_type, null); } - public TypeBuilder DefineNestedType (string name, TypeAttributes attr, Type parent) { + public TypeBuilder DefineNestedType (string name, TypeAttributes attr, Type parent) + { return DefineNestedType (name, attr, parent, null); } private TypeBuilder DefineNestedType (string name, TypeAttributes attr, Type parent, Type[] interfaces, - PackingSize packsize, int typesize) + PackingSize packSize, int typeSize) { - check_name ("name", name); // Visibility must be NestedXXX /* This breaks mcs if (((attrs & TypeAttributes.VisibilityMask) == TypeAttributes.Public) || @@ -377,7 +414,7 @@ namespace System.Reflection.Emit { if (iface == null) throw new ArgumentNullException ("interfaces"); - TypeBuilder res = new TypeBuilder (pmodule, name, attr, parent, interfaces, packsize, typesize, this); + TypeBuilder res = new TypeBuilder (pmodule, name, attr, parent, interfaces, packSize, typeSize, this); res.fullname = res.GetFullName (); pmodule.RegisterTypeName (res, res.fullname); if (subtypes != null) { @@ -395,22 +432,26 @@ namespace System.Reflection.Emit { #if NET_2_0 [ComVisible (true)] #endif - public TypeBuilder DefineNestedType (string name, TypeAttributes attr, Type parent, Type[] interfaces) { + public TypeBuilder DefineNestedType (string name, TypeAttributes attr, Type parent, Type[] interfaces) + { return DefineNestedType (name, attr, parent, interfaces, PackingSize.Unspecified, UnspecifiedTypeSize); } - public TypeBuilder DefineNestedType (string name, TypeAttributes attr, Type parent, int typesize) { - return DefineNestedType (name, attr, parent, null, PackingSize.Unspecified, typesize); + public TypeBuilder DefineNestedType (string name, TypeAttributes attr, Type parent, int typeSize) + { + return DefineNestedType (name, attr, parent, null, PackingSize.Unspecified, typeSize); } - public TypeBuilder DefineNestedType (string name, TypeAttributes attr, Type parent, PackingSize packsize) { - return DefineNestedType (name, attr, parent, null, packsize, UnspecifiedTypeSize); + public TypeBuilder DefineNestedType (string name, TypeAttributes attr, Type parent, PackingSize packSize) + { + return DefineNestedType (name, attr, parent, null, packSize, UnspecifiedTypeSize); } #if NET_2_0 [ComVisible (true)] #endif - public ConstructorBuilder DefineConstructor (MethodAttributes attributes, CallingConventions callingConvention, Type[] parameterTypes) { + public ConstructorBuilder DefineConstructor (MethodAttributes attributes, CallingConventions callingConvention, Type[] parameterTypes) + { return DefineConstructor (attributes, callingConvention, parameterTypes, null, null); } @@ -425,7 +466,9 @@ namespace System.Reflection.Emit { ConstructorBuilder DefineConstructor (MethodAttributes attributes, CallingConventions callingConvention, Type[] parameterTypes, Type[][] requiredCustomModifiers, Type[][] optionalCustomModifiers) { check_not_created (); - ConstructorBuilder cb = new ConstructorBuilder (this, attributes, callingConvention, parameterTypes, requiredCustomModifiers, optionalCustomModifiers); + ConstructorBuilder cb = new ConstructorBuilder (this, attributes, + callingConvention, parameterTypes, requiredCustomModifiers, + optionalCustomModifiers); if (ctors != null) { ConstructorBuilder[] new_ctors = new ConstructorBuilder [ctors.Length+1]; System.Array.Copy (ctors, new_ctors, ctors.Length); @@ -462,7 +505,7 @@ namespace System.Reflection.Emit { } ConstructorBuilder cb = DefineConstructor (attributes, - CallingConventions.Standard, new Type[0]); + CallingConventions.Standard, Type.EmptyTypes); ILGenerator ig = cb.GetILGenerator (); ig.Emit (OpCodes.Ldarg_0); ig.Emit (OpCodes.Call, parent_constructor); @@ -470,7 +513,8 @@ namespace System.Reflection.Emit { return cb; } - private void append_method (MethodBuilder mb) { + private void append_method (MethodBuilder mb) + { if (methods != null) { if (methods.Length == num_methods) { MethodBuilder[] new_methods = new MethodBuilder [methods.Length * 2]; @@ -484,12 +528,16 @@ namespace System.Reflection.Emit { num_methods ++; } - public MethodBuilder DefineMethod( string name, MethodAttributes attributes, Type returnType, Type[] parameterTypes) { - return DefineMethod (name, attributes, CallingConventions.Standard, returnType, parameterTypes); + public MethodBuilder DefineMethod (string name, MethodAttributes attributes, Type returnType, Type[] parameterTypes) + { + return DefineMethod (name, attributes, CallingConventions.Standard, + returnType, parameterTypes); } - public MethodBuilder DefineMethod( string name, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] parameterTypes) { - return DefineMethod (name, attributes, callingConvention, returnType, null, null, parameterTypes, null, null); + public MethodBuilder DefineMethod (string name, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] parameterTypes) + { + return DefineMethod (name, attributes, callingConvention, returnType, + null, null, parameterTypes, null, null); } #if NET_2_0 || BOOTSTRAP_NET_2_0 @@ -497,24 +545,33 @@ namespace System.Reflection.Emit { #else internal #endif - MethodBuilder DefineMethod( string name, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers, Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers) { + MethodBuilder DefineMethod (string name, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers, Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers) + { check_name ("name", name); check_not_created (); if (IsInterface && ( !((attributes & MethodAttributes.Abstract) != 0) || !((attributes & MethodAttributes.Virtual) != 0)) && !(((attributes & MethodAttributes.Static) != 0))) - throw new ArgumentException ("attributes", "Interface method must be abstract and virtual."); + throw new ArgumentException ("Interface method must be abstract and virtual."); if (returnType == null) returnType = pmodule.assemblyb.corlib_void_type; - MethodBuilder res = new MethodBuilder (this, name, attributes, callingConvention, returnType, returnTypeRequiredCustomModifiers, returnTypeOptionalCustomModifiers, parameterTypes, parameterTypeRequiredCustomModifiers, parameterTypeOptionalCustomModifiers); + MethodBuilder res = new MethodBuilder (this, name, attributes, + callingConvention, returnType, + returnTypeRequiredCustomModifiers, + returnTypeOptionalCustomModifiers, parameterTypes, + parameterTypeRequiredCustomModifiers, + parameterTypeOptionalCustomModifiers); append_method (res); return res; } - public MethodBuilder DefinePInvokeMethod (string name, string dllName, string entryName, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] parameterTypes, CallingConvention nativeCallConv, CharSet nativeCharSet) { - return DefinePInvokeMethod (name, dllName, entryName, attributes, callingConvention, returnType, null, null, parameterTypes, null, null, nativeCallConv, nativeCharSet); + public MethodBuilder DefinePInvokeMethod (string name, string dllName, string entryName, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] parameterTypes, CallingConvention nativeCallConv, CharSet nativeCharSet) + { + return DefinePInvokeMethod (name, dllName, entryName, attributes, + callingConvention, returnType, null, null, parameterTypes, + null, null, nativeCallConv, nativeCharSet); } #if NET_2_0 || BOOTSTRAP_NET_2_0 @@ -534,14 +591,15 @@ namespace System.Reflection.Emit { Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers, CallingConvention nativeCallConv, - CharSet nativeCharSet) { + CharSet nativeCharSet) + { check_name ("name", name); check_name ("dllName", dllName); check_name ("entryName", entryName); if ((attributes & MethodAttributes.Abstract) != 0) - throw new ArgumentException ("attributes", "PInvoke methods must be static and native and cannot be abstract."); + throw new ArgumentException ("PInvoke methods must be static and native and cannot be abstract."); if (IsInterface) - throw new ArgumentException ("PInvoke methods cannot exist on interfaces."); + throw new ArgumentException ("PInvoke methods cannot exist on interfaces."); check_not_created (); MethodBuilder res @@ -570,16 +628,19 @@ namespace System.Reflection.Emit { } #if NET_2_0 || BOOTSTRAP_NET_2_0 - public MethodBuilder DefineMethod (string name, MethodAttributes attributes) { + public MethodBuilder DefineMethod (string name, MethodAttributes attributes) + { return DefineMethod (name, attributes, CallingConventions.Standard); } - public MethodBuilder DefineMethod (string name, MethodAttributes attributes, CallingConventions callConv) { - return DefineMethod (name, attributes, callConv, null, null); + public MethodBuilder DefineMethod (string name, MethodAttributes attributes, CallingConventions callingConvention) + { + return DefineMethod (name, attributes, callingConvention, null, null); } #endif - public void DefineMethodOverride( MethodInfo methodInfoBody, MethodInfo methodInfoDeclaration) { + public void DefineMethodOverride (MethodInfo methodInfoBody, MethodInfo methodInfoDeclaration) + { if (methodInfoBody == null) throw new ArgumentNullException ("methodInfoBody"); if (methodInfoDeclaration == null) @@ -592,7 +653,8 @@ namespace System.Reflection.Emit { } } - public FieldBuilder DefineField( string fieldName, Type type, FieldAttributes attributes) { + public FieldBuilder DefineField (string fieldName, Type type, FieldAttributes attributes) + { return DefineField (fieldName, type, null, null, attributes); } @@ -601,13 +663,14 @@ namespace System.Reflection.Emit { #else internal #endif - FieldBuilder DefineField (string fieldName, Type type, Type[] requiredCustomAttributes, Type[] optionalCustomAttributes, FieldAttributes attributes) { + FieldBuilder DefineField (string fieldName, Type type, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers, FieldAttributes attributes) + { check_name ("fieldName", fieldName); if (type == typeof (void)) - throw new ArgumentException ("type", "Bad field type in defining field."); + throw new ArgumentException ("Bad field type in defining field."); check_not_created (); - FieldBuilder res = new FieldBuilder (this, fieldName, type, attributes, requiredCustomAttributes, optionalCustomAttributes); + FieldBuilder res = new FieldBuilder (this, fieldName, type, attributes, requiredCustomModifiers, optionalCustomModifiers); if (fields != null) { if (fields.Length == num_fields) { FieldBuilder[] new_fields = new FieldBuilder [fields.Length * 2]; @@ -622,10 +685,17 @@ namespace System.Reflection.Emit { num_fields ++; create_internal_class (this); } + + if (IsEnum && !IsCompilerContext) { + if (underlying_type == null && (attributes & FieldAttributes.Static) == 0) + underlying_type = type; + } + return res; } - public PropertyBuilder DefineProperty( string name, PropertyAttributes attributes, Type returnType, Type[] parameterTypes) { + public PropertyBuilder DefineProperty (string name, PropertyAttributes attributes, Type returnType, Type[] parameterTypes) + { return DefineProperty (name, attributes, returnType, null, null, parameterTypes, null, null); } @@ -634,7 +704,8 @@ namespace System.Reflection.Emit { #else internal #endif - PropertyBuilder DefineProperty (string name, PropertyAttributes attributes, Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers, Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers) { + PropertyBuilder DefineProperty (string name, PropertyAttributes attributes, Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers, Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers) + { check_name ("name", name); if (parameterTypes != null) foreach (Type param in parameterTypes) @@ -659,14 +730,19 @@ namespace System.Reflection.Emit { #if NET_2_0 [ComVisible (true)] #endif - public ConstructorBuilder DefineTypeInitializer() { - return DefineConstructor (MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName, CallingConventions.Standard, null); + public ConstructorBuilder DefineTypeInitializer() + { + return DefineConstructor (MethodAttributes.Public | + MethodAttributes.Static | MethodAttributes.SpecialName | + MethodAttributes.RTSpecialName, CallingConventions.Standard, + null); } [MethodImplAttribute(MethodImplOptions.InternalCall)] private extern Type create_runtime_class (TypeBuilder tb); - private bool is_nested_in (Type t) { + private bool is_nested_in (Type t) + { while (t != null) { if (t == this) return true; @@ -675,12 +751,31 @@ namespace System.Reflection.Emit { } return false; } + + // Return whenever this type has a ctor defined using DefineMethod () + private bool has_ctor_method () { + MethodAttributes ctor_attrs = MethodAttributes.SpecialName | MethodAttributes.RTSpecialName; + + for (int i = 0; i < num_methods; ++i) { + MethodBuilder mb = (MethodBuilder)(methods[i]); + + if (mb.Name == ConstructorInfo.ConstructorName && (mb.Attributes & ctor_attrs) == ctor_attrs) + return true; + } + + return false; + } - public Type CreateType() { + public Type CreateType() + { /* handle nesting_type */ - if (created != null) + if (createTypeCalled) return created; + if (!IsInterface && (parent == null) && (this != pmodule.assemblyb.corlib_object_type) && (FullName != "")) { + SetParent (pmodule.assemblyb.corlib_object_type); + } + create_generic_class (); // Fire TypeResolve events for fields whose type is an unfinished @@ -708,23 +803,30 @@ namespace System.Reflection.Emit { if ((parent != null) && parent.IsSealed) throw new TypeLoadException ("Could not load type '" + FullName + "' from assembly '" + Assembly + "' because the parent type is sealed."); + if (parent == pmodule.assemblyb.corlib_enum_type && methods != null) + throw new TypeLoadException ("Could not load type '" + FullName + "' from assembly '" + Assembly + "' because it is an enum with methods."); + if (methods != null) { - for (int i = 0; i < num_methods; ++i) - ((MethodBuilder)(methods[i])).fixup (); + for (int i = 0; i < num_methods; ++i) { + MethodBuilder mb = (MethodBuilder)(methods[i]); + mb.check_override (); + mb.fixup (); + } } // // On classes, define a default constructor if not provided // if (!(IsInterface || IsValueType) && (ctors == null) && (tname != "") && - (GetAttributeFlagsImpl () & TypeAttributes.Abstract | TypeAttributes.Sealed) != (TypeAttributes.Abstract | TypeAttributes.Sealed)) + (GetAttributeFlagsImpl () & TypeAttributes.Abstract | TypeAttributes.Sealed) != (TypeAttributes.Abstract | TypeAttributes.Sealed) && !has_ctor_method ()) DefineDefaultConstructor (MethodAttributes.Public); if (ctors != null){ foreach (ConstructorBuilder ctor in ctors) ctor.fixup (); } - + + createTypeCalled = true; created = create_runtime_class (this); if (created != null) return created; @@ -748,6 +850,11 @@ namespace System.Reflection.Emit { } symbolWriter.CloseNamespace (); + + if (subtypes != null) { + for (int i = 0; i < subtypes.Length; ++i) + subtypes [i].GenerateDebugInfo (symbolWriter); + } } #if NET_2_0 @@ -755,6 +862,9 @@ namespace System.Reflection.Emit { #endif public override ConstructorInfo[] GetConstructors (BindingFlags bindingAttr) { + if (is_created) + return created.GetConstructors (bindingAttr); + if (ctors == null) return new ConstructorInfo [0]; ArrayList l = new ArrayList (); @@ -790,12 +900,14 @@ namespace System.Reflection.Emit { return result; } - public override Type GetElementType () { + public override Type GetElementType () + { check_created (); return created.GetElementType (); } - public override EventInfo GetEvent (string name, BindingFlags bindingAttr) { + public override EventInfo GetEvent (string name, BindingFlags bindingAttr) + { check_created (); return created.GetEvent (name, bindingAttr); } @@ -806,7 +918,8 @@ namespace System.Reflection.Emit { return GetEvents (DefaultBindingFlags); } - public override EventInfo[] GetEvents (BindingFlags bindingAttr) { + public override EventInfo[] GetEvents (BindingFlags bindingAttr) + { /* FIXME: mcs calls this check_created (); */ @@ -863,7 +976,11 @@ namespace System.Reflection.Emit { return result; } - public override FieldInfo GetField( string name, BindingFlags bindingAttr) { + public override FieldInfo GetField (string name, BindingFlags bindingAttr) + { + if (created != null) + return created.GetField (name, bindingAttr); + if (fields == null) return null; @@ -901,7 +1018,11 @@ namespace System.Reflection.Emit { return null; } - public override FieldInfo[] GetFields (BindingFlags bindingAttr) { + public override FieldInfo[] GetFields (BindingFlags bindingAttr) + { + if (created != null) + return created.GetFields (bindingAttr); + if (fields == null) return new FieldInfo [0]; ArrayList l = new ArrayList (); @@ -939,12 +1060,14 @@ namespace System.Reflection.Emit { return result; } - public override Type GetInterface (string name, bool ignoreCase) { + public override Type GetInterface (string name, bool ignoreCase) + { check_created (); return created.GetInterface (name, ignoreCase); } - public override Type[] GetInterfaces () { + public override Type[] GetInterfaces () + { if (interfaces != null) { Type[] ret = new Type [interfaces.Length]; interfaces.CopyTo (ret, 0); @@ -955,26 +1078,68 @@ namespace System.Reflection.Emit { } public override MemberInfo[] GetMember (string name, MemberTypes type, - BindingFlags bindingAttr) { + BindingFlags bindingAttr) + { check_created (); return created.GetMember (name, type, bindingAttr); } - public override MemberInfo[] GetMembers (BindingFlags bindingAttr) { + public override MemberInfo[] GetMembers (BindingFlags bindingAttr) + { check_created (); return created.GetMembers (bindingAttr); } - private MethodInfo[] GetMethodsByName (string name, BindingFlags bindingAttr, bool ignoreCase, Type reflected_type) { + private MethodInfo[] GetMethodsByName (string name, BindingFlags bindingAttr, bool ignoreCase, Type reflected_type) + { MethodInfo[] candidates; + bool match; + MethodAttributes mattrs; + if (((bindingAttr & BindingFlags.DeclaredOnly) == 0) && (parent != null)) { - MethodInfo[] parent_methods = parent.GetMethods (bindingAttr); - if (methods == null) - candidates = parent_methods; - else { - candidates = new MethodInfo [methods.Length + parent_methods.Length]; - parent_methods.CopyTo (candidates, 0); - methods.CopyTo (candidates, parent_methods.Length); + MethodInfo [] parent_methods = parent.GetMethods (bindingAttr); + ArrayList parent_candidates = new ArrayList (parent_methods.Length); + + bool flatten = (bindingAttr & BindingFlags.FlattenHierarchy) != 0; + + for (int i = 0; i < parent_methods.Length; i++) { + MethodInfo m = parent_methods [i]; + + mattrs = m.Attributes; + + if (m.IsStatic && !flatten) + continue; + + switch (mattrs & MethodAttributes.MemberAccessMask) { + case MethodAttributes.Public: + match = (bindingAttr & BindingFlags.Public) != 0; + break; + case MethodAttributes.Assembly: +#if NET_2_0 + match = (bindingAttr & BindingFlags.NonPublic) != 0; +#else + match = false; +#endif + break; + case MethodAttributes.Private: + match = false; + break; + default: + match = (bindingAttr & BindingFlags.NonPublic) != 0; + break; + } + + if (match) + parent_candidates.Add (m); + } + + if (methods == null) { + candidates = new MethodInfo [parent_candidates.Count]; + parent_candidates.CopyTo (candidates); + } else { + candidates = new MethodInfo [methods.Length + parent_candidates.Count]; + parent_candidates.CopyTo (candidates, 0); + methods.CopyTo (candidates, parent_candidates.Count); } } else @@ -984,8 +1149,6 @@ namespace System.Reflection.Emit { return new MethodInfo [0]; ArrayList l = new ArrayList (); - bool match; - MethodAttributes mattrs; foreach (MethodInfo c in candidates) { if (c == null) @@ -1023,7 +1186,8 @@ namespace System.Reflection.Emit { return result; } - public override MethodInfo[] GetMethods (BindingFlags bindingAttr) { + public override MethodInfo[] GetMethods (BindingFlags bindingAttr) + { return GetMethodsByName (null, bindingAttr, false, this); } @@ -1076,12 +1240,14 @@ namespace System.Reflection.Emit { return (MethodInfo)binder.SelectMethod (bindingAttr, match, types, modifiers); } - public override Type GetNestedType( string name, BindingFlags bindingAttr) { + public override Type GetNestedType (string name, BindingFlags bindingAttr) + { check_created (); return created.GetNestedType (name, bindingAttr); } - public override Type[] GetNestedTypes (BindingFlags bindingAttr) { + public override Type[] GetNestedTypes (BindingFlags bindingAttr) + { bool match; ArrayList result = new ArrayList (); @@ -1105,7 +1271,11 @@ namespace System.Reflection.Emit { return r; } - public override PropertyInfo[] GetProperties( BindingFlags bindingAttr) { + public override PropertyInfo[] GetProperties (BindingFlags bindingAttr) + { + if (is_created) + return created.GetProperties (bindingAttr); + if (properties == null) return new PropertyInfo [0]; ArrayList l = new ArrayList (); @@ -1147,16 +1317,25 @@ namespace System.Reflection.Emit { return result; } - protected override PropertyInfo GetPropertyImpl( string name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers) { + protected override PropertyInfo GetPropertyImpl (string name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers) + { throw not_supported (); } - protected override bool HasElementTypeImpl () { + protected override bool HasElementTypeImpl () + { +#if NET_2_0 + // a TypeBuilder can never represent an array, pointer + if (!is_created) + return false; +#else check_created (); +#endif return created.HasElementType; } - public override object InvokeMember( string name, BindingFlags invokeAttr, Binder binder, object target, object[] args, ParameterModifier[] modifiers, CultureInfo culture, string[] namedParameters) { + public override object InvokeMember (string name, BindingFlags invokeAttr, Binder binder, object target, object[] args, ParameterModifier[] modifiers, CultureInfo culture, string[] namedParameters) + { check_created (); return created.InvokeMember (name, invokeAttr, binder, target, args, modifiers, culture, namedParameters); } @@ -1166,35 +1345,78 @@ namespace System.Reflection.Emit { return Type.IsArrayImpl (this); } - protected override bool IsByRefImpl () { + protected override bool IsByRefImpl () + { // FIXME return false; } - protected override bool IsCOMObjectImpl () { - return false; + + protected override bool IsCOMObjectImpl () + { + return ((GetAttributeFlagsImpl () & TypeAttributes.Import) != 0); } - protected override bool IsPointerImpl () { + + protected override bool IsPointerImpl () + { // FIXME return false; } - protected override bool IsPrimitiveImpl () { + + protected override bool IsPrimitiveImpl () + { // FIXME return false; } - protected override bool IsValueTypeImpl () { + + // FIXME: I doubt just removing this still works. + protected override bool IsValueTypeImpl () + { return ((type_is_subtype_of (this, pmodule.assemblyb.corlib_value_type, false) || type_is_subtype_of (this, typeof(System.ValueType), false)) && this != pmodule.assemblyb.corlib_value_type && this != pmodule.assemblyb.corlib_enum_type); } - public override RuntimeTypeHandle TypeHandle { - get { +#if NET_2_0 + [MonoTODO] + public override Type MakeArrayType () + { + return base.MakeArrayType (); + } + + [MonoTODO] + public override Type MakeArrayType (int rank) + { + return base.MakeArrayType (rank); + } + + [MonoTODO] + public override Type MakeByRefType () + { + return base.MakeByRefType (); + } + + [MonoTODO] + public override Type MakeGenericType (params Type [] typeArguments) + { + return base.MakeGenericType (typeArguments); + } + + [MonoTODO] + public override Type MakePointerType () + { + return base.MakePointerType (); + } +#endif + + public override RuntimeTypeHandle TypeHandle { + get { check_created (); return created.TypeHandle; - } + } } - public void SetCustomAttribute( CustomAttributeBuilder customBuilder) { + public void SetCustomAttribute (CustomAttributeBuilder customBuilder) + { if (customBuilder == null) throw new ArgumentNullException ("customBuilder"); @@ -1290,6 +1512,8 @@ namespace System.Reflection.Emit { } else if (attrname == "System.Runtime.InteropServices.ComImportAttribute") { attrs |= TypeAttributes.Import; return; + } else if (attrname == "System.Security.SuppressUnmanagedCodeSecurityAttribute") { + attrs |= TypeAttributes.HasSecurity; } if (cattrs != null) { @@ -1306,14 +1530,16 @@ namespace System.Reflection.Emit { #if NET_2_0 [ComVisible (true)] #endif - public void SetCustomAttribute( ConstructorInfo con, byte[] binaryAttribute) { + public void SetCustomAttribute (ConstructorInfo con, byte[] binaryAttribute) + { SetCustomAttribute (new CustomAttributeBuilder (con, binaryAttribute)); } - public EventBuilder DefineEvent( string name, EventAttributes attributes, Type eventtype) { + public EventBuilder DefineEvent (string name, EventAttributes attributes, Type eventtype) + { check_name ("name", name); if (eventtype == null) - throw new ArgumentNullException ("eventtype"); + throw new ArgumentNullException ("type"); check_not_created (); EventBuilder res = new EventBuilder (this, name, attributes, eventtype); @@ -1329,25 +1555,25 @@ namespace System.Reflection.Emit { return res; } - public FieldBuilder DefineInitializedData( string name, byte[] data, FieldAttributes attributes) { + public FieldBuilder DefineInitializedData (string name, byte[] data, FieldAttributes attributes) { if (data == null) throw new ArgumentNullException ("data"); - if ((data.Length == 0) || (data.Length > 0x3f0000)) - throw new ArgumentException ("data", "Data size must be > 0 and < 0x3f0000"); FieldBuilder res = DefineUninitializedData (name, data.Length, attributes); res.SetRVAData (data); - return res; } static int UnmanagedDataCount = 0; - public FieldBuilder DefineUninitializedData( string name, int size, FieldAttributes attributes) - { - check_name ("name", name); + public FieldBuilder DefineUninitializedData (string name, int size, FieldAttributes attributes) + { + if (name == null) + throw new ArgumentNullException ("name"); + if (name.Length == 0) + throw new ArgumentException ("Empty name is not legal", "name"); if ((size <= 0) || (size > 0x3f0000)) - throw new ArgumentException ("size", "Data size must be > 0 and < 0x3f0000"); + throw new ArgumentException ("Data size must be > 0 and < 0x3f0000"); check_not_created (); string typeName = "$ArrayType$" + size; @@ -1367,16 +1593,33 @@ namespace System.Reflection.Emit { return new TypeToken (0x02000000 | table_idx); } } - public void SetParent (Type parentType) { + + public void SetParent (Type parent) + { check_not_created (); - if (parentType == null && (attrs & TypeAttributes.Interface) == 0) - throw new ArgumentNullException ("parentType"); - - parent = parentType; +#if NET_2_0 + if (parent == null) { + if ((attrs & TypeAttributes.Interface) != 0) { + if ((attrs & TypeAttributes.Abstract) == 0) + throw new InvalidOperationException ("Interface must be declared abstract."); + this.parent = null; + } else { + this.parent = typeof (object); + } + } else { + this.parent = parent; + } +#else + if (parent == null) + throw new ArgumentNullException ("parent"); + this.parent = parent; +#endif + // will just set the parent-related bits if called a second time setup_internal_class (this); } + internal int get_next_table_index (object obj, int table, bool inc) { return pmodule.get_next_table_index (obj, table, inc); } @@ -1392,6 +1635,12 @@ namespace System.Reflection.Emit { return created.GetInterfaceMap (interfaceType); } + internal bool IsCompilerContext { + get { + return pmodule.assemblyb.IsCompilerContext; + } + } + internal bool is_created { get { return created != null; @@ -1421,7 +1670,7 @@ namespace System.Reflection.Emit { throw new ArgumentNullException (argName); if (name.Length == 0) throw new ArgumentException ("Empty name is not legal", argName); - if (name.IndexOf ((char)0) != -1) + if (name [0] == ((char)0)) throw new ArgumentException ("Illegal name", argName); } @@ -1452,12 +1701,18 @@ namespace System.Reflection.Emit { return true; if (c.IsInterface) { + if (parent != null && is_created) { + if (c.IsAssignableFrom (parent)) + return true; + } + if (interfaces == null) return false; foreach (Type t in interfaces) if (c.IsAssignableFrom (t)) return true; - return false; + if (!is_created) + return false; } if (parent == null) @@ -1467,7 +1722,8 @@ namespace System.Reflection.Emit { } #if NET_2_0 || BOOTSTRAP_NET_2_0 - public bool IsCreated () { + public bool IsCreated () + { return is_created; } @@ -1531,52 +1787,83 @@ namespace System.Reflection.Emit { return generic_params; } - public static ConstructorInfo GetConstructor (Type instanciated, ConstructorInfo ctor) - { - ConstructorInfo res = instanciated.GetConstructor (ctor); + public static ConstructorInfo GetConstructor (Type type, ConstructorInfo constructor) + { + ConstructorInfo res = type.GetConstructor (constructor); if (res == null) throw new System.Exception ("constructor not found"); else return res; - } + } - public static MethodInfo GetMethod (Type instanciated, MethodInfo meth) - { - MethodInfo res = instanciated.GetMethod (meth); + static bool IsValidGetMethodType (Type type) + { + if (type is TypeBuilder || type is MonoGenericClass) + return true; + /*GetMethod() must work with TypeBuilders after CreateType() was called.*/ + if (type.Module is ModuleBuilder) + return true; + if (type.IsGenericParameter) + return false; + + Type[] inst = type.GetGenericArguments (); + if (inst == null) + return false; + for (int i = 0; i < inst.Length; ++i) { + if (IsValidGetMethodType (inst [i])) + return true; + } + return false; + } + + public static MethodInfo GetMethod (Type type, MethodInfo method) + { + if (!IsValidGetMethodType (type)) + throw new ArgumentException ("type is not TypeBuilder but " + type.GetType (), "type"); + + if (!type.IsGenericType) + throw new ArgumentException ("type is not a generic type", "type"); + + if (!method.DeclaringType.IsGenericTypeDefinition) + throw new ArgumentException ("method declaring type is not a generic type definition", "method"); + if (method.DeclaringType != type.GetGenericTypeDefinition ()) + throw new ArgumentException ("method declaring type is not the generic type definition of type", "method"); + + MethodInfo res = type.GetMethod (method); if (res == null) - throw new System.Exception ("method not found"); - else - return res; - } + throw new ArgumentException (String.Format ("method {0} not found in type {1}", method.Name, type)); + + return res; + } - public static FieldInfo GetField (Type instanciated, FieldInfo fld) - { - FieldInfo res = instanciated.GetField (fld); + public static FieldInfo GetField (Type type, FieldInfo field) + { + FieldInfo res = type.GetField (field); if (res == null) throw new System.Exception ("field not found"); else return res; - } + } #endif - void _TypeBuilder.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId) - { - throw new NotImplementedException (); - } - - void _TypeBuilder.GetTypeInfo (uint iTInfo, uint lcid, IntPtr ppTInfo) - { - throw new NotImplementedException (); - } - - void _TypeBuilder.GetTypeInfoCount (out uint pcTInfo) - { - throw new NotImplementedException (); - } - - void _TypeBuilder.Invoke (uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr) - { - throw new NotImplementedException (); - } + void _TypeBuilder.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId) + { + throw new NotImplementedException (); + } + + void _TypeBuilder.GetTypeInfo (uint iTInfo, uint lcid, IntPtr ppTInfo) + { + throw new NotImplementedException (); + } + + void _TypeBuilder.GetTypeInfoCount (out uint pcTInfo) + { + throw new NotImplementedException (); + } + + void _TypeBuilder.Invoke (uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr) + { + throw new NotImplementedException (); + } } }