Skip to content

Commit

Permalink
Add type cast fixes for .NET 9 NativeAOT, based on WASDK XAML compiler
Browse files Browse the repository at this point in the history
  • Loading branch information
driver1998 committed Aug 19, 2024
1 parent 7138d70 commit 485dbca
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 70 deletions.
168 changes: 99 additions & 69 deletions BuildTasks/NativeAotFixup.cs
Original file line number Diff line number Diff line change
@@ -1,69 +1,99 @@
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
using System;
using System.IO;
using System.Text.RegularExpressions;

namespace BuildTasks
{
public class NativeAotFixup : Task
{
[Required]
public string ObjDirectory { get; set; }

public override bool Execute()
{
try
{
{
var xamlTypeInfoCs = Path.Combine(ObjDirectory, "XamlTypeInfo.g.cs");
if (!File.Exists(xamlTypeInfoCs))
{
Log.LogError("XamlTypeInfo.g.cs does not exist in " + ObjDirectory);
return false;
}
var str = File.ReadAllText(xamlTypeInfoCs);
str = Regex.Replace(str,
"public sealed class XamlMetaDataProvider : global::Windows.UI.Xaml.Markup.IXamlMetadataProvider",
"public sealed partial class XamlMetaDataProvider : global::Windows.UI.Xaml.Markup.IXamlMetadataProvider");
str = Regex.Replace(str,
"internal class XamlSystemBaseType : global::Windows.UI.Xaml.Markup.IXamlType",
"internal partial class XamlSystemBaseType : global::Windows.UI.Xaml.Markup.IXamlType");
str = Regex.Replace(str,
"internal class XamlUserType : global::(.*?)_XamlTypeInfo.XamlSystemBaseType",
"internal partial class XamlUserType : global::$1_XamlTypeInfo.XamlSystemBaseType");
str = Regex.Replace(str,
"internal class XamlMember : global::Windows.UI.Xaml.Markup.IXamlMember",
"internal partial class XamlMember : global::Windows.UI.Xaml.Markup.IXamlMember");
File.WriteAllText(xamlTypeInfoCs, str);
}

var pagePass2CsList = Directory.GetFiles(ObjDirectory, "*.g.cs");
foreach (var pagePass2Cs in pagePass2CsList)
{
var filename = Path.GetFileName(pagePass2Cs);
if (string.Equals(filename, "App.g.cs", StringComparison.InvariantCultureIgnoreCase) ||
string.Equals(filename, "XamlTypeInfo.g.cs", StringComparison.InvariantCultureIgnoreCase))
{
continue;
}

var path = Path.Combine(ObjDirectory, filename);

var str = File.ReadAllText(path);
str = Regex.Replace(str,
"private class (.*?_obj\\d*_Bindings) :(\\s+global::Windows.UI.Xaml.(?:IDataTemplateExtension|Markup.IDataTemplateComponent|Markup.IXamlBindScopeDiagnostics|Markup.IComponentConnector),)",
"private partial class $1 :$2");
File.WriteAllText(path, str);
}

return true;
}
catch (Exception ex)
{
Log.LogErrorFromException(ex, showStackTrace: true);
return false;
}
}
}
}
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
using System;
using System.IO;
using System.Text.RegularExpressions;

