Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 58 additions & 1 deletion Cpp2IL.Core.Tests/MethodOverridesTests.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System.Linq;
using Cpp2IL.Core.Model.Contexts;

namespace Cpp2IL.Core.Tests;

Expand Down Expand Up @@ -39,4 +38,62 @@ public void OverridesTests()
Assert.That(iList.Methods.Select(m => m.Overrides.Count()), Is.All.EqualTo(0));
}
}

[Test]
public void InterfaceMethodsShouldNotOverrideAnything()
{
var appContext = TestGameLoader.LoadSimple2019Game();

using (Assert.EnterMultipleScope())
{
var count = 0;
foreach (var assembly in appContext.Assemblies)
{
foreach (var type in assembly.Types)
{
if (!type.IsInterface)
continue;

foreach (var method in type.Methods)
{
if (!method.IsVirtual && !method.IsAbstract)
continue;

if (method.IsStatic || !method.IsNewSlot)
continue;

Assert.That(method.Overrides, Is.Empty);
count++;
}
}
}
Assert.That(count, Is.GreaterThan(0));
}
}

[Test]
public void InterfaceMethodsShouldHaveNoBaseMethod()
{
var appContext = TestGameLoader.LoadSimple2019Game();

using (Assert.EnterMultipleScope())
{
var count = 0;
foreach (var assembly in appContext.Assemblies)
{
foreach (var type in assembly.Types)
{
if (!type.IsInterface)
continue;

foreach (var method in type.Methods)
{
Assert.That(method.BaseMethod, Is.Null);
count++;
}
}
}
Assert.That(count, Is.GreaterThan(0));
}
}
}
52 changes: 52 additions & 0 deletions Cpp2IL.Core.Tests/TypeAnalysisContextTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
namespace Cpp2IL.Core.Tests;

public class TypeAnalysisContextTests
{
[Test]
public void InterfacesHaveNoBaseType()
{
var appContext = TestGameLoader.LoadSimple2019Game();

using (Assert.EnterMultipleScope())
{
var count = 0;
foreach (var assembly in appContext.Assemblies)
{
foreach (var type in assembly.Types)
{
if (!type.IsInterface)
continue;

Assert.That(type.DefaultBaseType, Is.Null);
Assert.That(type.BaseType, Is.Null);
count++;
}
}
Assert.That(count, Is.GreaterThan(0));
}
}

[Test]
public void StaticClassesHaveObjectBaseType()
{
var appContext = TestGameLoader.LoadSimple2019Game();

using (Assert.EnterMultipleScope())
{
var count = 0;
foreach (var assembly in appContext.Assemblies)
{
foreach (var type in assembly.Types)
{
if (!type.IsStatic)
continue;

Assert.That(type.DefaultBaseType, Is.EqualTo(appContext.SystemTypes.SystemObjectType));
Assert.That(type.BaseType, Is.EqualTo(appContext.SystemTypes.SystemObjectType));
count++;
}
}
Assert.That(count, Is.GreaterThan(0));
}
}
}
4 changes: 4 additions & 0 deletions Cpp2IL.Core/Model/Contexts/MethodAnalysisContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ public class MethodAnalysisContext : HasGenericParameters, IMethodInfoProvider

public bool IsVirtual => (Attributes & MethodAttributes.Virtual) != 0;

public bool IsAbstract => (Attributes & MethodAttributes.Abstract) != 0;

public bool IsNewSlot => (Attributes & MethodAttributes.NewSlot) != 0;

protected override int CustomAttributeIndex => Definition?.customAttributeIndex ?? throw new("Subclasses of MethodAnalysisContext should override CustomAttributeIndex if they have custom attributes");

public override AssemblyAnalysisContext CustomAttributeAssembly => DeclaringType?.DeclaringAssembly ?? throw new("Subclasses of MethodAnalysisContext should override CustomAttributeAssembly if they have custom attributes");
Expand Down
2 changes: 1 addition & 1 deletion Cpp2IL.Core/Model/Contexts/TypeAnalysisContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ public class TypeAnalysisContext : HasGenericParameters, ITypeInfoProvider, ICSh

public TypeAttributes Attributes => OverrideAttributes ?? DefaultAttributes;

public virtual TypeAnalysisContext? DefaultBaseType => Definition == null ? null : DeclaringAssembly.ResolveIl2CppType(Definition.RawBaseType);
public virtual TypeAnalysisContext? DefaultBaseType => Definition == null || DefaultAttributes.HasFlag(TypeAttributes.Interface) ? null : DeclaringAssembly.ResolveIl2CppType(Definition.RawBaseType);

public TypeAnalysisContext? OverrideBaseType { get; set; }

Expand Down
Loading