Implement MemberInfo, FieldInfo, TypeInfo.DeclaredFields
Rename Type to TypeInfo Add TypeInfo.CSharpName Implement some generic types/parameters Implement arrays Remove obsolete Il2CppType.GetTypeFromTypeIndex Implement enhanced Il2CppReflector.GetTypeFromTypeIndex (can create array and generic types on-the-fly from Il2CppType usages)
This commit is contained in:
@@ -1,4 +1,6 @@
|
||||
public static class DefineConstants
|
||||
using System.Collections.Generic;
|
||||
|
||||
public static class DefineConstants
|
||||
{
|
||||
public const int FIELD_ATTRIBUTE_PRIVATE = 0x0001;
|
||||
public const int FIELD_ATTRIBUTE_PUBLIC = 0x0006;
|
||||
@@ -17,4 +19,80 @@
|
||||
public const int TYPE_ATTRIBUTE_SERIALIZABLE = 0x00002000;
|
||||
public const int PARAM_ATTRIBUTE_OUT = 0x0002;
|
||||
public const int PARAM_ATTRIBUTE_OPTIONAL = 0x0010;
|
||||
|
||||
public static List<string> CSharpTypeString = new List<string>
|
||||
{
|
||||
"END",
|
||||
"void",
|
||||
"bool",
|
||||
"char",
|
||||
"sbyte",
|
||||
"byte",
|
||||
"short",
|
||||
"ushort",
|
||||
"int",
|
||||
"uint",
|
||||
"long",
|
||||
"ulong",
|
||||
"float",
|
||||
"double",
|
||||
"string",
|
||||
"PTR", // Processed separately
|
||||
"BYREF",
|
||||
"VALUETYPE", // Processed separately
|
||||
"CLASS", // Processed separately
|
||||
"T",
|
||||
"Array", // Processed separately
|
||||
"GENERICINST", // Processed separately
|
||||
"TYPEDBYREF",
|
||||
"None",
|
||||
"IntPtr",
|
||||
"UIntPtr",
|
||||
"None",
|
||||
"delegate",
|
||||
"object",
|
||||
"SZARRAY", // Processed separately
|
||||
"T",
|
||||
"CMOD_REQD",
|
||||
"CMOD_OPT",
|
||||
"INTERNAL",
|
||||
};
|
||||
|
||||
public static List<string> FullNameTypeString = new List<string>
|
||||
{
|
||||
"END",
|
||||
"System.Void",
|
||||
"System.Boolean",
|
||||
"System.Char",
|
||||
"System.SByte",
|
||||
"System.Byte",
|
||||
"System.Int16",
|
||||
"System.UInt16",
|
||||
"System.Int32",
|
||||
"System.UInt32",
|
||||
"System.Int64",
|
||||
"System.UInt64",
|
||||
"System.Single",
|
||||
"System.Double",
|
||||
"System.String",
|
||||
"PTR", // Processed separately
|
||||
"BYREF",
|
||||
"System.ValueType", // Processed separately
|
||||
"CLASS", // Processed separately
|
||||
"T",
|
||||
"System.Array", // Processed separately
|
||||
"GENERICINST", // Processed separately
|
||||
"TYPEDBYREF",
|
||||
"None",
|
||||
"System.IntPtr",
|
||||
"System.UIntPtr",
|
||||
"None",
|
||||
"System.Delegate",
|
||||
"System.Object",
|
||||
"SZARRAY", // Processed separately
|
||||
"T",
|
||||
"CMOD_REQD",
|
||||
"CMOD_OPT",
|
||||
"INTERNAL",
|
||||
};
|
||||
}
|
||||
@@ -8,6 +8,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
namespace Il2CppInspector
|
||||
@@ -103,18 +104,13 @@ namespace Il2CppInspector
|
||||
ret = $"{GetTypeName(type)}[]";
|
||||
}
|
||||
else {
|
||||
if ((int)pType.type >= szTypeString.Length)
|
||||
if ((int)pType.type >= DefineConstants.CSharpTypeString.Count)
|
||||
ret = "unknow";
|
||||
else
|
||||
ret = szTypeString[(int)pType.type];
|
||||
ret = DefineConstants.CSharpTypeString[(int)pType.type];
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public Il2CppType GetTypeFromTypeIndex(int idx) {
|
||||
return Binary.Types[idx];
|
||||
}
|
||||
|
||||
public int GetFieldOffsetFromIndex(int typeIndex, int fieldIndexInType) {
|
||||
// Versions from 22 onwards use an array of pointers in fieldOffsets
|
||||
bool fieldOffsetsArePointers = (Metadata.Version >= 22);
|
||||
@@ -144,7 +140,7 @@ namespace Il2CppInspector
|
||||
return null;
|
||||
|
||||
var pValue = Metadata.Header.fieldAndParameterDefaultValueDataOffset + def.dataIndex;
|
||||
Il2CppType type = GetTypeFromTypeIndex(def.typeIndex);
|
||||
Il2CppType type = Binary.Types[def.typeIndex];
|
||||
if (pValue == 0)
|
||||
return null;
|
||||
|
||||
@@ -192,43 +188,5 @@ namespace Il2CppInspector
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
private readonly string[] szTypeString =
|
||||
{
|
||||
"END",
|
||||
"void",
|
||||
"bool",
|
||||
"char",
|
||||
"sbyte",
|
||||
"byte",
|
||||
"short",
|
||||
"ushort",
|
||||
"int",
|
||||
"uint",
|
||||
"long",
|
||||
"ulong",
|
||||
"float",
|
||||
"double",
|
||||
"string",
|
||||
"PTR",//eg. void*
|
||||
"BYREF",
|
||||
"VALUETYPE",
|
||||
"CLASS",
|
||||
"T",
|
||||
"ARRAY",
|
||||
"GENERICINST",
|
||||
"TYPEDBYREF",
|
||||
"None",
|
||||
"IntPtr",
|
||||
"UIntPtr",
|
||||
"None",
|
||||
"FNPTR",
|
||||
"object",
|
||||
"SZARRAY",
|
||||
"T",
|
||||
"CMOD_REQD",
|
||||
"CMOD_OPT",
|
||||
"INTERNAL",
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,23 +1,53 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Il2CppInspector.Reflection
|
||||
{
|
||||
public class Il2CppReflector
|
||||
{
|
||||
public Il2CppInspector Package { get; }
|
||||
public List<Assembly> Assemblies { get; } = new List<Assembly>();
|
||||
|
||||
public Il2CppReflector(Il2CppInspector package) {
|
||||
Package = package;
|
||||
|
||||
// Create Assembly objects from Il2Cpp package
|
||||
for (var image = 0; image < package.Metadata.Images.Length; image++)
|
||||
Assemblies.Add(new Assembly(package, image));
|
||||
Assemblies.Add(new Assembly(this, image));
|
||||
}
|
||||
|
||||
// Get the assembly in which a type is defined
|
||||
public Assembly GetAssembly(Type type) => Assemblies.FirstOrDefault(x => x.DefinedTypes.Contains(type));
|
||||
public Assembly GetAssembly(TypeInfo type) => Assemblies.FirstOrDefault(x => x.DefinedTypes.Contains(type));
|
||||
|
||||
// Get a type from its IL2CPP type index
|
||||
public Type GetTypeFromIndex(int typeIndex) => Assemblies.SelectMany(x => x.DefinedTypes).FirstOrDefault(x => x.Index == typeIndex);
|
||||
public TypeInfo GetTypeFromIndex(int typeIndex) => Assemblies.SelectMany(x => x.DefinedTypes).FirstOrDefault(x => x.Index == typeIndex);
|
||||
|
||||
// Get or generate a type from its IL2CPP binary type usage reference
|
||||
// (field, return type, generic type parameter etc.)
|
||||
public TypeInfo GetType(Il2CppType pType, MemberTypes memberType = MemberTypes.All) {
|
||||
switch (pType.type) {
|
||||
case Il2CppTypeEnum.IL2CPP_TYPE_CLASS:
|
||||
case Il2CppTypeEnum.IL2CPP_TYPE_VALUETYPE:
|
||||
// Classes defined in the metadata
|
||||
return GetTypeFromIndex((int) pType.datapoint);
|
||||
|
||||
case Il2CppTypeEnum.IL2CPP_TYPE_GENERICINST:
|
||||
case Il2CppTypeEnum.IL2CPP_TYPE_ARRAY:
|
||||
case Il2CppTypeEnum.IL2CPP_TYPE_SZARRAY:
|
||||
case Il2CppTypeEnum.IL2CPP_TYPE_PTR:
|
||||
case Il2CppTypeEnum.IL2CPP_TYPE_VAR:
|
||||
// Everything that requires special handling
|
||||
return new TypeInfo(this, pType, memberType);
|
||||
|
||||
default:
|
||||
// Basic primitive types
|
||||
if ((int) pType.type >= DefineConstants.FullNameTypeString.Count)
|
||||
return null;
|
||||
|
||||
return Assemblies.SelectMany(x => x.DefinedTypes).First(x => x.FullName == DefineConstants.FullNameTypeString[(int)pType.type]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,7 @@ namespace Il2CppInspector.Reflection {
|
||||
public class Assembly
|
||||
{
|
||||
// IL2CPP-specific data
|
||||
public Il2CppReflector Model { get; }
|
||||
public Il2CppImageDefinition Definition { get; }
|
||||
public int Index { get; }
|
||||
|
||||
@@ -15,27 +16,28 @@ namespace Il2CppInspector.Reflection {
|
||||
public string FullName { get; }
|
||||
|
||||
// Entry point method for the assembly
|
||||
public MethodInfo EntryPoint { get; }
|
||||
//public MethodInfo EntryPoint { get; } // TODO
|
||||
|
||||
// List of types defined in the assembly
|
||||
public List<Type> DefinedTypes { get; } = new List<Type>();
|
||||
public List<TypeInfo> DefinedTypes { get; } = new List<TypeInfo>();
|
||||
|
||||
// Get a type from its string name (including namespace)
|
||||
public Type GetType(string typeName) => DefinedTypes.FirstOrDefault(x => x.FullName == typeName);
|
||||
public TypeInfo GetType(string typeName) => DefinedTypes.FirstOrDefault(x => x.FullName == typeName);
|
||||
|
||||
// Initialize from specified assembly index in package
|
||||
public Assembly(Il2CppInspector pkg, int imageIndex) {
|
||||
Definition = pkg.Metadata.Images[imageIndex];
|
||||
public Assembly(Il2CppReflector model, int imageIndex) {
|
||||
Model = model;
|
||||
Definition = Model.Package.Metadata.Images[imageIndex];
|
||||
Index = Definition.assemblyIndex;
|
||||
FullName = pkg.Metadata.Strings[Definition.nameIndex];
|
||||
FullName = Model.Package.Metadata.Strings[Definition.nameIndex];
|
||||
|
||||
if (Definition.entryPointIndex != -1) {
|
||||
// TODO: Generate EntryPoint method from entryPointIndex
|
||||
}
|
||||
|
||||
// Generate types in DefinedTypes from typeStart to typeStart+typeCount-1
|
||||
for (int t = Definition.typeStart; t < Definition.typeStart + Definition.typeCount; t++)
|
||||
DefinedTypes.Add(new Type(pkg, t, this));
|
||||
for (var t = Definition.typeStart; t < Definition.typeStart + Definition.typeCount; t++)
|
||||
DefinedTypes.Add(new TypeInfo(Model.Package, t, this));
|
||||
}
|
||||
}
|
||||
}
|
||||
63
Il2CppInspector/Reflection/FieldInfo.cs
Normal file
63
Il2CppInspector/Reflection/FieldInfo.cs
Normal file
@@ -0,0 +1,63 @@
|
||||
using System.Reflection;
|
||||
|
||||
namespace Il2CppInspector.Reflection {
|
||||
public class FieldInfo : MemberInfo
|
||||
{
|
||||
// IL2CPP-specific data
|
||||
public Il2CppFieldDefinition Definition { get; }
|
||||
public int Index { get; }
|
||||
|
||||
// Information/flags about the field
|
||||
public FieldAttributes Attributes { get; }
|
||||
|
||||
// Type of field
|
||||
private readonly Il2CppType fieldType;
|
||||
public TypeInfo FieldType => Assembly.Model.GetType(fieldType, MemberTypes.Field);
|
||||
|
||||
// For the Is* definitions below, see:
|
||||
// https://docs.microsoft.com/en-us/dotnet/api/system.reflection.fieldinfo.isfamilyandassembly?view=netframework-4.7.1#System_Reflection_FieldInfo_IsFamilyAndAssembly
|
||||
|
||||
// True if the field is declared as internal
|
||||
public bool IsAssembly { get; } // TODO
|
||||
|
||||
// True if the field is declared as protected
|
||||
public bool IsFamily { get; } // TODO
|
||||
|
||||
// True if the field is declared as 'protected private' (always false)
|
||||
public bool IsFamilyAndAssembly => false;
|
||||
|
||||
// True if the field is declared as protected public
|
||||
public bool IsFamilyOrAssembly { get; } // TODO
|
||||
|
||||
// True if the field is declared as readonly
|
||||
public bool IsInitOnly => (Attributes & FieldAttributes.InitOnly) == FieldAttributes.InitOnly;
|
||||
|
||||
// True if the field is declared a private
|
||||
public bool IsPrivate => (Attributes & FieldAttributes.Private) == FieldAttributes.Private;
|
||||
|
||||
// True if the field is declared as public
|
||||
public bool IsPublic => (Attributes & FieldAttributes.Public) == FieldAttributes.Public;
|
||||
|
||||
// True if the field is declared as static
|
||||
public bool IsStatic => (Attributes & FieldAttributes.Static) == FieldAttributes.Static;
|
||||
|
||||
public override MemberTypes MemberType { get; }
|
||||
|
||||
public FieldInfo(Il2CppInspector pkg, int fieldIndex, TypeInfo declaringType) :
|
||||
base(declaringType) {
|
||||
Definition = pkg.Metadata.Fields[fieldIndex];
|
||||
Index = fieldIndex;
|
||||
Name = pkg.Metadata.Strings[pkg.Metadata.Fields[fieldIndex].nameIndex];
|
||||
|
||||
fieldType = pkg.Binary.Types[Definition.typeIndex];
|
||||
if ((fieldType.attrs & DefineConstants.FIELD_ATTRIBUTE_PRIVATE) == DefineConstants.FIELD_ATTRIBUTE_PRIVATE)
|
||||
Attributes |= FieldAttributes.Private;
|
||||
if ((fieldType.attrs & DefineConstants.FIELD_ATTRIBUTE_PUBLIC) == DefineConstants.FIELD_ATTRIBUTE_PUBLIC)
|
||||
Attributes |= FieldAttributes.Public;
|
||||
if ((fieldType.attrs & DefineConstants.FIELD_ATTRIBUTE_STATIC) == DefineConstants.FIELD_ATTRIBUTE_STATIC)
|
||||
Attributes |= FieldAttributes.Static;
|
||||
if ((fieldType.attrs & DefineConstants.FIELD_ATTRIBUTE_INIT_ONLY) == DefineConstants.FIELD_ATTRIBUTE_INIT_ONLY)
|
||||
Attributes |= FieldAttributes.InitOnly;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,21 +4,35 @@ using System.Reflection;
|
||||
namespace Il2CppInspector.Reflection {
|
||||
public abstract class MemberInfo
|
||||
{
|
||||
// Assembly that this member is defined in
|
||||
public Assembly Assembly { get; set; }
|
||||
// Assembly that this member is defined in. Only set when MemberType == TypeInfo
|
||||
public Assembly Assembly { get; }
|
||||
|
||||
// Custom attributes for this member
|
||||
public IEnumerable<CustomAttributeData> CustomAttributes { get; set; } // TODO
|
||||
public IEnumerable<CustomAttributeData> CustomAttributes { get; } // TODO
|
||||
|
||||
// Type that this type is declared in for nested types
|
||||
public Type DeclaringType { get; set; } // TODO
|
||||
public TypeInfo DeclaringType { get; }
|
||||
|
||||
// What sort of member this is, eg. method, field etc.
|
||||
public MemberTypes MemberType { get; set; } // TODO
|
||||
public abstract MemberTypes MemberType { get; }
|
||||
|
||||
// Name of the member
|
||||
public string Name { get; set; }
|
||||
public virtual string Name { get; protected set; }
|
||||
|
||||
// TODO: GetCustomAttributes etc.
|
||||
|
||||
// For top-level members in an assembly (ie. non-nested types)
|
||||
protected MemberInfo(Assembly asm, TypeInfo declaringType = null) {
|
||||
Assembly = asm;
|
||||
DeclaringType = declaringType;
|
||||
}
|
||||
|
||||
// For lower level members, eg. fields, properties etc. and nested types
|
||||
protected MemberInfo(TypeInfo declaringType) {
|
||||
if (declaringType != null) {
|
||||
Assembly = declaringType.Assembly;
|
||||
DeclaringType = declaringType;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ using System.Reflection;
|
||||
|
||||
namespace Il2CppInspector.Reflection
|
||||
{
|
||||
/*
|
||||
public abstract class MethodBase : MemberInfo
|
||||
{
|
||||
// (not code attributes)
|
||||
@@ -21,11 +22,6 @@ namespace Il2CppInspector.Reflection
|
||||
// TODO
|
||||
}
|
||||
|
||||
public class FieldInfo : MemberInfo
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
public class PropertyInfo : MemberInfo
|
||||
{
|
||||
// TODO
|
||||
@@ -35,4 +31,5 @@ namespace Il2CppInspector.Reflection
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
@@ -1,99 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Il2CppInspector.Reflection {
|
||||
public class Type : MemberInfo
|
||||
{
|
||||
// IL2CPP-specific data
|
||||
public Il2CppTypeDefinition Definition { get; }
|
||||
public int Index { get; }
|
||||
|
||||
// (not code attributes)
|
||||
// Undefined if the Type represents a generic type parameter
|
||||
public TypeAttributes Attributes { get; } // TODO
|
||||
|
||||
// Type that this type inherits from
|
||||
public Type BaseType { get; } // TODO
|
||||
|
||||
// TODO: ContainsGenericParameters
|
||||
|
||||
// Method that the type is declared in if this is a type parameter of a generic method
|
||||
public MethodBase DeclaringMethod { get; } // TODO
|
||||
|
||||
// Gets the type of the object encompassed or referred to by the current array, pointer or reference type
|
||||
public Type ElementType { get; } // TODO
|
||||
|
||||
// Type name including namespace
|
||||
public string FullName => Namespace + "." + Name;
|
||||
|
||||
// TODO: Generic stuff
|
||||
|
||||
public bool HasElementType { get; } // TODO
|
||||
public bool IsAbstract { get; }
|
||||
public bool IsArray { get; } // TODO
|
||||
public bool IsByRef { get; } // TODO
|
||||
public bool IsClass { get; }
|
||||
public bool IsEnum { get; } // TODO
|
||||
public bool IsGenericParameter { get; } // TODO
|
||||
public bool IsGenericType { get; } // TODO
|
||||
public bool IsGenericTypeDefinition { get; } // TODO
|
||||
public bool IsInterface { get; }
|
||||
public bool IsNested { get; } // TODO
|
||||
public bool IsNestedPrivate { get; } // TODO
|
||||
public bool IsNestedPublic { get; } // TODO
|
||||
public bool IsPointer { get; } // TODO
|
||||
public bool IsPrimitive { get; } // TODO
|
||||
public bool IsPublic { get; }
|
||||
public bool IsSealed { get; }
|
||||
public bool IsSerializable { get; }
|
||||
public bool IsValueType { get; } // TODO
|
||||
|
||||
public string Namespace { get; }
|
||||
|
||||
// Number of dimensions of an array
|
||||
public int GetArrayRank() => throw new NotImplementedException();
|
||||
|
||||
public List<ConstructorInfo> Constructors { get; } // TODO
|
||||
|
||||
public List<Type> Inerfaces { get; } // TODO
|
||||
|
||||
public List<MemberInfo> Members { get; } // TODO
|
||||
|
||||
public List<MethodInfo> Methods { get; } // TODO
|
||||
|
||||
public List<FieldInfo> Fields { get; } // TODO
|
||||
|
||||
public List<Type> NestedTypes { get; } // TODO
|
||||
|
||||
public List<PropertyInfo> Properties { get; } // TODO
|
||||
|
||||
// TODO: Custom attribute stuff
|
||||
|
||||
public string[] GetEnumNames() => throw new NotImplementedException();
|
||||
|
||||
public Type GetEnumUnderlyingType() => throw new NotImplementedException();
|
||||
|
||||
public Array GetEnumValues() => throw new NotImplementedException();
|
||||
|
||||
// TODO: Event stuff
|
||||
|
||||
// TODO: Generic stuff
|
||||
|
||||
// Initialize from specified type index in package
|
||||
public Type(Il2CppInspector pkg, int typeIndex, Assembly owner) {
|
||||
Assembly = owner;
|
||||
Definition = pkg.Metadata.Types[typeIndex];
|
||||
Index = typeIndex;
|
||||
Name = pkg.Metadata.Strings[Definition.nameIndex];
|
||||
Namespace = pkg.Metadata.Strings[Definition.namespaceIndex];
|
||||
|
||||
IsSerializable = (Definition.flags & DefineConstants.TYPE_ATTRIBUTE_SERIALIZABLE) != 0;
|
||||
IsPublic = (Definition.flags & DefineConstants.TYPE_ATTRIBUTE_VISIBILITY_MASK) == DefineConstants.TYPE_ATTRIBUTE_PUBLIC;
|
||||
IsAbstract = (Definition.flags & DefineConstants.TYPE_ATTRIBUTE_ABSTRACT) != 0;
|
||||
IsSealed = (Definition.flags & DefineConstants.TYPE_ATTRIBUTE_SEALED) != 0;
|
||||
IsInterface = (Definition.flags & DefineConstants.TYPE_ATTRIBUTE_INTERFACE) != 0;
|
||||
IsClass = !IsInterface;
|
||||
}
|
||||
}
|
||||
}
|
||||
202
Il2CppInspector/Reflection/TypeInfo.cs
Normal file
202
Il2CppInspector/Reflection/TypeInfo.cs
Normal file
@@ -0,0 +1,202 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Il2CppInspector.Reflection {
|
||||
public class TypeInfo : MemberInfo
|
||||
{
|
||||
// IL2CPP-specific data
|
||||
public Il2CppTypeDefinition Definition { get; }
|
||||
public int Index { get; }
|
||||
|
||||
// Information/flags about the type
|
||||
// Undefined if the Type represents a generic type parameter
|
||||
public TypeAttributes Attributes { get; } // TODO
|
||||
|
||||
// Type that this type inherits from
|
||||
public TypeInfo BaseType { get; } // TODO
|
||||
|
||||
// True if the type contains unresolved generic type parameters
|
||||
public bool ContainsGenericParameters { get; }
|
||||
|
||||
// C# colloquial name of the type (if available)
|
||||
public string CSharpName {
|
||||
get {
|
||||
var s = Namespace + "." + base.Name;
|
||||
var i = DefineConstants.FullNameTypeString.IndexOf(s);
|
||||
var n = (i != -1 ? DefineConstants.CSharpTypeString[i] : base.Name);
|
||||
if (IsArray)
|
||||
n = ElementType.CSharpName;
|
||||
var g = (GenericTypeParameters != null ? "<" + string.Join(", ", GenericTypeParameters.Select(x => x.CSharpName)) + ">" : "");
|
||||
return (IsPointer ? "void *" : "") + n + g + (IsArray ? "[]" : "");
|
||||
}
|
||||
}
|
||||
|
||||
public List<ConstructorInfo> DeclaredConstructors { get; } // TODO
|
||||
public List<EventInfo> DeclaredEvents { get; } // TODO
|
||||
public List<FieldInfo> DeclaredFields { get; } = new List<FieldInfo>();
|
||||
public List<MemberInfo> DeclaredMembers { get; } // TODO
|
||||
public List<MethodInfo> DeclaredMethods { get; } // TODO
|
||||
public List<TypeInfo> DeclaredNestedTypes { get; } // TODO
|
||||
public List<PropertyInfo> DeclaredProperties { get; } // TODO
|
||||
|
||||
// Method that the type is declared in if this is a type parameter of a generic method
|
||||
public MethodBase DeclaringMethod { get; } // TODO
|
||||
|
||||
// Gets the type of the object encompassed or referred to by the current array, pointer or reference type
|
||||
public TypeInfo ElementType { get; }
|
||||
|
||||
// Type name including namespace
|
||||
public string FullName => (IsPointer? "void *" : "")
|
||||
+ Namespace
|
||||
+ (Namespace.Length > 0? "." : "")
|
||||
+ base.Name
|
||||
+ (GenericTypeParameters != null ? "<" + string.Join(", ", GenericTypeParameters.Select(x => x.Name)) + ">" : "")
|
||||
+ (IsArray? "[]" : "");
|
||||
|
||||
// TODO: Alot of other generics stuff
|
||||
|
||||
public List<TypeInfo> GenericTypeParameters { get; }
|
||||
|
||||
public bool HasElementType => ElementType != null;
|
||||
public bool IsAbstract { get; }
|
||||
public bool IsArray { get; }
|
||||
public bool IsByRef { get; } // TODO
|
||||
public bool IsClass { get; }
|
||||
public bool IsEnum { get; } // TODO
|
||||
public bool IsGenericParameter { get; }
|
||||
public bool IsGenericType { get; } // TODO
|
||||
public bool IsGenericTypeDefinition { get; } // TODO
|
||||
public bool IsInterface { get; }
|
||||
public bool IsNested { get; } // TODO
|
||||
public bool IsNestedPrivate { get; } // TODO
|
||||
public bool IsNestedPublic { get; } // TODO
|
||||
public bool IsPointer { get; } // TODO
|
||||
public bool IsPrimitive { get; } // TODO
|
||||
public bool IsPublic { get; }
|
||||
public bool IsSealed { get; }
|
||||
public bool IsSerializable { get; }
|
||||
public bool IsValueType { get; } // TODO
|
||||
|
||||
public override MemberTypes MemberType { get; }
|
||||
|
||||
public override string Name {
|
||||
get => (IsPointer ? "void *" : "")
|
||||
+ base.Name
|
||||
+ (GenericTypeParameters != null? "<" + string.Join(", ", GenericTypeParameters.Select(x => x.Name)) + ">" : "")
|
||||
+ (IsArray ? "[]" : "");
|
||||
protected set => base.Name = value;
|
||||
}
|
||||
|
||||
public string Namespace { get; }
|
||||
|
||||
// Number of dimensions of an array
|
||||
private readonly int arrayRank;
|
||||
public int GetArrayRank() => arrayRank;
|
||||
|
||||
// TODO: Custom attribute stuff
|
||||
|
||||
public string[] GetEnumNames() => throw new NotImplementedException();
|
||||
|
||||
public TypeInfo GetEnumUnderlyingType() => throw new NotImplementedException();
|
||||
|
||||
public Array GetEnumValues() => throw new NotImplementedException();
|
||||
|
||||
// TODO: Event stuff
|
||||
|
||||
// TODO: Generic stuff
|
||||
|
||||
// Initialize from specified type index in metadata
|
||||
public TypeInfo(Il2CppInspector pkg, int typeIndex, Assembly owner) :
|
||||
base(owner) {
|
||||
Definition = pkg.Metadata.Types[typeIndex];
|
||||
Index = typeIndex;
|
||||
Namespace = pkg.Metadata.Strings[Definition.namespaceIndex];
|
||||
Name = pkg.Metadata.Strings[pkg.Metadata.Types[typeIndex].nameIndex];
|
||||
|
||||
IsSerializable = (Definition.flags & DefineConstants.TYPE_ATTRIBUTE_SERIALIZABLE) != 0;
|
||||
IsPublic = (Definition.flags & DefineConstants.TYPE_ATTRIBUTE_VISIBILITY_MASK) == DefineConstants.TYPE_ATTRIBUTE_PUBLIC;
|
||||
IsAbstract = (Definition.flags & DefineConstants.TYPE_ATTRIBUTE_ABSTRACT) != 0;
|
||||
IsSealed = (Definition.flags & DefineConstants.TYPE_ATTRIBUTE_SEALED) != 0;
|
||||
IsInterface = (Definition.flags & DefineConstants.TYPE_ATTRIBUTE_INTERFACE) != 0;
|
||||
IsClass = !IsInterface;
|
||||
|
||||
for (var f = Definition.fieldStart; f < Definition.fieldStart + Definition.field_count; f++)
|
||||
DeclaredFields.Add(new FieldInfo(pkg, f, this));
|
||||
|
||||
MemberType = MemberTypes.TypeInfo;
|
||||
}
|
||||
|
||||
// Initialize type from binary usage
|
||||
public TypeInfo(Il2CppReflector model, Il2CppType pType, MemberTypes memberType) : base(null) {
|
||||
var image = model.Package.Binary.Image;
|
||||
|
||||
IsNested = true;
|
||||
MemberType = memberType;
|
||||
|
||||
// Generic type unresolved and concrete instance types
|
||||
if (pType.type == Il2CppTypeEnum.IL2CPP_TYPE_GENERICINST) {
|
||||
var generic = image.ReadMappedObject<Il2CppGenericClass>(pType.datapoint);
|
||||
var genericTypeDef = model.GetTypeFromIndex(generic.typeDefinitionIndex);
|
||||
|
||||
Namespace = genericTypeDef.Namespace;
|
||||
Name = genericTypeDef.Name;
|
||||
|
||||
// TODO: Generic* properties and ContainsGenericParameters
|
||||
|
||||
// Get the instantiation
|
||||
var genericInstance = image.ReadMappedObject<Il2CppGenericInst>(generic.context.class_inst);
|
||||
|
||||
// Get list of pointers to type parameters (both unresolved and concrete)
|
||||
var genericTypeParameters = image.ReadMappedArray<uint>(genericInstance.type_argv, (int)genericInstance.type_argc);
|
||||
|
||||
GenericTypeParameters = new List<TypeInfo>();
|
||||
foreach (var pArg in genericTypeParameters) {
|
||||
var argType = image.ReadMappedObject<Il2CppType>(pArg);
|
||||
// TODO: Detect whether unresolved or concrete (add concrete to GenericTypeArguments instead)
|
||||
// TODO: GenericParameterPosition etc. in types we generate here
|
||||
GenericTypeParameters.Add(model.GetType(argType)); // TODO: Fix MemberType here
|
||||
}
|
||||
|
||||
IsClass = true;
|
||||
IsInterface = !IsClass;
|
||||
}
|
||||
|
||||
// Array with known dimensions and bounds
|
||||
if (pType.type == Il2CppTypeEnum.IL2CPP_TYPE_ARRAY) {
|
||||
var descriptor = image.ReadMappedObject<Il2CppArrayType>(pType.datapoint);
|
||||
var elementType = image.ReadMappedObject<Il2CppType>(descriptor.etype);
|
||||
ElementType = model.GetType(elementType);
|
||||
Namespace = ElementType.Namespace;
|
||||
Name = ElementType.Name;
|
||||
|
||||
IsArray = true;
|
||||
arrayRank = descriptor.rank;
|
||||
}
|
||||
|
||||
// Dynamically allocated array
|
||||
if (pType.type == Il2CppTypeEnum.IL2CPP_TYPE_SZARRAY) {
|
||||
var elementType = image.ReadMappedObject<Il2CppType>(pType.datapoint);
|
||||
ElementType = model.GetType(elementType);
|
||||
Namespace = ElementType.Namespace;
|
||||
Name = ElementType.Name;
|
||||
|
||||
IsArray = true;
|
||||
}
|
||||
|
||||
// Unresolved generic type variable
|
||||
if (pType.type == Il2CppTypeEnum.IL2CPP_TYPE_VAR) {
|
||||
ContainsGenericParameters = true;
|
||||
IsClass = true;
|
||||
IsGenericParameter = true;
|
||||
Name = "T"; // TODO: Don't hardcode parameter name
|
||||
|
||||
// TODO: GenericTypeParameters?
|
||||
}
|
||||
|
||||
// Pointer type
|
||||
IsPointer = (pType.type == Il2CppTypeEnum.IL2CPP_TYPE_PTR);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user