Merge pull request #3626 from lateralusX/jlorenss/win-api-family-support-eglib
[mono.git] / mcs / class / corlib / System.Reflection.Emit / ModuleBuilder.cs
index e5326dc08f603cd258460221d1d28a53c24d16f5..8d485153e38157f892cea66037eb53e78e76057a 100644 (file)
@@ -67,7 +67,8 @@ namespace System.Reflection.Emit {
                
                private TypeBuilder global_type;
                private Type global_type_created;
-               Hashtable name_cache;
+               // name_cache keys are display names
+               Dictionary<TypeName, TypeBuilder> name_cache;
                Dictionary<string, int> us_string_cache;
                private int[] table_indexes;
                bool transient;
@@ -90,7 +91,7 @@ namespace System.Reflection.Emit {
                        guid = Guid.FastNewGuidArray ();
                        // guid = Guid.NewGuid().ToByteArray ();
                        table_idx = get_next_table_index (this, 0x00, true);
-                       name_cache = new Hashtable ();
+                       name_cache = new Dictionary<TypeName, TypeBuilder> ();
                        us_string_cache = new Dictionary<string, int> (512);
 
                        basic_init (this);
@@ -262,24 +263,27 @@ namespace System.Reflection.Emit {
                private TypeBuilder DefineType (string name, TypeAttributes attr, Type parent, Type[] interfaces, PackingSize packingSize, int typesize) {
                        if (name == null)
                                throw new ArgumentNullException ("fullname");
-                       if (name_cache.ContainsKey (name))
+                       TypeIdentifier ident = TypeIdentifiers.FromInternal (name);
+                       if (name_cache.ContainsKey (ident))
                                throw new ArgumentException ("Duplicate type name within an assembly.");
                        TypeBuilder res = new TypeBuilder (this, name, attr, parent, interfaces, packingSize, typesize, null);
                        AddType (res);
 
-                       name_cache.Add (name, res);
+                       name_cache.Add (ident, res);
                        
                        return res;
                }
 
-               internal void RegisterTypeName (TypeBuilder tb, string name)
+               internal void RegisterTypeName (TypeBuilder tb, TypeName name)
                {
                        name_cache.Add (name, tb);
                }
                
-               internal TypeBuilder GetRegisteredType (string name)
+               internal TypeBuilder GetRegisteredType (TypeName name)
                {
-                       return (TypeBuilder) name_cache [name];
+                       TypeBuilder result = null;
+                       name_cache.TryGetValue (name, out result);
+                       return result;
                }
 
                [ComVisible (true)]
@@ -288,7 +292,7 @@ namespace System.Reflection.Emit {
                }
 
                public TypeBuilder DefineType (string name, TypeAttributes attr, Type parent, int typesize) {
-                       return DefineType (name, attr, parent, null, PackingSize.Unspecified, TypeBuilder.UnspecifiedTypeSize);
+                       return DefineType (name, attr, parent, null, PackingSize.Unspecified, typesize);
                }
 
                public TypeBuilder DefineType (string name, TypeAttributes attr, Type parent, PackingSize packsize) {
@@ -304,13 +308,14 @@ namespace System.Reflection.Emit {
                }
 
                public EnumBuilder DefineEnum( string name, TypeAttributes visibility, Type underlyingType) {
-                       if (name_cache.Contains (name))
+                       TypeIdentifier ident = TypeIdentifiers.FromInternal (name);
+                       if (name_cache.ContainsKey (ident))
                                throw new ArgumentException ("Duplicate type name within an assembly.");
 
                        EnumBuilder eb = new EnumBuilder (this, name, visibility, underlyingType);
                        TypeBuilder res = eb.GetTypeBuilder ();
                        AddType (res);
-                       name_cache.Add (name, res);
+                       name_cache.Add (ident, res);
                        return eb;
                }
 
@@ -324,48 +329,36 @@ namespace System.Reflection.Emit {
                        return GetType (className, false, ignoreCase);
                }
 
-               private TypeBuilder search_in_array (TypeBuilder[] arr, int validElementsInArray, string className) {
+               private TypeBuilder search_in_array (TypeBuilder[] arr, int validElementsInArray, TypeName className) {
                        int i;
                        for (i = 0; i < validElementsInArray; ++i) {
-                               if (String.Compare (className, arr [i].FullName, true, CultureInfo.InvariantCulture) == 0) {
+                               if (String.Compare (className.DisplayName, arr [i].FullName, true, CultureInfo.InvariantCulture) == 0) {
                                        return arr [i];
                                }
                        }
                        return null;
                }
 
-               private TypeBuilder search_nested_in_array (TypeBuilder[] arr, int validElementsInArray, string className) {
+               private TypeBuilder search_nested_in_array (TypeBuilder[] arr, int validElementsInArray, TypeName className) {
                        int i;
                        for (i = 0; i < validElementsInArray; ++i) {
-                               if (String.Compare (className, arr [i].Name, true, CultureInfo.InvariantCulture) == 0)
+                               if (String.Compare (className.DisplayName, arr [i].Name, true, CultureInfo.InvariantCulture) == 0)
                                        return arr [i];
                        }
                        return null;
                }
 
-               [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               private static extern Type create_modified_type (TypeBuilder tb, string modifiers);
-
-               static readonly char [] type_modifiers = {'&', '[', '*'};
-
-               private TypeBuilder GetMaybeNested (TypeBuilder t, string className) {
-                       int subt;
-                       string pname, rname;
+               private TypeBuilder GetMaybeNested (TypeBuilder t, IEnumerable<TypeName> nested) {
+                       TypeBuilder result = t;
 
-                       subt = className.IndexOf ('+');
-                       if (subt < 0) {
-                               if (t.subtypes != null)
-                                       return search_nested_in_array (t.subtypes, t.subtypes.Length, className);
-                               return null;
-                       }
-                       if (t.subtypes != null) {
-                               pname = className.Substring (0, subt);
-                               rname = className.Substring (subt + 1);
-                               TypeBuilder result = search_nested_in_array (t.subtypes, t.subtypes.Length, pname);
-                               if (result != null)
-                                       return GetMaybeNested (result, rname);
+                       foreach (TypeName pname in nested) {
+                               if (result.subtypes == null)
+                                       return null;
+                               result = search_nested_in_array(result.subtypes, result.subtypes.Length, pname);
+                               if (result == null)
+                                       return null;
                        }
-                       return null;
+                       return result;
                }
 
                [ComVisible (true)]
@@ -376,41 +369,47 @@ namespace System.Reflection.Emit {
                        if (className.Length == 0)
                                throw new ArgumentException ("className");
 
-                       int subt;
-                       string orig = className;
-                       string modifiers;
                        TypeBuilder result = null;
 
                        if (types == null && throwOnError)
                                throw new TypeLoadException (className);
 
-                       subt = className.IndexOfAny (type_modifiers);
-                       if (subt >= 0) {
-                               modifiers = className.Substring (subt);
-                               className = className.Substring (0, subt);
-                       } else
-                               modifiers = null;
+                       TypeSpec ts = TypeSpec.Parse (className);
 
                        if (!ignoreCase) {
-                               result =  name_cache [className] as TypeBuilder;
+                               var displayNestedName = ts.TypeNameWithoutModifiers();
+                               name_cache.TryGetValue (displayNestedName, out result);
                        } else {
-                               subt = className.IndexOf ('+');
-                               if (subt < 0) {
-                                       if (types != null)
-                                               result = search_in_array (types, num_types,  className);
-                               } else {
-                                       string pname, rname;
-                                       pname = className.Substring (0, subt);
-                                       rname = className.Substring (subt + 1);
-                                       result = search_in_array (types, num_types, pname);
-                                       if (result != null)
-                                               result = GetMaybeNested (result, rname);
+                               if (types != null)
+                                       result = search_in_array (types, num_types,  ts.Name);
+                               if (!ts.IsNested && result != null) {
+                                       result = GetMaybeNested (result, ts.Nested);
                                }
                        }
                        if ((result == null) && throwOnError)
-                               throw new TypeLoadException (orig);
-                       if (result != null && (modifiers != null)) {
-                               Type mt = create_modified_type (result, modifiers);
+                               throw new TypeLoadException (className);
+                       if (result != null && (ts.HasModifiers || ts.IsByRef)) {
+                               Type mt = result;
+                               if (result is TypeBuilder) {
+                                       var tb = result as TypeBuilder;
+                                       if (tb.is_created)
+                                               mt = tb.CreateType ();
+                               }
+                               foreach (var mod in ts.Modifiers) {
+                                       if (mod is PointerSpec)
+                                               mt = mt.MakePointerType ();
+                                       else if (mod is ArraySpec) {
+                                               var spec = mod as ArraySpec;
+                                               if (spec.IsBound)
+                                                       return null;
+                                               if (spec.Rank == 1)
+                                                       mt = mt.MakeArrayType ();
+                                               else
+                                                       mt = mt.MakeArrayType (spec.Rank);
+                                       }
+                               }
+                               if (ts.IsByRef)
+                                       mt = mt.MakeByRefType ();
                                result = mt as TypeBuilder;
                                if (result == null)
                                        return mt;
@@ -583,10 +582,17 @@ namespace System.Reflection.Emit {
                {
                        if (method == null)
                                throw new ArgumentNullException ("method");
-                       if (method.DeclaringType.Module != this)
-                               throw new InvalidOperationException ("The method is not in this module");
+
                        return new MethodToken (GetToken (method));
                }
+               
+               public MethodToken GetMethodToken (MethodInfo method, IEnumerable<Type> optionalParameterTypes)
+               {
+                       if (method == null)
+                               throw new ArgumentNullException ("method");
+
+                       return new MethodToken (GetToken (method, optionalParameterTypes));
+               }
 
                public MethodToken GetArrayMethodToken (Type arrayClass, string methodName, CallingConventions callingConvention, Type returnType, Type[] parameterTypes)
                {
@@ -598,17 +604,23 @@ namespace System.Reflection.Emit {
                {
                        if (con == null)
                                throw new ArgumentNullException ("con");
-                       if (con.DeclaringType.Module != this)
-                               throw new InvalidOperationException ("The constructor is not in this module");
+
                        return new MethodToken (GetToken (con));
                }
+               
+               public MethodToken GetConstructorToken (ConstructorInfo constructor, IEnumerable<Type> optionalParameterTypes)
+               {
+                       if (constructor == null)
+                               throw new ArgumentNullException ("constructor");
+
+                       return new MethodToken (GetToken (constructor, optionalParameterTypes));
+               }
 
                public FieldToken GetFieldToken (FieldInfo field)
                {
                        if (field == null)
                                throw new ArgumentNullException ("field");
-                       if (field.DeclaringType.Module != this)
-                               throw new InvalidOperationException ("The method is not in this module");
+
                        return new FieldToken (GetToken (field));
                }
 
@@ -677,6 +689,14 @@ namespace System.Reflection.Emit {
                        return getToken (this, member, create_open_instance);
                }
 
+               internal int GetToken (MethodBase method, IEnumerable<Type> opt_param_types) {
+                       if (opt_param_types == null)
+                               return getToken (this, method, true);
+
+                       var optParamTypes = new List<Type> (opt_param_types);
+                       return  getMethodToken (this, method, optParamTypes.ToArray ());
+               }
+               
                internal int GetToken (MethodBase method, Type[] opt_param_types) {
                        return getMethodToken (this, method, opt_param_types);
                }
@@ -692,6 +712,12 @@ namespace System.Reflection.Emit {
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                internal extern void RegisterToken (object obj, int token);
 
+               /*
+                * Returns MemberInfo registered with the given token.
+                */
+               [MethodImplAttribute(MethodImplOptions.InternalCall)]
+               internal extern object GetRegisteredToken (int token);
+
                internal TokenGenerator GetTokenGenerator () {
                        if (token_gen == null)
                                token_gen = new ModuleBuilderTokenGenerator (this);
@@ -724,7 +750,7 @@ namespace System.Reflection.Emit {
                                        if (resource_writers != null && (rwriter = resource_writers [resources [i].name] as IResourceWriter) != null) {
                                                ResourceWriter writer = (ResourceWriter)rwriter;
                                                writer.Generate ();
-                                               MemoryStream mstream = (MemoryStream)writer.Stream;
+                                               MemoryStream mstream = (MemoryStream)writer._output;
                                                resources [i].data = new byte [mstream.Length];
                                                mstream.Seek (0, SeekOrigin.Begin);
                                                mstream.Read (resources [i].data, 0, (int)mstream.Length);
@@ -875,6 +901,20 @@ namespace System.Reflection.Emit {
                                return m;
                }
 
+               internal MemberInfo ResolveOrGetRegisteredToken (int metadataToken, Type [] genericTypeArguments, Type [] genericMethodArguments)
+               {
+                       ResolveTokenError error;
+                       MemberInfo m = ResolveMemberToken (_impl, metadataToken, ptrs_from_types (genericTypeArguments), ptrs_from_types (genericMethodArguments), out error);
+                       if (m != null)
+                               return m;
+
+                       m = GetRegisteredToken (metadataToken) as MemberInfo;
+                       if (m == null)
+                               throw resolve_token_exception (metadataToken, error, "MemberInfo");
+                       else
+                               return m;
+               }
+
                public override MethodBase ResolveMethod (int metadataToken, Type [] genericTypeArguments, Type [] genericMethodArguments) {
                        ResolveTokenError error;