Skip to content

Commit

Permalink
Prevent duplicates when overriding or shadowing methods
Browse files Browse the repository at this point in the history
The current code will insert multiple definitions of a method when that method has been overridden or shadowed.

The approach is the same as that already used for property deduplication, which is to group by the method definition.
  • Loading branch information
Simon McKenzie committed Jun 14, 2024
1 parent 218ba17 commit b7999a0
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 0 deletions.
7 changes: 7 additions & 0 deletions AutomaticInterface/AutomaticInterface/Builder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,11 @@ private static void AddMethodsToInterface(
InterfaceBuilder codeGenerator
)
{
var methodDisplayFormatForDeduplication = new SymbolDisplayFormat(
memberOptions: SymbolDisplayMemberOptions.IncludeParameters,
parameterOptions: SymbolDisplayParameterOptions.IncludeType
);

classSymbol
.GetAllMembers()
.Where(x => x.Kind == SymbolKind.Method)
Expand All @@ -72,6 +77,8 @@ InterfaceBuilder codeGenerator
.Where(x => x.MethodKind == MethodKind.Ordinary)
.Where(x => !x.IsStatic)
.Where(x => x.ContainingType.Name != nameof(Object))
.GroupBy(x => x.ToDisplayString(methodDisplayFormatForDeduplication))
.Select(x => x.First())
.ToList()
.ForEach(method =>
{
Expand Down
98 changes: 98 additions & 0 deletions AutomaticInterface/Tests/GeneratorTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2211,4 +2211,102 @@ public partial interface ISecondClass
""";
GenerateCode(code).Should().Be(expected);
}

[Fact]
public void WorksWithMethodOverrides()
{
const string code = """
using AutomaticInterfaceAttribute;
namespace AutomaticInterfaceExample;
public class BaseClass
{
public virtual bool AMethod();
}
[GenerateAutomaticInterface]
public class DemoClass : BaseClass
{
public override bool AMethod() => return true;
}
""";

const string expected = """
//--------------------------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
//
// Changes to this file may cause incorrect behavior and will be lost if the code is regenerated.
// </auto-generated>
//--------------------------------------------------------------------------------------------------
using System.CodeDom.Compiler;
using AutomaticInterfaceAttribute;
namespace AutomaticInterfaceExample
{
[GeneratedCode("AutomaticInterface", "")]
public partial interface IDemoClass
{
/// <inheritdoc />
bool AMethod();
}
}
""";
GenerateCode(code).Should().Be(expected);
}

[Fact]
public void WorksWithMethodShadowing()
{
const string code = """
using AutomaticInterfaceAttribute;
namespace AutomaticInterfaceExample;
public class BaseClass
{
public bool AMethod();
}
[GenerateAutomaticInterface]
public class DemoClass : BaseClass
{
public new bool AMethod() => return true;
}
""";

const string expected = """
//--------------------------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
//
// Changes to this file may cause incorrect behavior and will be lost if the code is regenerated.
// </auto-generated>
//--------------------------------------------------------------------------------------------------
using System.CodeDom.Compiler;
using AutomaticInterfaceAttribute;
namespace AutomaticInterfaceExample
{
[GeneratedCode("AutomaticInterface", "")]
public partial interface IDemoClass
{
/// <inheritdoc />
bool AMethod();
}
}
""";
GenerateCode(code).Should().Be(expected);
}
}

0 comments on commit b7999a0

Please sign in to comment.