Skip to content

Commit 812b3bb

Browse files
committed
Core: Fix exceptions in CustomAttributeTypeParameter for generics
1 parent 7d8d90f commit 812b3bb

File tree

7 files changed

+67
-6
lines changed

7 files changed

+67
-6
lines changed

Cpp2IL.Core/Api/ICSharpSourceToken.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
namespace Cpp2IL.Core.Api;
2+
3+
public interface ICSharpSourceToken
4+
{
5+
/// <summary>
6+
/// Returns a string of C# source code which would be equivalent to this token. For example, for types, this would be the type name, for generic types, the full type name with generic arguments, etc.
7+
/// </summary>
8+
public string GetCSharpSourceString();
9+
}

Cpp2IL.Core/Model/Contexts/GenericInstanceTypeAnalysisContext.cs

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System.Linq;
2+
using System.Text;
23
using Cpp2IL.Core.Utils;
34
using LibCpp2IL.BinaryStructures;
45

@@ -16,4 +17,26 @@ public GenericInstanceTypeAnalysisContext(Il2CppType rawType, AssemblyAnalysisCo
1617

1718
GenericArguments.AddRange(gClass.Context.ClassInst.Types.Select(referencedFrom.ResolveIl2CppType)!);
1819
}
19-
}
20+
21+
public override string GetCSharpSourceString()
22+
{
23+
var sb = new StringBuilder();
24+
25+
sb.Append(ElementType.GetCSharpSourceString());
26+
sb.Append('<');
27+
var first = true;
28+
foreach (var genericArgument in GenericArguments)
29+
{
30+
if (!first)
31+
sb.Append(", ");
32+
else
33+
first = false;
34+
35+
sb.Append(genericArgument.GetCSharpSourceString());
36+
}
37+
38+
sb.Append('>');
39+
40+
return sb.ToString();
41+
}
42+
}

Cpp2IL.Core/Model/Contexts/GenericParameterTypeAnalysisContext.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,4 @@ public GenericParameterTypeAnalysisContext(Il2CppType rawType, AssemblyAnalysisC
1313

1414
GenericParameter = rawType.GetGenericParameterDef();
1515
}
16-
}
16+
}

Cpp2IL.Core/Model/Contexts/ReferencedTypeAnalysisContext.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,9 @@ public override string ToString()
4646
{
4747
return $"{DefaultName}";
4848
}
49-
}
49+
50+
public override string GetCSharpSourceString()
51+
{
52+
return Name;
53+
}
54+
}

Cpp2IL.Core/Model/Contexts/TypeAnalysisContext.cs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
using System.IO;
44
using System.Linq;
55
using System.Reflection;
6+
using System.Text;
7+
using Cpp2IL.Core.Api;
68
using Cpp2IL.Core.Utils;
79
using LibCpp2IL.BinaryStructures;
810
using LibCpp2IL.Metadata;
@@ -14,7 +16,7 @@ namespace Cpp2IL.Core.Model.Contexts;
1416
/// <summary>
1517
/// Represents one managed type in the application.
1618
/// </summary>
17-
public class TypeAnalysisContext : HasCustomAttributesAndName, ITypeInfoProvider
19+
public class TypeAnalysisContext : HasCustomAttributesAndName, ITypeInfoProvider, ICSharpSourceToken
1820
{
1921
/// <summary>
2022
/// The context for the assembly this type was defined in.
@@ -137,6 +139,19 @@ public TypeAnalysisContext(Il2CppTypeDefinition? il2CppTypeDefinition, AssemblyA
137139
public List<MethodAnalysisContext> GetConstructors() => Methods.Where(m => m.Definition!.Name == ".ctor").ToList();
138140

139141
public override string ToString() => $"Type: {Definition?.FullName}";
142+
public virtual string GetCSharpSourceString()
143+
{
144+
if (Definition != null)
145+
return Definition.FullName!;
146+
147+
var ret = new StringBuilder();
148+
if(OverrideNs != null)
149+
ret.Append(OverrideNs).Append('.');
150+
151+
ret.Append(Name);
152+
153+
return ret.ToString();
154+
}
140155

141156
#region StableNameDotNet implementation
142157

Cpp2IL.Core/Model/CustomAttributes/CustomAttributeTypeParameter.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using AsmResolver.DotNet.Signatures.Types;
44
using Cpp2IL.Core.Extensions;
55
using Cpp2IL.Core.Model.Contexts;
6+
using Cpp2IL.Core.Utils;
67
using Cpp2IL.Core.Utils.AsmResolver;
78
using LibCpp2IL;
89
using LibCpp2IL.BinaryStructures;
@@ -43,7 +44,15 @@ public override string ToString()
4344

4445
if (Type.Type.IsIl2CppPrimitive())
4546
return $"typeof({LibCpp2ILUtils.GetTypeName(Owner.Constructor.AppContext.Metadata, Owner.Constructor.AppContext.Binary, Type)}";
47+
48+
if (Type.Type is not Il2CppTypeEnum.IL2CPP_TYPE_CLASS and not Il2CppTypeEnum.IL2CPP_TYPE_VALUETYPE)
49+
{
50+
//Some sort of wrapper type, like a generic parameter or a generic instance.
51+
var typeContext = Owner.Constructor.CustomAttributeAssembly.ResolveIl2CppType(Type);
52+
return $"typeof({typeContext.GetCSharpSourceString()})";
53+
}
4654

55+
//Basic class/struct
4756
return $"typeof({Type.AsClass().Name})";
4857
}
4958

Cpp2IL.Core/Utils/Il2CppTypeToContext.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
namespace Cpp2IL.Core.Utils;
88

9-
internal static class Il2CppTypeToContext
9+
public static class Il2CppTypeToContext
1010
{
1111
private static TypeAnalysisContext GetPrimitive(this SystemTypesContext context, Il2CppTypeEnum type) =>
1212
type switch
@@ -54,4 +54,4 @@ private static TypeAnalysisContext GetPrimitive(this SystemTypesContext context,
5454

5555
return new GenericParameterTypeAnalysisContext(type, context);
5656
}
57-
}
57+
}

0 commit comments

Comments
 (0)