using System.Text; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp.Syntax; namespace Polonium.Generators.Generators; [Generator] public class PoloniumFactoryGenerator : AssetProcessGenerator { public override void Execute(GeneratorExecutionContext context) { if (!(context.SyntaxReceiver is ClassSyntaxReceiver receiver)) return; StringBuilder sb = new(); sb .AppendLine("using System;") .AppendLine("using Polonium.Attributes;") .AppendLine("using Polonium.Interfaces;") .AppendLine("using Polonium.Resources;") .AppendLine("using Polonium.MessageManager;") .AppendLine("[AutoRegister]") .AppendLine("public class PoloniumFactoryRegister") .AppendLine("{") .AppendLine(" public static void Register()") .AppendLine(" {") .AppendLine(" GlobalRegistry.PoloniumFactory = new PoloniumFactory();") .AppendLine(" }") .AppendLine(" public class PoloniumFactory : IPoloniumFactory") .AppendLine(" {") .AppendLine(" public MessageHeader CreateMessageHeader()") .AppendLine(" {"); Compilation compilation = context.Compilation; INamedTypeSymbol? signalHeader = compilation.GetTypeByMetadataName("Polonium.MessageManager.MessageHeader"); bool founded = false; foreach (ClassDeclarationSyntax cls in receiver.Classes) { SemanticModel semanticModel = compilation.GetSemanticModel(cls.SyntaxTree); INamedTypeSymbol? nCls = semanticModel.GetDeclaredSymbol(cls) as INamedTypeSymbol; if(nCls is null) continue; if (IsDerivedFrom(nCls, signalHeader) && !nCls.IsAbstract) { sb.AppendLine($" return new {nCls.ToDisplayString()}();"); founded = true; break; } } if (!founded) sb.AppendLine($" throw new NotImplementedException();"); sb .AppendLine(" }") .AppendLine(" }") .AppendLine("}"); context.AddSource("PoloniumFactoryRegistry.g.cs", sb.ToString()); } }