Implement NestedTypes for generic instances

In the C# reflection API, DeclaredNestedTypes on concrete generic types
just returns the nested types of the type definition. Notably, type
parameters are not substituted, because nested types are not guaranteed
to use the same containing type's type parameters.
This commit is contained in:
Robert Xiao
2020-04-13 01:31:52 -07:00
committed by Katy
parent 6fb95c52da
commit a36c93514d

View File

@@ -95,13 +95,26 @@ namespace Il2CppInspector.Reflection {
public List<MemberInfo> DeclaredMembers => new IEnumerable<MemberInfo>[] { public List<MemberInfo> DeclaredMembers => new IEnumerable<MemberInfo>[] {
DeclaredConstructors, DeclaredEvents, DeclaredFields, DeclaredMethods, DeclaredConstructors, DeclaredEvents, DeclaredFields, DeclaredMethods,
DeclaredNestedTypes?.ToList() ?? new List<TypeInfo>(), DeclaredProperties DeclaredNestedTypes, DeclaredProperties
}.SelectMany(m => m).ToList(); }.SelectMany(m => m).ToList();
public List<MethodInfo> DeclaredMethods { get; } = new List<MethodInfo>(); public List<MethodInfo> DeclaredMethods { get; } = new List<MethodInfo>();
private readonly int[] declaredNestedTypes; private readonly TypeRef[] declaredNestedTypes;
public IEnumerable<TypeInfo> DeclaredNestedTypes => declaredNestedTypes.Select(x => Assembly.Model.TypesByDefinitionIndex[x]); public IEnumerable<TypeInfo> DeclaredNestedTypes {
get {
if (declaredNestedTypes != null)
return declaredNestedTypes.Select(x => x.Value);
/* Type parameters are not substituted into nested classes,
* as nested classes aren't required to use the parameters
* from the containing class.
* This also matches the behaviour of the C# reflection API.
*/
if (genericTypeDefinition != null)
return genericTypeDefinition.DeclaredNestedTypes;
return Enumerable.Empty<TypeInfo>();
}
}
public List<PropertyInfo> DeclaredProperties { get; } = new List<PropertyInfo>(); public List<PropertyInfo> DeclaredProperties { get; } = new List<PropertyInfo>();
@@ -656,9 +669,9 @@ namespace Il2CppInspector.Reflection {
implementedInterfaceReferences[i] = TypeRef.FromReferenceIndex(Assembly.Model, pkg.InterfaceUsageIndices[Definition.interfacesStart + i]); implementedInterfaceReferences[i] = TypeRef.FromReferenceIndex(Assembly.Model, pkg.InterfaceUsageIndices[Definition.interfacesStart + i]);
// Add all nested types // Add all nested types
declaredNestedTypes = new int[Definition.nested_type_count]; declaredNestedTypes = new TypeRef[Definition.nested_type_count];
for (var n = 0; n < Definition.nested_type_count; n++) for (var n = 0; n < Definition.nested_type_count; n++)
declaredNestedTypes[n] = pkg.NestedTypeIndices[Definition.nestedTypesStart + n]; declaredNestedTypes[n] = TypeRef.FromDefinitionIndex(Assembly.Model, pkg.NestedTypeIndices[Definition.nestedTypesStart + n]);
// Add all fields // Add all fields
for (var f = Definition.fieldStart; f < Definition.fieldStart + Definition.field_count; f++) for (var f = Definition.fieldStart; f < Definition.fieldStart + Definition.field_count; f++)