namespace IKVM.Reflection.Reader
{
- sealed class TypeDefImpl : Type
+ sealed class TypeDefImpl : TypeInfo
{
private readonly ModuleReader module;
private readonly int index;
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
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;
}
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);
}
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;
{
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)
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;
}
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
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()
{
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();
}
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;
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; }
{
get { return index == 0; }
}
+
+ internal override bool IsBaked
+ {
+ get { return true; }
+ }
}
}