diff --git a/AutomaticInterface/AutomaticInterface/Builder.cs b/AutomaticInterface/AutomaticInterface/Builder.cs
index dd04845..b5fa56c 100644
--- a/AutomaticInterface/AutomaticInterface/Builder.cs
+++ b/AutomaticInterface/AutomaticInterface/Builder.cs
@@ -11,6 +11,13 @@ public static class Builder
{
private const string InheritDoc = "/// "; // we use inherit doc because that should be able to fetch documentation from base classes.
+ private static readonly SymbolDisplayFormat MethodSignatureDisplayFormat =
+ new(
+ memberOptions: SymbolDisplayMemberOptions.IncludeParameters,
+ parameterOptions: SymbolDisplayParameterOptions.IncludeType
+ | SymbolDisplayParameterOptions.IncludeParamsRefOut
+ );
+
public static string BuildInterfaceFor(ITypeSymbol typeSymbol)
{
if (
@@ -72,6 +79,8 @@ InterfaceBuilder codeGenerator
.Where(x => x.MethodKind == MethodKind.Ordinary)
.Where(x => !x.IsStatic)
.Where(x => x.ContainingType.Name != nameof(Object))
+ .GroupBy(x => x.ToDisplayString(MethodSignatureDisplayFormat))
+ .Select(g => g.First())
.ToList()
.ForEach(method =>
{
diff --git a/AutomaticInterface/Tests/GeneratorTests.cs b/AutomaticInterface/Tests/GeneratorTests.cs
index fe3ff9f..ec4de03 100644
--- a/AutomaticInterface/Tests/GeneratorTests.cs
+++ b/AutomaticInterface/Tests/GeneratorTests.cs
@@ -2211,4 +2211,151 @@ 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 = """
+ //--------------------------------------------------------------------------------------------------
+ //
+ // This code was generated by a tool.
+ //
+ // Changes to this file may cause incorrect behavior and will be lost if the code is regenerated.
+ //
+ //--------------------------------------------------------------------------------------------------
+
+ using System.CodeDom.Compiler;
+ using AutomaticInterfaceAttribute;
+
+ namespace AutomaticInterfaceExample
+ {
+ [GeneratedCode("AutomaticInterface", "")]
+ public partial interface IDemoClass
+ {
+ ///
+ 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 = """
+ //--------------------------------------------------------------------------------------------------
+ //
+ // This code was generated by a tool.
+ //
+ // Changes to this file may cause incorrect behavior and will be lost if the code is regenerated.
+ //
+ //--------------------------------------------------------------------------------------------------
+
+ using System.CodeDom.Compiler;
+ using AutomaticInterfaceAttribute;
+
+ namespace AutomaticInterfaceExample
+ {
+ [GeneratedCode("AutomaticInterface", "")]
+ public partial interface IDemoClass
+ {
+ ///
+ bool AMethod();
+
+ }
+ }
+
+ """;
+ GenerateCode(code).Should().Be(expected);
+ }
+
+ [Fact]
+ public void WorksWithParameterDirectionOverloads()
+ {
+ const string code = """
+
+ using AutomaticInterfaceAttribute;
+
+ namespace AutomaticInterfaceExample;
+
+ [GenerateAutomaticInterface]
+ public class DemoClass
+ {
+ public void AMethod(int val) => return true;
+
+ public void AMethod(ref int val) => return true;
+ }
+
+ """;
+
+ const string expected = """
+ //--------------------------------------------------------------------------------------------------
+ //
+ // This code was generated by a tool.
+ //
+ // Changes to this file may cause incorrect behavior and will be lost if the code is regenerated.
+ //
+ //--------------------------------------------------------------------------------------------------
+
+ using System.CodeDom.Compiler;
+ using AutomaticInterfaceAttribute;
+
+ namespace AutomaticInterfaceExample
+ {
+ [GeneratedCode("AutomaticInterface", "")]
+ public partial interface IDemoClass
+ {
+ ///
+ void AMethod(int val);
+
+ ///
+ void AMethod(ref int val);
+
+ }
+ }
+
+ """;
+ GenerateCode(code).Should().Be(expected);
+ }
}