116 lines
4.9 KiB
C#
116 lines
4.9 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 TemplateDirectory { get; set; }
|
|
|
|
[Required]
|
|
public string AttributeName { get; set; }
|
|
|
|
public override bool Execute()
|
|
{
|
|
try
|
|
{
|
|
|
|
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 sbx = new StringBuilder();
|
|
sbx
|
|
.AppendLine("// meta-default: true")
|
|
.AppendLine("using _BINDINGS_NAMESPACE_;")
|
|
.AppendLine("using System;")
|
|
.AppendLine($"public partial class _CLASS_ : {GetDisplayName(cls)}")
|
|
.AppendLine("{");
|
|
IEnumerable<MethodDeclarationSyntax> methods = cls.Members
|
|
.OfType<MethodDeclarationSyntax>()
|
|
.Where(m => m.AttributeLists
|
|
.SelectMany(a => a.Attributes)
|
|
.Any(attr => attr.Name.ToString().Contains("ProxyMethod"))
|
|
);
|
|
IEnumerable<PropertyDeclarationSyntax> properties = cls.Members
|
|
.OfType<PropertyDeclarationSyntax>()
|
|
.Where(m => m.AttributeLists
|
|
.SelectMany(a => a.Attributes)
|
|
.Any(attr => attr.Name.ToString().Contains("ProxyProperty"))
|
|
);
|
|
foreach (PropertyDeclarationSyntax prop in properties)
|
|
{
|
|
sbx.AppendLine($" public override {prop.Type.ToString()} {prop.Identifier.ToString()} => base.{prop.Identifier.ToString()};");
|
|
}
|
|
|
|
foreach (MethodDeclarationSyntax proxyMethod in methods)
|
|
{
|
|
string methodReturnType = proxyMethod.ReturnType.ToString();
|
|
string methodName = proxyMethod.Identifier.Text;
|
|
string methodArgs = string.Join(", ", proxyMethod.ParameterList.Parameters.Select(p => p.ToString()));
|
|
string paramNames = string.Join(", ", proxyMethod.ParameterList.Parameters.Select(p => p.Identifier.Text));
|
|
sbx
|
|
.AppendLine($" public override {methodReturnType} {methodName}({methodArgs})")
|
|
.AppendLine(" {");
|
|
if(methodReturnType=="void")
|
|
sbx.AppendLine($" base.{methodName}({paramNames});");
|
|
else
|
|
sbx.AppendLine($" return base.{methodName}({paramNames});");
|
|
sbx.AppendLine(" }");
|
|
}
|
|
sbx
|
|
.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;
|
|
}
|
|
|
|
} |