add: registry pass through

This commit is contained in:
h z
2025-02-19 17:09:07 +00:00
parent cadb3e02ac
commit f70cab525b
5 changed files with 173 additions and 26 deletions

View File

@@ -12,4 +12,8 @@
TaskName="GenerateTextureSetTask"
AssemblyFile="$(TasksAssembly)"
/>
<UsingTask
TaskName="GenerateRegistryPassThrough"
AssemblyFile="$(TasksAssembly)"
/>
</Project>

86
src/PoloniumTask.cs Normal file
View File

@@ -0,0 +1,86 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.Build.Utilities;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
namespace Polonium.Tasks;
public abstract class PoloniumTask : Task
{
protected static bool HasGetterOnly(PropertyDeclarationSyntax property)
{
var registryAttribute = property.AttributeLists
.SelectMany(a => a.Attributes)
.FirstOrDefault(a => a.Name.ToString() == "RegistryPassThrough");
if (registryAttribute?.ArgumentList != null)
{
foreach (var argument in registryAttribute.ArgumentList.Arguments)
{
if (argument.Expression is LiteralExpressionSyntax literal)
{
if (literal.Kind() == SyntaxKind.TrueLiteralExpression)
{
return true;
}
if (literal.Kind() == SyntaxKind.FalseLiteralExpression)
{
return false;
}
}
}
}
return false;
}
protected static 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;
}
protected static string GetRelativePath(string basePath, string fullPath)
{
Uri baseUri = new Uri(basePath.EndsWith(Path.DirectorySeparatorChar.ToString()) ? basePath : basePath + Path.DirectorySeparatorChar);
Uri fullUri = new Uri(fullPath);
return Uri.UnescapeDataString(baseUri.MakeRelativeUri(fullUri).ToString().Replace('/', Path.DirectorySeparatorChar));
}
protected static string GetDisplayName(TypeSyntax type)
{
if (type is IdentifierNameSyntax identifierName)
return identifierName.Identifier.Text;
if (type is QualifiedNameSyntax qualifiedName)
return GetDisplayName(qualifiedName.Left) + "." + GetDisplayName(qualifiedName.Right);
if (type is GenericNameSyntax genericName)
{
string typeName = genericName.Identifier.Text;
string typeArguments = string.Join(", ", genericName.TypeArgumentList.Arguments.Select(GetDisplayName));
return $"{typeName}<{typeArguments}>";
}
if (type is AliasQualifiedNameSyntax aliasQualifiedName)
return $"{aliasQualifiedName.Alias.Identifier.Text}::{GetDisplayName(aliasQualifiedName.Name)}";
if (type is PredefinedTypeSyntax predefinedType)
return predefinedType.Keyword.Text;
return type.ToString();
}
protected static IEnumerable<string> GetUsings(string code)
{
SyntaxTree tree = CSharpSyntaxTree.ParseText(code);
CompilationUnitSyntax root = tree.GetCompilationUnitRoot();
return root.Usings
.Select(u => u.ToString());
}
}

View File

@@ -4,13 +4,13 @@ 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;
using Polonium.Tasks;
public class GenerateProxyNodesTask : Task
// ReSharper disable once CheckNamespace
public class GenerateProxyNodesTask : PoloniumTask
{
[Required]
public string SourceDirectory { get; set; }
@@ -97,19 +97,6 @@ public class GenerateProxyNodesTask : Task
}
}
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;
}
}

View File

@@ -0,0 +1,75 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Microsoft.Build.Framework;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Polonium.Tasks;
// ReSharper disable once CheckNamespace
public class GenerateRegistryPassThrough : PoloniumTask
{
[Required] public string ProjectDir { get; set; }
public override bool Execute()
{
try
{
StringBuilder sb = new();
string csFile = Directory
.GetFiles($"{ProjectDir}src", "PoloniumRegistry.cs", SearchOption.TopDirectoryOnly)
.FirstOrDefault();
string code = File.ReadAllText(csFile!);
sb.AppendLine("#pragma warning disable IDE0130");
foreach (string use in GetUsings(code))
sb.AppendLine(use);
sb
.AppendLine("// ReSharper disable once CheckNamespace")
.AppendLine("public static partial class GlobalRegistry")
.AppendLine("{");
SyntaxTree tree = CSharpSyntaxTree.ParseText(code);
CompilationUnitSyntax root = tree.GetCompilationUnitRoot();
ClassDeclarationSyntax clas = root
.DescendantNodes()
.OfType<ClassDeclarationSyntax>()
.FirstOrDefault(cls => cls.Identifier.Text == "PoloniumRegistry");
IEnumerable<PropertyDeclarationSyntax> properties = clas!.Members
.OfType<PropertyDeclarationSyntax>()
.Where(m => m.AttributeLists
.SelectMany(a => a.Attributes)
.Any(a => a.Name.ToString() == "RegistryPassThrough"));
foreach (PropertyDeclarationSyntax property in properties)
{
if (HasGetterOnly(property))
sb.AppendLine($" public static {GetDisplayName(property.Type)} {property.Identifier.ToString()} => GlobalRegistry.{property.Identifier.ValueText};");
else
{
sb
.AppendLine($" public static {GetDisplayName(property.Type)} {property.Identifier.ToString()}")
.AppendLine(" {")
.AppendLine($" get => GlobalRegistry.{property.Identifier.ValueText};")
.AppendLine($" set => GlobalRegistry.{property.Identifier.ValueText} = value;")
.AppendLine(" }");
}
}
sb
.AppendLine("}")
.AppendLine("#pragma warning restore IDE0130");
File.WriteAllText($"{ProjectDir}Package/embedded/Patches/RegistryPassThrough.p.cs", sb.ToString());
return true;
}
catch (Exception e)
{
Log.LogErrorFromException(e);
return false;
}
}
}

View File

@@ -2,11 +2,11 @@ using System;
using System.IO;
using System.Text;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
using Polonium.Tasks;
namespace Polonium.Tasks;
public class GenerateTextureSetTask : Task
// ReSharper disable once CheckNamespace
public class GenerateTextureSetTask : PoloniumTask
{
[Required]
public string RootPath { get; set; }
@@ -103,11 +103,6 @@ public class GenerateTextureSetTask : Task
}
}
private string GetRelativePath(string basePath, string fullPath)
{
Uri baseUri = new Uri(basePath.EndsWith(Path.DirectorySeparatorChar.ToString()) ? basePath : basePath + Path.DirectorySeparatorChar);
Uri fullUri = new Uri(fullPath);
return Uri.UnescapeDataString(baseUri.MakeRelativeUri(fullUri).ToString().Replace('/', Path.DirectorySeparatorChar));
}
}