2024-05-05 10:20:33 +00:00
|
|
|
using System.Text;
|
|
|
|
|
|
|
|
using Microsoft.CodeAnalysis;
|
|
|
|
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
|
|
|
using Microsoft.CodeAnalysis.Text;
|
|
|
|
|
|
|
|
namespace CSV_Metrics_Logger_Generator;
|
|
|
|
|
|
|
|
[Generator]
|
|
|
|
public class CSVConverterGenerator : ISourceGenerator
|
|
|
|
{
|
|
|
|
private const string ARRAY_DELIMITER = ", ";
|
|
|
|
|
|
|
|
#region Implementation of ISourceGenerator
|
|
|
|
|
|
|
|
public void Initialize(GeneratorInitializationContext context)
|
|
|
|
{
|
|
|
|
context.RegisterForSyntaxNotifications(() => new SyntaxReceiver());
|
|
|
|
}
|
|
|
|
|
|
|
|
public void Execute(GeneratorExecutionContext context)
|
|
|
|
{
|
|
|
|
if (context.SyntaxReceiver is not SyntaxReceiver receiver)
|
|
|
|
return;
|
|
|
|
|
|
|
|
foreach (var dataStructure in receiver.DataStructures)
|
|
|
|
this.ProcessStructure(context, dataStructure);
|
|
|
|
}
|
|
|
|
|
|
|
|
private void ProcessStructure(GeneratorExecutionContext context, TypeDeclarationSyntax dataStructure)
|
|
|
|
{
|
2024-05-21 07:31:46 +00:00
|
|
|
var generatedFileName = $"{dataStructure.Identifier}.Generated.cs";
|
|
|
|
var namespaceName = this.GetNamespaceFrom(dataStructure);
|
|
|
|
|
2024-05-05 10:20:33 +00:00
|
|
|
var accessModifiers = string.Join(' ', dataStructure.Modifiers.Select(n => n.Text));
|
|
|
|
var declarationType = dataStructure switch
|
|
|
|
{
|
|
|
|
RecordDeclarationSyntax => "record struct",
|
|
|
|
StructDeclarationSyntax => "struct",
|
|
|
|
|
|
|
|
_ => string.Empty
|
|
|
|
};
|
2024-05-21 07:31:46 +00:00
|
|
|
|
|
|
|
var typeParameters = dataStructure switch
|
|
|
|
{
|
|
|
|
{ TypeParameterList: not null } => $"<{string.Join(", ", dataStructure.TypeParameterList.Parameters.Select(t => t.Identifier.Text))}>",
|
|
|
|
_ => 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();
|
2024-05-05 10:20:33 +00:00
|
|
|
|
|
|
|
var numberProperties = allProperties.Count;
|
|
|
|
var header = string.Join(ARRAY_DELIMITER, allProperties.Select(n => $"\"{n}\""));
|
2024-05-21 07:31:46 +00:00
|
|
|
var allFieldsString = string.Join(ARRAY_DELIMITER, allProperties.Select(n => $$"""string.Create(CultureInfo.InvariantCulture, $"{this.{{n}}}")"""));
|
2024-05-05 10:20:33 +00:00
|
|
|
|
|
|
|
var sourceCode = SourceText.From(
|
|
|
|
$$"""
|
|
|
|
using System.Globalization;
|
|
|
|
using CSV_Metrics_Logger;
|
|
|
|
namespace {{namespaceName}};
|
2024-05-21 07:31:46 +00:00
|
|
|
{{accessModifiers}} {{declarationType}} {{dataStructure.Identifier}}{{typeParameters}} : IConvertToCSV
|
2024-05-05 10:20:33 +00:00
|
|
|
{
|
|
|
|
public uint GetCSVColumnCount()
|
|
|
|
{
|
|
|
|
return (uint){{numberProperties}};
|
|
|
|
}
|
|
|
|
|
|
|
|
public IList<string> GetCSVHeaders()
|
|
|
|
{
|
|
|
|
return [ {{header}} ];
|
|
|
|
}
|
|
|
|
|
|
|
|
public IList<string> ConvertToCSVDataLine()
|
|
|
|
{
|
|
|
|
return [ {{allFieldsString}} ];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
""", Encoding.UTF8);
|
|
|
|
|
2024-05-21 07:31:46 +00:00
|
|
|
context.AddSource(generatedFileName, sourceCode);
|
2024-05-05 10:20:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private string GetNamespaceFrom(SyntaxNode? node) => node switch
|
|
|
|
{
|
|
|
|
BaseNamespaceDeclarationSyntax namespaceDeclarationSyntax => namespaceDeclarationSyntax.Name.ToString(),
|
|
|
|
null => string.Empty,
|
|
|
|
|
|
|
|
_ => this.GetNamespaceFrom(node.Parent)
|
|
|
|
};
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
}
|