// (C) 2001 Ximian, Inc. http://www.ximian.com
//
+//
+// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
using System;
+using System.Text;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Security.Permissions;
namespace System.Reflection.Emit {
+
public sealed class TypeBuilder : Type {
+ #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;
- private TypeAttributes attrs;
+ 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;
+#else
+ private Object generic_params; /* so offsets don't change */
+#endif
+ private RefEmitPermissionSet[] permissions;
private Type created;
+ #endregion
string fullname;
public const int UnspecifiedTypeSize = 0;
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private extern void create_internal_class (TypeBuilder tb);
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ private extern void setup_generic_class ();
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ private extern void create_generic_class ();
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ private extern EventInfo get_event_info (EventBuilder eb);
+
internal TypeBuilder (ModuleBuilder mb, TypeAttributes attr) {
this.parent = null;
this.attrs = attr;
- this.class_size = -1;
+ this.class_size = UnspecifiedTypeSize;
+ this.table_idx = 1;
fullname = this.tname = "<Module>";
this.nspace = "";
pmodule = mb;
setup_internal_class (this);
}
- internal TypeBuilder (ModuleBuilder mb, string name, TypeAttributes attr, Type parent, Type[] interfaces, PackingSize packing_size, int type_size) {
+ 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;
sep_index = name.LastIndexOf('.');
if (sep_index != -1) {
this.tname = name.Substring (sep_index + 1);
public override Assembly Assembly {
get {return pmodule.Assembly;}
}
+
public override string AssemblyQualifiedName {
get {
- return fullname + ", " + Assembly.ToString();
+ return fullname + ", " + Assembly.GetName().FullName;
}
}
public override Type BaseType {
}
}
public override Type DeclaringType {get {return nesting_type;}}
+
+/* public override bool IsSubclassOf (Type c)
+ {
+ Type t;
+ if (c == null)
+ return false;
+ if (c == this)
+ return false;
+ t = parent;
+ while (t != null) {
+ if (c == t)
+ return true;
+ t = t.BaseType;
+ }
+ return false;
+ }*/
+
+ [MonoTODO]
public override Type UnderlyingSystemType {
get {
+ // This should return the type itself for non-enum types but
+ // that breaks mcs.
if (fields != null) {
foreach (FieldBuilder f in fields) {
- if ((f.Attributes & FieldAttributes.Static) == 0)
+ if ((f != null) && (f.Attributes & FieldAttributes.Static) == 0)
return f.FieldType;
}
}
- throw new InvalidOperationException (String.Format ("typebuilder: {0}", this));
+ throw new InvalidOperationException ("Underlying type information on enumeration is not specified.");
}
}
}
public override Guid GUID {
- get {return Guid.Empty;}
+ get {
+ check_created ();
+ return created.GUID;
+ }
}
public override Module Module {
public PackingSize PackingSize {
get {return packing_size;}
}
- public override Type ReflectedType {get {return nesting_type;}}
- public override MemberTypes MemberType {
- get {return MemberTypes.TypeInfo;}
+ public int Size {
+ get { return class_size; }
}
+ public override Type ReflectedType {get {return nesting_type;}}
- [MonoTODO]
public void AddDeclarativeSecurity( SecurityAction action, PermissionSet pset) {
- throw new NotImplementedException ();
+ if (pset == null)
+ throw new ArgumentNullException ("pset");
+ if ((action == SecurityAction.RequestMinimum) ||
+ (action == SecurityAction.RequestOptional) ||
+ (action == SecurityAction.RequestRefuse))
+ throw new ArgumentException ("Request* values are not permitted", "action");
+
+ check_not_created ();
+
+ if (permissions != null) {
+ /* Check duplicate actions */
+ foreach (RefEmitPermissionSet set in permissions)
+ if (set.action == action)
+ throw new InvalidOperationException ("Multiple permission sets specified with the same SecurityAction.");
+
+ RefEmitPermissionSet[] new_array = new RefEmitPermissionSet [permissions.Length + 1];
+ permissions.CopyTo (new_array, 0);
+ permissions = new_array;
+ }
+ else
+ permissions = new RefEmitPermissionSet [1];
+
+ permissions [permissions.Length - 1] = new RefEmitPermissionSet (action, pset.ToXml ().ToString ());
+ attrs |= TypeAttributes.HasSecurity;
}
public void AddInterfaceImplementation( Type interfaceType) {
+ if (interfaceType == null)
+ throw new ArgumentNullException ("interfaceType");
+ check_not_created ();
+
if (interfaces != null) {
+ // Check for duplicates
+ foreach (Type t in interfaces)
+ if (t == interfaceType)
+ return;
+
Type[] ifnew = new Type [interfaces.Length + 1];
interfaces.CopyTo (ifnew, 0);
ifnew [interfaces.Length] = interfaceType;
}
[MonoTODO]
- protected override ConstructorInfo GetConstructorImpl (BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers) {
- throw new NotImplementedException ();
+ 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;
+
+ 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)
+ continue;
+ match [count++] = m;
+ }
+ }
+ if (binder == null)
+ binder = Binder.DefaultBinder;
+ return (ConstructorInfo)binder.SelectMethod (bindingAttr, match, types, modifiers);
}
- public override bool IsDefined( Type attributeType, bool inherit) {
- return false;
+ public override bool IsDefined( Type attributeType, bool inherit)
+ {
+ /*
+ * MS throws NotSupported here, but we can't because some corlib
+ * classes make calls to IsDefined.
+ */
+ return MonoCustomAttrs.IsDefined (this, attributeType, inherit);
}
- public override object[] GetCustomAttributes(bool inherit) {
- return null;
+
+ public override object[] GetCustomAttributes(bool inherit)
+ {
+ check_created ();
+
+ return created.GetCustomAttributes (inherit);
}
- public override object[] GetCustomAttributes(Type attributeType, bool inherit) {
- return null;
+
+ public override object[] GetCustomAttributes(Type attributeType, bool inherit)
+ {
+ check_created ();
+
+ return created.GetCustomAttributes (attributeType, inherit);
}
- [MonoTODO]
public TypeBuilder DefineNestedType (string name) {
- // FIXME: LAMESPEC: what other attributes should we use here as default?
- return DefineNestedType (name, TypeAttributes.Public, pmodule.assemblyb.corlib_object_type, null);
+ return DefineNestedType (name, TypeAttributes.NestedPrivate, pmodule.assemblyb.corlib_object_type, null);
}
public TypeBuilder DefineNestedType (string name, TypeAttributes attr) {
return DefineNestedType (name, attr, parent, null);
}
- private TypeBuilder DefineNestedType (string name, TypeAttributes attr, Type parent, Type[] interfaces, PackingSize packsize, int typesize) {
- TypeBuilder res = new TypeBuilder (pmodule, name, attr, parent, interfaces, packsize, typesize);
- res.nesting_type = this;
+ private TypeBuilder DefineNestedType (string name, TypeAttributes attr, Type parent, Type[] interfaces,
+ PackingSize packsize, int typesize)
+ {
+ check_name ("name", name);
+ // Visibility must be NestedXXX
+ /* This breaks mcs
+ if (((attrs & TypeAttributes.VisibilityMask) == TypeAttributes.Public) ||
+ ((attrs & TypeAttributes.VisibilityMask) == TypeAttributes.NotPublic))
+ throw new ArgumentException ("attr", "Bad type flags for nested type.");
+ */
+ if (interfaces != null)
+ foreach (Type iface in interfaces)
+ if (iface == null)
+ throw new ArgumentNullException ("interfaces");
+
+ TypeBuilder res = new TypeBuilder (pmodule, name, attr, parent, interfaces, packsize, typesize, this);
res.fullname = res.GetFullName ();
pmodule.RegisterTypeName (res, res.fullname);
if (subtypes != null) {
return DefineNestedType (name, attr, parent, null, packsize, UnspecifiedTypeSize);
}
- public ConstructorBuilder DefineConstructor( MethodAttributes attributes, CallingConventions callingConvention, Type[] parameterTypes) {
- ConstructorBuilder cb = new ConstructorBuilder (this, attributes, callingConvention, parameterTypes);
+ public ConstructorBuilder DefineConstructor (MethodAttributes attributes, CallingConventions callingConvention, Type[] parameterTypes) {
+ return DefineConstructor (attributes, callingConvention, parameterTypes, null, null);
+ }
+
+#if NET_2_0 || BOOTSTRAP_NET_2_0
+ public
+#else
+ internal
+#endif
+ 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);
if (ctors != null) {
ConstructorBuilder[] new_ctors = new ConstructorBuilder [ctors.Length+1];
System.Array.Copy (ctors, new_ctors, ctors.Length);
return cb;
}
- public ConstructorBuilder DefineDefaultConstructor( MethodAttributes attributes) {
- return DefineConstructor (attributes, CallingConventions.Standard, null);
+ public ConstructorBuilder DefineDefaultConstructor (MethodAttributes attributes)
+ {
+ Type parent_type;
+
+ if (parent != null)
+ parent_type = parent;
+ else
+ parent_type = pmodule.assemblyb.corlib_object_type;
+
+ ConstructorInfo parent_constructor =
+ parent_type.GetConstructor (
+ BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance,
+ null, Type.EmptyTypes, null);
+ if (parent_constructor == null) {
+ throw new NotSupportedException ("Parent does"
+ + " not have a default constructor."
+ + " The default constructor must be"
+ + " explicitly defined.");
+ }
+
+ ConstructorBuilder cb = DefineConstructor (attributes,
+ CallingConventions.Standard, new Type[0]);
+ ILGenerator ig = cb.GetILGenerator ();
+ ig.Emit (OpCodes.Ldarg_0);
+ ig.Emit (OpCodes.Call, parent_constructor);
+ ig.Emit (OpCodes.Ret);
+ return cb;
}
public MethodBuilder DefineMethod( string name, MethodAttributes attributes, Type returnType, Type[] parameterTypes) {
private void append_method (MethodBuilder mb) {
if (methods != null) {
- MethodBuilder[] new_methods = new MethodBuilder [methods.Length+1];
- System.Array.Copy (methods, new_methods, methods.Length);
- new_methods [methods.Length] = mb;
- methods = new_methods;
+ if (methods.Length == num_methods) {
+ MethodBuilder[] new_methods = new MethodBuilder [methods.Length * 2];
+ System.Array.Copy (methods, new_methods, num_methods);
+ methods = new_methods;
+ }
} else {
methods = new MethodBuilder [1];
- methods [0] = mb;
}
+ methods [num_methods] = mb;
+ num_methods ++;
}
public MethodBuilder DefineMethod( string name, MethodAttributes attributes, CallingConventions callingConvention, Type returnType, Type[] parameterTypes) {
- MethodBuilder res = new MethodBuilder (this, name, attributes, callingConvention, returnType, parameterTypes);
+ return DefineMethod (name, attributes, callingConvention, returnType, null, null, parameterTypes, null, null);
+ }
+
+#if NET_2_0 || BOOTSTRAP_NET_2_0
+ public
+#else
+ internal
+#endif
+ 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)))
+ throw new ArgumentException ("attributes", "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);
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) {
- MethodBuilder res = new MethodBuilder (this, name, attributes, callingConvention, returnType, parameterTypes,
- dllName, entryName, nativeCallConv, nativeCharSet);
+ return DefinePInvokeMethod (name, dllName, entryName, attributes, callingConvention, returnType, null, null, parameterTypes, null, null, nativeCallConv, nativeCharSet);
+ }
+
+#if NET_2_0 || BOOTSTRAP_NET_2_0
+ public
+#else
+ internal
+#endif
+ MethodBuilder DefinePInvokeMethod (
+ string name,
+ string dllName,
+ string entryName, MethodAttributes attributes,
+ CallingConventions callingConvention,
+ Type returnType,
+ Type[] returnTypeRequiredCustomModifiers,
+ Type[] returnTypeOptionalCustomModifiers,
+ Type[] parameterTypes,
+ Type[][] parameterTypeRequiredCustomModifiers,
+ Type[][] parameterTypeOptionalCustomModifiers,
+ CallingConvention nativeCallConv,
+ 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.");
+ if (IsInterface)
+ throw new ArgumentException ("PInvoke methods cannot exist on interfaces.");
+ check_not_created ();
+
+ MethodBuilder res
+ = new MethodBuilder (
+ this,
+ name,
+ attributes,
+ callingConvention,
+ returnType,
+ returnTypeRequiredCustomModifiers,
+ returnTypeOptionalCustomModifiers,
+ parameterTypes,
+ parameterTypeRequiredCustomModifiers,
+ parameterTypeOptionalCustomModifiers,
+ dllName,
+ entryName,
+ nativeCallConv,
+ nativeCharSet);
append_method (res);
return res;
}
}
public void DefineMethodOverride( MethodInfo methodInfoBody, MethodInfo methodInfoDeclaration) {
+ if (methodInfoBody == null)
+ throw new ArgumentNullException ("methodInfoBody");
+ if (methodInfoDeclaration == null)
+ throw new ArgumentNullException ("methodInfoDeclaration");
+ check_not_created ();
+
if (methodInfoBody is MethodBuilder) {
MethodBuilder mb = (MethodBuilder)methodInfoBody;
mb.set_override (methodInfoDeclaration);
}
public FieldBuilder DefineField( string fieldName, Type type, FieldAttributes attributes) {
- FieldBuilder res = new FieldBuilder (this, fieldName, type, attributes);
+ return DefineField (fieldName, type, null, null, attributes);
+ }
+
+#if NET_2_0 || BOOTSTRAP_NET_2_0
+ public
+#else
+ internal
+#endif
+ FieldBuilder DefineField (string fieldName, Type type, Type[] requiredCustomAttributes, Type[] optionalCustomAttributes, FieldAttributes attributes) {
+ check_name ("fieldName", fieldName);
+ if (type == typeof (void))
+ throw new ArgumentException ("type", "Bad field type in defining field.");
+ check_not_created ();
+
+ FieldBuilder res = new FieldBuilder (this, fieldName, type, attributes, requiredCustomAttributes, optionalCustomAttributes);
if (fields != null) {
- FieldBuilder[] new_fields = new FieldBuilder [fields.Length+1];
- System.Array.Copy (fields, new_fields, fields.Length);
- new_fields [fields.Length] = res;
- fields = new_fields;
+ if (fields.Length == num_fields) {
+ FieldBuilder[] new_fields = new FieldBuilder [fields.Length * 2];
+ System.Array.Copy (fields, new_fields, num_fields);
+ fields = new_fields;
+ }
+ fields [num_fields] = res;
+ num_fields ++;
} else {
fields = new FieldBuilder [1];
fields [0] = res;
+ num_fields ++;
create_internal_class (this);
}
return res;
}
public PropertyBuilder DefineProperty( string name, PropertyAttributes attributes, Type returnType, Type[] parameterTypes) {
+ check_name ("name", name);
+ if (parameterTypes != null)
+ foreach (Type param in parameterTypes)
+ if (param == null)
+ throw new ArgumentNullException ("parameterTypes");
+ check_not_created ();
+
PropertyBuilder res = new PropertyBuilder (this, name, attributes, returnType, parameterTypes);
if (properties != null) {
return res;
}
- [MonoTODO]
public ConstructorBuilder DefineTypeInitializer() {
- throw new NotImplementedException ();
+ 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) {
+ while (t != null) {
+ if (t == this)
+ return true;
+ else
+ t = t.DeclaringType;
+ }
+ return false;
+ }
public Type CreateType() {
/* handle nesting_type */
- if (created != null) {
- string err="type already created: " + created.ToString();
- throw new InvalidOperationException (err);
+ if (created != null)
+ return created;
+
+ // Fire TypeResolve events for fields whose type is an unfinished
+ // value type.
+ if (fields != null) {
+ foreach (FieldBuilder fb in fields) {
+ if (fb == null)
+ continue;
+ Type ft = fb.FieldType;
+ if (!fb.IsStatic && (ft is TypeBuilder) && ft.IsValueType && (ft != this) && is_nested_in (ft)) {
+ TypeBuilder tb = (TypeBuilder)ft;
+ if (!tb.is_created) {
+ AppDomain.CurrentDomain.DoTypeResolve (tb);
+ if (!tb.is_created) {
+ // FIXME: We should throw an exception here,
+ // but mcs expects that the type is created
+ // even if the exception is thrown
+ //throw new TypeLoadException ("Could not load type " + tb);
+ }
+ }
+ }
+ }
}
+
if (methods != null) {
- foreach (MethodBuilder method in methods) {
- method.fixup ();
- }
+ for (int i = 0; i < num_methods; ++i)
+ ((MethodBuilder)(methods[i])).fixup ();
}
- if (ctors != null) {
- foreach (ConstructorBuilder ctor in ctors) {
+
+ //
+ // On classes, define a default constructor if not provided
+ //
+ if (!(IsInterface || IsValueType) && (ctors == null) && (tname != "<Module>") &&
+ (GetAttributeFlagsImpl () & TypeAttributes.Abstract | TypeAttributes.Sealed) != (TypeAttributes.Abstract | TypeAttributes.Sealed))
+ DefineDefaultConstructor (MethodAttributes.Public);
+
+ if (ctors != null){
+ foreach (ConstructorBuilder ctor in ctors)
ctor.fixup ();
- }
}
+
created = create_runtime_class (this);
if (created != null)
return created;
return this;
}
- public override ConstructorInfo[] GetConstructors (BindingFlags bindingAttr) {
+ public override ConstructorInfo[] GetConstructors (BindingFlags bindingAttr)
+ {
if (ctors == null)
return new ConstructorInfo [0];
ArrayList l = new ArrayList ();
return result;
}
- public override Type GetElementType () { return null; }
+ public override Type GetElementType () {
+ check_created ();
+ return created.GetElementType ();
+ }
- [MonoTODO]
public override EventInfo GetEvent (string name, BindingFlags bindingAttr) {
- throw new NotImplementedException ();
+ check_created ();
+ return created.GetEvent (name, bindingAttr);
+ }
+
+ /* Needed to keep signature compatibility with MS.NET */
+ public override EventInfo[] GetEvents ()
+ {
+ return GetEvents (DefaultBindingFlags);
}
public override EventInfo[] GetEvents (BindingFlags bindingAttr) {
- return new EventInfo [0];
+ /* FIXME: mcs calls this
+ check_created ();
+ */
+ if (!is_created)
+ return new EventInfo [0];
+ else
+ return created.GetEvents (bindingAttr);
+ }
+
+ // This is only used from MonoGenericInst.initialize().
+ internal EventInfo[] GetEvents_internal (BindingFlags bindingAttr)
+ {
+ if (events == null)
+ return new EventInfo [0];
+ ArrayList l = new ArrayList ();
+ bool match;
+ MethodAttributes mattrs;
+ MethodInfo accessor;
+
+ foreach (EventBuilder eb in events) {
+ if (eb == null)
+ continue;
+ EventInfo c = get_event_info (eb);
+ match = false;
+ accessor = c.GetAddMethod (true);
+ if (accessor == null)
+ accessor = c.GetRemoveMethod (true);
+ if (accessor == null)
+ continue;
+ mattrs = accessor.Attributes;
+ if ((mattrs & MethodAttributes.MemberAccessMask) == MethodAttributes.Public) {
+ if ((bindingAttr & BindingFlags.Public) != 0)
+ match = true;
+ } else {
+ if ((bindingAttr & BindingFlags.NonPublic) != 0)
+ match = true;
+ }
+ if (!match)
+ continue;
+ match = false;
+ if ((mattrs & MethodAttributes.Static) != 0) {
+ if ((bindingAttr & BindingFlags.Static) != 0)
+ match = true;
+ } else {
+ if ((bindingAttr & BindingFlags.Instance) != 0)
+ match = true;
+ }
+ if (!match)
+ continue;
+ l.Add (c);
+ }
+ EventInfo[] result = new EventInfo [l.Count];
+ l.CopyTo (result);
+ return result;
}
- [MonoTODO]
public override FieldInfo GetField( string name, BindingFlags bindingAttr) {
- //FIXME
- throw new NotImplementedException ();
+ if (fields == null)
+ return null;
+
+ bool match;
+ FieldAttributes mattrs;
+
+ foreach (FieldInfo c in fields) {
+ if (c == null)
+ continue;
+ if (c.Name != name)
+ continue;
+ match = false;
+ mattrs = c.Attributes;
+ if ((mattrs & FieldAttributes.FieldAccessMask) == FieldAttributes.Public) {
+ if ((bindingAttr & BindingFlags.Public) != 0)
+ match = true;
+ } else {
+ if ((bindingAttr & BindingFlags.NonPublic) != 0)
+ match = true;
+ }
+ if (!match)
+ continue;
+ match = false;
+ if ((mattrs & FieldAttributes.Static) != 0) {
+ if ((bindingAttr & BindingFlags.Static) != 0)
+ match = true;
+ } else {
+ if ((bindingAttr & BindingFlags.Instance) != 0)
+ match = true;
+ }
+ if (!match)
+ continue;
+ return c;
+ }
+ return null;
}
public override FieldInfo[] GetFields (BindingFlags bindingAttr) {
FieldAttributes mattrs;
foreach (FieldInfo c in fields) {
+ if (c == null)
+ continue;
match = false;
mattrs = c.Attributes;
if ((mattrs & FieldAttributes.FieldAccessMask) == FieldAttributes.Public) {
return result;
}
- [MonoTODO]
public override Type GetInterface (string name, bool ignoreCase) {
- throw new NotImplementedException ();
+ check_created ();
+ return created.GetInterface (name, ignoreCase);
}
public override Type[] GetInterfaces () {
}
}
- [MonoTODO]
- public override MemberInfo[] GetMembers( BindingFlags bindingAttr) {
- // FIXME
- throw new NotImplementedException ();
+ public override MemberInfo[] GetMember (string name, MemberTypes type,
+ BindingFlags bindingAttr) {
+ check_created ();
+ return created.GetMember (name, type, bindingAttr);
}
- public override MethodInfo[] GetMethods (BindingFlags bindingAttr) {
- if (methods == null)
+ public override MemberInfo[] GetMembers (BindingFlags bindingAttr) {
+ check_created ();
+ return created.GetMembers (bindingAttr);
+ }
+
+ private MethodInfo[] GetMethodsByName (string name, BindingFlags bindingAttr, bool ignoreCase, Type reflected_type) {
+ MethodInfo[] candidates;
+ 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);
+ }
+ }
+ else
+ candidates = methods;
+
+ if (candidates == null)
return new MethodInfo [0];
+
ArrayList l = new ArrayList ();
bool match;
MethodAttributes mattrs;
- foreach (MethodInfo c in methods) {
+ foreach (MethodInfo c in candidates) {
+ if (c == null)
+ continue;
+ if (name != null) {
+ if (String.Compare (c.Name, name, ignoreCase) != 0)
+ continue;
+ }
match = false;
mattrs = c.Attributes;
if ((mattrs & MethodAttributes.MemberAccessMask) == MethodAttributes.Public) {
continue;
l.Add (c);
}
+
MethodInfo[] result = new MethodInfo [l.Count];
l.CopyTo (result);
return result;
}
- [MonoTODO]
- protected override MethodInfo GetMethodImpl( string name, BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers) {
- // FIXME
- throw new NotImplementedException ();
+ public override MethodInfo[] GetMethods (BindingFlags bindingAttr) {
+ return GetMethodsByName (null, bindingAttr, false, this);
}
-
- [MonoTODO]
+
+ protected override MethodInfo GetMethodImpl (string name, BindingFlags bindingAttr,
+ Binder binder,
+ CallingConventions callConvention,
+ Type[] types, ParameterModifier[] modifiers)
+ {
+ check_created ();
+
+ bool ignoreCase = ((bindingAttr & BindingFlags.IgnoreCase) != 0);
+ MethodInfo[] methods = GetMethodsByName (name, bindingAttr, ignoreCase, this);
+ MethodInfo found = null;
+ MethodBase[] match;
+ int typesLen = (types != null) ? types.Length : 0;
+ int count = 0;
+
+ foreach (MethodInfo m in methods) {
+ // Under MS.NET, Standard|HasThis matches Standard...
+ if (callConvention != CallingConventions.Any && ((m.CallingConvention & callConvention) != callConvention))
+ continue;
+ found = m;
+ count++;
+ }
+
+ if (count == 0)
+ return null;
+
+ if (count == 1 && typesLen == 0)
+ return found;
+
+ match = new MethodBase [count];
+ if (count == 1)
+ match [0] = found;
+ else {
+ count = 0;
+ foreach (MethodInfo m in methods) {
+ if (callConvention != CallingConventions.Any && ((m.CallingConvention & callConvention) != callConvention))
+ continue;
+ match [count++] = m;
+ }
+ }
+
+ if (types == null)
+ return (MethodInfo) Binder.FindMostDerivedMatch (match);
+
+ if (binder == null)
+ binder = Binder.DefaultBinder;
+
+ return (MethodInfo)binder.SelectMethod (bindingAttr, match, types, modifiers);
+ }
+
public override Type GetNestedType( string name, BindingFlags bindingAttr) {
- // FIXME
- throw new NotImplementedException ();
+ check_created ();
+ return created.GetNestedType (name, bindingAttr);
}
public override Type[] GetNestedTypes (BindingFlags bindingAttr) {
bool match;
ArrayList result = new ArrayList ();
-
+
if (subtypes == null)
return Type.EmptyTypes;
foreach (TypeBuilder t in subtypes) {
return result;
}
- [MonoTODO]
protected override PropertyInfo GetPropertyImpl( string name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers) {
- // FIXME
- throw new NotImplementedException ();
+ throw not_supported ();
}
protected override bool HasElementTypeImpl () {
- return IsArrayImpl() || IsByRefImpl() || IsPointerImpl ();
+ check_created ();
+ return created.HasElementType;
}
- [MonoTODO]
public override object InvokeMember( string name, BindingFlags invokeAttr, Binder binder, object target, object[] args, ParameterModifier[] modifiers, CultureInfo culture, string[] namedParameters) {
- // FIXME
- throw new NotImplementedException ();
+ check_created ();
+ return created.InvokeMember (name, invokeAttr, binder, target, args, modifiers, culture, namedParameters);
}
- protected override bool IsArrayImpl () {
- return type_is_subtype_of (this, typeof (System.Array), false);
+ protected override bool IsArrayImpl ()
+ {
+ return Type.IsArrayImpl (this);
}
+
protected override bool IsByRefImpl () {
// FIXME
return false;
this != pmodule.assemblyb.corlib_enum_type);
}
- public override RuntimeTypeHandle TypeHandle { get { return _impl; } }
+ public override RuntimeTypeHandle TypeHandle {
+ get {
+ check_created ();
+ return created.TypeHandle;
+ }
+ }
public void SetCustomAttribute( CustomAttributeBuilder customBuilder) {
+ if (customBuilder == null)
+ throw new ArgumentNullException ("customBuilder");
+
string attrname = customBuilder.Ctor.ReflectedType.FullName;
if (attrname == "System.Runtime.InteropServices.StructLayoutAttribute") {
byte[] data = customBuilder.Data;
int nnamed = (int)data [pos++];
nnamed |= ((int)data [pos++]) << 8;
for (int i = 0; i < nnamed; ++i) {
- byte named_type = data [pos++];
+ //byte named_type = data [pos++];
+ pos ++;
byte type = data [pos++];
- int len = CustomAttributeBuilder.decode_len (data, pos, out pos);
- string named_name = CustomAttributeBuilder.string_from_bytes (data, pos, len);
+ int len;
+ string named_name;
+
+ if (type == 0x55) {
+ len = CustomAttributeBuilder.decode_len (data, pos, out pos);
+ //string named_typename =
+ CustomAttributeBuilder.string_from_bytes (data, pos, len);
+ pos += len;
+ // FIXME: Check that 'named_type' and 'named_typename' match, etc.
+ // See related code/FIXME in mono/mono/metadata/reflection.c
+ }
+
+ len = CustomAttributeBuilder.decode_len (data, pos, out pos);
+ named_name = CustomAttributeBuilder.string_from_bytes (data, pos, len);
pos += len;
/* all the fields are integers in StructLayout */
int value = (int)data [pos++];
switch ((CharSet)value) {
case CharSet.None:
case CharSet.Ansi:
+ attrs &= ~(TypeAttributes.UnicodeClass | TypeAttributes.AutoClass);
break;
case CharSet.Unicode:
+ attrs &= ~TypeAttributes.AutoClass;
attrs |= TypeAttributes.UnicodeClass;
break;
case CharSet.Auto:
+ attrs &= ~TypeAttributes.UnicodeClass;
attrs |= TypeAttributes.AutoClass;
break;
default:
}
public EventBuilder DefineEvent( string name, EventAttributes attributes, Type eventtype) {
+ check_name ("name", name);
+ if (eventtype == null)
+ throw new ArgumentNullException ("eventtype");
+ check_not_created ();
+
EventBuilder res = new EventBuilder (this, name, attributes, eventtype);
if (events != null) {
EventBuilder[] new_events = new EventBuilder [events.Length+1];
return res;
}
- static int InitializedDataCount = 0;
-
public FieldBuilder DefineInitializedData( string name, byte[] data, FieldAttributes attributes) {
- TypeBuilder datablobtype = DefineNestedType ("$ArrayType$"+InitializedDataCount.ToString(),
- TypeAttributes.NestedPrivate|TypeAttributes.ExplicitLayout|TypeAttributes.Sealed,
- pmodule.assemblyb.corlib_value_type, null, PackingSize.Size1, data.Length);
- datablobtype.packing_size = PackingSize.Size1;
- datablobtype.class_size = data.Length;
- datablobtype.CreateType ();
- FieldBuilder res = DefineField (name, datablobtype, attributes|FieldAttributes.Assembly|FieldAttributes.Static|FieldAttributes.HasFieldRVA);
+ 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);
- InitializedDataCount++;
+
return res;
}
- [MonoTODO]
+ static int UnmanagedDataCount = 0;
+
public FieldBuilder DefineUninitializedData( string name, int size, FieldAttributes attributes) {
- throw new NotImplementedException ();
+ check_name ("name", name);
+ if ((size <= 0) || (size > 0x3f0000))
+ throw new ArgumentException ("size", "Data size must be > 0 and < 0x3f0000");
+ check_not_created ();
+
+ string s = "$ArrayType$"+UnmanagedDataCount.ToString();
+ UnmanagedDataCount++;
+ TypeBuilder datablobtype = DefineNestedType (s,
+ TypeAttributes.NestedPrivate|TypeAttributes.ExplicitLayout|TypeAttributes.Sealed,
+ pmodule.assemblyb.corlib_value_type, null, PackingSize.Size1, size);
+ datablobtype.CreateType ();
+ return DefineField (name, datablobtype, attributes|FieldAttributes.Static|FieldAttributes.HasFieldRVA);
}
public TypeToken TypeToken {
}
}
public void SetParent (Type parentType) {
+ if (parentType == null)
+ throw new ArgumentNullException ("parentType");
+ check_not_created ();
+
parent = parentType;
+ // 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);
return created.GetInterfaceMap (interfaceType);
}
+
+ internal bool is_created {
+ get {
+ return created != null;
+ }
+ }
+
+ private Exception not_supported ()
+ {
+ return new NotSupportedException ("The invoked member is not supported in a dynamic module.");
+ }
+
+ private void check_not_created ()
+ {
+ if (is_created)
+ throw new InvalidOperationException ("Unable to change after type has been created.");
+ }
+
+ private void check_created ()
+ {
+ if (!is_created)
+ throw not_supported ();
+ }
+
+ private void check_name (string argName, string name)
+ {
+ if (name == null)
+ throw new ArgumentNullException (argName);
+ if (name == "")
+ throw new ArgumentException (argName, "Empty name is not legal.");
+ if (name.IndexOf ((char)0) != -1)
+ throw new ArgumentException (argName, "Illegal name.");
+ }
+
+ public override String ToString ()
+ {
+ return FullName;
+ }
+
+ [MonoTODO]
+ public override bool IsAssignableFrom (Type c)
+ {
+ return base.IsAssignableFrom (c);
+ }
+
+ [MonoTODO]
+ public override bool IsSubclassOf (Type c)
+ {
+ return base.IsSubclassOf (c);
+ }
+
+ [MonoTODO ("arrays")]
+ internal bool IsAssignableTo (Type c)
+ {
+ if (c == this)
+ return true;
+
+ if (c.IsInterface) {
+ if (interfaces == null)
+ return false;
+ foreach (Type t in interfaces)
+ if (c.IsAssignableFrom (t))
+ return true;
+ return false;
+ }
+
+ if (parent == null)
+ return c == typeof (object);
+ else
+ return c.IsAssignableFrom (parent);
+ }
+
+#if NET_2_0 || BOOTSTRAP_NET_2_0
+ public bool IsCreated () {
+ return is_created;
+ }
+
+ public override Type[] GetGenericArguments ()
+ {
+ if (generic_params != null)
+ return generic_params;
+
+ throw new InvalidOperationException ();
+ }
+
+ public override Type GetGenericTypeDefinition ()
+ {
+ create_generic_class ();
+
+ return base.GetGenericTypeDefinition ();
+ }
+
+ public override bool HasGenericArguments {
+ get {
+ throw new NotImplementedException ();
+ }
+ }
+
+ public override bool ContainsGenericParameters {
+ get {
+ return generic_params != null;
+ }
+ }
+
+ public extern override bool IsGenericParameter {
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ get;
+ }
+
+ public override int GenericParameterPosition {
+ get {
+ throw new NotImplementedException ();
+ }
+ }
+
+ public override MethodInfo DeclaringMethod {
+ get {
+ throw new NotImplementedException ();
+ }
+ }
+
+ public GenericTypeParameterBuilder[] DefineGenericParameters (params string[] names)
+ {
+ setup_generic_class ();
+
+ generic_params = new GenericTypeParameterBuilder [names.Length];
+ for (int i = 0; i < names.Length; i++)
+ generic_params [i] = new GenericTypeParameterBuilder (
+ this, null, names [i], i);
+
+ return generic_params;
+ }
+
+ public MethodBuilder DefineGenericMethod (string name, MethodAttributes attributes)
+ {
+ return DefineMethod (name, attributes, CallingConventions.Standard, null, null);
+ }
+#endif
}
}