added support for records
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
using System.Runtime.CompilerServices;
|
||||
using FluentAssertions;
|
||||
using Xunit;
|
||||
|
||||
namespace InterfaceGenerator.Tests
|
||||
{
|
||||
public class RecordInterfaceGenerationTests
|
||||
{
|
||||
private readonly ITestRecord _sut;
|
||||
|
||||
public RecordInterfaceGenerationTests()
|
||||
{
|
||||
_sut = new TestRecord(420);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RecordProperty_IsGenerated()
|
||||
{
|
||||
var prop = typeof(ITestRecord)
|
||||
.GetProperty(nameof(TestRecord.RecordProperty));
|
||||
|
||||
prop.Should().NotBeNull();
|
||||
|
||||
prop.GetMethod.Should().NotBeNull();
|
||||
prop.SetMethod.Should().NotBeNull();
|
||||
prop.SetMethod.ReturnParameter.GetRequiredCustomModifiers().Should().Contain(typeof(IsExternalInit));
|
||||
|
||||
_sut.RecordProperty.Should().Be(420);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RecordMethod_IsGenerated()
|
||||
{
|
||||
var method = typeof(ITestRecord).GetMethod(
|
||||
nameof(TestRecord.RecordMethod));
|
||||
|
||||
method.Should().NotBeNull();
|
||||
method.ReturnType.Should().Be(typeof(void));
|
||||
|
||||
var parameters = method.GetParameters();
|
||||
parameters.Should().BeEmpty();
|
||||
|
||||
_sut.RecordMethod();
|
||||
}
|
||||
}
|
||||
|
||||
[GenerateAutoInterface]
|
||||
internal record TestRecord(int RecordProperty) : ITestRecord
|
||||
{
|
||||
public void RecordMethod()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -236,7 +236,6 @@ namespace InterfaceGenerator
|
||||
if (propertySymbol.IsIndexer)
|
||||
{
|
||||
writer.Write("{0} this[", propertySymbol.Type);
|
||||
//writer.WriteJoin(", ", propertySymbol.Parameters, (w, param) => { w.Write("{0} {1}", param.Type, param.Name); });
|
||||
writer.WriteJoin(", ", propertySymbol.Parameters, WriteMethodParam);
|
||||
writer.Write("] ");
|
||||
}
|
||||
@@ -273,6 +272,12 @@ namespace InterfaceGenerator
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (methodSymbol.IsImplicitlyDeclared)
|
||||
{
|
||||
// omit methods that are auto generated by the compiler (eg. record's methods)
|
||||
return;
|
||||
}
|
||||
|
||||
WriteMemberDocs(writer, methodSymbol);
|
||||
|
||||
@@ -386,14 +391,14 @@ namespace InterfaceGenerator
|
||||
|
||||
private static IEnumerable<INamedTypeSymbol> GetImplTypeSymbols(Compilation compilation, SyntaxReceiver receiver)
|
||||
{
|
||||
return receiver.CandidateClasses.Select(candidate => GetClassSymbol(compilation, candidate));
|
||||
return receiver.CandidateTypes.Select(candidate => GetTypeSymbol(compilation, candidate));
|
||||
}
|
||||
|
||||
private static INamedTypeSymbol GetClassSymbol(Compilation compilation, ClassDeclarationSyntax @class)
|
||||
private static INamedTypeSymbol GetTypeSymbol(Compilation compilation, TypeDeclarationSyntax type)
|
||||
{
|
||||
var model = compilation.GetSemanticModel(@class.SyntaxTree);
|
||||
var classSymbol = ModelExtensions.GetDeclaredSymbol(model, @class)!;
|
||||
return (INamedTypeSymbol)classSymbol;
|
||||
var model = compilation.GetSemanticModel(type.SyntaxTree);
|
||||
var typeSymbol = ModelExtensions.GetDeclaredSymbol(model, type)!;
|
||||
return (INamedTypeSymbol)typeSymbol;
|
||||
}
|
||||
|
||||
private static Compilation GetCompilation(GeneratorExecutionContext context)
|
||||
|
||||
@@ -6,15 +6,21 @@ namespace InterfaceGenerator
|
||||
{
|
||||
internal class SyntaxReceiver : ISyntaxReceiver
|
||||
{
|
||||
public IList<ClassDeclarationSyntax> CandidateClasses { get; } = new List<ClassDeclarationSyntax>();
|
||||
public IList<TypeDeclarationSyntax> CandidateTypes { get; } = new List<TypeDeclarationSyntax>();
|
||||
|
||||
public void OnVisitSyntaxNode(SyntaxNode syntaxNode)
|
||||
{
|
||||
if (syntaxNode is ClassDeclarationSyntax classDeclarationSyntax &&
|
||||
classDeclarationSyntax.AttributeLists.Count > 0)
|
||||
if (syntaxNode is TypeDeclarationSyntax typeDeclarationSyntax &&
|
||||
IsClassOrRecord(typeDeclarationSyntax) &&
|
||||
typeDeclarationSyntax.AttributeLists.Count > 0)
|
||||
{
|
||||
CandidateClasses.Add(classDeclarationSyntax);
|
||||
CandidateTypes.Add(typeDeclarationSyntax);
|
||||
}
|
||||
}
|
||||
|
||||
private static bool IsClassOrRecord(TypeDeclarationSyntax typeDeclarationSyntax)
|
||||
{
|
||||
return typeDeclarationSyntax is ClassDeclarationSyntax || typeDeclarationSyntax is RecordDeclarationSyntax;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user