This commit is contained in:
h z
2025-02-10 02:11:23 +00:00
commit 8bf643f194
6 changed files with 257 additions and 0 deletions

View File

@@ -0,0 +1,85 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
namespace Polonium.Tasks;
public class GenerateProxyNodesTask : Task
{
[Required]
public string SourceDirectory { get; set; }
[Required]
public string OutputDirectory { get; set; }
[Required]
public string AttributeName { get; set; }
public override bool Execute()
{
try
{
if(Directory.Exists(OutputDirectory))
Directory.Delete(OutputDirectory, true);
Directory.CreateDirectory(OutputDirectory);
string[] csFiles = Directory.GetFiles(SourceDirectory, "*.cs", SearchOption.AllDirectories);
foreach (string csFile in csFiles)
{
string code = File.ReadAllText(csFile);
SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(code);
CompilationUnitSyntax root = syntaxTree.GetCompilationUnitRoot();
IEnumerable<ClassDeclarationSyntax> classes = root.DescendantNodes().OfType<ClassDeclarationSyntax>()
.Where(cls => cls.AttributeLists
.SelectMany(attrList => attrList.Attributes)
.Any(attr => attr.Name.ToString().Contains(AttributeName)));
foreach (ClassDeclarationSyntax cls in classes)
{
string className = cls.Identifier.Text;
StringBuilder sb = new StringBuilder();
sb.AppendLine("using Godot;");
sb.AppendLine($"namespace GlobalProxy {{");
sb.AppendLine($" [GlobalClass]");
sb.AppendLine($" [Tool]");
sb.AppendLine($" public partial class {className} : {GetDisplayName(cls)} {{ }}");
sb.AppendLine("}");
string outputFile = Path.Combine(OutputDirectory, $"{className}.cs");
File.WriteAllText(outputFile, sb.ToString());
Log.LogMessage(MessageImportance.High, $"Generated proxy file: {outputFile}");
}
}
return true;
}
catch (Exception ex)
{
Log.LogErrorFromException(ex);
return false;
}
}
private string GetDisplayName(ClassDeclarationSyntax cls)
{
string name = cls.Identifier.Text;
SyntaxNode node = cls.Parent;
while (node is not null)
{
if(node is NamespaceDeclarationSyntax ns)
name = ns.Name.ToString() + "." + name;
else if (node is FileScopedNamespaceDeclarationSyntax fs)
name = fs.Name.ToString() + "." + name;
node = node.Parent;
}
return name;
}
}