using System; using System.Collections.Immutable; using System.IO; using System.Linq; using System.Text; using Microsoft.CodeAnalysis; namespace Polonium.Generators.Generators; [Generator] public class AssetRegisterGenerator : AssetProcessGenerator { public override void Execute(GeneratorExecutionContext context) { if (!(context.SyntaxReceiver is ClassSyntaxReceiver receiver)) return; Compilation compilation = context.Compilation; StringBuilder sb = new(); sb .AppendLine("using System;") .AppendLine("using Godot;") .AppendLine("using Polonium;") .AppendLine("using Polonium.Attributes;") .AppendLine("[AutoRegister]") .AppendLine("public static class AssetRegister") .AppendLine("{") .AppendLine(" public static void Register()") .AppendLine(" {"); foreach (var derivedClassDeclaration in receiver.Classes) { SemanticModel model = compilation.GetSemanticModel(derivedClassDeclaration.SyntaxTree); INamedTypeSymbol? symbol = model.GetDeclaredSymbol(derivedClassDeclaration) as INamedTypeSymbol; string filePath = derivedClassDeclaration.SyntaxTree.FilePath.Replace(".cs", ".tscn"); if(!filePath.Contains("Assets") || symbol == null) continue; ImmutableArray additionalFiles = context.AdditionalFiles; if (additionalFiles.Select(y => y.Path).Contains(filePath)) { string rs = filePath.Replace("\\", "/").Replace(" ", "%20"); rs = rs.Substring(rs.IndexOf("Assets", StringComparison.Ordinal)); string gdPath = "res://" + rs; string className = Path.GetFileNameWithoutExtension(filePath); sb .AppendLine( $" PoloniumRegistry.Asset<{className}>.Scene = ResourceLoader.Load(\"{gdPath}\");" ); } } sb .AppendLine(" }") .AppendLine("}"); context.AddSource("AssetRegistry.g.cs", sb.ToString()); } }