do not check order sequence if option /order was not used
[mono.git] / mcs / class / IKVM.Reflection / Reader / TypeDefImpl.cs
index 1a2f0171b5a0df8ab920680cbabeb7291f1dd6bc..e4a036d5674cd71a26560fa0babd6f52ceb2ce4b 100644 (file)
@@ -29,7 +29,7 @@ using IKVM.Reflection.Metadata;
 
 namespace IKVM.Reflection.Reader
 {
-       sealed class TypeDefImpl : Type
+       sealed class TypeDefImpl : TypeInfo
        {
                private readonly ModuleReader module;
                private readonly int index;
@@ -43,6 +43,7 @@ namespace IKVM.Reflection.Reader
                        this.index = index;
                        this.typeName = module.GetString(module.TypeDef.records[index].TypeName);
                        this.typeNamespace = module.GetString(module.TypeDef.records[index].TypeNamespace);
+                       MarkEnumOrValueType(typeNamespace, typeName);
                }
 
                public override Type BaseType
@@ -65,31 +66,26 @@ namespace IKVM.Reflection.Reader
 
                public override EventInfo[] __GetDeclaredEvents()
                {
-                       int token = this.MetadataToken;
-                       // TODO use binary search?
-                       for (int i = 0; i < module.EventMap.records.Length; i++)
+                       foreach (int i in module.EventMap.Filter(this.MetadataToken))
                        {
-                               if (module.EventMap.records[i].Parent == token)
+                               int evt = module.EventMap.records[i].EventList - 1;
+                               int end = module.EventMap.records.Length > i + 1 ? module.EventMap.records[i + 1].EventList - 1 : module.Event.records.Length;
+                               EventInfo[] events = new EventInfo[end - evt];
+                               if (module.EventPtr.RowCount == 0)
                                {
-                                       int evt = module.EventMap.records[i].EventList - 1;
-                                       int end = module.EventMap.records.Length > i + 1 ? module.EventMap.records[i + 1].EventList - 1 : module.Event.records.Length;
-                                       EventInfo[] events = new EventInfo[end - evt];
-                                       if (module.EventPtr.RowCount == 0)
+                                       for (int j = 0; evt < end; evt++, j++)
                                        {
-                                               for (int j = 0; evt < end; evt++, j++)
-                                               {
-                                                       events[j] = new EventInfoImpl(module, this, evt);
-                                               }
+                                               events[j] = new EventInfoImpl(module, this, evt);
                                        }
-                                       else
+                               }
+                               else
+                               {
+                                       for (int j = 0; evt < end; evt++, j++)
                                        {
-                                               for (int j = 0; evt < end; evt++, j++)
-                                               {
-                                                       events[j] = new EventInfoImpl(module, this, module.EventPtr.records[evt] - 1);
-                                               }
+                                               events[j] = new EventInfoImpl(module, this, module.EventPtr.records[evt] - 1);
                                        }
-                                       return events;
                                }
+                               return events;
                        }
                        return Empty<EventInfo>.Array;
                }
@@ -118,19 +114,14 @@ namespace IKVM.Reflection.Reader
 
                public override Type[] __GetDeclaredInterfaces()
                {
-                       int token = this.MetadataToken;
                        List<Type> list = null;
-                       // TODO use binary search?
-                       for (int i = 0; i < module.InterfaceImpl.records.Length; i++)
+                       foreach (int i in module.InterfaceImpl.Filter(this.MetadataToken))
                        {
-                               if (module.InterfaceImpl.records[i].Class == token)
+                               if (list == null)
                                {
-                                       if (list == null)
-                                       {
-                                               list = new List<Type>();
-                                       }
-                                       list.Add(module.ResolveType(module.InterfaceImpl.records[i].Interface, this));
+                                       list = new List<Type>();
                                }
+                               list.Add(module.ResolveType(module.InterfaceImpl.records[i].Interface, this));
                        }
                        return Util.ToArray(list, Type.EmptyTypes);
                }
@@ -159,25 +150,21 @@ namespace IKVM.Reflection.Reader
 
                public override __MethodImplMap __GetMethodImplMap()
                {
+                       PopulateGenericArguments();
                        List<MethodInfo> bodies = new List<MethodInfo>();
                        List<List<MethodInfo>> declarations = new List<List<MethodInfo>>();
-                       int token = this.MetadataToken;
-                       // TODO use binary search?
-                       for (int i = 0; i < module.MethodImpl.records.Length; i++)
+                       foreach (int i in module.MethodImpl.Filter(this.MetadataToken))
                        {
-                               if (module.MethodImpl.records[i].Class == token)
+                               MethodInfo body = (MethodInfo)module.ResolveMethod(module.MethodImpl.records[i].MethodBody, typeArgs, null);
+                               int index = bodies.IndexOf(body);
+                               if (index == -1)
                                {
-                                       MethodInfo body = (MethodInfo)module.ResolveMethod(module.MethodImpl.records[i].MethodBody, typeArgs, null);
-                                       int index = bodies.IndexOf(body);
-                                       if (index == -1)
-                                       {
-                                               index = bodies.Count;
-                                               bodies.Add(body);
-                                               declarations.Add(new List<MethodInfo>());
-                                       }
-                                       MethodInfo declaration = (MethodInfo)module.ResolveMethod(module.MethodImpl.records[i].MethodDeclaration, typeArgs, null);
-                                       declarations[index].Add(declaration);
+                                       index = bodies.Count;
+                                       bodies.Add(body);
+                                       declarations.Add(new List<MethodInfo>());
                                }
+                               MethodInfo declaration = (MethodInfo)module.ResolveMethod(module.MethodImpl.records[i].MethodDeclaration, typeArgs, null);
+                               declarations[index].Add(declaration);
                        }
                        __MethodImplMap map = new __MethodImplMap();
                        map.TargetType = this;
@@ -194,7 +181,7 @@ namespace IKVM.Reflection.Reader
                {
                        int token = this.MetadataToken;
                        List<Type> list = new List<Type>();
-                       // TODO use binary search?
+                       // note that the NestedClass table is sorted on NestedClass, so we can't use binary search
                        for (int i = 0; i < module.NestedClass.records.Length; i++)
                        {
                                if (module.NestedClass.records[i].EnclosingClass == token)
@@ -207,31 +194,26 @@ namespace IKVM.Reflection.Reader
 
                public override PropertyInfo[] __GetDeclaredProperties()
                {
-                       int token = this.MetadataToken;
-                       // TODO use binary search?
-                       for (int i = 0; i < module.PropertyMap.records.Length; i++)
+                       foreach (int i in module.PropertyMap.Filter(this.MetadataToken))
                        {
-                               if (module.PropertyMap.records[i].Parent == token)
+                               int property = module.PropertyMap.records[i].PropertyList - 1;
+                               int end = module.PropertyMap.records.Length > i + 1 ? module.PropertyMap.records[i + 1].PropertyList - 1 : module.Property.records.Length;
+                               PropertyInfo[] properties = new PropertyInfo[end - property];
+                               if (module.PropertyPtr.RowCount == 0)
                                {
-                                       int property = module.PropertyMap.records[i].PropertyList - 1;
-                                       int end = module.PropertyMap.records.Length > i + 1 ? module.PropertyMap.records[i + 1].PropertyList - 1 : module.Property.records.Length;
-                                       PropertyInfo[] properties = new PropertyInfo[end - property];
-                                       if (module.PropertyPtr.RowCount == 0)
+                                       for (int j = 0; property < end; property++, j++)
                                        {
-                                               for (int j = 0; property < end; property++, j++)
-                                               {
-                                                       properties[j] = new PropertyInfoImpl(module, this, property);
-                                               }
+                                               properties[j] = new PropertyInfoImpl(module, this, property);
                                        }
-                                       else
+                               }
+                               else
+                               {
+                                       for (int j = 0; property < end; property++, j++)
                                        {
-                                               for (int j = 0; property < end; property++, j++)
-                                               {
-                                                       properties[j] = new PropertyInfoImpl(module, this, module.PropertyPtr.records[property] - 1);
-                                               }
+                                               properties[j] = new PropertyInfoImpl(module, this, module.PropertyPtr.records[property] - 1);
                                        }
-                                       return properties;
                                }
+                               return properties;
                        }
                        return Empty<PropertyInfo>.Array;
                }
@@ -296,16 +278,10 @@ namespace IKVM.Reflection.Reader
                        return typeArgs[index];
                }
 
-               public override Type[][] __GetGenericArgumentsOptionalCustomModifiers()
+               public override CustomModifiers[] __GetGenericArgumentsCustomModifiers()
                {
                        PopulateGenericArguments();
-                       return Util.Copy(new Type[typeArgs.Length][]);
-               }
-
-               public override Type[][] __GetGenericArgumentsRequiredCustomModifiers()
-               {
-                       PopulateGenericArguments();
-                       return Util.Copy(new Type[typeArgs.Length][]);
+                       return new CustomModifiers[typeArgs.Length];
                }
 
                public override bool IsGenericType
@@ -315,7 +291,16 @@ namespace IKVM.Reflection.Reader
 
                public override bool IsGenericTypeDefinition
                {
-                       get { return module.GenericParam.FindFirstByOwner(this.MetadataToken) != -1; }
+                       get
+                       {
+                               if ((typeFlags & (TypeFlags.IsGenericTypeDefinition | TypeFlags.NotGenericTypeDefinition)) == 0)
+                               {
+                                       typeFlags |= module.GenericParam.FindFirstByOwner(this.MetadataToken) == -1
+                                               ? TypeFlags.NotGenericTypeDefinition
+                                               : TypeFlags.IsGenericTypeDefinition;
+                               }
+                               return (typeFlags & TypeFlags.IsGenericTypeDefinition) != 0;
+                       }
                }
 
                public override Type GetGenericTypeDefinition()
@@ -358,14 +343,9 @@ namespace IKVM.Reflection.Reader
                                {
                                        return null;
                                }
-                               // TODO use binary search (if sorted)
-                               int token = this.MetadataToken;
-                               for (int i = 0; i < module.NestedClass.records.Length; i++)
+                               foreach (int i in module.NestedClass.Filter(this.MetadataToken))
                                {
-                                       if (module.NestedClass.records[i].NestedClass == token)
-                                       {
-                                               return module.ResolveType(module.NestedClass.records[i].EnclosingClass, null, null);
-                                       }
+                                       return module.ResolveType(module.NestedClass.records[i].EnclosingClass, null, null);
                                }
                                throw new InvalidOperationException();
                        }
@@ -379,7 +359,8 @@ namespace IKVM.Reflection.Reader
                                switch (this.Attributes & TypeAttributes.LayoutMask)
                                {
                                        case TypeAttributes.AutoLayout:
-                                               return null;
+                                               layout = new StructLayoutAttribute(LayoutKind.Auto);
+                                               break;
                                        case TypeAttributes.SequentialLayout:
                                                layout = new StructLayoutAttribute(LayoutKind.Sequential);
                                                break;
@@ -389,36 +370,43 @@ namespace IKVM.Reflection.Reader
                                        default:
                                                throw new BadImageFormatException();
                                }
-                               int token = this.MetadataToken;
-                               // TODO use binary search?
-                               for (int i = 0; i < module.ClassLayout.records.Length; i++)
+                               switch (this.Attributes & TypeAttributes.StringFormatMask)
                                {
-                                       if (module.ClassLayout.records[i].Parent == token)
-                                       {
-                                               layout.Pack = module.ClassLayout.records[i].PackingSize;
-                                               layout.Size = module.ClassLayout.records[i].ClassSize;
-                                               switch (this.Attributes & TypeAttributes.StringFormatMask)
-                                               {
-                                                       case TypeAttributes.AnsiClass:
-                                                               layout.CharSet = CharSet.Ansi;
-                                                               break;
-                                                       case TypeAttributes.UnicodeClass:
-                                                               layout.CharSet = CharSet.Unicode;
-                                                               break;
-                                                       case TypeAttributes.AutoClass:
-                                                               layout.CharSet = CharSet.Auto;
-                                                               break;
-                                                       default:
-                                                               layout.CharSet = CharSet.None;
-                                                               break;
-                                               }
-                                               return layout;
-                                       }
+                                       case TypeAttributes.AnsiClass:
+                                               layout.CharSet = CharSet.Ansi;
+                                               break;
+                                       case TypeAttributes.UnicodeClass:
+                                               layout.CharSet = CharSet.Unicode;
+                                               break;
+                                       case TypeAttributes.AutoClass:
+                                               layout.CharSet = CharSet.Auto;
+                                               break;
+                                       default:
+                                               layout.CharSet = CharSet.None;
+                                               break;
+                               }
+                               if (!__GetLayout(out layout.Pack, out layout.Size))
+                               {
+                                       // compatibility with System.Reflection
+                                       layout.Pack = 8;
                                }
-                               return null;
+                               return layout;
                        }
                }
 
+               public override bool __GetLayout(out int packingSize, out int typeSize)
+               {
+                       foreach (int i in module.ClassLayout.Filter(this.MetadataToken))
+                       {
+                               packingSize = module.ClassLayout.records[i].PackingSize;
+                               typeSize = module.ClassLayout.records[i].ClassSize;
+                               return true;
+                       }
+                       packingSize = 0;
+                       typeSize = 0;
+                       return false;
+               }
+
                public override Module Module
                {
                        get { return module; }
@@ -428,5 +416,10 @@ namespace IKVM.Reflection.Reader
                {
                        get { return index == 0; }
                }
+
+               internal override bool IsBaked
+               {
+                       get { return true; }
+               }
        }
 }