Model: Implement various generic method properties
This commit is contained in:
@@ -607,8 +607,7 @@ namespace Il2CppInspector
|
|||||||
writer.Append("(" + method.GetParametersString(scope, !SuppressMetadata) + ")");
|
writer.Append("(" + method.GetParametersString(scope, !SuppressMetadata) + ")");
|
||||||
|
|
||||||
// Generic type constraints
|
// Generic type constraints
|
||||||
if (method.GenericTypeParameters != null)
|
foreach (var gp in method.GetGenericArguments()) {
|
||||||
foreach (var gp in method.GenericTypeParameters) {
|
|
||||||
var constraint = gp.GetTypeConstraintsString(scope);
|
var constraint = gp.GetTypeConstraintsString(scope);
|
||||||
if (constraint != string.Empty)
|
if (constraint != string.Empty)
|
||||||
writer.Append($"\n{prefix}\t\t{constraint}");
|
writer.Append($"\n{prefix}\t\t{constraint}");
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2017-2019 Katy Coe - http://www.hearthcode.org - http://www.djkaty.com
|
Copyright 2017-2020 Katy Coe - http://www.hearthcode.org - http://www.djkaty.com
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
*/
|
*/
|
||||||
@@ -9,7 +9,6 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
|
|
||||||
namespace Il2CppInspector.Reflection
|
namespace Il2CppInspector.Reflection
|
||||||
{
|
{
|
||||||
@@ -23,13 +22,9 @@ namespace Il2CppInspector.Reflection
|
|||||||
// Information/flags about the method
|
// Information/flags about the method
|
||||||
public MethodAttributes Attributes { get; protected set; }
|
public MethodAttributes Attributes { get; protected set; }
|
||||||
|
|
||||||
// True if the method contains unresolved generic type parameters
|
|
||||||
public bool ContainsGenericParameters { get; }
|
|
||||||
|
|
||||||
// Custom attributes for this member
|
// Custom attributes for this member
|
||||||
public override IEnumerable<CustomAttributeData> CustomAttributes => CustomAttributeData.GetCustomAttributes(this);
|
public override IEnumerable<CustomAttributeData> CustomAttributes => CustomAttributeData.GetCustomAttributes(this);
|
||||||
|
|
||||||
public List<TypeInfo> GenericTypeParameters { get; } // System.Reflection.MethodInfo.GetGenericArguments()
|
|
||||||
public List<ParameterInfo> DeclaredParameters { get; } = new List<ParameterInfo>();
|
public List<ParameterInfo> DeclaredParameters { get; } = new List<ParameterInfo>();
|
||||||
|
|
||||||
public bool IsAbstract => (Attributes & MethodAttributes.Abstract) == MethodAttributes.Abstract;
|
public bool IsAbstract => (Attributes & MethodAttributes.Abstract) == MethodAttributes.Abstract;
|
||||||
@@ -39,8 +34,6 @@ namespace Il2CppInspector.Reflection
|
|||||||
public bool IsFamilyAndAssembly => (Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.FamANDAssem;
|
public bool IsFamilyAndAssembly => (Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.FamANDAssem;
|
||||||
public bool IsFamilyOrAssembly => (Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.FamORAssem;
|
public bool IsFamilyOrAssembly => (Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.FamORAssem;
|
||||||
public bool IsFinal => (Attributes & MethodAttributes.Final) == MethodAttributes.Final;
|
public bool IsFinal => (Attributes & MethodAttributes.Final) == MethodAttributes.Final;
|
||||||
public bool IsGenericMethod { get; }
|
|
||||||
public bool IsGenericMethodDefinition { get; }
|
|
||||||
public bool IsHideBySig => (Attributes & MethodAttributes.HideBySig) == MethodAttributes.HideBySig;
|
public bool IsHideBySig => (Attributes & MethodAttributes.HideBySig) == MethodAttributes.HideBySig;
|
||||||
public bool IsPrivate => (Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Private;
|
public bool IsPrivate => (Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Private;
|
||||||
public bool IsPublic => (Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Public;
|
public bool IsPublic => (Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Public;
|
||||||
@@ -50,6 +43,25 @@ namespace Il2CppInspector.Reflection
|
|||||||
|
|
||||||
public virtual bool RequiresUnsafeContext => DeclaredParameters.Any(p => p.ParameterType.RequiresUnsafeContext);
|
public virtual bool RequiresUnsafeContext => DeclaredParameters.Any(p => p.ParameterType.RequiresUnsafeContext);
|
||||||
|
|
||||||
|
// True if the method contains unresolved generic type parameters, or if it is a non-generic method in an open ganeric type
|
||||||
|
// See: https://docs.microsoft.com/en-us/dotnet/api/system.reflection.methodbase.containsgenericparameters?view=netframework-4.8
|
||||||
|
public bool ContainsGenericParameters => DeclaringType.ContainsGenericParameters || genericArguments.Any(ga => ga.ContainsGenericParameters);
|
||||||
|
|
||||||
|
// For a generic method definition: the list of generic type parameters
|
||||||
|
// For an open generic method: a mix of generic type parameters and generic type arguments
|
||||||
|
// For a closed generic method: the list of generic type arguments
|
||||||
|
private readonly List<TypeInfo> genericArguments = new List<TypeInfo>();
|
||||||
|
|
||||||
|
// See: https://docs.microsoft.com/en-us/dotnet/api/system.reflection.methodbase.getgenericarguments?view=netframework-4.8
|
||||||
|
public List<TypeInfo> GetGenericArguments() => genericArguments;
|
||||||
|
|
||||||
|
// This was added in .NET Core 2.1 and isn't properly documented yet
|
||||||
|
public bool IsConstructedGenericMethod => genericArguments.All(ga => !ga.ContainsGenericParameters);
|
||||||
|
|
||||||
|
// See: https://docs.microsoft.com/en-us/dotnet/api/system.reflection.methodbase.isgenericmethod?view=netframework-4.8
|
||||||
|
public bool IsGenericMethod { get; }
|
||||||
|
public bool IsGenericMethodDefinition => genericArguments.Any() && genericArguments.All(a => a.IsGenericTypeParameter);
|
||||||
|
|
||||||
// TODO: GetMethodBody()
|
// TODO: GetMethodBody()
|
||||||
|
|
||||||
public string CSharpName =>
|
public string CSharpName =>
|
||||||
@@ -85,13 +97,11 @@ namespace Il2CppInspector.Reflection
|
|||||||
// Generic method definition?
|
// Generic method definition?
|
||||||
if (Definition.genericContainerIndex >= 0) {
|
if (Definition.genericContainerIndex >= 0) {
|
||||||
IsGenericMethod = true;
|
IsGenericMethod = true;
|
||||||
IsGenericMethodDefinition = true;
|
|
||||||
ContainsGenericParameters = true;
|
|
||||||
|
|
||||||
// Store the generic type parameters for later instantiation
|
// Store the generic type parameters for later instantiation
|
||||||
var container = pkg.GenericContainers[Definition.genericContainerIndex];
|
var container = pkg.GenericContainers[Definition.genericContainerIndex];
|
||||||
|
|
||||||
GenericTypeParameters = pkg.GenericParameters.Skip((int)container.genericParameterStart).Take(container.type_argc).Select(p => new TypeInfo(this, p)).ToList();
|
genericArguments = pkg.GenericParameters.Skip((int)container.genericParameterStart).Take(container.type_argc).Select(p => new TypeInfo(this, p)).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set method attributes
|
// Set method attributes
|
||||||
@@ -191,11 +201,11 @@ namespace Il2CppInspector.Reflection
|
|||||||
public string GetParametersString(Scope usingScope, bool emitPointer = false, bool commentAttributes = false)
|
public string GetParametersString(Scope usingScope, bool emitPointer = false, bool commentAttributes = false)
|
||||||
=> string.Join(", ", DeclaredParameters.Select(p => p.GetParameterString(usingScope, emitPointer, commentAttributes)));
|
=> string.Join(", ", DeclaredParameters.Select(p => p.GetParameterString(usingScope, emitPointer, commentAttributes)));
|
||||||
|
|
||||||
public string GetTypeParametersString(Scope usingScope) => GenericTypeParameters == null? "" :
|
public string GetTypeParametersString(Scope usingScope) => !GetGenericArguments().Any()? "" :
|
||||||
"<" + string.Join(", ", GenericTypeParameters.Select(p => p.GetScopedCSharpName(usingScope))) + ">";
|
"<" + string.Join(", ", GetGenericArguments().Select(p => p.GetScopedCSharpName(usingScope))) + ">";
|
||||||
|
|
||||||
public string GetFullTypeParametersString() => GenericTypeParameters == null? "" :
|
public string GetFullTypeParametersString() => !GetGenericArguments().Any()? "" :
|
||||||
"[" + string.Join(",", GenericTypeParameters.Select(p => p.FullName ?? p.Name)) + "]";
|
"[" + string.Join(",", GetGenericArguments().Select(p => p.FullName ?? p.Name)) + "]";
|
||||||
|
|
||||||
public abstract string GetSignatureString();
|
public abstract string GetSignatureString();
|
||||||
|
|
||||||
|
|||||||
@@ -773,8 +773,8 @@ namespace Il2CppInspector.Reflection {
|
|||||||
refs.UnionWith(DeclaredMethods.SelectMany(m => m.DeclaredParameters).Select(p => p.ParameterType));
|
refs.UnionWith(DeclaredMethods.SelectMany(m => m.DeclaredParameters).Select(p => p.ParameterType));
|
||||||
|
|
||||||
// Method generic type parameters and constraints
|
// Method generic type parameters and constraints
|
||||||
refs.UnionWith(DeclaredMethods.SelectMany(m => m.GenericTypeParameters ?? new List<TypeInfo>()));
|
refs.UnionWith(DeclaredMethods.SelectMany(m => m.GetGenericArguments()));
|
||||||
refs.UnionWith(DeclaredMethods.SelectMany(m => m.GenericTypeParameters ?? new List<TypeInfo>())
|
refs.UnionWith(DeclaredMethods.SelectMany(m => m.GetGenericArguments())
|
||||||
.SelectMany(p => p.GetGenericParameterConstraints()));
|
.SelectMany(p => p.GetGenericParameterConstraints()));
|
||||||
|
|
||||||
// Type declaration attributes
|
// Type declaration attributes
|
||||||
@@ -898,7 +898,7 @@ namespace Il2CppInspector.Reflection {
|
|||||||
// Find nearest ancestor base method which has us as a generic type parameter
|
// Find nearest ancestor base method which has us as a generic type parameter
|
||||||
var sig = DeclaringMethod.GetSignatureString();
|
var sig = DeclaringMethod.GetSignatureString();
|
||||||
var method = DeclaringMethod.DeclaringType.BaseType.GetAllMethods()
|
var method = DeclaringMethod.DeclaringType.BaseType.GetAllMethods()
|
||||||
.FirstOrDefault(m => m.IsHideBySig && m.IsVirtual && m.GetSignatureString() == sig && (m.GenericTypeParameters?.Any(p => p.Name == Name) ?? false));
|
.FirstOrDefault(m => m.IsHideBySig && m.IsVirtual && m.GetSignatureString() == sig && m.GetGenericArguments().Any(p => p.Name == Name));
|
||||||
|
|
||||||
// Stop if we are inherited from a base method
|
// Stop if we are inherited from a base method
|
||||||
if (method != null)
|
if (method != null)
|
||||||
|
|||||||
Reference in New Issue
Block a user