64 lines
2.6 KiB
C#
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());
|
|
}
|
|
}
|
|
}
|