Skip to content

Commit

Permalink
Merge pull request #33 from roflmuffin/fix-ref-duplicate-names
Browse files Browse the repository at this point in the history
Fix additional edge cases
  • Loading branch information
ChristianSauer authored Feb 13, 2024
2 parents c6f1da9 + 28266e1 commit 10189b3
Show file tree
Hide file tree
Showing 3 changed files with 162 additions and 4 deletions.
15 changes: 13 additions & 2 deletions AutomaticInterface/AutomaticInterface/Builder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -176,9 +176,16 @@ InterfaceBuilder codeGenerator

private static string GetMethodSignature(IParameterSymbol x)
{
var syntaxReference = x.DeclaringSyntaxReferences.FirstOrDefault();

var name =
syntaxReference != null
? ((ParameterSyntax)syntaxReference.GetSyntax()).Identifier.Text
: x.Name;

if (!x.HasExplicitDefaultValue)
{
return $"{x.Type.ToDisplayString()} {x.Name}";
return $"{x.Type.ToDisplayString()} {name}";
}

var optionalValue = x.ExplicitDefaultValue switch
Expand All @@ -189,7 +196,7 @@ private static string GetMethodSignature(IParameterSymbol x)
null => " = null",
_ => $" = {x.ExplicitDefaultValue}"
};
return $"{x.Type.ToDisplayString()} {x.Name}{optionalValue}";
return $"{x.Type.ToDisplayString()} {name}{optionalValue}";
}

private static void AddPropertiesToInterface(
Expand All @@ -204,6 +211,8 @@ InterfaceBuilder interfaceGenerator
.Where(x => x.DeclaredAccessibility == Accessibility.Public)
.Where(x => !x.IsStatic)
.Where(x => !x.IsIndexer)
.GroupBy(x => x.Name)
.Select(g => g.First())
.ToList()
.ForEach(prop =>
{
Expand All @@ -212,6 +221,7 @@ InterfaceBuilder interfaceGenerator
var name = prop.Name;
var hasGet = prop.GetMethod?.DeclaredAccessibility == Accessibility.Public;
var hasSet = prop.SetMethod?.DeclaredAccessibility == Accessibility.Public;
var isRef = prop.ReturnsByRef;
ActivateNullableIfNeeded(interfaceGenerator, type);
Expand All @@ -220,6 +230,7 @@ InterfaceBuilder interfaceGenerator
type.ToDisplayString(),
hasGet,
hasSet,
isRef,
InheritDoc
);
});
Expand Down
7 changes: 5 additions & 2 deletions AutomaticInterface/AutomaticInterface/InterfaceBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ internal sealed record PropertyInfo(
string Ttype,
bool HasGet,
bool HasSet,
bool IsRef,
string Documentation
);

Expand Down Expand Up @@ -50,10 +51,11 @@ public void AddPropertyToInterface(
string ttype,
bool hasGet,
bool hasSet,
bool isRef,
string documentation
)
{
propertyInfos.Add(new(name, ttype, hasGet, hasSet, documentation));
propertyInfos.Add(new(name, ttype, hasGet, hasSet, isRef, documentation));
}

public void AddGeneric(string v)
Expand Down Expand Up @@ -122,9 +124,10 @@ public string Build()
foreach (var prop in propertyInfos)
{
cb.AppendAndNormalizeMultipleLines(prop.Documentation);
var @ref = prop.IsRef ? "ref " : string.Empty;
var get = prop.HasGet ? "get; " : string.Empty;
var set = prop.HasSet ? "set; " : string.Empty;
cb.AppendLine($"{prop.Ttype} {prop.Name} {{ {get}{set}}}");
cb.AppendLine($"{@ref}{prop.Ttype} {prop.Name} {{ {get}{set}}}");
cb.AppendLine("");
}
cb.Dedent();
Expand Down
144 changes: 144 additions & 0 deletions AutomaticInterface/Tests/GeneratorTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2066,4 +2066,148 @@ public partial interface IDemoClass
""";
GenerateCode(code).Should().Be(expected);
}

[Fact]
public void WorksWithRef()
{
const string code = """

using AutomaticInterfaceAttribute;
using System.Threading.Tasks;

namespace AutomaticInterfaceExample;
[GenerateAutomaticInterface]
public class DemoClass
{
private string _aProperty;
public ref string AProperty => ref _aProperty;
}

""";

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;
using System.Threading.Tasks;

namespace AutomaticInterfaceExample
{
[GeneratedCode("AutomaticInterface", "")]
public partial interface IDemoClass
{
/// <inheritdoc />
ref string AProperty { get; }

}
}

""";
GenerateCode(code).Should().Be(expected);
}

[Fact]
public void WorksWithReservedNames()
{
const string code = """

using AutomaticInterfaceAttribute;
using System.Threading.Tasks;

namespace AutomaticInterfaceExample;
[GenerateAutomaticInterface]
public class DemoClass
{
public void AMethod(int @event)
{
}
}

""";

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;
using System.Threading.Tasks;

namespace AutomaticInterfaceExample
{
[GeneratedCode("AutomaticInterface", "")]
public partial interface IDemoClass
{
/// <inheritdoc />
void AMethod(int @event);

}
}

""";
GenerateCode(code).Should().Be(expected);
}

[Fact]
public void WorksWithNewKeyword()
{
const string code = """

using AutomaticInterfaceAttribute;
using System.Threading.Tasks;

namespace AutomaticInterfaceExample;

public abstract class FirstClass
{
public int AProperty { get; set; }
}

[GenerateAutomaticInterface]
public partial class SecondClass : FirstClass
{
public new int AProperty { get; set; }
}

""";

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;
using System.Threading.Tasks;

namespace AutomaticInterfaceExample
{
[GeneratedCode("AutomaticInterface", "")]
public partial interface ISecondClass
{
/// <inheritdoc />
int AProperty { get; set; }

}
}

""";
GenerateCode(code).Should().Be(expected);
}
}

0 comments on commit 10189b3

Please sign in to comment.