From 759a77031ebd91aa81735b216102d00c6ffbf94b Mon Sep 17 00:00:00 2001 From: Katy Coe Date: Sun, 2 Feb 2020 04:45:43 +0100 Subject: [PATCH] Model: Substitute concrete parameter types into generic methods from MethodSpecs --- Il2CppInspector/Reflection/MethodBase.cs | 10 +++++++++- Il2CppInspector/Reflection/ParameterInfo.cs | 12 +++++++++++- Il2CppTests/TestSources/GenericTypes.cs | 1 - 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/Il2CppInspector/Reflection/MethodBase.cs b/Il2CppInspector/Reflection/MethodBase.cs index 966c9c9..557350e 100644 --- a/Il2CppInspector/Reflection/MethodBase.cs +++ b/Il2CppInspector/Reflection/MethodBase.cs @@ -152,7 +152,14 @@ namespace Il2CppInspector.Reflection IsGenericMethod = true; genericArguments = model.ResolveGenericArguments(spec.methodIndexIndex); - // TODO: Substitute generic type arguments for concrete type arguments + // Substitute matching generic type parameters with concrete type arguments + foreach (var p in methodDef.DeclaredParameters) { + if (!p.ParameterType.IsGenericMethodParameter) + DeclaredParameters.Add(p); + else + DeclaredParameters.Add(new ParameterInfo(model, p, genericArguments[p.ParameterType.GenericParameterPosition])); + } + // TODO: Populate VirtualAddress via Il2CppGenericMethodFunctionsDefinitions } @@ -219,6 +226,7 @@ namespace Il2CppInspector.Reflection public string GetTypeParametersString(Scope usingScope) => !GetGenericArguments().Any()? "" : "<" + string.Join(", ", GetGenericArguments().Select(p => p.GetScopedCSharpName(usingScope))) + ">"; + // TODO: The scope output for some System types does not match the real .NET output here public string GetFullTypeParametersString() => !GetGenericArguments().Any()? "" : "[" + string.Join(",", GetGenericArguments().Select(p => p.FullName ?? p.Name)) + "]"; diff --git a/Il2CppInspector/Reflection/ParameterInfo.cs b/Il2CppInspector/Reflection/ParameterInfo.cs index 1c00750..9630c16 100644 --- a/Il2CppInspector/Reflection/ParameterInfo.cs +++ b/Il2CppInspector/Reflection/ParameterInfo.cs @@ -97,7 +97,17 @@ namespace Il2CppInspector.Reflection // Create a concrete type parameter from a generic type parameter public ParameterInfo(Il2CppModel model, ParameterInfo generic, TypeInfo concrete) { - // TODO: Implement generic parameter substitution + + DeclaringMethod = generic.DeclaringMethod; + Name = generic.Name; + Position = generic.Position; + Attributes = generic.Attributes; + + // TODO: Duplicate instances of 'concrete' may cause this search to fail. Replace with a straight lookup after eliminating GetTypeFromVirtualAddress + paramTypeReference = Array.IndexOf(model.TypesByReferenceIndex, concrete); + + DefaultValue = generic.DefaultValue; + DefaultValueMetadataAddress = generic.DefaultValueMetadataAddress; } // ref will be handled as part of the type name diff --git a/Il2CppTests/TestSources/GenericTypes.cs b/Il2CppTests/TestSources/GenericTypes.cs index 5dfb56c..50b2283 100644 --- a/Il2CppTests/TestSources/GenericTypes.cs +++ b/Il2CppTests/TestSources/GenericTypes.cs @@ -6,7 +6,6 @@ using System; using System.Collections.Generic; -using Il2CppInspector; namespace Il2CppTests.TestSources {