Resolve "Need support for type params" #3

Merged
thorsten merged 3 commits from 1-need-support-for-type-params into main 2024-05-21 07:37:10 +00:00
3 changed files with 41 additions and 8 deletions
Showing only changes of commit a81e88c727 - Show all commits

View File

@ -29,6 +29,9 @@ public class CSVConverterGenerator : ISourceGenerator
private void ProcessStructure(GeneratorExecutionContext context, TypeDeclarationSyntax dataStructure) private void ProcessStructure(GeneratorExecutionContext context, TypeDeclarationSyntax dataStructure)
{ {
var generatedFileName = $"{dataStructure.Identifier}.Generated.cs";
var namespaceName = this.GetNamespaceFrom(dataStructure);
var accessModifiers = string.Join(' ', dataStructure.Modifiers.Select(n => n.Text)); var accessModifiers = string.Join(' ', dataStructure.Modifiers.Select(n => n.Text));
var declarationType = dataStructure switch var declarationType = dataStructure switch
{ {
@ -37,22 +40,27 @@ public class CSVConverterGenerator : ISourceGenerator
_ => string.Empty _ => string.Empty
}; };
var namespaceName = this.GetNamespaceFrom(dataStructure);
var parameterProperties = dataStructure.ParameterList?.Parameters.Select(n => n.Identifier.ValueText).ToList() ?? []; var typeParameters = dataStructure switch
var bodyProperties = dataStructure.Members.OfType<PropertyDeclarationSyntax>().Select(n => n.Identifier.ValueText).ToList(); {
var allProperties = new List<string>(parameterProperties); { TypeParameterList: not null } => $"<{string.Join(", ", dataStructure.TypeParameterList.Parameters.Select(t => t.Identifier.Text))}>",
allProperties.AddRange(bodyProperties); _ => string.Empty
};
var parameterProperties = dataStructure.ParameterList?.Parameters.Select(n => n.Identifier.ValueText) ?? [];
var bodyProperties = dataStructure.Members.OfType<PropertyDeclarationSyntax>().Select(n => n.Identifier.ValueText);
var allProperties = parameterProperties.Concat(bodyProperties).ToList();
var numberProperties = allProperties.Count; var numberProperties = allProperties.Count;
var header = string.Join(ARRAY_DELIMITER, allProperties.Select(n => $"\"{n}\"")); var header = string.Join(ARRAY_DELIMITER, allProperties.Select(n => $"\"{n}\""));
var allFieldsString = string.Join(ARRAY_DELIMITER, allProperties.Select(n => $"this.{n}.ToString(CultureInfo.InvariantCulture)")); var allFieldsString = string.Join(ARRAY_DELIMITER, allProperties.Select(n => $$"""string.Create(CultureInfo.InvariantCulture, $"{this.{{n}}}")"""));
var sourceCode = SourceText.From( var sourceCode = SourceText.From(
$$""" $$"""
using System.Globalization; using System.Globalization;
using CSV_Metrics_Logger; using CSV_Metrics_Logger;
namespace {{namespaceName}}; namespace {{namespaceName}};
{{accessModifiers}} {{declarationType}} {{dataStructure.Identifier}} : IConvertToCSV {{accessModifiers}} {{declarationType}} {{dataStructure.Identifier}}{{typeParameters}} : IConvertToCSV
{ {
public uint GetCSVColumnCount() public uint GetCSVColumnCount()
{ {
@ -71,7 +79,7 @@ public class CSVConverterGenerator : ISourceGenerator
} }
""", Encoding.UTF8); """, Encoding.UTF8);
context.AddSource($"{dataStructure.Identifier}.Generated.cs", sourceCode); context.AddSource(generatedFileName, sourceCode);
} }
private string GetNamespaceFrom(SyntaxNode? node) => node switch private string GetNamespaceFrom(SyntaxNode? node) => node switch

8
Tests/TestGeneric.cs Normal file
View File

@ -0,0 +1,8 @@
using System.Numerics;
using CSV_Metrics_Logger;
namespace Tests;
[CSVRecord]
public readonly partial record struct TestGeneric<TNum>(string Name, sbyte Age, TNum Value) where TNum : IFloatingPointIeee754<TNum>;

View File

@ -60,6 +60,23 @@ public sealed class Tests
}); });
} }
[Test]
public void TestGeneric()
{
var testData = new TestGeneric<float>("Bob", 120, 4.78f);
Assert.Multiple(() =>
{
var numberColumns = testData.GetCSVColumnCount();
Assert.That(numberColumns, Is.EqualTo(3));
var header = testData.GetCSVHeaders();
Assert.That(header, Is.EquivalentTo(new[] { "Name", "Age", "Value" }));
var dataLine = testData.ConvertToCSVDataLine();
Assert.That(dataLine, Is.EquivalentTo(new[] { "Bob", "120", "4.78" }));
});
}
[Test] [Test]
public void TestRegularStruct() public void TestRegularStruct()
{ {