Files
Polonium.Generators/src/Generators/TemplateInlineGenerator.cs
2025-02-22 03:56:27 +00:00

64 lines
2.6 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
namespace Polonium.Generators.Generators;
[Generator]
public class TemplateInlineGenerator : AssetProcessGenerator
{
public override void Execute(GeneratorExecutionContext context)
{
if (!(context.SyntaxReceiver is ClassSyntaxReceiver receiver))
return;
Compilation compilation = context.Compilation;
INamedTypeSymbol? templateDefine = compilation.GetTypeByMetadataName("Polonium.Attributes.TemplateDefines.TemplateInline");
foreach (ClassDeclarationSyntax? cls in context.GetClassesWithAttribute(receiver, templateDefine))
{
if(!cls.Modifiers.Any(m => m.IsKind(SyntaxKind.PartialKeyword)))
continue;
string isStatic = "";
if(cls.Modifiers.Any(m => m.IsKind(SyntaxKind.StaticKeyword)))
isStatic = "static";
StringBuilder sb = new StringBuilder();
sb
.AppendLine($"public {isStatic} partial class {cls.Identifier.ToString()}")
.AppendLine("{");
HashSet<string> headers = new();
foreach (AttributeData attr in context.GetAttributes(cls, templateDefine))
{
string template = attr.ConstructorArguments[0].Value?.ToString()??string.Empty;
string dataFile = attr.ConstructorArguments[1].Value?.ToString()??string.Empty;
string depsString = attr.ConstructorArguments[2].Value?.ToString()??string.Empty;
string[] deps = depsString.Split(';');
foreach (string dep in deps)
headers.Add(dep);
AdditionalText? df = context.AdditionalFiles.FirstOrDefault(f => f.Path.EndsWith(dataFile));
string[] data =(df?.GetText()?.ToString() ?? "").Split('\n');
foreach (string d in data)
{
if(d.Trim().Equals(""))
continue;
sb.AppendLine($" {Format(template, d)}");
}
}
sb.AppendLine("}");
StringBuilder hb = new();
foreach(string header in headers)
{
if(header.Trim().Equals(""))
continue;
hb.AppendLine($"using {header};");
}
hb.Append(sb);
Console.WriteLine(hb.ToString());
context.AddSource($"{cls.Identifier.ToString()}_TemplateInline.g.cs", hb.ToString());
}
}
}