103 lines
3.8 KiB
C#
103 lines
3.8 KiB
C#
|
|
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 TemplateDirectory { 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;")
|
|
.AppendLine("namespace GlobalClasses;")
|
|
.AppendLine("[GlobalClass]")
|
|
.AppendLine("[Tool]")
|
|
.AppendLine($"public partial class {className} : {GetDisplayName(cls)}")
|
|
.AppendLine("{")
|
|
.AppendLine("}");
|
|
|
|
string outputFile = Path.Combine(OutputDirectory, $"{className}.cs");
|
|
File.WriteAllText(outputFile, sb.ToString());
|
|
Log.LogMessage(MessageImportance.High, $"Generated proxy file: {outputFile}");
|
|
|
|
StringBuilder sbx = new StringBuilder();
|
|
sbx
|
|
.AppendLine("// meta-default: true")
|
|
.AppendLine("using _BINDINGS_NAMESPACE_;")
|
|
.AppendLine("using System;")
|
|
.AppendLine("public partial class _CLASS_ : GlobalClasses._CLASS_")
|
|
.AppendLine("{")
|
|
.AppendLine("}");
|
|
if(!Directory.Exists($"{TemplateDirectory}/{className}"))
|
|
Directory.CreateDirectory($"{TemplateDirectory}/{className}");
|
|
string templateFile = $"{TemplateDirectory}/{className}/Polonium_{className}.cs";
|
|
File.WriteAllText(templateFile, sbx.ToString());
|
|
}
|
|
}
|
|
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;
|
|
}
|
|
|
|
} |