namespace BuildTasks
{
internal class NativeAotFixupException : Exception
{
public NativeAotFixupException(string message) : base(message) { }
}
public class NativeAotFixup : Task
{
[Required]
public string ObjDirectory { get; set; }

private void Pass1Fixes()
{
var xamlTypeInfoCs = Path.Combine(ObjDirectory, "XamlTypeInfo.g.cs");
if (!File.Exists(xamlTypeInfoCs))
{
throw new NativeAotFixupException($"XamlTypeInfo.g.cs does not exist in {ObjDirectory}, XAML compilation may be failed.");
}

var str = File.ReadAllText(xamlTypeInfoCs);
str = Regex.Replace(str,
"public sealed class XamlMetaDataProvider : global::Windows.UI.Xaml.Markup.IXamlMetadataProvider",
"public sealed partial class XamlMetaDataProvider : global::Windows.UI.Xaml.Markup.IXamlMetadataProvider");
str = Regex.Replace(str,
"internal class XamlSystemBaseType : global::Windows.UI.Xaml.Markup.IXamlType",
"internal partial class XamlSystemBaseType : global::Windows.UI.Xaml.Markup.IXamlType");
str = Regex.Replace(str,
"internal class XamlUserType : global::(.*?)_XamlTypeInfo.XamlSystemBaseType",
"internal partial class XamlUserType : global::$1_XamlTypeInfo.XamlSystemBaseType");
str = Regex.Replace(str,
"internal class XamlMember : global::Windows.UI.Xaml.Markup.IXamlMember",
"internal partial class XamlMember : global::Windows.UI.Xaml.Markup.IXamlMember");
File.WriteAllText(xamlTypeInfoCs, str);
}

private void Pass2Fixes()
{
Log.LogMessage(MessageImportance.High, "Pass2AddPartial");
var pagePass2CsList = Directory.GetFiles(ObjDirectory, "*.g.cs");
foreach (var pagePass2Cs in pagePass2CsList)
{
var filename = Path.GetFileName(pagePass2Cs);
if (string.Equals(filename, "App.g.cs", StringComparison.InvariantCultureIgnoreCase) ||
string.Equals(filename, "XamlTypeInfo.g.cs", StringComparison.InvariantCultureIgnoreCase))
{
continue;
}

var path = Path.Combine(ObjDirectory, filename);

var str = File.ReadAllText(path);
str = Regex.Replace(str,
"private class (.*?_obj\\d*_Bindings) :(\\s+global::Windows.UI.Xaml.(?:IDataTemplateExtension|Markup.IDataTemplateComponent|Markup.IXamlBindScopeDiagnostics|Markup.IComponentConnector),)",
"private partial class $1 :$2");

// IComponentConnector.Connect(int connectionId, global::System.Object target);
// Connect(int connectionId, object target);
str = Regex.Replace(str,
"(\\s+?case \\d*: \\/\\/ .*?\\.xaml line \\d+\\s+\\{{0,1}\\s+?(?:global::.*? element\\d+|this\\..+?) = )\\((global::.*?)\\)\\({0,1}(target)\\){0,1};",
"$1global::WinRT.CastExtensions.As<$2>($3);");
str = Regex.Replace(str,
"(\\s+?case \\d*: \\/\\/ .*?\\.xaml line \\d+\\s+\\{{0,1}\\s+?(?:global::.*? element\\d+|this\\..+?) = new global::System.WeakReference)\\(\\((.*?)\\)(.*?)\\);",
"$1(global::WinRT.CastExtensions.As<$2>($3));");

// ElementName_objX_Bindings.SetDataRoot(global::System.Object newDataRoot)
str = Regex.Replace(str,
"(this.dataRoot = )\\((global::.*?)\\)(.*?);",
"$1global::WinRT.CastExtensions.As<$2>($3);");
File.WriteAllText(path, str);
}
}

public override bool Execute()
{
try
{
Pass1Fixes();
Pass2Fixes();
return true;
}
catch (NativeAotFixupException ex)
{
Log.LogError(ex.Message);
return false;
}
catch (Exception ex)
{
Log.LogErrorFromException(ex, showStackTrace: true);
return false;
}
}
}
}
2 changes: 1 addition & 1 deletion ModernXamlCompiler/ModernXamlCompiler.msbuildproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

<PropertyGroup>
<PackageId>DisposableMemory.ModernNetUAP.XamlCompiler</PackageId>
<Version>0.2.1</Version>
<Version>0.2.2-preview1</Version>
<Authors>driver1998</Authors>
<Description>UWP (Windows.UI.Xaml) Xaml Compiler support for Modern .NET</Description>
<PackageProjectUrl>https://github.com/driver1998/ModernNetUAP.XamlCompiler</PackageProjectUrl>
Expand Down

0 comments on commit 485dbca

Please sign in to comment.