Skip to content

Commit d7f5ccf

Browse files
authored
Add methods for resolving il2cpp definitions to their contexts (#364)
1 parent 02545f5 commit d7f5ccf

File tree

3 files changed

+85
-3
lines changed

3 files changed

+85
-3
lines changed
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
using System.Linq;
2+
3+
namespace Cpp2IL.Core.Tests;
4+
5+
public class MemberResolutionTests
6+
{
7+
[SetUp]
8+
public void Setup()
9+
{
10+
Cpp2IlApi.ResetInternalState();
11+
TestGameLoader.LoadSimple2019Game();
12+
}
13+
14+
[Test]
15+
public void TestMethodResolving()
16+
{
17+
var appContext = Cpp2IlApi.CurrentAppContext;
18+
19+
var methodContext = appContext!.AllTypes.SelectMany(t => t.Methods).First(m => m.Definition is not null);
20+
21+
Assert.That(appContext.ResolveContextForMethod(methodContext.Definition), Is.EqualTo(methodContext));
22+
}
23+
24+
[Test]
25+
public void TestFieldResolving()
26+
{
27+
var appContext = Cpp2IlApi.CurrentAppContext;
28+
29+
var fieldContext = appContext!.AllTypes.SelectMany(t => t.Fields).First(f => f.BackingData?.Field is not null);
30+
31+
Assert.That(appContext.ResolveContextForField(fieldContext.BackingData!.Field), Is.EqualTo(fieldContext));
32+
}
33+
34+
[Test]
35+
public void TestEventResolving()
36+
{
37+
var appContext = Cpp2IlApi.CurrentAppContext;
38+
39+
var eventContext = appContext!.AllTypes.SelectMany(t => t.Events).First(e => e.Definition is not null);
40+
41+
Assert.That(appContext.ResolveContextForEvent(eventContext.Definition), Is.EqualTo(eventContext));
42+
}
43+
44+
[Test]
45+
public void TestPropertyResolving()
46+
{
47+
var appContext = Cpp2IlApi.CurrentAppContext;
48+
49+
var propertyContext = appContext!.AllTypes.SelectMany(t => t.Properties).First(p => p.Definition is not null);
50+
51+
Assert.That(appContext.ResolveContextForProperty(propertyContext.Definition), Is.EqualTo(propertyContext));
52+
}
53+
}

Cpp2IL.Core/Model/Contexts/ApplicationAnalysisContext.cs

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,32 @@ private void PopulateMethodsByAddressTable()
161161
return AssembliesByName[name];
162162
}
163163

164-
public TypeAnalysisContext? ResolveContextForType(Il2CppTypeDefinition typeDefinition) => GetAssemblyByName(typeDefinition.DeclaringAssembly!.Name!)?.GetTypeByDefinition(typeDefinition);
164+
public TypeAnalysisContext? ResolveContextForType(Il2CppTypeDefinition? typeDefinition)
165+
{
166+
return typeDefinition is not null
167+
? GetAssemblyByName(typeDefinition.DeclaringAssembly!.Name!)?.GetTypeByDefinition(typeDefinition)
168+
: null;
169+
}
170+
171+
public MethodAnalysisContext? ResolveContextForMethod(Il2CppMethodDefinition? methodDefinition)
172+
{
173+
return ResolveContextForType(methodDefinition?.DeclaringType)?.Methods.FirstOrDefault(m => m.Definition == methodDefinition);
174+
}
175+
176+
public FieldAnalysisContext? ResolveContextForField(Il2CppFieldDefinition? field)
177+
{
178+
return ResolveContextForType(field?.DeclaringType)?.Fields.FirstOrDefault(f => f.BackingData?.Field == field);
179+
}
180+
181+
public EventAnalysisContext? ResolveContextForEvent(Il2CppEventDefinition? eventDefinition)
182+
{
183+
return ResolveContextForType(eventDefinition?.DeclaringType)?.Events.FirstOrDefault(e => e.Definition == eventDefinition);
184+
}
185+
186+
public PropertyAnalysisContext? ResolveContextForProperty(Il2CppPropertyDefinition? propertyDefinition)
187+
{
188+
return ResolveContextForType(propertyDefinition?.DeclaringType)?.Properties.FirstOrDefault(p => p.Definition == propertyDefinition);
189+
}
165190

166191
public BaseKeyFunctionAddresses GetOrCreateKeyFunctionAddresses()
167192
{

Cpp2IL.Core/Model/Contexts/ConcreteGenericMethodAnalysisContext.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@ private ConcreteGenericMethodAnalysisContext(Cpp2IlMethodRef methodRef, Assembly
3535
DeclaringAsm = declaringAssembly;
3636
BaseMethodContext = ResolveBaseMethod(methodRef, declaringAssembly.GetTypeByDefinition(methodRef.DeclaringType)!);
3737

38-
var genericTypeParameters = ResolveTypeArray(methodRef.TypeGenericParams, declaringAssembly);
39-
var genericMethodParameters = ResolveTypeArray(methodRef.MethodGenericParams, declaringAssembly);
38+
var genericTypeParameters = ResolveTypeGenericParameters();
39+
var genericMethodParameters = ResolveMethodGenericParameters();
4040

4141
for (var i = 0; i < BaseMethodContext.Parameters.Count; i++)
4242
{
@@ -58,6 +58,10 @@ private ConcreteGenericMethodAnalysisContext(Cpp2IlMethodRef methodRef, Assembly
5858
rawMethodBody = AppContext.InstructionSet.GetRawBytesForMethod(this, false);
5959
}
6060

61+
public TypeAnalysisContext[] ResolveTypeGenericParameters() => ResolveTypeArray(MethodRef.TypeGenericParams, DeclaringAsm);
62+
63+
public TypeAnalysisContext[] ResolveMethodGenericParameters() => ResolveTypeArray(MethodRef.MethodGenericParams, DeclaringAsm);
64+
6165
private static AssemblyAnalysisContext ResolveDeclaringAssembly(Cpp2IlMethodRef methodRef, ApplicationAnalysisContext context)
6266
{
6367
return context.GetAssemblyByName(methodRef.DeclaringType.DeclaringAssembly!.Name!)

0 commit comments

Comments
 (0)