86 lines
3.1 KiB
C#
86 lines
3.1 KiB
C#
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)
|
|
{
|
|
var accessModifiers = string.Join(' ', dataStructure.Modifiers.Select(n => n.Text));
|
|
var declarationType = dataStructure switch
|
|
{
|
|
RecordDeclarationSyntax => "record struct",
|
|
StructDeclarationSyntax => "struct",
|
|
|
|
_ => string.Empty
|
|
};
|
|
var namespaceName = this.GetNamespaceFrom(dataStructure);
|
|
var parameterProperties = dataStructure.ParameterList?.Parameters.Select(n => n.Identifier.ValueText).ToList() ?? [];
|
|
var bodyProperties = dataStructure.Members.OfType<PropertyDeclarationSyntax>().Select(n => n.Identifier.ValueText).ToList();
|
|
var allProperties = new List<string>(parameterProperties);
|
|
allProperties.AddRange(bodyProperties);
|
|
|
|
var numberProperties = allProperties.Count;
|
|
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 sourceCode = SourceText.From(
|
|
$$"""
|
|
using System.Globalization;
|
|
using CSV_Metrics_Logger;
|
|
namespace {{namespaceName}};
|
|
{{accessModifiers}} {{declarationType}} {{dataStructure.Identifier}} : IConvertToCSV
|
|
{
|
|
public uint GetCSVColumnCount()
|
|
{
|
|
return (uint){{numberProperties}};
|
|
}
|
|
|
|
public IList<string> GetCSVHeaders()
|
|
{
|
|
return [ {{header}} ];
|
|
}
|
|
|
|
public IList<string> ConvertToCSVDataLine()
|
|
{
|
|
return [ {{allFieldsString}} ];
|
|
}
|
|
}
|
|
""", Encoding.UTF8);
|
|
|
|
context.AddSource($"{dataStructure.Identifier}.Generated.cs", sourceCode);
|
|
}
|
|
|
|
private string GetNamespaceFrom(SyntaxNode? node) => node switch
|
|
{
|
|
BaseNamespaceDeclarationSyntax namespaceDeclarationSyntax => namespaceDeclarationSyntax.Name.ToString(),
|
|
null => string.Empty,
|
|
|
|
_ => this.GetNamespaceFrom(node.Parent)
|
|
};
|
|
|
|
#endregion
|
|
} |