-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Generate fake WinMD for XAML compiler
Generate fake WinMD from projection dlls instead of swapping WinMDs and projections around
- Loading branch information
1 parent
8f6d768
commit 3ac2565
Showing
18 changed files
with
213 additions
and
457 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>netstandard2.0</TargetFramework> | ||
<AssemblyName>DisposableMemory.ModernUAP.BuildTasks</AssemblyName> | ||
<LangVersion>8</LangVersion> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Microsoft.Build.Utilities.Core" Version="17.10.4" PrivateAssets="all" ExcludeAssets="Runtime"/> | ||
<PackageReference Include="Mono.Cecil" Version="$(_PkgMono_Cecil_Version)" PrivateAssets="all"/> | ||
</ItemGroup> | ||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
using System; | ||
using System.Linq; | ||
using System.Runtime.CompilerServices; | ||
using Microsoft.Build.Framework; | ||
using Microsoft.Build.Utilities; | ||
using Mono.Cecil; | ||
|
||
namespace DisposableMemory.ModernUAP.BuildTasks | ||
{ | ||
public class GenerateFakeWinMD : Task | ||
{ | ||
[Required] | ||
public ITaskItem[] SourceProjectionDlls { get; set; } | ||
|
||
[Required] | ||
public string TargetWinMD { get; set; } | ||
|
||
public override bool Execute() | ||
{ | ||
try | ||
{ | ||
Log.LogMessage(MessageImportance.High, "Generating Fake WinMD..."); | ||
|
||
var assemblyName = new AssemblyNameDefinition("Windows.FakeWinMetadata", new Version(0, 0, 0, 0)); | ||
using var outputAssembly = AssemblyDefinition.CreateAssembly(assemblyName, "Windows.FakeWinMetadata.dll", ModuleKind.Dll); | ||
outputAssembly.Name.IsWindowsRuntime = true; | ||
|
||
var outputModule = outputAssembly.MainModule; | ||
MethodReference fowardedToAttrCtor = outputModule.ImportReference(typeof(TypeForwardedToAttribute).GetConstructor(new Type[] { typeof(Type) })); | ||
|
||
var sourceAssemblyList = SourceProjectionDlls.Select(p => p.ItemSpec).ToList(); | ||
Log.LogMessage(MessageImportance.High, "Source projections: \n" + string.Join("\n", sourceAssemblyList)); | ||
|
||
foreach (var sourceAssemblyFile in sourceAssemblyList) | ||
{ | ||
using var sourceAssembly = AssemblyDefinition.ReadAssembly(sourceAssemblyFile); | ||
foreach (var type in sourceAssembly.MainModule.Types) | ||
{ | ||
if (string.IsNullOrEmpty(type.Namespace)) | ||
{ | ||
continue; | ||
} | ||
if (!type.IsPublic) | ||
{ | ||
continue; | ||
} | ||
if (!type.CustomAttributes.Any(p => p.AttributeType.FullName == "WinRT.WindowsRuntimeTypeAttribute")) | ||
{ | ||
continue; | ||
} | ||
|
||
var attr = new CustomAttribute(fowardedToAttrCtor); | ||
var typeRef = outputModule.ImportReference(type); | ||
var attrParam = new CustomAttributeArgument(outputModule.ImportReference(typeof(Type)), typeRef); | ||
attr.ConstructorArguments.Add(attrParam); | ||
outputAssembly.CustomAttributes.Add(attr); | ||
outputModule.ExportedTypes.Add(new ExportedType(typeRef.Namespace, typeRef.Name, typeRef.Module, typeRef.Scope)); | ||
} | ||
} | ||
|
||
outputAssembly.Write(TargetWinMD); | ||
Log.LogMessage(MessageImportance.High, "Output file: " + TargetWinMD); | ||
return true; | ||
} | ||
catch (Exception ex) | ||
{ | ||
Log.LogErrorFromException(ex, showStackTrace: true); | ||
return false; | ||
} | ||
|
||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
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; | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | ||
<PropertyGroup> | ||
<_PkgMono_Cecil_Version>0.11.5</_PkgMono_Cecil_Version> | ||
</PropertyGroup> | ||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.