using System.Collections.Generic; using System.Collections.Immutable; using System.Linq; using System.Text; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Text; namespace Godot.Sharp.Extended.Generators; [Generator] public class ActionGenerator : IIncrementalGenerator { public void Initialize(IncrementalGeneratorInitializationContext context) { var projectFile = context.AdditionalTextsProvider .Where(file => file.Path.EndsWith("project.godot")) .Select((file, token) => file.GetText()) .Collect(); context.RegisterSourceOutput(projectFile, GenerateCode); } private void GenerateCode(SourceProductionContext ctx, ImmutableArray texts) { var memberCode = new StringBuilder(); foreach (var text in texts) { if (text == null) continue; var content = text.ToString(); var inputs = GetActions(content); var fields = inputs.Select(keyData => $$"""\tpublic static StringName {{keyData.ToPascalCase()}} = "{{keyData}}";"""); foreach (var field in fields) memberCode.AppendLine(field); } var code = $$""" // using System; using Godot; namespace Godot.Sharp.Extended.Generators; public partial class Actions { {{memberCode}} } """; ctx.AddSource("Godot.Sharp.Extended.Generators.Actions.g.cs", SourceText.From(code, Encoding.UTF8)); } public List GetActions(string content) { var results = new List(); var inputSection = false; foreach (var line in content.Split(['\n'])) { if (line.Equals("[input]")) inputSection = true; else if (line.StartsWith("[") && inputSection) break; if (!inputSection) continue; var kv = line.Split(['='], 2); if (kv.Length == 2) results.Add(kv[0].Trim()); } return results; } }