diff --git a/Il2CppInspector/Reflection/FieldInfo.cs b/Il2CppInspector/Reflection/FieldInfo.cs index 72716b9..75e863f 100644 --- a/Il2CppInspector/Reflection/FieldInfo.cs +++ b/Il2CppInspector/Reflection/FieldInfo.cs @@ -60,7 +60,7 @@ namespace Il2CppInspector.Reflection { Definition = pkg.Metadata.Fields[fieldIndex]; Index = fieldIndex; Offset = pkg.FieldOffsets[fieldIndex]; - Name = pkg.Strings[pkg.Metadata.Fields[fieldIndex].nameIndex]; + Name = pkg.Strings[Definition.nameIndex]; fieldType = pkg.TypeUsages[Definition.typeIndex]; if ((fieldType.attrs & DefineConstants.FIELD_ATTRIBUTE_PRIVATE) == DefineConstants.FIELD_ATTRIBUTE_PRIVATE) diff --git a/Il2CppInspector/Reflection/MethodBase.cs b/Il2CppInspector/Reflection/MethodBase.cs index 16bf41d..3370df2 100644 --- a/Il2CppInspector/Reflection/MethodBase.cs +++ b/Il2CppInspector/Reflection/MethodBase.cs @@ -4,16 +4,41 @@ All rights reserved. */ +using System; +using System.Collections.Generic; using System.Reflection; namespace Il2CppInspector.Reflection { public abstract class MethodBase : MemberInfo { - // (not code attributes) - public MethodAttributes Attributes { get; set; } + // Information/flags about the method + public MethodAttributes Attributes { get; protected set; } - // TODO: ContainsGenericParameters + // True if the type contains unresolved generic type parameters + public bool ContainsGenericParameters => throw new NotImplementedException(); + + // TODO: Custom attribute stuff + + public List DeclaredParameters => throw new NotImplementedException(); + + public bool IsAbstract => (Attributes & MethodAttributes.Abstract) == MethodAttributes.Abstract; + public bool IsAssembly => throw new NotImplementedException(); + public bool IsConstructor => throw new NotImplementedException(); + public bool IsFamily => throw new NotImplementedException(); + public bool IsFamilyAndAssembly => throw new NotImplementedException(); + public bool IsFamilyOrAssembly => throw new NotImplementedException(); + public bool IsFinal => throw new NotImplementedException(); + public bool IsGenericMethod => throw new NotImplementedException(); + public bool IsGenericMethodDefinition => throw new NotImplementedException(); + public bool IsHideBySig => throw new NotImplementedException(); + public bool IsPrivate => (Attributes & MethodAttributes.Private) == MethodAttributes.Private; + public bool IsPublic => (Attributes & MethodAttributes.Public) == MethodAttributes.Public; + public bool IsStatic => (Attributes & MethodAttributes.Static) == MethodAttributes.Static; + public bool IsVirtual => (Attributes & MethodAttributes.Virtual) == MethodAttributes.Virtual; + + // TODO: GetMethodBody() + // TODO: GetParameters() protected MethodBase(TypeInfo declaringType) : base(declaringType) { } } diff --git a/Il2CppInspector/Reflection/MethodInfo.cs b/Il2CppInspector/Reflection/MethodInfo.cs index a26fad0..49b03cc 100644 --- a/Il2CppInspector/Reflection/MethodInfo.cs +++ b/Il2CppInspector/Reflection/MethodInfo.cs @@ -10,10 +10,40 @@ namespace Il2CppInspector.Reflection { public class MethodInfo : MethodBase { - // TODO + // IL2CPP-specific data + public Il2CppMethodDefinition Definition { get; } + public int Index { get; } + public uint VirtualAddress { get; } + public override MemberTypes MemberType => MemberTypes.Method; + // Info about the return parameter + public ParameterInfo ReturnParameter { get; } + + // Return type of the method + private readonly Il2CppType returnType; + + public TypeInfo ReturnType => Assembly.Model.GetType(returnType, MemberTypes.TypeInfo); + + // TODO: ReturnTypeCustomAttributes + public MethodInfo(Il2CppInspector pkg, int methodIndex, TypeInfo declaringType) : - base(declaringType) { } + base(declaringType) { + Definition = pkg.Metadata.Methods[methodIndex]; + Index = methodIndex; + VirtualAddress = pkg.Binary.MethodPointers[methodIndex]; + Name = pkg.Strings[Definition.nameIndex]; + + returnType = pkg.TypeUsages[Definition.returnType]; + + if ((Definition.flags & DefineConstants.METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == DefineConstants.METHOD_ATTRIBUTE_PRIVATE) + Attributes |= MethodAttributes.Private; + if ((Definition.flags & DefineConstants.METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == DefineConstants.METHOD_ATTRIBUTE_PUBLIC) + Attributes |= MethodAttributes.Public; + if ((Definition.flags & DefineConstants.METHOD_ATTRIBUTE_VIRTUAL) != 0) + Attributes |= MethodAttributes.Virtual; + if ((Definition.flags & DefineConstants.METHOD_ATTRIBUTE_STATIC) != 0) + Attributes |= MethodAttributes.Static; + } } } \ No newline at end of file diff --git a/Il2CppInspector/Reflection/ParameterInfo.cs b/Il2CppInspector/Reflection/ParameterInfo.cs new file mode 100644 index 0000000..bb1f70c --- /dev/null +++ b/Il2CppInspector/Reflection/ParameterInfo.cs @@ -0,0 +1,41 @@ +/* + Copyright 2017 Katy Coe - http://www.hearthcode.org - http://www.djkaty.com + + All rights reserved. +*/ + +using System; +using System.Reflection; + +namespace Il2CppInspector.Reflection +{ + public class ParameterInfo + { + // Information/flags about the parameter + public ParameterAttributes Attributes { get; } + + // TODO: CustomAttributes + + // True if the parameter has a default value + public bool HasDefaultValue { get; } + + // Default value for the parameter + public object DefaultValue { get; } + + public bool IsIn { get; } + public bool IsOptional { get; } + public bool IsOut { get; } + + // The member in which the parameter is defined + public MemberInfo Member { get; } + + // Name of parameter + public string Name { get; } + + // Type of this parameter + public TypeInfo ParameterType { get; } + + // Zero-indexed position of the parameter in parameter list + public int Position { get; } + } +} diff --git a/Il2CppInspector/Reflection/TypeInfo.cs b/Il2CppInspector/Reflection/TypeInfo.cs index 1d0066b..5f978fb 100644 --- a/Il2CppInspector/Reflection/TypeInfo.cs +++ b/Il2CppInspector/Reflection/TypeInfo.cs @@ -18,7 +18,7 @@ namespace Il2CppInspector.Reflection { // Information/flags about the type // Undefined if the Type represents a generic type parameter - public TypeAttributes Attributes => throw new NotImplementedException(); + public TypeAttributes Attributes { get; } // Type that this type inherits from public TypeInfo BaseType => throw new NotImplementedException(); @@ -66,23 +66,23 @@ namespace Il2CppInspector.Reflection { public List GenericTypeParameters { get; } public bool HasElementType => ElementType != null; - public bool IsAbstract { get; } + public bool IsAbstract => (Attributes & TypeAttributes.Abstract) == TypeAttributes.Abstract; public bool IsArray { get; } public bool IsByRef => throw new NotImplementedException(); - public bool IsClass { get; } + public bool IsClass => (Attributes & TypeAttributes.Class) == TypeAttributes.Class; public bool IsEnum => throw new NotImplementedException(); public bool IsGenericParameter { get; } public bool IsGenericType => throw new NotImplementedException(); public bool IsGenericTypeDefinition => throw new NotImplementedException(); - public bool IsInterface { get; } + public bool IsInterface => (Attributes & TypeAttributes.Interface) == TypeAttributes.Interface; public bool IsNested { get; } // TODO: Partially implemented public bool IsNestedPrivate => throw new NotImplementedException(); public bool IsNestedPublic => throw new NotImplementedException(); public bool IsPointer { get; } public bool IsPrimitive => throw new NotImplementedException(); - public bool IsPublic { get; } - public bool IsSealed { get; } - public bool IsSerializable { get; } + public bool IsPublic => (Attributes & TypeAttributes.Public) == TypeAttributes.Public; + public bool IsSealed => (Attributes & TypeAttributes.Sealed) == TypeAttributes.Sealed; + public bool IsSerializable => (Attributes & TypeAttributes.Serializable) == TypeAttributes.Serializable; public bool IsValueType => throw new NotImplementedException(); public override MemberTypes MemberType { get; } @@ -121,12 +121,20 @@ namespace Il2CppInspector.Reflection { Namespace = pkg.Strings[Definition.namespaceIndex]; Name = pkg.Strings[pkg.TypeDefinitions[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; + if ((Definition.flags & DefineConstants.TYPE_ATTRIBUTE_SERIALIZABLE) != 0) + Attributes |= TypeAttributes.Serializable; + if ((Definition.flags & DefineConstants.TYPE_ATTRIBUTE_VISIBILITY_MASK) == DefineConstants.TYPE_ATTRIBUTE_PUBLIC) + Attributes |= TypeAttributes.Public; + if ((Definition.flags & DefineConstants.TYPE_ATTRIBUTE_ABSTRACT) != 0) + Attributes |= TypeAttributes.Abstract; + if ((Definition.flags & DefineConstants.TYPE_ATTRIBUTE_SEALED) != 0) + Attributes |= TypeAttributes.Sealed; + if ((Definition.flags & DefineConstants.TYPE_ATTRIBUTE_INTERFACE) != 0) + Attributes |= TypeAttributes.Interface; + + // Not sure about this, works for now + if (!IsInterface) + Attributes |= TypeAttributes.Class; for (var f = Definition.fieldStart; f < Definition.fieldStart + Definition.field_count; f++) DeclaredFields.Add(new FieldInfo(pkg, f, this)); @@ -164,9 +172,7 @@ namespace Il2CppInspector.Reflection { // TODO: GenericParameterPosition etc. in types we generate here GenericTypeParameters.Add(model.GetType(argType)); // TODO: Fix MemberType here } - - IsClass = true; - IsInterface = !IsClass; + Attributes |= TypeAttributes.Class; } // Array with known dimensions and bounds @@ -194,7 +200,7 @@ namespace Il2CppInspector.Reflection { // Unresolved generic type variable if (pType.type == Il2CppTypeEnum.IL2CPP_TYPE_VAR) { ContainsGenericParameters = true; - IsClass = true; + Attributes |= TypeAttributes.Class; IsGenericParameter = true; Name = "T"; // TODO: Don't hardcode parameter name