Skip to content

Commit

Permalink
(#41) ImportLogic: do not skip static interface methods
Browse files Browse the repository at this point in the history
  • Loading branch information
ForNeVeR committed Dec 30, 2024
1 parent df8239c commit d55229e
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 10 deletions.
33 changes: 25 additions & 8 deletions src/Refasmer/Importer/ImportLogic.cs
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ private TypeDefinitionHandle ImportTypeDefinitionSkeleton(TypeDefinitionHandle s
if (!forcePreservePrivateFields)
PostProcessSkippedValueTypeFields(skippedInstanceFields!, importedInstanceFields!);

var implementations = GetAllowedInterfaceMethodImplementations(src);
var implementations = GetCurrentAssemblyInterfaceMethodImplementations(src);

foreach (var srcMethodHandle in src.GetMethods())
{
Expand Down Expand Up @@ -402,12 +402,29 @@ public bool IsReferenceAssembly() =>
.Select(_reader.GetFullname)
.Any(name => name == FullNames.ReferenceAssembly);

private ImmutableHashSet<MethodDefinitionHandle> GetAllowedInterfaceMethodImplementations(TypeDefinition type) =>
type.GetMethodImplementations()
.Select(_reader.GetMethodImplementation)
.Where(mi => AllowImportType(_reader.GetMethodClass(mi.MethodDeclaration)))
.Select(mi => (MethodDefinitionHandle)mi.MethodBody)
.ToImmutableHashSet();
private ImmutableHashSet<MethodDefinitionHandle> GetCurrentAssemblyInterfaceMethodImplementations(
TypeDefinition type)
{
return GetImplementations().ToImmutableHashSet();

IEnumerable<MethodDefinitionHandle> GetImplementations()
{
var implementations = type.GetMethodImplementations()
.Select(_reader.GetMethodImplementation);
foreach (var mi in implementations)
{
if (!AllowImportType(_reader.GetMethodClass(mi.MethodDeclaration)))
continue;

var bodyHandle = (MethodDefinitionHandle)mi.MethodBody;
var method = _reader.GetMethodDefinition(bodyHandle);
var isStatic = (method.Attributes & MethodAttributes.Static) != 0;
if (isStatic) continue;

yield return bodyHandle;
}
}
}

private bool AllowImportMethod(
IImmutableSet<MethodDefinitionHandle> implementations,
Expand Down Expand Up @@ -655,7 +672,7 @@ private IEnumerable<TypeDefinitionHandle> CalculateInternalTypesToPreserve(
AcceptFieldSignature(field, collector);
}

var methodImplementations = GetAllowedInterfaceMethodImplementations(type);
var methodImplementations = GetCurrentAssemblyInterfaceMethodImplementations(type);
foreach (var methodHandle in type.GetMethods())
{
var method = _reader.GetMethodDefinition(methodHandle);
Expand Down
6 changes: 5 additions & 1 deletion tests/Refasmer.Tests/IntegrationTestBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ namespace JetBrains.Refasmer.Tests;

public abstract class IntegrationTestBase
{
private const string TestAssemblyTargetFramework = "net7.0";

protected static async Task<string> BuildTestAssembly()
{
var root = FindSourceRoot();
Expand All @@ -19,7 +21,9 @@ protected static async Task<string> BuildTestAssembly()
Is.EqualTo(0),
$"Failed to build test assembly, exit code {result.ExitCode}. StdOut:\n{result.StandardOutput}\nStdErr: {result.StandardError}");

return Path.Combine(root, "tests/RefasmerTestAssembly/bin/Release/net6.0/RefasmerTestAssembly.dll");
return Path.Combine(
root,
$"tests/RefasmerTestAssembly/bin/Release/{TestAssemblyTargetFramework}/RefasmerTestAssembly.dll");
}

protected static async Task<string> BuildTestAssemblyWithInternalTypeInPublicApi()
Expand Down
11 changes: 11 additions & 0 deletions tests/Refasmer.Tests/IntegrationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,4 +66,15 @@ await VerifyTypeContents(
assertTypeExists: false,
parameters: [mainClassName]);
}

[Test]
public async Task InterfaceImplementations()
{
var assemblyPath = await BuildTestAssemblyWithInternalTypeInPublicApi();
var resultAssembly = RefasmTestAssembly(assemblyPath, omitNonApiMembers: true);

await VerifyTypeContents(
resultAssembly,
["RefasmerTestAssembly.InterfaceImplementations", "RefasmerTestAssembly.IWithStaticMethods`1"]);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
public class: RefasmerTestAssembly.InterfaceImplementations
- interface impl: RefasmerTestAssembly.IWithStaticMethods`1<RefasmerTestAssembly.InterfaceImplementations>
methods:
- Equals(System.Object obj): System.Boolean:
- GetHashCode(): System.Int32:
- op_Equality(RefasmerTestAssembly.InterfaceImplementations a, RefasmerTestAssembly.InterfaceImplementations b): System.Boolean:
- op_Inequality(RefasmerTestAssembly.InterfaceImplementations a, RefasmerTestAssembly.InterfaceImplementations b): System.Boolean:
- .ctor(): System.Void:
public interface: RefasmerTestAssembly.IWithStaticMethods`1
methods:
- op_Equality(TSelf a, TSelf b): System.Boolean:
- <abstract>
- op_Inequality(TSelf a, TSelf b): System.Boolean:
- <abstract>
19 changes: 19 additions & 0 deletions tests/RefasmerTestAssembly/InterfaceImplementations.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using System;

namespace RefasmerTestAssembly;

public interface IWithStaticMethods<TSelf> where TSelf : IWithStaticMethods<TSelf>
{
static abstract bool operator ==(TSelf a, TSelf b);
static abstract bool operator !=(TSelf a, TSelf b);
}
public class InterfaceImplementations : IWithStaticMethods<InterfaceImplementations>
{
public override bool Equals(object? obj) => throw new NotSupportedException();

public override int GetHashCode() => throw new NotSupportedException();

public static bool operator ==(InterfaceImplementations a, InterfaceImplementations b) => throw new NotSupportedException();

public static bool operator !=(InterfaceImplementations a, InterfaceImplementations b) => throw new NotSupportedException();
}
2 changes: 1 addition & 1 deletion tests/RefasmerTestAssembly/RefasmerTestAssembly.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework>net7.0</TargetFramework>
<LangVersion>Latest</LangVersion>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<ProduceReferenceAssembly>true</ProduceReferenceAssembly>
Expand Down

0 comments on commit d55229e

Please sign in to comment.