Remove index from BaseType, DeclaringType
All types will need to eventually be fully generic. Therefore, we need to eliminate indices when referring to types, and also be very lazy when accessing TypeInfo properties so that we don't access uninitialized types during model creation.
This commit is contained in:
@@ -20,8 +20,7 @@ namespace Il2CppInspector.Reflection {
|
|||||||
public CustomAttributeData[] GetCustomAttributes(string fullTypeName) => CustomAttributes.Where(a => a.AttributeType.FullName == fullTypeName).ToArray();
|
public CustomAttributeData[] GetCustomAttributes(string fullTypeName) => CustomAttributes.Where(a => a.AttributeType.FullName == fullTypeName).ToArray();
|
||||||
|
|
||||||
// Type that this type is declared in for nested types
|
// Type that this type is declared in for nested types
|
||||||
protected int declaringTypeDefinitionIndex { private get; set; } = -1;
|
public virtual TypeInfo DeclaringType { get; private set; }
|
||||||
public TypeInfo DeclaringType => declaringTypeDefinitionIndex != -1? Assembly.Model.TypesByDefinitionIndex[declaringTypeDefinitionIndex] : null;
|
|
||||||
|
|
||||||
// What sort of member this is, eg. method, field etc.
|
// What sort of member this is, eg. method, field etc.
|
||||||
public abstract MemberTypes MemberType { get; }
|
public abstract MemberTypes MemberType { get; }
|
||||||
@@ -36,11 +35,9 @@ namespace Il2CppInspector.Reflection {
|
|||||||
protected MemberInfo(Assembly asm) => Assembly = asm;
|
protected MemberInfo(Assembly asm) => Assembly = asm;
|
||||||
|
|
||||||
// For lower level members, eg. fields, properties etc. and nested types
|
// For lower level members, eg. fields, properties etc. and nested types
|
||||||
protected MemberInfo(TypeInfo declaringType = null) {
|
protected MemberInfo(TypeInfo declaringType) {
|
||||||
if (declaringType != null) {
|
|
||||||
Assembly = declaringType.Assembly;
|
Assembly = declaringType.Assembly;
|
||||||
declaringTypeDefinitionIndex = declaringType.Index;
|
DeclaringType = declaringType;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string ToString() => Name;
|
public override string ToString() => Name;
|
||||||
|
|||||||
@@ -21,15 +21,48 @@ namespace Il2CppInspector.Reflection {
|
|||||||
// Undefined if the Type represents a generic type parameter
|
// Undefined if the Type represents a generic type parameter
|
||||||
public TypeAttributes Attributes { get; }
|
public TypeAttributes Attributes { get; }
|
||||||
|
|
||||||
// Type that this type inherits from
|
public TypeInfo BaseType {
|
||||||
private readonly int baseTypeReference = -1;
|
get {
|
||||||
|
if (IsPointer || IsByRef)
|
||||||
|
return null;
|
||||||
|
if (IsArray)
|
||||||
|
return Assembly.Model.TypesByFullName["System.Array"];
|
||||||
|
if (Definition != null) {
|
||||||
|
if (Definition.parentIndex >= 0)
|
||||||
|
return Assembly.Model.TypesByReferenceIndex[Definition.parentIndex];
|
||||||
|
}
|
||||||
|
if (genericTypeDefinition != null) {
|
||||||
|
/* TODO substitute generic arguments */
|
||||||
|
return genericTypeDefinition.BaseType;
|
||||||
|
}
|
||||||
|
if (Namespace != "System" || BaseName != "Object")
|
||||||
|
return Assembly.Model.TypesByFullName["System.Object"];
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public TypeInfo BaseType => IsPointer? null :
|
public override TypeInfo DeclaringType {
|
||||||
baseTypeReference != -1?
|
get {
|
||||||
Assembly.Model.TypesByReferenceIndex[baseTypeReference]
|
if (Definition != null) {
|
||||||
: IsArray? Assembly.Model.TypesByFullName["System.Array"]
|
/* Type definition */
|
||||||
: Namespace != "System" || BaseName != "Object" ? Assembly.Model.TypesByFullName["System.Object"]
|
if (Definition.declaringTypeIndex == -1)
|
||||||
: null;
|
return null;
|
||||||
|
var type = Assembly.Model.TypesByReferenceIndex[Definition.declaringTypeIndex];
|
||||||
|
if (type == null) {
|
||||||
|
/* This might happen while initially setting up the types */
|
||||||
|
var typeRef = Assembly.Model.Package.TypeReferences[Definition.declaringTypeIndex];
|
||||||
|
type = Assembly.Model.TypesByDefinitionIndex[(int)typeRef.datapoint];
|
||||||
|
}
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
if (genericTypeDefinition != null) {
|
||||||
|
/* Generic type instance */
|
||||||
|
/* TODO substitute generic arguments */
|
||||||
|
return genericTypeDefinition.DeclaringType;
|
||||||
|
}
|
||||||
|
return base.DeclaringType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// True if the type contains unresolved generic type parameters
|
// True if the type contains unresolved generic type parameters
|
||||||
public bool ContainsGenericParameters => IsGenericParameter || genericArguments.Any(ga => ga.ContainsGenericParameters);
|
public bool ContainsGenericParameters => IsGenericParameter || genericArguments.Any(ga => ga.ContainsGenericParameters);
|
||||||
@@ -68,6 +101,11 @@ namespace Il2CppInspector.Reflection {
|
|||||||
return types;
|
return types;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private readonly TypeInfo genericTypeDefinition;
|
||||||
|
|
||||||
|
/* https://docs.microsoft.com/en-us/dotnet/api/system.type.getgenerictypedefinition?view=netframework-4.8 */
|
||||||
|
public TypeInfo GetGenericTypeDefinition() => genericTypeDefinition;
|
||||||
|
|
||||||
// Get a method by its name
|
// Get a method by its name
|
||||||
public MethodInfo GetMethod(string name) => DeclaredMethods.FirstOrDefault(m => m.Name == name);
|
public MethodInfo GetMethod(string name) => DeclaredMethods.FirstOrDefault(m => m.Name == name);
|
||||||
|
|
||||||
@@ -102,7 +140,7 @@ namespace Il2CppInspector.Reflection {
|
|||||||
|
|
||||||
// Method that the type is declared in if this is a type parameter of a generic method
|
// Method that the type is declared in if this is a type parameter of a generic method
|
||||||
// TODO: Make a unit test from this: https://docs.microsoft.com/en-us/dotnet/api/system.type.declaringmethod?view=netframework-4.8
|
// TODO: Make a unit test from this: https://docs.microsoft.com/en-us/dotnet/api/system.type.declaringmethod?view=netframework-4.8
|
||||||
public MethodBase DeclaringMethod;
|
public MethodBase DeclaringMethod { get; }
|
||||||
|
|
||||||
// IsGenericTypeParameter and IsGenericMethodParameter from https://github.com/dotnet/corefx/issues/23883
|
// IsGenericTypeParameter and IsGenericMethodParameter from https://github.com/dotnet/corefx/issues/23883
|
||||||
public bool IsGenericTypeParameter => IsGenericParameter && DeclaringMethod == null;
|
public bool IsGenericTypeParameter => IsGenericParameter && DeclaringMethod == null;
|
||||||
@@ -526,13 +564,8 @@ namespace Il2CppInspector.Reflection {
|
|||||||
Namespace = pkg.Strings[Definition.namespaceIndex];
|
Namespace = pkg.Strings[Definition.namespaceIndex];
|
||||||
Name = pkg.Strings[Definition.nameIndex];
|
Name = pkg.Strings[Definition.nameIndex];
|
||||||
|
|
||||||
// Derived type?
|
|
||||||
if (Definition.parentIndex >= 0)
|
|
||||||
baseTypeReference = Definition.parentIndex;
|
|
||||||
|
|
||||||
// Nested type?
|
// Nested type?
|
||||||
if (Definition.declaringTypeIndex >= 0) {
|
if (Definition.declaringTypeIndex >= 0) {
|
||||||
declaringTypeDefinitionIndex = (int) pkg.TypeReferences[Definition.declaringTypeIndex].datapoint;
|
|
||||||
MemberType |= MemberTypes.NestedType;
|
MemberType |= MemberTypes.NestedType;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -736,7 +769,9 @@ namespace Il2CppInspector.Reflection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Initialize a type from a concrete generic instance
|
// Initialize a type from a concrete generic instance
|
||||||
public TypeInfo(TypeInfo genericTypeDefinition, Il2CppGenericInst instance) : base(genericTypeDefinition.Assembly) {
|
public TypeInfo(TypeInfo genericTypeDef, Il2CppGenericInst instance) : base(genericTypeDef.Assembly) {
|
||||||
|
genericTypeDefinition = genericTypeDef;
|
||||||
|
|
||||||
// Same visibility attributes as generic type definition
|
// Same visibility attributes as generic type definition
|
||||||
Attributes = genericTypeDefinition.Attributes;
|
Attributes = genericTypeDefinition.Attributes;
|
||||||
|
|
||||||
@@ -746,16 +781,7 @@ namespace Il2CppInspector.Reflection {
|
|||||||
// Same name as generic type definition
|
// Same name as generic type definition
|
||||||
Namespace = genericTypeDefinition.Namespace;
|
Namespace = genericTypeDefinition.Namespace;
|
||||||
Name = genericTypeDefinition.BaseName; // use BaseName to exclude the type parameters so we can supply our own
|
Name = genericTypeDefinition.BaseName; // use BaseName to exclude the type parameters so we can supply our own
|
||||||
|
MemberType = genericTypeDefinition.MemberType;
|
||||||
// Derived type?
|
|
||||||
if (genericTypeDefinition.Definition.parentIndex >= 0)
|
|
||||||
baseTypeReference = genericTypeDefinition.Definition.parentIndex;
|
|
||||||
|
|
||||||
// Nested type?
|
|
||||||
if (genericTypeDefinition.Definition.declaringTypeIndex >= 0) {
|
|
||||||
declaringTypeDefinitionIndex = (int)Assembly.Model.Package.TypeReferences[genericTypeDefinition.Definition.declaringTypeIndex].datapoint;
|
|
||||||
MemberType |= MemberTypes.NestedType;
|
|
||||||
}
|
|
||||||
|
|
||||||
IsGenericParameter = false;
|
IsGenericParameter = false;
|
||||||
IsGenericType = true;
|
IsGenericType = true;
|
||||||
|
|||||||
Reference in New Issue
Block a user