Model: Handle generic type arguments in generic type declarations
This commit is contained in:
@@ -41,7 +41,7 @@ namespace Il2CppInspector.Reflection
|
|||||||
case Il2CppTypeEnum.IL2CPP_TYPE_CLASS:
|
case Il2CppTypeEnum.IL2CPP_TYPE_CLASS:
|
||||||
case Il2CppTypeEnum.IL2CPP_TYPE_VALUETYPE:
|
case Il2CppTypeEnum.IL2CPP_TYPE_VALUETYPE:
|
||||||
// Classes defined in the metadata
|
// Classes defined in the metadata
|
||||||
return TypesByDefinitionIndex[usage.datapoint];
|
return TypesByDefinitionIndex[usage.datapoint]; // klassIndex
|
||||||
|
|
||||||
case Il2CppTypeEnum.IL2CPP_TYPE_GENERICINST:
|
case Il2CppTypeEnum.IL2CPP_TYPE_GENERICINST:
|
||||||
case Il2CppTypeEnum.IL2CPP_TYPE_ARRAY:
|
case Il2CppTypeEnum.IL2CPP_TYPE_ARRAY:
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ namespace Il2CppInspector.Reflection {
|
|||||||
public abstract class MemberInfo
|
public abstract class MemberInfo
|
||||||
{
|
{
|
||||||
// Assembly that this member is defined in. Only set when MemberType == TypeInfo
|
// Assembly that this member is defined in. Only set when MemberType == TypeInfo
|
||||||
public Assembly Assembly { get; }
|
public Assembly Assembly { get; protected set; }
|
||||||
|
|
||||||
// Custom attributes for this member
|
// Custom attributes for this member
|
||||||
public IEnumerable<CustomAttributeData> CustomAttributes => throw new NotImplementedException();
|
public IEnumerable<CustomAttributeData> CustomAttributes => throw new NotImplementedException();
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ namespace Il2CppInspector.Reflection {
|
|||||||
{
|
{
|
||||||
// IL2CPP-specific data
|
// IL2CPP-specific data
|
||||||
public Il2CppTypeDefinition Definition { get; }
|
public Il2CppTypeDefinition Definition { get; }
|
||||||
public int Index { get; }
|
public int Index { get; } = -1;
|
||||||
|
|
||||||
// Information/flags about the type
|
// Information/flags about the type
|
||||||
// Undefined if the Type represents a generic type parameter
|
// Undefined if the Type represents a generic type parameter
|
||||||
@@ -41,6 +41,7 @@ namespace Il2CppInspector.Reflection {
|
|||||||
if (IsArray)
|
if (IsArray)
|
||||||
n = ElementType.CSharpName;
|
n = ElementType.CSharpName;
|
||||||
var g = (GenericTypeParameters != null ? "<" + string.Join(", ", GenericTypeParameters.Select(x => x.CSharpName)) + ">" : "");
|
var g = (GenericTypeParameters != null ? "<" + string.Join(", ", GenericTypeParameters.Select(x => x.CSharpName)) + ">" : "");
|
||||||
|
g = (GenericTypeArguments != null ? "<" + string.Join(", ", GenericTypeArguments.Select(x => x.CSharpName)) + ">" : g);
|
||||||
return (IsPointer ? "void *" : "") + n + g + (IsArray ? "[]" : "");
|
return (IsPointer ? "void *" : "") + n + g + (IsArray ? "[]" : "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -82,6 +83,7 @@ namespace Il2CppInspector.Reflection {
|
|||||||
+ (DeclaringType != null? DeclaringType.Name + "." : "")
|
+ (DeclaringType != null? DeclaringType.Name + "." : "")
|
||||||
+ base.Name
|
+ base.Name
|
||||||
+ (GenericTypeParameters != null ? "<" + string.Join(", ", GenericTypeParameters.Select(x => x.Name)) + ">" : "")
|
+ (GenericTypeParameters != null ? "<" + string.Join(", ", GenericTypeParameters.Select(x => x.Name)) + ">" : "")
|
||||||
|
+ (GenericTypeArguments != null ? "<" + string.Join(", ", GenericTypeArguments.Select(x => x.Name)) + ">" : "")
|
||||||
+ (IsArray? "[]" : "");
|
+ (IsArray? "[]" : "");
|
||||||
|
|
||||||
// TODO: Alot of other generics stuff
|
// TODO: Alot of other generics stuff
|
||||||
@@ -105,7 +107,7 @@ namespace Il2CppInspector.Reflection {
|
|||||||
public bool IsGenericTypeDefinition { get; }
|
public bool IsGenericTypeDefinition { get; }
|
||||||
public bool IsImport => (Attributes & TypeAttributes.Import) == TypeAttributes.Import;
|
public bool IsImport => (Attributes & TypeAttributes.Import) == TypeAttributes.Import;
|
||||||
public bool IsInterface => (Attributes & TypeAttributes.ClassSemanticsMask) == TypeAttributes.Interface;
|
public bool IsInterface => (Attributes & TypeAttributes.ClassSemanticsMask) == TypeAttributes.Interface;
|
||||||
public bool IsNested => DeclaringType != null;
|
public bool IsNested => (MemberType & MemberTypes.NestedType) == MemberTypes.NestedType;
|
||||||
public bool IsNestedAssembly => (Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedAssembly;
|
public bool IsNestedAssembly => (Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedAssembly;
|
||||||
public bool IsNestedFamANDAssem => (Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedFamANDAssem;
|
public bool IsNestedFamANDAssem => (Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedFamANDAssem;
|
||||||
public bool IsNestedFamily => (Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedFamily;
|
public bool IsNestedFamily => (Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedFamily;
|
||||||
@@ -125,10 +127,13 @@ namespace Il2CppInspector.Reflection {
|
|||||||
// May get overridden by Il2CppType-based constructor below
|
// May get overridden by Il2CppType-based constructor below
|
||||||
public override MemberTypes MemberType { get; } = MemberTypes.TypeInfo;
|
public override MemberTypes MemberType { get; } = MemberTypes.TypeInfo;
|
||||||
|
|
||||||
|
public string BaseName => base.Name;
|
||||||
|
|
||||||
public override string Name {
|
public override string Name {
|
||||||
get => (IsPointer ? "void *" : "")
|
get => (IsPointer ? "void *" : "")
|
||||||
+ (base.Name.IndexOf("`", StringComparison.Ordinal) == -1? base.Name : base.Name.Remove(base.Name.IndexOf("`", StringComparison.Ordinal)))
|
+ (base.Name.IndexOf("`", StringComparison.Ordinal) == -1? base.Name : base.Name.Remove(base.Name.IndexOf("`", StringComparison.Ordinal)))
|
||||||
+ (GenericTypeParameters != null? "<" + string.Join(", ", GenericTypeParameters.Select(x => x.Name)) + ">" : "")
|
+ (GenericTypeParameters != null? "<" + string.Join(", ", GenericTypeParameters.Select(x => x.Name)) + ">" : "")
|
||||||
|
+ (GenericTypeArguments != null ? "<" + string.Join(", ", GenericTypeArguments.Select(x => x.Name)) + ">" : "")
|
||||||
+ (IsArray ? "[]" : "");
|
+ (IsArray ? "[]" : "");
|
||||||
protected set => base.Name = value;
|
protected set => base.Name = value;
|
||||||
}
|
}
|
||||||
@@ -266,20 +271,27 @@ namespace Il2CppInspector.Reflection {
|
|||||||
public TypeInfo(Il2CppModel model, Il2CppType pType, MemberTypes memberType) {
|
public TypeInfo(Il2CppModel model, Il2CppType pType, MemberTypes memberType) {
|
||||||
var image = model.Package.BinaryImage;
|
var image = model.Package.BinaryImage;
|
||||||
|
|
||||||
// TODO: IsNested = true;
|
// Finding TypeDefinitions adapted from il2cpp::vm::Class::FromIl2CppType
|
||||||
MemberType = memberType;
|
|
||||||
|
|
||||||
// TODO: Set Assembly and DeclaringType
|
|
||||||
|
|
||||||
// Generic type unresolved and concrete instance types
|
// Generic type unresolved and concrete instance types
|
||||||
if (pType.type == Il2CppTypeEnum.IL2CPP_TYPE_GENERICINST) {
|
if (pType.type == Il2CppTypeEnum.IL2CPP_TYPE_GENERICINST) {
|
||||||
var generic = image.ReadMappedObject<Il2CppGenericClass>(pType.datapoint);
|
var generic = image.ReadMappedObject<Il2CppGenericClass>(pType.datapoint); // Il2CppGenericClass *
|
||||||
var genericTypeDef = model.TypesByDefinitionIndex[generic.typeDefinitionIndex];
|
var genericTypeDef = model.TypesByDefinitionIndex[generic.typeDefinitionIndex];
|
||||||
|
|
||||||
|
Assembly = genericTypeDef.Assembly;
|
||||||
Namespace = genericTypeDef.Namespace;
|
Namespace = genericTypeDef.Namespace;
|
||||||
Name = genericTypeDef.Name;
|
Name = genericTypeDef.BaseName;
|
||||||
Attributes |= TypeAttributes.Class;
|
Attributes |= TypeAttributes.Class;
|
||||||
|
|
||||||
|
// Derived type?
|
||||||
|
if (genericTypeDef.Definition.parentIndex >= 0)
|
||||||
|
baseTypeUsage = genericTypeDef.Definition.parentIndex;
|
||||||
|
|
||||||
|
if (genericTypeDef.Definition.declaringTypeIndex >= 0) {
|
||||||
|
declaringTypeDefinitionIndex = (int)model.Package.TypeUsages[genericTypeDef.Definition.declaringTypeIndex].datapoint;
|
||||||
|
MemberType = memberType | MemberTypes.NestedType;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Generic* properties and ContainsGenericParameters
|
// TODO: Generic* properties and ContainsGenericParameters
|
||||||
|
|
||||||
// Get the instantiation
|
// Get the instantiation
|
||||||
@@ -294,11 +306,13 @@ namespace Il2CppInspector.Reflection {
|
|||||||
var argType = model.GetTypeFromVirtualAddress((ulong) pArg);
|
var argType = model.GetTypeFromVirtualAddress((ulong) pArg);
|
||||||
// TODO: Detect whether unresolved or concrete (add concrete to GenericTypeArguments instead)
|
// TODO: Detect whether unresolved or concrete (add concrete to GenericTypeArguments instead)
|
||||||
// TODO: GenericParameterPosition etc. in types we generate here
|
// TODO: GenericParameterPosition etc. in types we generate here
|
||||||
// TODO: Assembly
|
// TODO: Assembly etc.
|
||||||
GenericTypeArguments.Add(argType); // TODO: Fix MemberType here
|
GenericTypeArguments.Add(argType); // TODO: Fix MemberType here
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Set Assembly, BaseType and DeclaringType for all of the below
|
||||||
|
|
||||||
// Array with known dimensions and bounds
|
// Array with known dimensions and bounds
|
||||||
if (pType.type == Il2CppTypeEnum.IL2CPP_TYPE_ARRAY) {
|
if (pType.type == Il2CppTypeEnum.IL2CPP_TYPE_ARRAY) {
|
||||||
var descriptor = image.ReadMappedObject<Il2CppArrayType>(pType.datapoint);
|
var descriptor = image.ReadMappedObject<Il2CppArrayType>(pType.datapoint);
|
||||||
|
|||||||
Reference in New Issue
Block a user