From 4a84c729d0f7e2b56da16e97bd8d49f6bd739434 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Fri, 18 Aug 2023 11:36:53 -0700 Subject: [PATCH 01/46] Start prototype with TODOs on supporting build-time/runtime-startup selected WUX vs MUX mode. --- src/Authoring/WinRT.SourceGenerator/Helper.cs | 288 +++---- src/Perf/IIDOptimizer/SignatureGenerator.cs | 3 + src/WinRT.Runtime/GuidGenerator.cs | 60 +- src/WinRT.Runtime/Projections.cs | 69 +- src/cswinrt/cswinrt.vcxproj | 6 + src/cswinrt/helpers.h | 82 +- .../Windows.UI.Xaml.Controls.Primitives.cs | 73 ++ .../Windows.UI.Xaml.Media.Animation.cs | 326 ++++++++ .../Windows.UI.Xaml.Media.Media3D.cs | 711 ++++++++++++++++ .../Windows.UI.Xaml.Media.cs | 263 ++++++ .../Windows.UI.Xaml/Windows.UI.Xaml.SR.cs | 17 + .../Windows.UI.Xaml/Windows.UI.Xaml.cs | 774 ++++++++++++++++++ 12 files changed, 2486 insertions(+), 186 deletions(-) create mode 100644 src/cswinrt/strings/additions/Windows.UI.Xaml.Controls/Windows.UI.Xaml.Controls.Primitives.cs create mode 100644 src/cswinrt/strings/additions/Windows.UI.Xaml.Media.Animation/Windows.UI.Xaml.Media.Animation.cs create mode 100644 src/cswinrt/strings/additions/Windows.UI.Xaml.Media.Media3D/Windows.UI.Xaml.Media.Media3D.cs create mode 100644 src/cswinrt/strings/additions/Windows.UI.Xaml.Media/Windows.UI.Xaml.Media.cs create mode 100644 src/cswinrt/strings/additions/Windows.UI.Xaml/Windows.UI.Xaml.SR.cs create mode 100644 src/cswinrt/strings/additions/Windows.UI.Xaml/Windows.UI.Xaml.cs diff --git a/src/Authoring/WinRT.SourceGenerator/Helper.cs b/src/Authoring/WinRT.SourceGenerator/Helper.cs index c271ec578..9ce98add8 100644 --- a/src/Authoring/WinRT.SourceGenerator/Helper.cs +++ b/src/Authoring/WinRT.SourceGenerator/Helper.cs @@ -1,154 +1,154 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. - -using Microsoft.CodeAnalysis; + +using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Diagnostics; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; using System.Text.RegularExpressions; -namespace Generator -{ - public static class Helper - { - public static Guid EncodeGuid(byte[] data) - { - if (BitConverter.IsLittleEndian) - { - // swap bytes of int a - byte t = data[0]; - data[0] = data[3]; - data[3] = t; - t = data[1]; - data[1] = data[2]; - data[2] = t; - // swap bytes of short b - t = data[4]; - data[4] = data[5]; - data[5] = t; - // swap bytes of short c and encode rfc time/version field - t = data[6]; - data[6] = data[7]; - data[7] = (byte)((t & 0x0f) | (5 << 4)); - // encode rfc clock/reserved field - data[8] = (byte)((data[8] & 0x3f) | 0x80); - } - return new Guid(data.Take(16).ToArray()); - } - } - - class AttributeDataComparer : IEqualityComparer - { - public bool Equals(AttributeData x, AttributeData y) - { - return string.CompareOrdinal(x.ToString(), y.ToString()) == 0; - } - - public int GetHashCode(AttributeData obj) - { - return obj.ToString().GetHashCode(); - } - } - - static class GeneratorExecutionContextHelper - { - public static string GetAssemblyName(this GeneratorExecutionContext context) - { - context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.AssemblyName", out var assemblyName); - return assemblyName; - } - - public static string GetAssemblyVersion(this GeneratorExecutionContext context) - { - context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.AssemblyVersion", out var assemblyVersion); - return assemblyVersion; - } - - public static string GetGeneratedFilesDir(this GeneratorExecutionContext context) - { - context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.CsWinRTGeneratedFilesDir", out var generatedFilesDir); - Directory.CreateDirectory(generatedFilesDir); - return generatedFilesDir; - } - - public static bool IsCsWinRTComponent(this GeneratorExecutionContext context) - { - if (context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.CsWinRTComponent", out var isCsWinRTComponentStr)) - { - return bool.TryParse(isCsWinRTComponentStr, out var isCsWinRTComponent) && isCsWinRTComponent; - } - - return false; - } - - public static bool IsCsWinRTComponent(this AnalyzerConfigOptionsProvider provider) - { - if (provider.GlobalOptions.TryGetValue("build_property.CsWinRTComponent", out var isCsWinRTComponentStr)) - { - return bool.TryParse(isCsWinRTComponentStr, out var isCsWinRTComponent) && isCsWinRTComponent; - } - - return false; - } - - public static bool IsCsWinRTAotOptimizerEnabled(this AnalyzerConfigOptionsProvider provider) - { - if (provider.GlobalOptions.TryGetValue("build_property.CsWinRTAotOptimizerEnabled", out var isCsWinRTAotOptimizerEnabledStr)) - { - return bool.TryParse(isCsWinRTAotOptimizerEnabledStr, out var isCsWinRTAotOptimizerEnabled) && isCsWinRTAotOptimizerEnabled; - } - - return false; - } - - public static bool ShouldGenerateWinMDOnly(this GeneratorExecutionContext context) - { - if (context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.CsWinRTGenerateWinMDOnly", out var CsWinRTGenerateWinMDOnlyStr)) - { - return bool.TryParse(CsWinRTGenerateWinMDOnlyStr, out var CsWinRTGenerateWinMDOnly) && CsWinRTGenerateWinMDOnly; - } - - return false; - } - - public static string GetCsWinRTExe(this GeneratorExecutionContext context) - { - context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.CsWinRTExe", out var cswinrtExe); - return cswinrtExe; - } - - public static bool GetKeepGeneratedSources(this GeneratorExecutionContext context) - { - context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.CsWinRTKeepGeneratedSources", out var keepGeneratedSourcesStr); - return keepGeneratedSourcesStr != null && bool.TryParse(keepGeneratedSourcesStr, out var keepGeneratedSources) && keepGeneratedSources; - } - - public static string GetCsWinRTWindowsMetadata(this GeneratorExecutionContext context) - { - context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.CsWinRTWindowsMetadata", out var cswinrtWindowsMetadata); - return cswinrtWindowsMetadata; - } - - public static string GetCsWinRTDependentMetadata(this GeneratorExecutionContext context) - { - context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.CsWinRTAuthoringInputs", out var winmds); - return winmds; - } - - public static string GetWinmdOutputFile(this GeneratorExecutionContext context) - { +namespace Generator +{ + public static class Helper + { + public static Guid EncodeGuid(byte[] data) + { + if (BitConverter.IsLittleEndian) + { + // swap bytes of int a + byte t = data[0]; + data[0] = data[3]; + data[3] = t; + t = data[1]; + data[1] = data[2]; + data[2] = t; + // swap bytes of short b + t = data[4]; + data[4] = data[5]; + data[5] = t; + // swap bytes of short c and encode rfc time/version field + t = data[6]; + data[6] = data[7]; + data[7] = (byte)((t & 0x0f) | (5 << 4)); + // encode rfc clock/reserved field + data[8] = (byte)((data[8] & 0x3f) | 0x80); + } + return new Guid(data.Take(16).ToArray()); + } + } + + class AttributeDataComparer : IEqualityComparer + { + public bool Equals(AttributeData x, AttributeData y) + { + return string.CompareOrdinal(x.ToString(), y.ToString()) == 0; + } + + public int GetHashCode(AttributeData obj) + { + return obj.ToString().GetHashCode(); + } + } + + static class GeneratorExecutionContextHelper + { + public static string GetAssemblyName(this GeneratorExecutionContext context) + { + context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.AssemblyName", out var assemblyName); + return assemblyName; + } + + public static string GetAssemblyVersion(this GeneratorExecutionContext context) + { + context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.AssemblyVersion", out var assemblyVersion); + return assemblyVersion; + } + + public static string GetGeneratedFilesDir(this GeneratorExecutionContext context) + { + context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.CsWinRTGeneratedFilesDir", out var generatedFilesDir); + Directory.CreateDirectory(generatedFilesDir); + return generatedFilesDir; + } + + public static bool IsCsWinRTComponent(this GeneratorExecutionContext context) + { + if (context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.CsWinRTComponent", out var isCsWinRTComponentStr)) + { + return bool.TryParse(isCsWinRTComponentStr, out var isCsWinRTComponent) && isCsWinRTComponent; + } + + return false; + } + + public static bool IsCsWinRTComponent(this AnalyzerConfigOptionsProvider provider) + { + if (provider.GlobalOptions.TryGetValue("build_property.CsWinRTComponent", out var isCsWinRTComponentStr)) + { + return bool.TryParse(isCsWinRTComponentStr, out var isCsWinRTComponent) && isCsWinRTComponent; + } + + return false; + } + + public static bool IsCsWinRTAotOptimizerEnabled(this AnalyzerConfigOptionsProvider provider) + { + if (provider.GlobalOptions.TryGetValue("build_property.CsWinRTAotOptimizerEnabled", out var isCsWinRTAotOptimizerEnabledStr)) + { + return bool.TryParse(isCsWinRTAotOptimizerEnabledStr, out var isCsWinRTAotOptimizerEnabled) && isCsWinRTAotOptimizerEnabled; + } + + return false; + } + + public static bool ShouldGenerateWinMDOnly(this GeneratorExecutionContext context) + { + if (context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.CsWinRTGenerateWinMDOnly", out var CsWinRTGenerateWinMDOnlyStr)) + { + return bool.TryParse(CsWinRTGenerateWinMDOnlyStr, out var CsWinRTGenerateWinMDOnly) && CsWinRTGenerateWinMDOnly; + } + + return false; + } + + public static string GetCsWinRTExe(this GeneratorExecutionContext context) + { + context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.CsWinRTExe", out var cswinrtExe); + return cswinrtExe; + } + + public static bool GetKeepGeneratedSources(this GeneratorExecutionContext context) + { + context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.CsWinRTKeepGeneratedSources", out var keepGeneratedSourcesStr); + return keepGeneratedSourcesStr != null && bool.TryParse(keepGeneratedSourcesStr, out var keepGeneratedSources) && keepGeneratedSources; + } + + public static string GetCsWinRTWindowsMetadata(this GeneratorExecutionContext context) + { + context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.CsWinRTWindowsMetadata", out var cswinrtWindowsMetadata); + return cswinrtWindowsMetadata; + } + + public static string GetCsWinRTDependentMetadata(this GeneratorExecutionContext context) + { + context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.CsWinRTAuthoringInputs", out var winmds); + return winmds; + } + + public static string GetWinmdOutputFile(this GeneratorExecutionContext context) + { var fileName = context.GetAssemblyName(); if (context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.CsWinRTWinMDOutputFile", out var ret)) { fileName = ret!; - } - return Path.Combine(context.GetGeneratedFilesDir(), fileName + ".winmd"); - } - } - + } + return Path.Combine(context.GetGeneratedFilesDir(), fileName + ".winmd"); + } + } + static class GeneratorHelper { private static bool IsFundamentalType(ISymbol type) @@ -712,6 +712,8 @@ internal static (string, string, string, bool, bool) GetSystemTypeCustomMapping( } // This should be in sync with the reverse mapping from WinRT.Runtime/Projections.cs and cswinrt/helpers.h. + // TODO-WuxMux: Update this table to respect a property the defines WUX vs MUX projections. + // Additionally, output a module initializer that validates the MUX/WUX projection mode to ensure that things don't get out of sync. public static readonly Dictionary MappedCSharpTypes = new(StringComparer.Ordinal) { { "System.DateTimeOffset", new MappedType("Windows.Foundation", "DateTime", "Windows.Foundation.FoundationContract", true, false) }, @@ -756,5 +758,5 @@ internal static (string, string, string, bool, bool) GetSystemTypeCustomMapping( { "System.Collections.Generic.IList`1", new MappedType("Windows.Foundation.Collections", "IVector`1", "Windows.Foundation.FoundationContract") }, { "Windows.UI.Color", new MappedType("Windows.UI", "Color", "Windows.Foundation.UniversalApiContract", true, true) }, }; - } -} + } +} diff --git a/src/Perf/IIDOptimizer/SignatureGenerator.cs b/src/Perf/IIDOptimizer/SignatureGenerator.cs index 7c9271254..819bcabaa 100644 --- a/src/Perf/IIDOptimizer/SignatureGenerator.cs +++ b/src/Perf/IIDOptimizer/SignatureGenerator.cs @@ -167,6 +167,9 @@ public SignaturePart GetSignatureParts(TypeReference type) return new RuntimeClassSignature(type, GetSignatureParts(iface)); } + // TODO-WuxMux: We need to intercept the WUX/MUX types here and do one of the following options: + // - Take an option in the IID optimizer to hard-code for one or the other (for OutputType Exe or for libraries that are one flavor only, this is reasonable) + // - Fall back to runtime-based IID lookup for the type (works for everything, less efficient) Guid? guidAttributeValue = type.ReadGuidFromAttribute(guidAttributeType, winRTRuntimeAssembly); if (guidAttributeValue == null) { diff --git a/src/WinRT.Runtime/GuidGenerator.cs b/src/WinRT.Runtime/GuidGenerator.cs index f9861c16e..066536625 100644 --- a/src/WinRT.Runtime/GuidGenerator.cs +++ b/src/WinRT.Runtime/GuidGenerator.cs @@ -22,12 +22,16 @@ public static Guid GetGUID(Type type) return type.GetGuidType().GUID; } - public static Guid GetIID( + public static Guid GetIID( #if NET [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] #endif Type type) { + if (Projections.FindCustomIIDForAbiType(type) is Guid customIID) + { + return customIID; + } type = type.GetGuidType(); if (!type.IsGenericType) { @@ -36,21 +40,21 @@ public static Guid GetIID( return (Guid)type.GetField("PIID").GetValue(null); } - public static string GetSignature( + public static string GetSignature( #if NET [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] #endif Type type) - { + { if (type == typeof(object)) { return "cinterface(IInspectable)"; - } - + } + if (type == typeof(string)) { return "string"; - } + } var helperType = type.FindHelperType(); if (helperType != null) @@ -89,32 +93,32 @@ public static string GetSignature( if (!type.IsPrimitive) { var winrtTypeAttribute = type.GetCustomAttribute(); - if (winrtTypeAttribute != null && !string.IsNullOrEmpty(winrtTypeAttribute.GuidSignature)) - { - return winrtTypeAttribute.GuidSignature; + if (winrtTypeAttribute != null && !string.IsNullOrEmpty(winrtTypeAttribute.GuidSignature)) + { + return winrtTypeAttribute.GuidSignature; } - else - { - var args = type.GetFields(BindingFlags.Instance | BindingFlags.Public).Select(fi => GetSignature(fi.FieldType)); - return "struct(" + type.FullName + ";" + String.Join(";", args) + ")"; + else + { + var args = type.GetFields(BindingFlags.Instance | BindingFlags.Public).Select(fi => GetSignature(fi.FieldType)); + return "struct(" + type.FullName + ";" + String.Join(";", args) + ")"; } } throw new InvalidOperationException("unsupported value type"); } } } - - // For authoring interfaces, we can use the metadata type or the helper type to get the guid. - // For built-in system interfaces that are custom type mapped, we use the helper type to get the guid. - // For others, either the type itself or the helper type has the same guid and can be used. + + // For authoring interfaces, we can use the metadata type or the helper type to get the guid. + // For built-in system interfaces that are custom type mapped, we use the helper type to get the guid. + // For others, either the type itself or the helper type has the same guid and can be used. type = type.IsInterface ? (helperType ?? type) : type; if (type.IsGenericType) { var args = type.GetGenericArguments().Select(t => GetSignature(t)); return "pinterface({" + GetGUID(type) + "};" + String.Join(";", args) + ")"; - } - + } + if (type.IsDelegate()) { return "delegate({" + GetGUID(type) + "})"; @@ -166,14 +170,14 @@ public static Guid CreateIID(Type type) { return new Guid(sig); } - else - { - return CreateIIDForGenericType(sig); + else + { + return CreateIIDForGenericType(sig); } } - internal static Guid CreateIIDForGenericType(string signature) - { + internal static Guid CreateIIDForGenericType(string signature) + { #if !NET var data = wrt_pinterface_namespace.ToByteArray().Concat(UTF8Encoding.UTF8.GetBytes(signature)).ToArray(); @@ -188,10 +192,10 @@ internal static Guid CreateIIDForGenericType(string signature) Span dataSpan = data; wrt_pinterface_namespace.TryWriteBytes(dataSpan); var numBytes = UTF8Encoding.UTF8.GetBytes(signature, dataSpan[16..]); - data = data[..(16 + numBytes)]; - - return encode_guid(SHA1.HashData(data)); -#endif + data = data[..(16 + numBytes)]; + + return encode_guid(SHA1.HashData(data)); +#endif } } } diff --git a/src/WinRT.Runtime/Projections.cs b/src/WinRT.Runtime/Projections.cs index 1f4d66d43..0ee03e99d 100644 --- a/src/WinRT.Runtime/Projections.cs +++ b/src/WinRT.Runtime/Projections.cs @@ -25,9 +25,19 @@ namespace WinRT #endif static class Projections { + private enum UiXamlMode + { + Unsupported, + MicrosoftUiXaml, + WindowsUiXaml + } + + private static UiXamlMode UiXamlMode { get; } = AppContext.GetData("CsWinRT.UiXamlMode") is string str && Enum.TryParse(str, out var mode) ? mode : UiXamlMode.Unsupported; + private static readonly ReaderWriterLockSlim rwlock = new ReaderWriterLockSlim(); private static readonly Dictionary CustomTypeToHelperTypeMappings = new Dictionary(); + private static readonly Dictionary CustomTypeToIIDMappings = new Dictionary(); private static readonly Dictionary CustomAbiTypeToTypeMappings = new Dictionary(); private static readonly Dictionary CustomAbiTypeNameToTypeMappings = new Dictionary(StringComparer.Ordinal); private static readonly Dictionary CustomTypeToAbiTypeNameMappings = new Dictionary(); @@ -62,13 +72,46 @@ static Projections() RegisterCustomAbiTypeMappingNoLock(typeof(Exception), typeof(ABI.System.Exception), "Windows.Foundation.HResult"); RegisterCustomAbiTypeMappingNoLock(typeof(TimeSpan), typeof(ABI.System.TimeSpan), "Windows.Foundation.TimeSpan"); RegisterCustomAbiTypeMappingNoLock(typeof(Uri), typeof(ABI.System.Uri), "Windows.Foundation.Uri", isRuntimeClass: true); - RegisterCustomAbiTypeMappingNoLock(typeof(DataErrorsChangedEventArgs), typeof(ABI.System.ComponentModel.DataErrorsChangedEventArgs), "Microsoft.UI.Xaml.Data.DataErrorsChangedEventArgs", isRuntimeClass: true); - RegisterCustomAbiTypeMappingNoLock(typeof(PropertyChangedEventArgs), typeof(ABI.System.ComponentModel.PropertyChangedEventArgs), "Microsoft.UI.Xaml.Data.PropertyChangedEventArgs", isRuntimeClass: true); - RegisterCustomAbiTypeMappingNoLock(typeof(PropertyChangedEventHandler), typeof(ABI.System.ComponentModel.PropertyChangedEventHandler), "Microsoft.UI.Xaml.Data.PropertyChangedEventHandler"); - RegisterCustomAbiTypeMappingNoLock(typeof(INotifyDataErrorInfo), typeof(ABI.System.ComponentModel.INotifyDataErrorInfo), "Microsoft.UI.Xaml.Data.INotifyDataErrorInfo"); - RegisterCustomAbiTypeMappingNoLock(typeof(INotifyPropertyChanged), typeof(ABI.System.ComponentModel.INotifyPropertyChanged), "Microsoft.UI.Xaml.Data.INotifyPropertyChanged"); - RegisterCustomAbiTypeMappingNoLock(typeof(ICommand), typeof(ABI.System.Windows.Input.ICommand), "Microsoft.UI.Xaml.Interop.ICommand"); - RegisterCustomAbiTypeMappingNoLock(typeof(IServiceProvider), typeof(ABI.System.IServiceProvider), "Microsoft.UI.Xaml.IXamlServiceProvider"); + + if (UiXamlMode == UiXamlMode.MicrosoftUiXaml) + { + RegisterCustomAbiTypeMappingNoLock(typeof(DataErrorsChangedEventArgs), typeof(ABI.System.ComponentModel.DataErrorsChangedEventArgs), "Microsoft.UI.Xaml.Data.DataErrorsChangedEventArgs", isRuntimeClass: true); + RegisterCustomAbiTypeMappingNoLock(typeof(PropertyChangedEventArgs), typeof(ABI.System.ComponentModel.PropertyChangedEventArgs), "Microsoft.UI.Xaml.Data.PropertyChangedEventArgs", isRuntimeClass: true); + RegisterCustomAbiTypeMappingNoLock(typeof(PropertyChangedEventHandler), typeof(ABI.System.ComponentModel.PropertyChangedEventHandler), "Microsoft.UI.Xaml.Data.PropertyChangedEventHandler"); + RegisterCustomAbiTypeMappingNoLock(typeof(INotifyDataErrorInfo), typeof(ABI.System.ComponentModel.INotifyDataErrorInfo), "Microsoft.UI.Xaml.Data.INotifyDataErrorInfo"); + RegisterCustomAbiTypeMappingNoLock(typeof(INotifyPropertyChanged), typeof(ABI.System.ComponentModel.INotifyPropertyChanged), "Microsoft.UI.Xaml.Data.INotifyPropertyChanged"); + RegisterCustomAbiTypeMappingNoLock(typeof(ICommand), typeof(ABI.System.Windows.Input.ICommand), "Microsoft.UI.Xaml.Interop.ICommand"); + RegisterCustomAbiTypeMappingNoLock(typeof(IServiceProvider), typeof(ABI.System.IServiceProvider), "Microsoft.UI.Xaml.IXamlServiceProvider"); + RegisterCustomAbiTypeMappingNoLock(typeof(IEnumerable), typeof(ABI.System.Collections.IEnumerable), "Microsoft.UI.Xaml.Interop.IBindableIterable"); + RegisterCustomAbiTypeMappingNoLock(typeof(IList), typeof(ABI.System.Collections.IList), "Microsoft.UI.Xaml.Interop.IBindableVector"); + RegisterCustomAbiTypeMappingNoLock(typeof(INotifyCollectionChanged), typeof(ABI.System.Collections.Specialized.INotifyCollectionChanged), "Microsoft.UI.Xaml.Interop.INotifyCollectionChanged"); + RegisterCustomAbiTypeMappingNoLock(typeof(NotifyCollectionChangedAction), typeof(ABI.System.Collections.Specialized.NotifyCollectionChangedAction), "Microsoft.UI.Xaml.Interop.NotifyCollectionChangedAction"); + RegisterCustomAbiTypeMappingNoLock(typeof(NotifyCollectionChangedEventArgs), typeof(ABI.System.Collections.Specialized.NotifyCollectionChangedEventArgs), "Microsoft.UI.Xaml.Interop.NotifyCollectionChangedEventArgs", isRuntimeClass: true); + RegisterCustomAbiTypeMappingNoLock(typeof(NotifyCollectionChangedEventHandler), typeof(ABI.System.Collections.Specialized.NotifyCollectionChangedEventHandler), "Microsoft.UI.Xaml.Interop.NotifyCollectionChangedEventHandler"); + CustomTypeToHelperTypeMappings.Add(typeof(Microsoft.UI.Xaml.Interop.IBindableVector), typeof(ABI.System.Collections.IList)); + + // TODO-WuxMux: Add custom IIDs to the IID lookup + } + else if (UiXamlMode == UiXamlMode.WindowsUiXaml) + { + RegisterCustomAbiTypeMappingNoLock(typeof(DataErrorsChangedEventArgs), typeof(ABI.System.ComponentModel.DataErrorsChangedEventArgs), "Windows.UI.Xaml.Data.DataErrorsChangedEventArgs", isRuntimeClass: true); + RegisterCustomAbiTypeMappingNoLock(typeof(PropertyChangedEventArgs), typeof(ABI.System.ComponentModel.PropertyChangedEventArgs), "Windows.UI.Xaml.Data.PropertyChangedEventArgs", isRuntimeClass: true); + RegisterCustomAbiTypeMappingNoLock(typeof(PropertyChangedEventHandler), typeof(ABI.System.ComponentModel.PropertyChangedEventHandler), "Windows.UI.Xaml.Data.PropertyChangedEventHandler"); + RegisterCustomAbiTypeMappingNoLock(typeof(INotifyDataErrorInfo), typeof(ABI.System.ComponentModel.INotifyDataErrorInfo), "Windows.UI.Xaml.Data.INotifyDataErrorInfo"); + RegisterCustomAbiTypeMappingNoLock(typeof(INotifyPropertyChanged), typeof(ABI.System.ComponentModel.INotifyPropertyChanged), "Windows.UI.Xaml.Data.INotifyPropertyChanged"); + RegisterCustomAbiTypeMappingNoLock(typeof(ICommand), typeof(ABI.System.Windows.Input.ICommand), "Windows.UI.Xaml.Interop.ICommand"); + RegisterCustomAbiTypeMappingNoLock(typeof(IServiceProvider), typeof(ABI.System.IServiceProvider), "Windows.UI.Xaml.IXamlServiceProvider"); + RegisterCustomAbiTypeMappingNoLock(typeof(IEnumerable), typeof(ABI.System.Collections.IEnumerable), "Windows.UI.Xaml.Interop.IBindableIterable"); + RegisterCustomAbiTypeMappingNoLock(typeof(IList), typeof(ABI.System.Collections.IList), "Windows.UI.Xaml.Interop.IBindableVector"); + RegisterCustomAbiTypeMappingNoLock(typeof(INotifyCollectionChanged), typeof(ABI.System.Collections.Specialized.INotifyCollectionChanged), "Windows.UI.Xaml.Interop.INotifyCollectionChanged"); + RegisterCustomAbiTypeMappingNoLock(typeof(NotifyCollectionChangedAction), typeof(ABI.System.Collections.Specialized.NotifyCollectionChangedAction), "Windows.UI.Xaml.Interop.NotifyCollectionChangedAction"); + RegisterCustomAbiTypeMappingNoLock(typeof(NotifyCollectionChangedEventArgs), typeof(ABI.System.Collections.Specialized.NotifyCollectionChangedEventArgs), "Windows.UI.Xaml.Interop.NotifyCollectionChangedEventArgs", isRuntimeClass: true); + RegisterCustomAbiTypeMappingNoLock(typeof(NotifyCollectionChangedEventHandler), typeof(ABI.System.Collections.Specialized.NotifyCollectionChangedEventHandler), "Windows.UI.Xaml.Interop.NotifyCollectionChangedEventHandler"); + CustomTypeToHelperTypeMappings.Add(typeof(Windows.UI.Xaml.Interop.IBindableVector), typeof(ABI.System.Collections.IList)); + + // TODO-WuxMux: Add custom IIDs to the IID lookup + } + RegisterCustomAbiTypeMappingNoLock(typeof(EventHandler<>), typeof(ABI.System.EventHandler<>), "Windows.Foundation.EventHandler`1"); RegisterCustomAbiTypeMappingNoLock(typeof(KeyValuePair<,>), typeof(ABI.System.Collections.Generic.KeyValuePair<,>), "Windows.Foundation.Collections.IKeyValuePair`2"); @@ -80,12 +123,6 @@ static Projections() RegisterCustomAbiTypeMappingNoLock(typeof(IReadOnlyDictionary<,>), typeof(ABI.System.Collections.Generic.IReadOnlyDictionary<,>), "Windows.Foundation.Collections.IMapView`2"); RegisterCustomAbiTypeMappingNoLock(typeof(IDisposable), typeof(ABI.System.IDisposable), "Windows.Foundation.IClosable"); - RegisterCustomAbiTypeMappingNoLock(typeof(IEnumerable), typeof(ABI.System.Collections.IEnumerable), "Microsoft.UI.Xaml.Interop.IBindableIterable"); - RegisterCustomAbiTypeMappingNoLock(typeof(IList), typeof(ABI.System.Collections.IList), "Microsoft.UI.Xaml.Interop.IBindableVector"); - RegisterCustomAbiTypeMappingNoLock(typeof(INotifyCollectionChanged), typeof(ABI.System.Collections.Specialized.INotifyCollectionChanged), "Microsoft.UI.Xaml.Interop.INotifyCollectionChanged"); - RegisterCustomAbiTypeMappingNoLock(typeof(NotifyCollectionChangedAction), typeof(ABI.System.Collections.Specialized.NotifyCollectionChangedAction), "Microsoft.UI.Xaml.Interop.NotifyCollectionChangedAction"); - RegisterCustomAbiTypeMappingNoLock(typeof(NotifyCollectionChangedEventArgs), typeof(ABI.System.Collections.Specialized.NotifyCollectionChangedEventArgs), "Microsoft.UI.Xaml.Interop.NotifyCollectionChangedEventArgs", isRuntimeClass: true); - RegisterCustomAbiTypeMappingNoLock(typeof(NotifyCollectionChangedEventHandler), typeof(ABI.System.Collections.Specialized.NotifyCollectionChangedEventHandler), "Microsoft.UI.Xaml.Interop.NotifyCollectionChangedEventHandler"); RegisterCustomAbiTypeMappingNoLock(typeof(Matrix3x2), typeof(ABI.System.Numerics.Matrix3x2), "Windows.Foundation.Numerics.Matrix3x2"); RegisterCustomAbiTypeMappingNoLock(typeof(Matrix4x4), typeof(ABI.System.Numerics.Matrix4x4), "Windows.Foundation.Numerics.Matrix4x4"); @@ -100,7 +137,6 @@ static Projections() CustomTypeToHelperTypeMappings.Add(typeof(IVector<>), typeof(ABI.System.Collections.Generic.IList<>)); CustomTypeToHelperTypeMappings.Add(typeof(IMapView<,>), typeof(ABI.System.Collections.Generic.IReadOnlyDictionary<,>)); CustomTypeToHelperTypeMappings.Add(typeof(IVectorView<>), typeof(ABI.System.Collections.Generic.IReadOnlyList<>)); - CustomTypeToHelperTypeMappings.Add(typeof(Microsoft.UI.Xaml.Interop.IBindableVector), typeof(ABI.System.Collections.IList)); #if NET CustomTypeToHelperTypeMappings.Add(typeof(ICollection<>), typeof(ABI.System.Collections.Generic.ICollection<>)); @@ -260,6 +296,11 @@ public static string FindCustomAbiTypeNameForType(Type type) } } + internal static Guid? FindCustomIIDForAbiType(Type type) + { + return CustomTypeToIIDMappings.TryGetValue(type, out Guid iid) ? iid : null; + } + private readonly static ConcurrentDictionary IsTypeWindowsRuntimeTypeCache = new(); public static bool IsTypeWindowsRuntimeType(Type type) { diff --git a/src/cswinrt/cswinrt.vcxproj b/src/cswinrt/cswinrt.vcxproj index 674c12582..6980f4ebe 100644 --- a/src/cswinrt/cswinrt.vcxproj +++ b/src/cswinrt/cswinrt.vcxproj @@ -109,6 +109,12 @@ + + + + + + diff --git a/src/cswinrt/helpers.h b/src/cswinrt/helpers.h index fcc3f7cc3..8e43f270f 100644 --- a/src/cswinrt/helpers.h +++ b/src/cswinrt/helpers.h @@ -671,6 +671,7 @@ namespace cswinrt { // Make sure to keep this table consistent with the registrations in WinRT.Runtime/Projections.cs // and the reverse mapping in WinRT.SourceGenerator/WinRTTypeWriter.cs. + // This table can include both the MUX and WUX types as only one will be selected at runtime. // NOTE: Must keep namespaces sorted (outer) and abi type names sorted (inner) { "Microsoft.UI.Xaml", { @@ -816,13 +817,92 @@ namespace cswinrt { "IColorHelperStatics2" }, } }, - // Temporary, until WinUI provides TypeName + { "Windows.UI.Xaml", + { + { "CornerRadius", "Windows.UI.Xaml", "CornerRadius" }, + { "CornerRadiusHelper" }, + { "Duration", "Windows.UI.Xaml", "Duration" }, + { "DurationHelper" }, + { "DurationType", "Windows.UI.Xaml", "DurationType" }, + { "GridLength", "Windows.UI.Xaml", "GridLength" }, + { "GridLengthHelper" }, + { "GridUnitType", "Windows.UI.Xaml", "GridUnitType" }, + { "ICornerRadiusHelper" }, + { "ICornerRadiusHelperStatics" }, + { "IDurationHelper" }, + { "IDurationHelperStatics" }, + { "IGridLengthHelper" }, + { "IGridLengthHelperStatics" }, + { "IThicknessHelper" }, + { "IThicknessHelperStatics" }, + { "Thickness", "Windows.UI.Xaml", "Thickness" }, + { "ThicknessHelper" }, + { "IXamlServiceProvider", "System", "IServiceProvider" }, + } + }, + { "Windows.UI.Xaml.Controls.Primitives", + { + { "GeneratorPosition", "Windows.UI.Xaml.Controls.Primitives", "GeneratorPosition" }, + { "GeneratorPositionHelper" }, + { "IGeneratorPositionHelper" }, + { "IGeneratorPositionHelperStatics" }, + } + }, + { "Windows.UI.Xaml.Data", + { + { "DataErrorsChangedEventArgs", "System.ComponentModel", "DataErrorsChangedEventArgs" }, + { "INotifyDataErrorInfo", "System.ComponentModel", "INotifyDataErrorInfo", true, true }, + { "INotifyPropertyChanged", "System.ComponentModel", "INotifyPropertyChanged" }, + { "PropertyChangedEventArgs", "System.ComponentModel", "PropertyChangedEventArgs" }, + { "PropertyChangedEventHandler", "System.ComponentModel", "PropertyChangedEventHandler" }, + } + }, + { "Windows.UI.Xaml.Input", + { + { "ICommand", "System.Windows.Input", "ICommand", true } + } + }, { "Windows.UI.Xaml.Interop", { + { "IBindableIterable", "System.Collections", "IEnumerable", true, true }, + { "IBindableVector", "System.Collections", "IList", true, true }, + { "INotifyCollectionChanged", "System.Collections.Specialized", "INotifyCollectionChanged", true }, + { "NotifyCollectionChangedAction", "System.Collections.Specialized", "NotifyCollectionChangedAction" }, + { "NotifyCollectionChangedEventArgs", "System.Collections.Specialized", "NotifyCollectionChangedEventArgs", true }, + { "NotifyCollectionChangedEventHandler", "System.Collections.Specialized", "NotifyCollectionChangedEventHandler", true }, { "TypeKind", "Windows.UI.Xaml.Interop", "TypeKind", true }, { "TypeName", "System", "Type", true } } }, + { "Windows.UI.Xaml.Media", + { + { "IMatrixHelper" }, + { "IMatrixHelperStatics" }, + { "Matrix", "Windows.UI.Xaml.Media", "Matrix" }, + { "MatrixHelper" }, + } + }, + { "Windows.UI.Xaml.Media.Animation", + { + { "IKeyTimeHelper" }, + { "IKeyTimeHelperStatics" }, + { "IRepeatBehaviorHelper" }, + { "IRepeatBehaviorHelperStatics" }, + { "KeyTime", "Windows.UI.Xaml.Media.Animation", "KeyTime" }, + { "KeyTimeHelper" }, + { "RepeatBehavior", "Windows.UI.Xaml.Media.Animation", "RepeatBehavior" }, + { "RepeatBehaviorHelper" }, + { "RepeatBehaviorType", "Windows.UI.Xaml.Media.Animation", "RepeatBehaviorType" } + } + }, + { "Windows.UI.Xaml.Media.Media3D", + { + { "IMatrix3DHelper" }, + { "IMatrix3DHelperStatics" }, + { "Matrix3D", "Windows.UI.Xaml.Media.Media3D", "Matrix3D" }, + { "Matrix3DHelper" }, + } + }, }; auto nsItr = std::lower_bound(std::begin(mapped_types), std::end(mapped_types), typeNamespace, [](auto&& v, std::string_view ns) diff --git a/src/cswinrt/strings/additions/Windows.UI.Xaml.Controls/Windows.UI.Xaml.Controls.Primitives.cs b/src/cswinrt/strings/additions/Windows.UI.Xaml.Controls/Windows.UI.Xaml.Controls.Primitives.cs new file mode 100644 index 000000000..8326013d9 --- /dev/null +++ b/src/cswinrt/strings/additions/Windows.UI.Xaml.Controls/Windows.UI.Xaml.Controls.Primitives.cs @@ -0,0 +1,73 @@ + +namespace Windows.UI.Xaml.Controls.Primitives +{ + using global::Windows.Foundation; + + [global::WinRT.WindowsRuntimeType("Microsoft.UI")] + [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Windows.UI.Xaml.Controls.Primitives.GeneratorPosition))] + [StructLayout(LayoutKind.Sequential)] +#if EMBED + internal +#else + public +#endif + struct GeneratorPosition + { + private int _index; + private int _offset; + + public int Index { get { return _index; } set { _index = value; } } + public int Offset { get { return _offset; } set { _offset = value; } } + + public GeneratorPosition(int index, int offset) + { + _index = index; + _offset = offset; + } + + public override int GetHashCode() + { + return _index.GetHashCode() + _offset.GetHashCode(); + } + + public override string ToString() + { + return string.Concat("GeneratorPosition (", _index.ToString(global::System.Globalization.CultureInfo.InvariantCulture), ",", _offset.ToString(global::System.Globalization.CultureInfo.InvariantCulture), ")"); + } + + public override bool Equals(object o) + { + if (o is GeneratorPosition) + { + GeneratorPosition that = (GeneratorPosition)o; + return _index == that._index && + _offset == that._offset; + } + return false; + } + + public static bool operator ==(GeneratorPosition gp1, GeneratorPosition gp2) + { + return gp1._index == gp2._index && + gp1._offset == gp2._offset; + } + + public static bool operator !=(GeneratorPosition gp1, GeneratorPosition gp2) + { + return !(gp1 == gp2); + } + } +} + +namespace ABI.Windows.UI.Xaml.Controls.Primitives +{ +#if EMBED + internal +#else + public +#endif + static class GeneratorPosition + { + public static string GetGuidSignature() => $"struct(Windows.UI.Xaml.Controls.Primitives.GeneratorPosition;i4;i4)"; + } +} diff --git a/src/cswinrt/strings/additions/Windows.UI.Xaml.Media.Animation/Windows.UI.Xaml.Media.Animation.cs b/src/cswinrt/strings/additions/Windows.UI.Xaml.Media.Animation/Windows.UI.Xaml.Media.Animation.cs new file mode 100644 index 000000000..789928089 --- /dev/null +++ b/src/cswinrt/strings/additions/Windows.UI.Xaml.Media.Animation/Windows.UI.Xaml.Media.Animation.cs @@ -0,0 +1,326 @@ + +namespace Windows.UI.Xaml.Media.Animation +{ + using global::Windows.Foundation; + + [global::WinRT.WindowsRuntimeType("Microsoft.UI")] + [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Windows.UI.Xaml.Media.Animation.KeyTime))] + [StructLayout(LayoutKind.Sequential)] +#if EMBED + internal +#else + public +#endif + struct KeyTime + { + private TimeSpan _timeSpan; + + public static KeyTime FromTimeSpan(TimeSpan timeSpan) + { + if (timeSpan < TimeSpan.Zero) + { + throw new ArgumentOutOfRangeException(nameof(timeSpan)); + } + + KeyTime keyTime = default; + + keyTime._timeSpan = timeSpan; + + return keyTime; + } + + public static bool Equals(KeyTime keyTime1, KeyTime keyTime2) + { + return (keyTime1._timeSpan == keyTime2._timeSpan); + } + + public static bool operator ==(KeyTime keyTime1, KeyTime keyTime2) + { + return KeyTime.Equals(keyTime1, keyTime2); + } + + public static bool operator !=(KeyTime keyTime1, KeyTime keyTime2) + { + return !KeyTime.Equals(keyTime1, keyTime2); + } + + public bool Equals(KeyTime value) + { + return KeyTime.Equals(this, value); + } + + public override bool Equals(object value) + { + return value is KeyTime && this == (KeyTime)value; + } + + public override int GetHashCode() + { + return _timeSpan.GetHashCode(); + } + + public override string ToString() + { + return _timeSpan.ToString(); + } + + public static implicit operator KeyTime(TimeSpan timeSpan) + { + return KeyTime.FromTimeSpan(timeSpan); + } + + public TimeSpan TimeSpan + { + get + { + return _timeSpan; + } + } + } + + [global::WinRT.WindowsRuntimeType("Microsoft.UI")] +#if EMBED + internal +#else + public +#endif + enum RepeatBehaviorType + { + Count, + Duration, + Forever + } + + [global::WinRT.WindowsRuntimeType("Microsoft.UI")] + [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Windows.UI.Xaml.Media.Animation.RepeatBehavior))] + [StructLayout(LayoutKind.Sequential)] +#if EMBED + internal +#else + public +#endif + struct RepeatBehavior : IFormattable + { + private double _Count; + private TimeSpan _Duration; + private RepeatBehaviorType _Type; + + internal static bool IsFinite(double value) + { + return !(double.IsNaN(value) || double.IsInfinity(value)); + } + + public RepeatBehavior(double count) + { + if (!IsFinite(count) || count < 0.0) + { + throw new ArgumentOutOfRangeException(nameof(count)); + } + + _Duration = new TimeSpan(0); + _Count = count; + _Type = RepeatBehaviorType.Count; + } + + public RepeatBehavior(TimeSpan duration) + { + if (duration < new TimeSpan(0)) + { + throw new ArgumentOutOfRangeException(nameof(duration)); + } + + _Duration = duration; + _Count = 0.0; + _Type = RepeatBehaviorType.Duration; + } + + public static RepeatBehavior Forever + { + get + { + RepeatBehavior forever = default; + forever.Type = RepeatBehaviorType.Forever; + + return forever; + } + } + + public bool HasCount + { + get + { + return Type == RepeatBehaviorType.Count; + } + } + + public bool HasDuration + { + get + { + return Type == RepeatBehaviorType.Duration; + } + } + + public double Count + { + get { return _Count; } + set { _Count = value; } + } + + public TimeSpan Duration + { + get { return _Duration; } + set { _Duration = value; } + } + + public RepeatBehaviorType Type + { + get { return _Type; } + set { _Type = value; } + } + + public override string ToString() + { + return InternalToString(null, null); + } + + public string ToString(IFormatProvider formatProvider) + { + return InternalToString(null, formatProvider); + } + + string IFormattable.ToString(string format, IFormatProvider formatProvider) + { + return InternalToString(format, formatProvider); + } + + internal string InternalToString(string format, IFormatProvider formatProvider) + { + switch (_Type) + { + case RepeatBehaviorType.Forever: + + return "Forever"; + + case RepeatBehaviorType.Count: + + global::System.Text.StringBuilder sb = new global::System.Text.StringBuilder(); + + sb.AppendFormat( + formatProvider, + "{0:" + format + "}x", + _Count); + + return sb.ToString(); + + case RepeatBehaviorType.Duration: + + return _Duration.ToString(); + + default: + return string.Empty; + } + } + + public override bool Equals(object value) + { + if (value is RepeatBehavior) + { + return this.Equals((RepeatBehavior)value); + } + else + { + return false; + } + } + + public bool Equals(RepeatBehavior repeatBehavior) + { + if (_Type == repeatBehavior._Type) + { + return _Type switch + { + RepeatBehaviorType.Forever => true, + RepeatBehaviorType.Count => _Count == repeatBehavior._Count, + RepeatBehaviorType.Duration => _Duration == repeatBehavior._Duration, + _ => false, + }; + } + else + { + return false; + } + } + + public static bool Equals(RepeatBehavior repeatBehavior1, RepeatBehavior repeatBehavior2) + { + return repeatBehavior1.Equals(repeatBehavior2); + } + + public override int GetHashCode() + { + return _Type switch + { + RepeatBehaviorType.Count => _Count.GetHashCode(), + RepeatBehaviorType.Duration => _Duration.GetHashCode(), + + // We try to choose an unlikely hash code value for Forever. + // All Forevers need to return the same hash code value. + RepeatBehaviorType.Forever => int.MaxValue - 42, + + _ => base.GetHashCode(), + }; + } + + public static bool operator ==(RepeatBehavior repeatBehavior1, RepeatBehavior repeatBehavior2) + { + return repeatBehavior1.Equals(repeatBehavior2); + } + + public static bool operator !=(RepeatBehavior repeatBehavior1, RepeatBehavior repeatBehavior2) + { + return !repeatBehavior1.Equals(repeatBehavior2); + } + } +} + +namespace ABI.Windows.UI.Xaml.Media.Animation +{ +#if EMBED + internal +#else + public +#endif + static class KeyTime + { + public static string GetGuidSignature() + { + string timeSpanSignature = global::WinRT.GuidGenerator.GetSignature(typeof(global::System.TimeSpan)); + return $"struct(Windows.UI.Xaml.Media.Animation.KeyTime;{timeSpanSignature})"; + } + } + +#if EMBED + internal +#else + public +#endif + static class RepeatBehavior + { + public static string GetGuidSignature() + { + string timeSpanSignature = global::WinRT.GuidGenerator.GetSignature(typeof(global::System.TimeSpan)); + return $"struct(Windows.UI.Xaml.Media.Animation.RepeatBehavior;f8;{timeSpanSignature};{RepeatBehaviorType.GetGuidSignature()})"; + } + } + +#if EMBED + internal +#else + public +#endif + static class RepeatBehaviorType + { + public static string GetGuidSignature() => "enum(Windows.UI.Xaml.Media.Animation.RepeatBehaviorType;i4)"; + } +} diff --git a/src/cswinrt/strings/additions/Windows.UI.Xaml.Media.Media3D/Windows.UI.Xaml.Media.Media3D.cs b/src/cswinrt/strings/additions/Windows.UI.Xaml.Media.Media3D/Windows.UI.Xaml.Media.Media3D.cs new file mode 100644 index 000000000..84e3837ff --- /dev/null +++ b/src/cswinrt/strings/additions/Windows.UI.Xaml.Media.Media3D/Windows.UI.Xaml.Media.Media3D.cs @@ -0,0 +1,711 @@ + +namespace Windows.UI.Xaml.Media.Media3D +{ + using global::Windows.Foundation; + + [global::WinRT.WindowsRuntimeType("Microsoft.UI")] + [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Windows.UI.Xaml.Media.Media3D.Matrix3D))] + [StructLayout(LayoutKind.Sequential)] +#if EMBED + internal +#else + public +#endif + struct Matrix3D : IFormattable + { + // Assuming this matrix has fourth column of 0,0,0,1 and isn't identity this function: + // Returns false if HasInverse is false, otherwise inverts the matrix. + private bool NormalizedAffineInvert() + { + double z20 = _m12 * _m23 - _m22 * _m13; + double z10 = _m32 * _m13 - _m12 * _m33; + double z00 = _m22 * _m33 - _m32 * _m23; + double det = _m31 * z20 + _m21 * z10 + _m11 * z00; + + if (IsZero(det)) + { + return false; + } + + // Compute 3x3 non-zero cofactors for the 2nd column + double z21 = _m21 * _m13 - _m11 * _m23; + double z11 = _m11 * _m33 - _m31 * _m13; + double z01 = _m31 * _m23 - _m21 * _m33; + + // Compute all six 2x2 determinants of 1st two columns + double y01 = _m11 * _m22 - _m21 * _m12; + double y02 = _m11 * _m32 - _m31 * _m12; + double y03 = _m11 * _offsetY - _offsetX * _m12; + double y12 = _m21 * _m32 - _m31 * _m22; + double y13 = _m21 * _offsetY - _offsetX * _m22; + double y23 = _m31 * _offsetY - _offsetX * _m32; + + // Compute all non-zero and non-one 3x3 cofactors for 2nd + // two columns + double z23 = _m23 * y03 - _offsetZ * y01 - _m13 * y13; + double z13 = _m13 * y23 - _m33 * y03 + _offsetZ * y02; + double z03 = _m33 * y13 - _offsetZ * y12 - _m23 * y23; + double z22 = y01; + double z12 = -y02; + double z02 = y12; + + double rcp = 1.0 / det; + + // Multiply all 3x3 cofactors by reciprocal & transpose + _m11 = (z00 * rcp); + _m12 = (z10 * rcp); + _m13 = (z20 * rcp); + + _m21 = (z01 * rcp); + _m22 = (z11 * rcp); + _m23 = (z21 * rcp); + + _m31 = (z02 * rcp); + _m32 = (z12 * rcp); + _m33 = (z22 * rcp); + + _offsetX = (z03 * rcp); + _offsetY = (z13 * rcp); + _offsetZ = (z23 * rcp); + + return true; + } + + // RETURNS true if has inverse & invert was done. Otherwise returns false & leaves matrix unchanged. + private bool InvertCore() + { + if (IsAffine) + { + return NormalizedAffineInvert(); + } + + // compute all six 2x2 determinants of 2nd two columns + double y01 = _m13 * _m24 - _m23 * _m14; + double y02 = _m13 * _m34 - _m33 * _m14; + double y03 = _m13 * _m44 - _offsetZ * _m14; + double y12 = _m23 * _m34 - _m33 * _m24; + double y13 = _m23 * _m44 - _offsetZ * _m24; + double y23 = _m33 * _m44 - _offsetZ * _m34; + + // Compute 3x3 cofactors for 1st the column + double z30 = _m22 * y02 - _m32 * y01 - _m12 * y12; + double z20 = _m12 * y13 - _m22 * y03 + _offsetY * y01; + double z10 = _m32 * y03 - _offsetY * y02 - _m12 * y23; + double z00 = _m22 * y23 - _m32 * y13 + _offsetY * y12; + + // Compute 4x4 determinant + double det = _offsetX * z30 + _m31 * z20 + _m21 * z10 + _m11 * z00; + + if (IsZero(det)) + { + return false; + } + + // Compute 3x3 cofactors for the 2nd column + double z31 = _m11 * y12 - _m21 * y02 + _m31 * y01; + double z21 = _m21 * y03 - _offsetX * y01 - _m11 * y13; + double z11 = _m11 * y23 - _m31 * y03 + _offsetX * y02; + double z01 = _m31 * y13 - _offsetX * y12 - _m21 * y23; + + // Compute all six 2x2 determinants of 1st two columns + y01 = _m11 * _m22 - _m21 * _m12; + y02 = _m11 * _m32 - _m31 * _m12; + y03 = _m11 * _offsetY - _offsetX * _m12; + y12 = _m21 * _m32 - _m31 * _m22; + y13 = _m21 * _offsetY - _offsetX * _m22; + y23 = _m31 * _offsetY - _offsetX * _m32; + + // Compute all 3x3 cofactors for 2nd two columns + double z33 = _m13 * y12 - _m23 * y02 + _m33 * y01; + double z23 = _m23 * y03 - _offsetZ * y01 - _m13 * y13; + double z13 = _m13 * y23 - _m33 * y03 + _offsetZ * y02; + double z03 = _m33 * y13 - _offsetZ * y12 - _m23 * y23; + double z32 = _m24 * y02 - _m34 * y01 - _m14 * y12; + double z22 = _m14 * y13 - _m24 * y03 + _m44 * y01; + double z12 = _m34 * y03 - _m44 * y02 - _m14 * y23; + double z02 = _m24 * y23 - _m34 * y13 + _m44 * y12; + + double rcp = 1.0 / det; + + // Multiply all 3x3 cofactors by reciprocal & transpose + _m11 = (z00 * rcp); + _m12 = (z10 * rcp); + _m13 = (z20 * rcp); + _m14 = (z30 * rcp); + + _m21 = (z01 * rcp); + _m22 = (z11 * rcp); + _m23 = (z21 * rcp); + _m24 = (z31 * rcp); + + _m31 = (z02 * rcp); + _m32 = (z12 * rcp); + _m33 = (z22 * rcp); + _m34 = (z32 * rcp); + + _offsetX = (z03 * rcp); + _offsetY = (z13 * rcp); + _offsetZ = (z23 * rcp); + _m44 = (z33 * rcp); + + return true; + } + + public Matrix3D(double m11, double m12, double m13, double m14, + double m21, double m22, double m23, double m24, + double m31, double m32, double m33, double m34, + double offsetX, double offsetY, double offsetZ, double m44) + { + _m11 = m11; + _m12 = m12; + _m13 = m13; + _m14 = m14; + _m21 = m21; + _m22 = m22; + _m23 = m23; + _m24 = m24; + _m31 = m31; + _m32 = m32; + _m33 = m33; + _m34 = m34; + _offsetX = offsetX; + _offsetY = offsetY; + _offsetZ = offsetZ; + _m44 = m44; + } + + // the transform is identity by default + // Actually fill in the fields - some (internal) code uses the fields directly for perf. + private static Matrix3D s_identity = CreateIdentity(); + + public double M11 + { + get + { + return _m11; + } + set + { + _m11 = value; + } + } + + public double M12 + { + get + { + return _m12; + } + set + { + _m12 = value; + } + } + + public double M13 + { + get + { + return _m13; + } + set + { + _m13 = value; + } + } + + public double M14 + { + get + { + return _m14; + } + set + { + _m14 = value; + } + } + + public double M21 + { + get + { + return _m21; + } + set + { + _m21 = value; + } + } + + public double M22 + { + get + { + return _m22; + } + set + { + _m22 = value; + } + } + + public double M23 + { + get + { + return _m23; + } + set + { + _m23 = value; + } + } + + public double M24 + { + get + { + return _m24; + } + set + { + _m24 = value; + } + } + + public double M31 + { + get + { + return _m31; + } + set + { + _m31 = value; + } + } + + public double M32 + { + get + { + return _m32; + } + set + { + _m32 = value; + } + } + + public double M33 + { + get + { + return _m33; + } + set + { + _m33 = value; + } + } + + public double M34 + { + get + { + return _m34; + } + set + { + _m34 = value; + } + } + + public double OffsetX + { + get + { + return _offsetX; + } + set + { + _offsetX = value; + } + } + + public double OffsetY + { + get + { + return _offsetY; + } + set + { + _offsetY = value; + } + } + + public double OffsetZ + { + get + { + return _offsetZ; + } + set + { + _offsetZ = value; + } + } + + public double M44 + { + get + { + return _m44; + } + set + { + _m44 = value; + } + } + + public static Matrix3D Identity + { + get + { + return s_identity; + } + } + + public bool IsIdentity + { + get + { + return (_m11 == 1 && _m12 == 0 && _m13 == 0 && _m14 == 0 && + _m21 == 0 && _m22 == 1 && _m23 == 0 && _m24 == 0 && + _m31 == 0 && _m32 == 0 && _m33 == 1 && _m34 == 0 && + _offsetX == 0 && _offsetY == 0 && _offsetZ == 0 && _m44 == 1); + } + } + + public override string ToString() + { + // Delegate to the internal method which implements all ToString calls. + return ConvertToString(null /* format string */, null /* format provider */); + } + + public string ToString(IFormatProvider provider) + { + // Delegate to the internal method which implements all ToString calls. + return ConvertToString(null /* format string */, provider); + } + + string IFormattable.ToString(string format, IFormatProvider provider) + { + // Delegate to the internal method which implements all ToString calls. + return ConvertToString(format, provider); + } + + private string ConvertToString(string format, IFormatProvider provider) + { + if (IsIdentity) + { + return "Identity"; + } + + // Helper to get the numeric list separator for a given culture. + char separator = TokenizerHelper.GetNumericListSeparator(provider); + return string.Format(provider, + "{1:" + format + "}{0}{2:" + format + "}{0}{3:" + format + "}{0}{4:" + format + "}{0}{5:" + format + + "}{0}{6:" + format + "}{0}{7:" + format + "}{0}{8:" + format + "}{0}{9:" + format + "}{0}{10:" + format + + "}{0}{11:" + format + "}{0}{12:" + format + "}{0}{13:" + format + "}{0}{14:" + format + "}{0}{15:" + format + "}{0}{16:" + format + "}", + separator, + _m11, _m12, _m13, _m14, + _m21, _m22, _m23, _m24, + _m31, _m32, _m33, _m34, + _offsetX, _offsetY, _offsetZ, _m44); + } + + public override int GetHashCode() + { + // Perform field-by-field XOR of HashCodes + return M11.GetHashCode() ^ + M12.GetHashCode() ^ + M13.GetHashCode() ^ + M14.GetHashCode() ^ + M21.GetHashCode() ^ + M22.GetHashCode() ^ + M23.GetHashCode() ^ + M24.GetHashCode() ^ + M31.GetHashCode() ^ + M32.GetHashCode() ^ + M33.GetHashCode() ^ + M34.GetHashCode() ^ + OffsetX.GetHashCode() ^ + OffsetY.GetHashCode() ^ + OffsetZ.GetHashCode() ^ + M44.GetHashCode(); + } + + public override bool Equals(object o) + { + return o is Matrix3D && Matrix3D.Equals(this, (Matrix3D)o); + } + + public bool Equals(Matrix3D value) + { + return Matrix3D.Equals(this, value); + } + + public static bool operator ==(Matrix3D matrix1, Matrix3D matrix2) + { + return matrix1.M11 == matrix2.M11 && + matrix1.M12 == matrix2.M12 && + matrix1.M13 == matrix2.M13 && + matrix1.M14 == matrix2.M14 && + matrix1.M21 == matrix2.M21 && + matrix1.M22 == matrix2.M22 && + matrix1.M23 == matrix2.M23 && + matrix1.M24 == matrix2.M24 && + matrix1.M31 == matrix2.M31 && + matrix1.M32 == matrix2.M32 && + matrix1.M33 == matrix2.M33 && + matrix1.M34 == matrix2.M34 && + matrix1.OffsetX == matrix2.OffsetX && + matrix1.OffsetY == matrix2.OffsetY && + matrix1.OffsetZ == matrix2.OffsetZ && + matrix1.M44 == matrix2.M44; + } + + public static bool operator !=(Matrix3D matrix1, Matrix3D matrix2) + { + return !(matrix1 == matrix2); + } + + public static Matrix3D operator *(Matrix3D matrix1, Matrix3D matrix2) + { + Matrix3D matrix3D = default; + + matrix3D.M11 = matrix1.M11 * matrix2.M11 + + matrix1.M12 * matrix2.M21 + + matrix1.M13 * matrix2.M31 + + matrix1.M14 * matrix2.OffsetX; + matrix3D.M12 = matrix1.M11 * matrix2.M12 + + matrix1.M12 * matrix2.M22 + + matrix1.M13 * matrix2.M32 + + matrix1.M14 * matrix2.OffsetY; + matrix3D.M13 = matrix1.M11 * matrix2.M13 + + matrix1.M12 * matrix2.M23 + + matrix1.M13 * matrix2.M33 + + matrix1.M14 * matrix2.OffsetZ; + matrix3D.M14 = matrix1.M11 * matrix2.M14 + + matrix1.M12 * matrix2.M24 + + matrix1.M13 * matrix2.M34 + + matrix1.M14 * matrix2.M44; + matrix3D.M21 = matrix1.M21 * matrix2.M11 + + matrix1.M22 * matrix2.M21 + + matrix1.M23 * matrix2.M31 + + matrix1.M24 * matrix2.OffsetX; + matrix3D.M22 = matrix1.M21 * matrix2.M12 + + matrix1.M22 * matrix2.M22 + + matrix1.M23 * matrix2.M32 + + matrix1.M24 * matrix2.OffsetY; + matrix3D.M23 = matrix1.M21 * matrix2.M13 + + matrix1.M22 * matrix2.M23 + + matrix1.M23 * matrix2.M33 + + matrix1.M24 * matrix2.OffsetZ; + matrix3D.M24 = matrix1.M21 * matrix2.M14 + + matrix1.M22 * matrix2.M24 + + matrix1.M23 * matrix2.M34 + + matrix1.M24 * matrix2.M44; + matrix3D.M31 = matrix1.M31 * matrix2.M11 + + matrix1.M32 * matrix2.M21 + + matrix1.M33 * matrix2.M31 + + matrix1.M34 * matrix2.OffsetX; + matrix3D.M32 = matrix1.M31 * matrix2.M12 + + matrix1.M32 * matrix2.M22 + + matrix1.M33 * matrix2.M32 + + matrix1.M34 * matrix2.OffsetY; + matrix3D.M33 = matrix1.M31 * matrix2.M13 + + matrix1.M32 * matrix2.M23 + + matrix1.M33 * matrix2.M33 + + matrix1.M34 * matrix2.OffsetZ; + matrix3D.M34 = matrix1.M31 * matrix2.M14 + + matrix1.M32 * matrix2.M24 + + matrix1.M33 * matrix2.M34 + + matrix1.M34 * matrix2.M44; + matrix3D.OffsetX = matrix1.OffsetX * matrix2.M11 + + matrix1.OffsetY * matrix2.M21 + + matrix1.OffsetZ * matrix2.M31 + + matrix1.M44 * matrix2.OffsetX; + matrix3D.OffsetY = matrix1.OffsetX * matrix2.M12 + + matrix1.OffsetY * matrix2.M22 + + matrix1.OffsetZ * matrix2.M32 + + matrix1.M44 * matrix2.OffsetY; + matrix3D.OffsetZ = matrix1.OffsetX * matrix2.M13 + + matrix1.OffsetY * matrix2.M23 + + matrix1.OffsetZ * matrix2.M33 + + matrix1.M44 * matrix2.OffsetZ; + matrix3D.M44 = matrix1.OffsetX * matrix2.M14 + + matrix1.OffsetY * matrix2.M24 + + matrix1.OffsetZ * matrix2.M34 + + matrix1.M44 * matrix2.M44; + + // matrix3D._type is not set. + + return matrix3D; + } + + public bool HasInverse + { + get + { + return !IsZero(Determinant); + } + } + + public void Invert() + { + if (!InvertCore()) + { + throw new InvalidOperationException(); + } + } + + private static Matrix3D CreateIdentity() + { + Matrix3D matrix3D = default; + matrix3D.SetMatrix(1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1); + return matrix3D; + } + + private void SetMatrix(double m11, double m12, double m13, double m14, + double m21, double m22, double m23, double m24, + double m31, double m32, double m33, double m34, + double offsetX, double offsetY, double offsetZ, double m44) + { + _m11 = m11; + _m12 = m12; + _m13 = m13; + _m14 = m14; + _m21 = m21; + _m22 = m22; + _m23 = m23; + _m24 = m24; + _m31 = m31; + _m32 = m32; + _m33 = m33; + _m34 = m34; + _offsetX = offsetX; + _offsetY = offsetY; + _offsetZ = offsetZ; + _m44 = m44; + } + + private static bool Equals(Matrix3D matrix1, Matrix3D matrix2) + { + return matrix1.M11.Equals(matrix2.M11) && + matrix1.M12.Equals(matrix2.M12) && + matrix1.M13.Equals(matrix2.M13) && + matrix1.M14.Equals(matrix2.M14) && + matrix1.M21.Equals(matrix2.M21) && + matrix1.M22.Equals(matrix2.M22) && + matrix1.M23.Equals(matrix2.M23) && + matrix1.M24.Equals(matrix2.M24) && + matrix1.M31.Equals(matrix2.M31) && + matrix1.M32.Equals(matrix2.M32) && + matrix1.M33.Equals(matrix2.M33) && + matrix1.M34.Equals(matrix2.M34) && + matrix1.OffsetX.Equals(matrix2.OffsetX) && + matrix1.OffsetY.Equals(matrix2.OffsetY) && + matrix1.OffsetZ.Equals(matrix2.OffsetZ) && + matrix1.M44.Equals(matrix2.M44); + } + + private double GetNormalizedAffineDeterminant() + { + double z20 = _m12 * _m23 - _m22 * _m13; + double z10 = _m32 * _m13 - _m12 * _m33; + double z00 = _m22 * _m33 - _m32 * _m23; + + return _m31 * z20 + _m21 * z10 + _m11 * z00; + } + + private bool IsAffine + { + get + { + return (_m14 == 0.0 && _m24 == 0.0 && _m34 == 0.0 && _m44 == 1.0); + } + } + + private double Determinant + { + get + { + if (IsAffine) + { + return GetNormalizedAffineDeterminant(); + } + + // compute all six 2x2 determinants of 2nd two columns + double y01 = _m13 * _m24 - _m23 * _m14; + double y02 = _m13 * _m34 - _m33 * _m14; + double y03 = _m13 * _m44 - _offsetZ * _m14; + double y12 = _m23 * _m34 - _m33 * _m24; + double y13 = _m23 * _m44 - _offsetZ * _m24; + double y23 = _m33 * _m44 - _offsetZ * _m34; + + // Compute 3x3 cofactors for 1st the column + double z30 = _m22 * y02 - _m32 * y01 - _m12 * y12; + double z20 = _m12 * y13 - _m22 * y03 + _offsetY * y01; + double z10 = _m32 * y03 - _offsetY * y02 - _m12 * y23; + double z00 = _m22 * y23 - _m32 * y13 + _offsetY * y12; + + return _offsetX * z30 + _m31 * z20 + _m21 * z10 + _m11 * z00; + } + } + + private static bool IsZero(double value) + { + return Math.Abs(value) < 10.0 * DBL_EPSILON_RELATIVE_1; + } + + private const double DBL_EPSILON_RELATIVE_1 = 1.1102230246251567e-016; /* smallest such that 1.0+DBL_EPSILON != 1.0 */ + + private double _m11; + private double _m12; + private double _m13; + private double _m14; + private double _m21; + private double _m22; + private double _m23; + private double _m24; + private double _m31; + private double _m32; + private double _m33; + private double _m34; + private double _offsetX; + private double _offsetY; + private double _offsetZ; + private double _m44; + } +} + +namespace ABI.Windows.UI.Xaml.Media.Media3D +{ +#if EMBED + internal +#else + public +#endif + static class Matrix3D + { + public static string GetGuidSignature() => + $"struct(Windows.UI.Xaml.Media.Media3D.Matrix3D;f8;f8;f8;f8;f8;f8;f8;f8;f8;f8;f8;f8;f8;f8;f8;f8)"; + } +} diff --git a/src/cswinrt/strings/additions/Windows.UI.Xaml.Media/Windows.UI.Xaml.Media.cs b/src/cswinrt/strings/additions/Windows.UI.Xaml.Media/Windows.UI.Xaml.Media.cs new file mode 100644 index 000000000..a731d74fb --- /dev/null +++ b/src/cswinrt/strings/additions/Windows.UI.Xaml.Media/Windows.UI.Xaml.Media.cs @@ -0,0 +1,263 @@ + +namespace Windows.UI.Xaml.Media +{ + using global::Windows.Foundation; + + [global::WinRT.WindowsRuntimeType("Microsoft.UI")] + [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Windows.UI.Xaml.Media.Matrix))] + [StructLayout(LayoutKind.Sequential)] +#if EMBED + internal +#else + public +#endif + struct Matrix : IFormattable + { + public Matrix(double m11, double m12, + double m21, double m22, + double offsetX, double offsetY) + { + _m11 = m11; + _m12 = m12; + _m21 = m21; + _m22 = m22; + _offsetX = offsetX; + _offsetY = offsetY; + } + + // the transform is identity by default + private static Matrix s_identity = CreateIdentity(); + + public double M11 + { + get + { + return _m11; + } + set + { + _m11 = value; + } + } + + public double M12 + { + get + { + return _m12; + } + set + { + _m12 = value; + } + } + + public double M21 + { + get + { + return _m21; + } + set + { + _m21 = value; + } + } + + public double M22 + { + get + { + return _m22; + } + set + { + _m22 = value; + } + } + + public double OffsetX + { + get + { + return _offsetX; + } + set + { + _offsetX = value; + } + } + + public double OffsetY + { + get + { + return _offsetY; + } + set + { + _offsetY = value; + } + } + + public static Matrix Identity + { + get + { + return s_identity; + } + } + + public bool IsIdentity + { + get + { + return (_m11 == 1 && _m12 == 0 && _m21 == 0 && _m22 == 1 && _offsetX == 0 && _offsetY == 0); + } + } + + public override string ToString() + { + // Delegate to the internal method which implements all ToString calls. + return ConvertToString(null /* format string */, null /* format provider */); + } + + public string ToString(IFormatProvider provider) + { + // Delegate to the internal method which implements all ToString calls. + return ConvertToString(null /* format string */, provider); + } + + string IFormattable.ToString(string format, IFormatProvider provider) + { + // Delegate to the internal method which implements all ToString calls. + return ConvertToString(format, provider); + } + + private string ConvertToString(string format, IFormatProvider provider) + { + if (IsIdentity) + { + return "Identity"; + } + + // Helper to get the numeric list separator for a given culture. + char separator = TokenizerHelper.GetNumericListSeparator(provider); + return string.Format(provider, + "{1:" + format + "}{0}{2:" + format + "}{0}{3:" + format + "}{0}{4:" + format + "}{0}{5:" + format + "}{0}{6:" + format + "}", + separator, + _m11, + _m12, + _m21, + _m22, + _offsetX, + _offsetY); + } + + public Point Transform(Point point) + { + float x = (float)point.X; + float y = (float)point.Y; + this.MultiplyPoint(ref x, ref y); + Point point2 = new Point(x, y); + return point2; + } + + public override int GetHashCode() + { + // Perform field-by-field XOR of HashCodes + return M11.GetHashCode() ^ + M12.GetHashCode() ^ + M21.GetHashCode() ^ + M22.GetHashCode() ^ + OffsetX.GetHashCode() ^ + OffsetY.GetHashCode(); + } + + public override bool Equals(object o) + { + return o is Matrix && Matrix.Equals(this, (Matrix)o); + } + + public bool Equals(Matrix value) + { + return Matrix.Equals(this, value); + } + + public static bool operator ==(Matrix matrix1, Matrix matrix2) + { + return matrix1.M11 == matrix2.M11 && + matrix1.M12 == matrix2.M12 && + matrix1.M21 == matrix2.M21 && + matrix1.M22 == matrix2.M22 && + matrix1.OffsetX == matrix2.OffsetX && + matrix1.OffsetY == matrix2.OffsetY; + } + + public static bool operator !=(Matrix matrix1, Matrix matrix2) + { + return !(matrix1 == matrix2); + } + + private static Matrix CreateIdentity() + { + Matrix matrix = default; + matrix.SetMatrix(1, 0, + 0, 1, + 0, 0); + return matrix; + } + + private void SetMatrix(double m11, double m12, + double m21, double m22, + double offsetX, double offsetY) + { + _m11 = m11; + _m12 = m12; + _m21 = m21; + _m22 = m22; + _offsetX = offsetX; + _offsetY = offsetY; + } + + private void MultiplyPoint(ref float x, ref float y) + { + double num = (y * _m21) + _offsetX; + double num2 = (x * _m12) + _offsetY; + x *= (float)_m11; + x += (float)num; + y *= (float)_m22; + y += (float)num2; + } + + private static bool Equals(Matrix matrix1, Matrix matrix2) + { + return matrix1.M11.Equals(matrix2.M11) && + matrix1.M12.Equals(matrix2.M12) && + matrix1.M21.Equals(matrix2.M21) && + matrix1.M22.Equals(matrix2.M22) && + matrix1.OffsetX.Equals(matrix2.OffsetX) && + matrix1.OffsetY.Equals(matrix2.OffsetY); + } + + private double _m11; + private double _m12; + private double _m21; + private double _m22; + private double _offsetX; + private double _offsetY; + } +} + +namespace ABI.Windows.UI.Xaml.Media +{ +#if EMBED + internal +#else + public +#endif + static class Matrix + { + public static string GetGuidSignature() => $"struct(Windows.UI.Xaml.Media.Matrix;f8;f8;f8;f8;f8;f8)"; + } +} diff --git a/src/cswinrt/strings/additions/Windows.UI.Xaml/Windows.UI.Xaml.SR.cs b/src/cswinrt/strings/additions/Windows.UI.Xaml/Windows.UI.Xaml.SR.cs new file mode 100644 index 000000000..cbb4596bb --- /dev/null +++ b/src/cswinrt/strings/additions/Windows.UI.Xaml/Windows.UI.Xaml.SR.cs @@ -0,0 +1,17 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace Windows.UI.Xaml +{ + static class SR + { + public static string DirectUI_CornerRadius_InvalidMember = "Invalid value for {0} property on CornerRadius."; + public static string DirectUI_InvalidArgument = "Invalid argument."; + public static string ElementNotAvailable_Default = "The element is not available."; + public static string ElementNotEnabled_Default = "The element is not enabled."; + public static string XamlParse_Default = "XAML parsing failed."; + public static string LayoutCycle_Default = "A cycle occurred while laying out the GUI."; + public static string PlatformNotSupported_WindowsRuntime = "Windows Runtime (WinRT) is not supported on this platform."; + } +} diff --git a/src/cswinrt/strings/additions/Windows.UI.Xaml/Windows.UI.Xaml.cs b/src/cswinrt/strings/additions/Windows.UI.Xaml/Windows.UI.Xaml.cs new file mode 100644 index 000000000..1ec6ea03d --- /dev/null +++ b/src/cswinrt/strings/additions/Windows.UI.Xaml/Windows.UI.Xaml.cs @@ -0,0 +1,774 @@ + +namespace Windows.UI.Xaml +{ + using global::Windows.Foundation; + + [global::WinRT.WindowsRuntimeType("Microsoft.UI")] + [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Windows.UI.Xaml.CornerRadius))] + [StructLayout(LayoutKind.Sequential)] +#if EMBED + internal +#else + public +#endif + struct CornerRadius + { + private double _TopLeft; + private double _TopRight; + private double _BottomRight; + private double _BottomLeft; + + public CornerRadius(double uniformRadius) + { + Validate(uniformRadius, uniformRadius, uniformRadius, uniformRadius); + _TopLeft = _TopRight = _BottomRight = _BottomLeft = uniformRadius; + } + + public CornerRadius(double topLeft, double topRight, double bottomRight, double bottomLeft) + { + Validate(topLeft, topRight, bottomRight, bottomLeft); + + _TopLeft = topLeft; + _TopRight = topRight; + _BottomRight = bottomRight; + _BottomLeft = bottomLeft; + } + + private static void Validate(double topLeft, double topRight, double bottomRight, double bottomLeft) + { + if (topLeft < 0.0 || double.IsNaN(topLeft)) + throw new ArgumentException(string.Format(SR.DirectUI_CornerRadius_InvalidMember, "TopLeft")); + + if (topRight < 0.0 || double.IsNaN(topRight)) + throw new ArgumentException(string.Format(SR.DirectUI_CornerRadius_InvalidMember, "TopRight")); + + if (bottomRight < 0.0 || double.IsNaN(bottomRight)) + throw new ArgumentException(string.Format(SR.DirectUI_CornerRadius_InvalidMember, "BottomRight")); + + if (bottomLeft < 0.0 || double.IsNaN(bottomLeft)) + throw new ArgumentException(string.Format(SR.DirectUI_CornerRadius_InvalidMember, "BottomLeft")); + } + + public override string ToString() + { + return ToString(global::System.Globalization.CultureInfo.InvariantCulture); + } + + internal string ToString(global::System.Globalization.CultureInfo cultureInfo) + { + char listSeparator = TokenizerHelper.GetNumericListSeparator(cultureInfo); + + // Initial capacity [64] is an estimate based on a sum of: + // 48 = 4x double (twelve digits is generous for the range of values likely) + // 8 = 4x Unit Type string (approx two characters) + // 4 = 4x separator characters + global::System.Text.StringBuilder sb = new global::System.Text.StringBuilder(64); + + sb.Append(InternalToString(_TopLeft, cultureInfo)); + sb.Append(listSeparator); + sb.Append(InternalToString(_TopRight, cultureInfo)); + sb.Append(listSeparator); + sb.Append(InternalToString(_BottomRight, cultureInfo)); + sb.Append(listSeparator); + sb.Append(InternalToString(_BottomLeft, cultureInfo)); + return sb.ToString(); + } + + internal string InternalToString(double l, global::System.Globalization.CultureInfo cultureInfo) + { + if (double.IsNaN(l)) return "Auto"; + return Convert.ToString(l, cultureInfo); + } + + public override bool Equals(object obj) + { + if (obj is CornerRadius) + { + CornerRadius otherObj = (CornerRadius)obj; + return (this == otherObj); + } + return (false); + } + + public bool Equals(CornerRadius cornerRadius) + { + return (this == cornerRadius); + } + + public override int GetHashCode() + { + return _TopLeft.GetHashCode() ^ _TopRight.GetHashCode() ^ _BottomLeft.GetHashCode() ^ _BottomRight.GetHashCode(); + } + + public static bool operator ==(CornerRadius cr1, CornerRadius cr2) + { + return cr1._TopLeft == cr2._TopLeft && cr1._TopRight == cr2._TopRight && cr1._BottomRight == cr2._BottomRight && cr1._BottomLeft == cr2._BottomLeft; + } + + public static bool operator !=(CornerRadius cr1, CornerRadius cr2) + { + return (!(cr1 == cr2)); + } + + public double TopLeft + { + get { return _TopLeft; } + set + { + Validate(value, 0, 0, 0); + _TopLeft = value; + } + } + + public double TopRight + { + get { return _TopRight; } + set + { + Validate(0, value, 0, 0); + _TopRight = value; + } + } + + public double BottomRight + { + get { return _BottomRight; } + set + { + Validate(0, 0, value, 0); + _BottomRight = value; + } + } + + public double BottomLeft + { + get { return _BottomLeft; } + set + { + Validate(0, 0, 0, value); + _BottomLeft = value; + } + } + } + + [global::WinRT.WindowsRuntimeType("Microsoft.UI")] +#if EMBED + internal +#else + public +#endif + enum GridUnitType + { + Auto = 0, + Pixel, + Star, + } + + [global::WinRT.WindowsRuntimeType("Microsoft.UI")] + [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Windows.UI.Xaml.GridLength))] + [StructLayout(LayoutKind.Sequential)] +#if EMBED + internal +#else + public +#endif + struct GridLength + { + private readonly double _unitValue; + private readonly GridUnitType _unitType; + + private const double Default = 1.0; + private static readonly GridLength s_auto = new GridLength(Default, GridUnitType.Auto); + + public GridLength(double pixels) + : this(pixels, GridUnitType.Pixel) + { + } + + internal static bool IsFinite(double value) + { + return !(double.IsNaN(value) || double.IsInfinity(value)); + } + + public GridLength(double value, GridUnitType type) + { + if (!IsFinite(value) || value < 0.0) + { + throw new ArgumentException(SR.DirectUI_InvalidArgument, nameof(value)); + } + if (type != GridUnitType.Auto && type != GridUnitType.Pixel && type != GridUnitType.Star) + { + throw new ArgumentException(SR.DirectUI_InvalidArgument, nameof(type)); + } + + _unitValue = (type == GridUnitType.Auto) ? Default : value; + _unitType = type; + } + + + public double Value { get { return ((_unitType == GridUnitType.Auto) ? s_auto._unitValue : _unitValue); } } + public GridUnitType GridUnitType { get { return (_unitType); } } + + + public bool IsAbsolute { get { return (_unitType == GridUnitType.Pixel); } } + public bool IsAuto { get { return (_unitType == GridUnitType.Auto); } } + public bool IsStar { get { return (_unitType == GridUnitType.Star); } } + + public static GridLength Auto + { + get { return (s_auto); } + } + + + public static bool operator ==(GridLength gl1, GridLength gl2) + { + return (gl1.GridUnitType == gl2.GridUnitType + && gl1.Value == gl2.Value); + } + + public static bool operator !=(GridLength gl1, GridLength gl2) + { + return (gl1.GridUnitType != gl2.GridUnitType + || gl1.Value != gl2.Value); + } + + public override bool Equals(object oCompare) + { + if (oCompare is GridLength) + { + GridLength l = (GridLength)oCompare; + return (this == l); + } + else + return false; + } + + public bool Equals(GridLength gridLength) + { + return (this == gridLength); + } + + public override int GetHashCode() + { + return ((int)_unitValue + (int)_unitType); + } + + public override string ToString() + { + return this.ToString(global::System.Globalization.CultureInfo.InvariantCulture); + } + + internal string ToString(global::System.Globalization.CultureInfo cultureInfo) + { + char listSeparator = TokenizerHelper.GetNumericListSeparator(cultureInfo); + + // Initial capacity [64] is an estimate based on a sum of: + // 12 = 1x double (twelve digits is generous for the range of values likely) + // 8 = 4x Unit Type string (approx two characters) + // 2 = 2x separator characters + + if (_unitType == GridUnitType.Auto) + { + return "Auto"; + } + else if (_unitType == GridUnitType.Pixel) + { + return Convert.ToString(_unitValue, cultureInfo); + } + else + { + return Convert.ToString(_unitValue, cultureInfo) + "*"; + } + } + } + + [global::WinRT.WindowsRuntimeType("Microsoft.UI")] + [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Windows.UI.Xaml.Thickness))] + [StructLayout(LayoutKind.Sequential)] +#if EMBED + internal +#else + public +#endif + struct Thickness + { + private double _Left; + private double _Top; + private double _Right; + private double _Bottom; + + public Thickness(double uniformLength) + { + _Left = _Top = _Right = _Bottom = uniformLength; + } + + public Thickness(double left, double top, double right, double bottom) + { + _Left = left; + _Top = top; + _Right = right; + _Bottom = bottom; + } + + public double Left + { + get { return _Left; } + set { _Left = value; } + } + + public double Top + { + get { return _Top; } + set { _Top = value; } + } + + public double Right + { + get { return _Right; } + set { _Right = value; } + } + + public double Bottom + { + get { return _Bottom; } + set { _Bottom = value; } + } + + public override string ToString() + { + return ToString(global::System.Globalization.CultureInfo.InvariantCulture); + } + + internal string ToString(global::System.Globalization.CultureInfo cultureInfo) + { + char listSeparator = TokenizerHelper.GetNumericListSeparator(cultureInfo); + + // Initial capacity [64] is an estimate based on a sum of: + // 48 = 4x double (twelve digits is generous for the range of values likely) + // 8 = 4x Unit Type string (approx two characters) + // 4 = 4x separator characters + global::System.Text.StringBuilder sb = new global::System.Text.StringBuilder(64); + + sb.Append(InternalToString(_Left, cultureInfo)); + sb.Append(listSeparator); + sb.Append(InternalToString(_Top, cultureInfo)); + sb.Append(listSeparator); + sb.Append(InternalToString(_Right, cultureInfo)); + sb.Append(listSeparator); + sb.Append(InternalToString(_Bottom, cultureInfo)); + return sb.ToString(); + } + + internal string InternalToString(double l, global::System.Globalization.CultureInfo cultureInfo) + { + if (double.IsNaN(l)) return "Auto"; + return Convert.ToString(l, cultureInfo); + } + + public override bool Equals(object obj) + { + if (obj is Thickness) + { + Thickness otherObj = (Thickness)obj; + return (this == otherObj); + } + return (false); + } + + public bool Equals(Thickness thickness) + { + return (this == thickness); + } + + public override int GetHashCode() + { + return _Left.GetHashCode() ^ _Top.GetHashCode() ^ _Right.GetHashCode() ^ _Bottom.GetHashCode(); + } + + public static bool operator ==(Thickness t1, Thickness t2) + { + return t1._Left == t2._Left && t1._Top == t2._Top && t1._Right == t2._Right && t1._Bottom == t2._Bottom; + } + + public static bool operator !=(Thickness t1, Thickness t2) + { + return (!(t1 == t2)); + } + } + + [global::WinRT.WindowsRuntimeType("Microsoft.UI")] +#if EMBED + internal +#else + public +#endif + enum DurationType + { + Automatic, + TimeSpan, + Forever + } + + [global::WinRT.WindowsRuntimeType("Microsoft.UI")] + [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Windows.UI.Xaml.Duration))] + [StructLayout(LayoutKind.Sequential)] +#if EMBED + internal +#else + public +#endif + struct Duration + { + private readonly TimeSpan _timeSpan; + private DurationType _durationType; + + public Duration(TimeSpan timeSpan) + { + _durationType = DurationType.TimeSpan; + _timeSpan = timeSpan; + } + + public static implicit operator Duration(TimeSpan timeSpan) + { + return new Duration(timeSpan); + } + + public static Duration operator +(Duration t1, Duration t2) + { + if (t1.HasTimeSpan && t2.HasTimeSpan) + { + return new Duration(t1._timeSpan + t2._timeSpan); + } + else if (t1._durationType != DurationType.Automatic && t2._durationType != DurationType.Automatic) + { + return Duration.Forever; + } + else + { + // Automatic + anything is Automatic + return Duration.Automatic; + } + } + + public static Duration operator -(Duration t1, Duration t2) + { + if (t1.HasTimeSpan && t2.HasTimeSpan) + { + return new Duration(t1._timeSpan - t2._timeSpan); + } + else if (t1._durationType == DurationType.Forever && t2.HasTimeSpan) + { + return Duration.Forever; + } + else + { + return Duration.Automatic; + } + } + + public static bool operator ==(Duration t1, Duration t2) + { + return t1.Equals(t2); + } + + public static bool operator !=(Duration t1, Duration t2) + { + return !(t1.Equals(t2)); + } + + public static bool operator >(Duration t1, Duration t2) + { + if (t1.HasTimeSpan && t2.HasTimeSpan) + { + return t1._timeSpan > t2._timeSpan; + } + else if (t1.HasTimeSpan && t2._durationType == DurationType.Forever) + { + return false; + } + else if (t1._durationType == DurationType.Forever && t2.HasTimeSpan) + { + return true; + } + else + { + return false; + } + } + + public static bool operator >=(Duration t1, Duration t2) + { + if (t1._durationType == DurationType.Automatic && t2._durationType == DurationType.Automatic) + { + return true; + } + else if (t1._durationType == DurationType.Automatic || t2._durationType == DurationType.Automatic) + { + return false; + } + else + { + return !(t1 < t2); + } + } + + public static bool operator <(Duration t1, Duration t2) + { + if (t1.HasTimeSpan && t2.HasTimeSpan) + { + return t1._timeSpan < t2._timeSpan; + } + else if (t1.HasTimeSpan && t2._durationType == DurationType.Forever) + { + return true; + } + else if (t1._durationType == DurationType.Forever && t2.HasTimeSpan) + { + return false; + } + else + { + return false; + } + } + + public static bool operator <=(Duration t1, Duration t2) + { + if (t1._durationType == DurationType.Automatic && t2._durationType == DurationType.Automatic) + { + return true; + } + else if (t1._durationType == DurationType.Automatic || t2._durationType == DurationType.Automatic) + { + return false; + } + else + { + return !(t1 > t2); + } + } + + public static int Compare(Duration t1, Duration t2) + { + if (t1._durationType == DurationType.Automatic) + { + if (t2._durationType == DurationType.Automatic) + { + return 0; + } + else + { + return -1; + } + } + else if (t2._durationType == DurationType.Automatic) + { + return 1; + } + else + { + if (t1 < t2) + { + return -1; + } + else if (t1 > t2) + { + return 1; + } + else + { + return 0; + } + } + } + + public static Duration operator +(Duration duration) + { + return duration; + } + + public bool HasTimeSpan + { + get + { + return _durationType == DurationType.TimeSpan; + } + } + + public static Duration Automatic + { + get + { + Duration duration = default; + duration._durationType = DurationType.Automatic; + + return duration; + } + } + + public static Duration Forever + { + get + { + Duration duration = default; + duration._durationType = DurationType.Forever; + + return duration; + } + } + + public TimeSpan TimeSpan + { + get + { + if (HasTimeSpan) + { + return _timeSpan; + } + else + { + throw new InvalidOperationException(); + } + } + } + + public Duration Add(Duration duration) + { + return this + duration; + } + + public override bool Equals(object value) + { + return value is Duration && Equals((Duration)value); + } + + public bool Equals(Duration duration) + { + if (HasTimeSpan) + { + if (duration.HasTimeSpan) + { + return _timeSpan == duration._timeSpan; + } + else + { + return false; + } + } + else + { + return _durationType == duration._durationType; + } + } + + public static bool Equals(Duration t1, Duration t2) + { + return t1.Equals(t2); + } + + public override int GetHashCode() + { + if (HasTimeSpan) + { + return _timeSpan.GetHashCode(); + } + else + { + return _durationType.GetHashCode() + 17; + } + } + + public Duration Subtract(Duration duration) + { + return this - duration; + } + + public override string ToString() + { + if (HasTimeSpan) + { + return _timeSpan.ToString(); // "00"; //TypeDescriptor.GetConverter(_timeSpan).ConvertToString(_timeSpan); + } + else if (_durationType == DurationType.Forever) + { + return "Forever"; + } + else // IsAutomatic + { + return "Automatic"; + } + } + } +} + +namespace ABI.Windows.UI.Xaml +{ +#if EMBED + internal +#else + public +#endif + static class CornerRadius + { + public static string GetGuidSignature() => $"struct(Windows.UI.Xaml.CornerRadius;f8;f8;f8;f8)"; + } + +#if EMBED + internal +#else + public +#endif + static class Duration + { + public static string GetGuidSignature() + { + string timeSpanSignature = global::WinRT.GuidGenerator.GetSignature(typeof(global::System.TimeSpan)); + string durationTypeSignature = global::WinRT.GuidGenerator.GetSignature(typeof(global::Windows.UI.Xaml.DurationType)); + return $"struct(Windows.UI.Xaml.Duration;{timeSpanSignature};{durationTypeSignature})"; + } + } + +#if EMBED + internal +#else + public +#endif + static class DurationType + { + public static string GetGuidSignature() => "enum(Windows.UI.Xaml.DurationType;i4)"; + } + +#if EMBED + internal +#else + public +#endif + static class GridLength + { + public static string GetGuidSignature() + { + string unitTypeSignature = global::WinRT.GuidGenerator.GetSignature(typeof(global::Windows.UI.Xaml.GridUnitType)); + return $"struct(Windows.UI.Xaml.GridLength;f8;{unitTypeSignature})"; + } + } + +#if EMBED + internal +#else + public +#endif + static class GridUnitType + { + public static string GetGuidSignature() => "enum(Windows.UI.Xaml.GridUnitType;i4)"; + } + +#if EMBED + internal +#else + public +#endif + static class Thickness + { + public static string GetGuidSignature() => $"struct(Windows.UI.Xaml.Thickness;f8;f8;f8;f8)"; + } +} From 0d84261cf005d671ac08511e4c4d1b5274e56065 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Fri, 15 Dec 2023 15:47:23 -0800 Subject: [PATCH 02/46] Implement the base TODO-WuxMux items that must be completed to support a runtime configuration WUX/MUX switch. --- .../WinRT.SourceGenerator/AotOptimizer.cs | 91 +- .../WinRT.SourceGenerator/DiagnosticUtils.cs | 9 +- .../WinRT.SourceGenerator/Generator.cs | 6 +- src/Authoring/WinRT.SourceGenerator/Helper.cs | 82 +- .../WinRT.SourceGenerator/TypeMapper.cs | 125 + .../WinRT.SourceGenerator/UiXamlMode.cs | 26 + .../WinRT.SourceGenerator/WinRTTypeWriter.cs | 36 +- src/Perf/IIDOptimizer/GuidPatcher.cs | 9 +- src/Perf/IIDOptimizer/SignatureGenerator.cs | 30 +- src/WinRT.Runtime/GuidGenerator.cs | 7 +- .../WuxMuxProjectedInterfaceAttribute.cs | 15 + src/WinRT.Runtime/Projections.cs | 35 +- .../Projections/Bindable.net5.cs | 2009 ++++++++--------- .../Projections/ICommand.net5.cs | 1 + .../ICustomPropertyProvider.net5.cs | 2 + .../Projections/IEnumerable.net5.cs | 7 +- .../INotifyCollectionChanged.net5.cs | 15 +- .../INotifyPropertyChanged.net5.cs | 15 +- .../Microsoft.UI.Xaml.Bindable.net5.cs | 367 +++ ...rosoft.UI.Xaml.Bindable.netstandard2.0.cs} | 0 .../NotifyCollectionChangedAction.cs | 7 +- .../NotifyCollectionChangedEventArgs.cs | 639 +++--- .../NotifyCollectionChangedEventHandler.cs | 6 +- .../Projections/PropertyChangedEventArgs.cs | 98 +- .../PropertyChangedEventHandler.cs | 5 +- .../Windows.UI.Xaml.Bindable.net5.cs | 367 +++ src/cswinrt/cswinrt.vcxproj.filters | 33 + src/cswinrt/helpers.h | 2 +- .../Windows.UI.Xaml.Controls.Primitives.cs | 2 +- .../Windows.UI.Xaml.Media.Animation.cs | 6 +- .../Windows.UI.Xaml.Media.Media3D.cs | 2 +- .../Windows.UI.Xaml.Media.cs | 2 +- .../Windows.UI.Xaml/Windows.UI.Xaml.cs | 12 +- 33 files changed, 2509 insertions(+), 1559 deletions(-) create mode 100644 src/Authoring/WinRT.SourceGenerator/TypeMapper.cs create mode 100644 src/Authoring/WinRT.SourceGenerator/UiXamlMode.cs create mode 100644 src/WinRT.Runtime/Interop/WuxMuxProjectedInterfaceAttribute.cs create mode 100644 src/WinRT.Runtime/Projections/Microsoft.UI.Xaml.Bindable.net5.cs rename src/WinRT.Runtime/Projections/{Bindable.netstandard2.0.cs => Microsoft.UI.Xaml.Bindable.netstandard2.0.cs} (100%) create mode 100644 src/WinRT.Runtime/Projections/Windows.UI.Xaml.Bindable.net5.cs diff --git a/src/Authoring/WinRT.SourceGenerator/AotOptimizer.cs b/src/Authoring/WinRT.SourceGenerator/AotOptimizer.cs index bba863fb5..085a9e255 100644 --- a/src/Authoring/WinRT.SourceGenerator/AotOptimizer.cs +++ b/src/Authoring/WinRT.SourceGenerator/AotOptimizer.cs @@ -20,17 +20,28 @@ public void Initialize(IncrementalGeneratorInitializationContext context) { var properties = context.AnalyzerConfigOptionsProvider.Select(static (provider, _) => (provider.IsCsWinRTAotOptimizerEnabled(), provider.IsCsWinRTComponent())); - var vtableAttributesToAdd = context.SyntaxProvider.CreateSyntaxProvider( + var typeMapper = context.AnalyzerConfigOptionsProvider.Select((options, ct) => options.GlobalOptions.GetUiXamlMode()).Select((mode, ct) => new TypeMapper(mode)); + + var possibleVtableAttributesToAdd = context.SyntaxProvider.CreateSyntaxProvider( static (n, _) => NeedVtableAttribute(n), - static (n, _) => GetVtableAttributeToAdd(n) - ).Where(vtableAttribute => vtableAttribute != null); + static (n, _) => n + ); + + var vtableAttributesToAdd = possibleVtableAttributesToAdd + .Combine(typeMapper) + .Select((data, ct) => GetVtableAttributeToAdd(data.Left, data.Right)) + .Where(n => n is not null); context.RegisterImplementationSourceOutput(vtableAttributesToAdd.Collect().Combine(properties), GenerateVtableAttributes); - var vtablesToAddOnLookupTable = context.SyntaxProvider.CreateSyntaxProvider( + var possibleVtablesToAddOnLookupTable = context.SyntaxProvider.CreateSyntaxProvider( static (n, _) => NeedVtableOnLookupTable(n), - static (n, _) => GetVtableAttributesToAddOnLookupTable(n) - ).Where(vtableAttribute => vtableAttribute != null); + static (n, _) => n); + + var vtablesToAddOnLookupTable = possibleVtablesToAddOnLookupTable + .Combine(typeMapper) + .Select((data, ct) => GetVtableAttributesToAddOnLookupTable(data.Left, data.Right)) + .Where(vtableAttribute => vtableAttribute != null); var genericInterfacesFromVtableAttribute = vtableAttributesToAdd.SelectMany(static (vtableAttribute, _) => vtableAttribute.GenericInterfaces).Collect(); var genericInterfacesFromVtableLookupTable = vtablesToAddOnLookupTable.SelectMany(static (vtable, _) => vtable.SelectMany(v => v.GenericInterfaces)).Collect(); @@ -52,10 +63,10 @@ private static bool NeedVtableAttribute(SyntaxNode node) !GeneratorHelper.IsWinRTType(declaration); // Making sure it isn't an RCW we are projecting. } - private static VtableAttribute GetVtableAttributeToAdd(GeneratorSyntaxContext context) + private static VtableAttribute GetVtableAttributeToAdd(GeneratorSyntaxContext context, TypeMapper typeMapper) { var symbol = context.SemanticModel.GetDeclaredSymbol(context.Node as ClassDeclarationSyntax); - return GetVtableAttributeToAdd(symbol, GeneratorHelper.IsWinRTType, context.SemanticModel.Compilation.Assembly, false); + return GetVtableAttributeToAdd(symbol, GeneratorHelper.IsWinRTType, typeMapper, context.SemanticModel.Compilation.Assembly, false); } private static string ToFullyQualifiedString(ISymbol symbol) @@ -88,7 +99,7 @@ private static string ToVtableLookupString(ISymbol symbol) } } - internal static VtableAttribute GetVtableAttributeToAdd(ITypeSymbol symbol, Func isWinRTType, IAssemblySymbol assemblySymbol, bool isAuthoring, string authoringDefaultInterface = "") + internal static VtableAttribute GetVtableAttributeToAdd(ITypeSymbol symbol, Func isWinRTType, TypeMapper mapper, IAssemblySymbol assemblySymbol, bool isAuthoring, string authoringDefaultInterface = "") { if (GeneratorHelper.HasNonInstantiatedGeneric(symbol) || GeneratorHelper.HasPrivateclass(symbol)) { @@ -105,13 +116,13 @@ internal static VtableAttribute GetVtableAttributeToAdd(ITypeSymbol symbol, Func foreach (var iface in symbol.AllInterfaces) { - if (isWinRTType(iface)) + if (isWinRTType(iface, mapper)) { interfacesToAddToVtable.Add(ToFullyQualifiedString(iface)); AddGenericInterfaceInstantiation(iface); } - if (iface.IsGenericType && TryGetCompatibleWindowsRuntimeTypesForVariantType(iface, null, isWinRTType, out var compatibleIfaces)) + if (iface.IsGenericType && TryGetCompatibleWindowsRuntimeTypesForVariantType(iface, mapper, null, isWinRTType, out var compatibleIfaces)) { foreach (var compatibleIface in compatibleIfaces) { @@ -181,7 +192,7 @@ void AddGenericInterfaceInstantiation(INamedTypeSymbol iface) genericParameters.Add(new GenericParameter( ToFullyQualifiedString(genericParameter), - GeneratorHelper.GetAbiType(genericParameter), + GeneratorHelper.GetAbiType(genericParameter, mapper), genericParameter.TypeKind)); } @@ -199,7 +210,7 @@ bool IsExternalInternalInterface(INamedTypeSymbol iface) } } - private static bool TryGetCompatibleWindowsRuntimeTypesForVariantType(INamedTypeSymbol type, Stack typeStack, Func isWinRTType, out IList compatibleTypes) + private static bool TryGetCompatibleWindowsRuntimeTypesForVariantType(INamedTypeSymbol type, TypeMapper mapper, Stack typeStack, Func isWinRTType, out IList compatibleTypes) { compatibleTypes = null; @@ -212,7 +223,7 @@ private static bool TryGetCompatibleWindowsRuntimeTypesForVariantType(INamedType } var definition = type.OriginalDefinition; - if (!isWinRTType(definition)) + if (!isWinRTType(definition, mapper)) { return false; } @@ -232,20 +243,20 @@ private static bool TryGetCompatibleWindowsRuntimeTypesForVariantType(INamedType HashSet compatibleTypesForGeneric = new(SymbolEqualityComparer.Default); - if (isWinRTType(type.TypeArguments[0])) + if (isWinRTType(type.TypeArguments[0], mapper)) { compatibleTypesForGeneric.Add(type.TypeArguments[0]); } foreach (var iface in type.TypeArguments[0].AllInterfaces) { - if (isWinRTType(iface)) + if (isWinRTType(iface, mapper)) { compatibleTypesForGeneric.Add(iface); } if (iface.IsGenericType - && TryGetCompatibleWindowsRuntimeTypesForVariantType(iface, typeStack, isWinRTType, out var compatibleIfaces)) + && TryGetCompatibleWindowsRuntimeTypesForVariantType(iface, mapper, typeStack, isWinRTType, out var compatibleIfaces)) { compatibleTypesForGeneric.UnionWith(compatibleIfaces); } @@ -254,7 +265,7 @@ private static bool TryGetCompatibleWindowsRuntimeTypesForVariantType(INamedType var baseType = type.TypeArguments[0].BaseType; while (baseType != null) { - if (isWinRTType(baseType)) + if (isWinRTType(baseType, mapper)) { compatibleTypesForGeneric.Add(baseType); } @@ -489,7 +500,7 @@ private static bool NeedVtableOnLookupTable(SyntaxNode node) node is AssignmentExpressionSyntax; } - private static List GetVtableAttributesToAddOnLookupTable(GeneratorSyntaxContext context) + private static List GetVtableAttributesToAddOnLookupTable(GeneratorSyntaxContext context, TypeMapper mapper) { HashSet vtableAttributes = new(); @@ -497,7 +508,7 @@ private static List GetVtableAttributesToAddOnLookupTable(Gener { var invocationSymbol = context.SemanticModel.GetSymbolInfo(invocation.Expression).Symbol; // Check if function is within a CsWinRT projected class or interface. - if (invocationSymbol is IMethodSymbol methodSymbol && GeneratorHelper.IsWinRTType(methodSymbol.ContainingSymbol)) + if (invocationSymbol is IMethodSymbol methodSymbol && GeneratorHelper.IsWinRTType(methodSymbol.ContainingSymbol, mapper)) { // Get the concrete types directly from the argument rather than // using what the method accepts, which might just be an interface, so @@ -516,14 +527,14 @@ private static List GetVtableAttributesToAddOnLookupTable(Gener { if (methodSymbol.Parameters[paramsIdx].Type is not IArrayTypeSymbol) { - var vtableAtribute = GetVtableAttributeToAdd(arrayType, GeneratorHelper.IsWinRTType, context.SemanticModel.Compilation.Assembly, false); + var vtableAtribute = GetVtableAttributeToAdd(arrayType, GeneratorHelper.IsWinRTType, mapper, context.SemanticModel.Compilation.Assembly, false); if (vtableAtribute != default) { vtableAttributes.Add(vtableAtribute); } // Also add the enumerator type to the lookup table as the native caller may call it. - AddEnumeratorAdapterForType(arrayType.ElementType, context.SemanticModel, vtableAttributes); + AddEnumeratorAdapterForType(arrayType.ElementType, mapper, context.SemanticModel, vtableAttributes); } } else if (argumentType.Type is not null) @@ -538,11 +549,11 @@ private static List GetVtableAttributesToAddOnLookupTable(Gener // information is available. if (argumentClassTypeSymbol.TypeKind == TypeKind.Delegate && argumentClassTypeSymbol.MetadataName.Contains("`") && - GeneratorHelper.IsWinRTType(argumentClassTypeSymbol) && + GeneratorHelper.IsWinRTType(argumentClassTypeSymbol, mapper) && methodSymbol.Parameters[paramsIdx].Type.SpecialType == SpecialType.System_Object) { var argumentClassNamedTypeSymbol = argumentClassTypeSymbol as INamedTypeSymbol; - vtableAttributes.Add(GetVtableAttributeToAdd(argumentClassTypeSymbol, GeneratorHelper.IsWinRTType, context.SemanticModel.Compilation.Assembly, false)); + vtableAttributes.Add(GetVtableAttributeToAdd(argumentClassTypeSymbol, GeneratorHelper.IsWinRTType, mapper, context.SemanticModel.Compilation.Assembly, false)); } // This handles the case where the source generator wasn't able to run @@ -555,19 +566,19 @@ private static List GetVtableAttributesToAddOnLookupTable(Gener // we handle it here. if (argumentClassTypeSymbol.TypeKind == TypeKind.Class && (argumentClassTypeSymbol.MetadataName.Contains("`") || - (!GeneratorHelper.IsWinRTType(argumentClassTypeSymbol) && + (!GeneratorHelper.IsWinRTType(argumentClassTypeSymbol, mapper) && !GeneratorHelper.HasWinRTExposedTypeAttribute(argumentClassTypeSymbol) && // If the type is defined in the same assembly as what the source generator is running on, // we let the WinRTExposedType attribute generator handle it. !SymbolEqualityComparer.Default.Equals(argumentClassTypeSymbol.ContainingAssembly, context.SemanticModel.Compilation.Assembly)))) { - var vtableAtribute = GetVtableAttributeToAdd(argumentClassTypeSymbol, GeneratorHelper.IsWinRTType, context.SemanticModel.Compilation.Assembly, false); + var vtableAtribute = GetVtableAttributeToAdd(argumentClassTypeSymbol, GeneratorHelper.IsWinRTType, mapper, context.SemanticModel.Compilation.Assembly, false); if (vtableAtribute != default) { vtableAttributes.Add(vtableAtribute); } - AddEnumeratorAdapterForEnumerableInterface(argumentClassTypeSymbol, context.SemanticModel, vtableAttributes); + AddEnumeratorAdapterForEnumerableInterface(argumentClassTypeSymbol, mapper, context.SemanticModel, vtableAttributes); } } } @@ -588,7 +599,7 @@ private static List GetVtableAttributesToAddOnLookupTable(Gener // Check if property being assigned to is within a CsWinRT projected class or interface. if (leftSymbol is IPropertySymbol propertySymbol && - GeneratorHelper.IsWinRTType(propertySymbol.ContainingSymbol)) + GeneratorHelper.IsWinRTType(propertySymbol.ContainingSymbol, mapper)) { var argumentType = context.SemanticModel.GetTypeInfo(assignment.Right); @@ -599,14 +610,14 @@ private static List GetVtableAttributesToAddOnLookupTable(Gener { if (propertySymbol.Type is not IArrayTypeSymbol) { - var vtableAtribute = GetVtableAttributeToAdd(arrayType, GeneratorHelper.IsWinRTType, context.SemanticModel.Compilation.Assembly, false); + var vtableAtribute = GetVtableAttributeToAdd(arrayType, GeneratorHelper.IsWinRTType, mapper, context.SemanticModel.Compilation.Assembly, false); if (vtableAtribute != default) { vtableAttributes.Add(vtableAtribute); } // Also add the enumerator type to the lookup table as the native caller can call it. - AddEnumeratorAdapterForType(arrayType.ElementType, context.SemanticModel, vtableAttributes); + AddEnumeratorAdapterForType(arrayType.ElementType, mapper, context.SemanticModel, vtableAttributes); } } else if (argumentType.Type is not null || argumentType.ConvertedType is not null) @@ -621,28 +632,28 @@ private static List GetVtableAttributesToAddOnLookupTable(Gener // assignment to object, it is not known, and that is handled here. if (argumentClassTypeSymbol.TypeKind == TypeKind.Delegate && argumentClassTypeSymbol.MetadataName.Contains("`") && - GeneratorHelper.IsWinRTType(argumentClassTypeSymbol) && + GeneratorHelper.IsWinRTType(argumentClassTypeSymbol, mapper) && propertySymbol.Type.SpecialType == SpecialType.System_Object) { var argumentClassNamedTypeSymbol = argumentClassTypeSymbol as INamedTypeSymbol; - vtableAttributes.Add(GetVtableAttributeToAdd(argumentClassTypeSymbol, GeneratorHelper.IsWinRTType, context.SemanticModel.Compilation.Assembly, false)); + vtableAttributes.Add(GetVtableAttributeToAdd(argumentClassTypeSymbol, GeneratorHelper.IsWinRTType, mapper, context.SemanticModel.Compilation.Assembly, false)); } if (argumentClassTypeSymbol.TypeKind == TypeKind.Class && (argumentClassTypeSymbol.MetadataName.Contains("`") || - (!GeneratorHelper.IsWinRTType(argumentClassTypeSymbol) && + (!GeneratorHelper.IsWinRTType(argumentClassTypeSymbol, mapper) && !GeneratorHelper.HasWinRTExposedTypeAttribute(argumentClassTypeSymbol) && // If the type is defined in the same assembly as what the source generator is running on, // we let the WinRTExposedType attribute generator handle it. !SymbolEqualityComparer.Default.Equals(argumentClassTypeSymbol.ContainingAssembly, context.SemanticModel.Compilation.Assembly)))) { - var vtableAtribute = GetVtableAttributeToAdd(argumentClassTypeSymbol, GeneratorHelper.IsWinRTType, context.SemanticModel.Compilation.Assembly, false); + var vtableAtribute = GetVtableAttributeToAdd(argumentClassTypeSymbol, GeneratorHelper.IsWinRTType, mapper, context.SemanticModel.Compilation.Assembly, false); if (vtableAtribute != default) { vtableAttributes.Add(vtableAtribute); } - AddEnumeratorAdapterForEnumerableInterface(argumentClassTypeSymbol, context.SemanticModel, vtableAttributes); + AddEnumeratorAdapterForEnumerableInterface(argumentClassTypeSymbol, mapper, context.SemanticModel, vtableAttributes); } } } @@ -654,11 +665,11 @@ private static List GetVtableAttributesToAddOnLookupTable(Gener // Any of the IEnumerable interfaces on the vtable can be used to get the enumerator. Given IEnumerable is // a covariant interface, it means that we can end up getting an instance of the enumerable adapter for any one // of those covariant interfaces and thereby need vtable lookup entries for all of them. - private static void AddEnumeratorAdapterForType(ITypeSymbol type, SemanticModel semanticModel, HashSet vtableAttributes) + private static void AddEnumeratorAdapterForType(ITypeSymbol type, TypeMapper mapper, SemanticModel semanticModel, HashSet vtableAttributes) { var enumerableType = semanticModel.Compilation.GetTypeByMetadataName("System.Collections.Generic.IEnumerable`1"). Construct(type); - if (TryGetCompatibleWindowsRuntimeTypesForVariantType(enumerableType, null, GeneratorHelper.IsWinRTType, out var compatibleIfaces)) + if (TryGetCompatibleWindowsRuntimeTypesForVariantType(enumerableType, mapper, null, GeneratorHelper.IsWinRTType, out var compatibleIfaces)) { foreach (var compatibleIface in compatibleIfaces) { @@ -667,20 +678,20 @@ private static void AddEnumeratorAdapterForType(ITypeSymbol type, SemanticModel { var enumeratorAdapterType = semanticModel.Compilation.GetTypeByMetadataName("ABI.System.Collections.Generic.ToAbiEnumeratorAdapter`1"). Construct(compatibleIface.TypeArguments[0]); - vtableAttributes.Add(GetVtableAttributeToAdd(enumeratorAdapterType, GeneratorHelper.IsWinRTType, semanticModel.Compilation.Assembly, false)); + vtableAttributes.Add(GetVtableAttributeToAdd(enumeratorAdapterType, GeneratorHelper.IsWinRTType, mapper, semanticModel.Compilation.Assembly, false)); } } } } - private static void AddEnumeratorAdapterForEnumerableInterface(ITypeSymbol classType, SemanticModel semanticModel, HashSet vtableAttributes) + private static void AddEnumeratorAdapterForEnumerableInterface(ITypeSymbol classType, TypeMapper mapper, SemanticModel semanticModel, HashSet vtableAttributes) { // Type may implement multiple unique IEnumerable interfaces. foreach (var iface in classType.AllInterfaces) { if (iface.MetadataName == "IEnumerable`1") { - AddEnumeratorAdapterForType(iface.TypeArguments[0], semanticModel, vtableAttributes); + AddEnumeratorAdapterForType(iface.TypeArguments[0], mapper, semanticModel, vtableAttributes); } } } diff --git a/src/Authoring/WinRT.SourceGenerator/DiagnosticUtils.cs b/src/Authoring/WinRT.SourceGenerator/DiagnosticUtils.cs index 9c2215de1..528bd1598 100644 --- a/src/Authoring/WinRT.SourceGenerator/DiagnosticUtils.cs +++ b/src/Authoring/WinRT.SourceGenerator/DiagnosticUtils.cs @@ -16,11 +16,13 @@ public WinRTComponentScanner(GeneratorExecutionContext context, string assemblyN _assemblyName = assemblyName; _context = context; _flag = false; + _typeMapper = new TypeMapper(context.AnalyzerConfigOptions.GlobalOptions.GetUiXamlMode()); } private readonly string _assemblyName; private readonly GeneratorExecutionContext _context; private bool _flag; + private readonly TypeMapper _typeMapper; public bool Found() { return _flag; } @@ -105,7 +107,7 @@ private void CheckDeclarations() var props = @class.DescendantNodes().OfType().Where(IsPublic); // filter out methods and properties that will be replaced with our custom type mappings - IgnoreCustomTypeMappings(classSymbol, ref publicMethods, ref props); + IgnoreCustomTypeMappings(classSymbol, _typeMapper, ref publicMethods, ref props); if (!classSymbol.IsSealed && !classSymbol.IsStatic) { @@ -137,7 +139,7 @@ private void CheckDeclarations() var props = @interface.DescendantNodes().OfType().Where(IsPublic); // filter out methods and properties that will be replaced with our custom type mappings - IgnoreCustomTypeMappings(interfaceSym, ref methods, ref props); + IgnoreCustomTypeMappings(interfaceSym, _typeMapper, ref methods, ref props); if (interfaceSym.IsGenericType) { @@ -206,6 +208,7 @@ private bool IsMethodImpl(IMethodSymbol m, IMethodSymbol interfaceMethod) } private void IgnoreCustomTypeMappings(INamedTypeSymbol typeSymbol, + TypeMapper typeMapper, ref IEnumerable methods, ref IEnumerable properties) { @@ -217,7 +220,7 @@ string QualifiedName(INamedTypeSymbol sym) HashSet classMethods = new(); foreach (var @interface in typeSymbol.AllInterfaces. - Where(symbol => GeneratorHelper.MappedCSharpTypes.ContainsKey(QualifiedName(symbol)) || + Where(symbol => typeMapper.HasMappingForType(QualifiedName(symbol)) || WinRTTypeWriter.ImplementedInterfacesWithoutMapping.Contains(QualifiedName(symbol)))) { foreach (var interfaceMember in @interface.GetMembers()) diff --git a/src/Authoring/WinRT.SourceGenerator/Generator.cs b/src/Authoring/WinRT.SourceGenerator/Generator.cs index 3bc10f2d2..90bb01286 100644 --- a/src/Authoring/WinRT.SourceGenerator/Generator.cs +++ b/src/Authoring/WinRT.SourceGenerator/Generator.cs @@ -20,11 +20,14 @@ public class ComponentGenerator private Logger Logger { get; } private readonly GeneratorExecutionContext context; private string tempFolder; + private readonly TypeMapper mapper; public ComponentGenerator(GeneratorExecutionContext context) { this.context = context; Logger = new Logger(context); + mapper = new(context.AnalyzerConfigOptions.GlobalOptions.GetUiXamlMode()); + // TODO-WuxMux: output a module initializer that validates the MUX/WUX projection mode to ensure that things don't get out of sync. } private string GetTempFolder(bool clearSourceFilesFromFolder = false) @@ -152,7 +155,8 @@ public void Generate() assembly, version, metadataBuilder, - Logger); + Logger, + mapper); WinRTSyntaxReceiver syntaxReceiver = (WinRTSyntaxReceiver)context.SyntaxReceiver; Logger.Log("Found " + syntaxReceiver.Declarations.Count + " types"); diff --git a/src/Authoring/WinRT.SourceGenerator/Helper.cs b/src/Authoring/WinRT.SourceGenerator/Helper.cs index 9ce98add8..a75bfe4c1 100644 --- a/src/Authoring/WinRT.SourceGenerator/Helper.cs +++ b/src/Authoring/WinRT.SourceGenerator/Helper.cs @@ -177,7 +177,7 @@ private static bool IsFundamentalType(ISymbol type) return type.ToDisplayString() == "System.Guid"; } - public static bool IsWinRTType(ISymbol type) + public static bool IsWinRTType(ISymbol type, TypeMapper mapper) { bool isProjectedType = type.GetAttributes(). Any(attribute => string.CompareOrdinal(attribute.AttributeClass.Name, "WindowsRuntimeTypeAttribute") == 0) || @@ -185,13 +185,13 @@ public static bool IsWinRTType(ISymbol type) if (!isProjectedType & type.ContainingNamespace != null) { - isProjectedType = MappedCSharpTypes.ContainsKey(string.Join(".", type.ContainingNamespace.ToDisplayString(), type.MetadataName)); + isProjectedType = mapper.HasMappingForType(string.Join(".", type.ContainingNamespace.ToDisplayString(), type.MetadataName)); } // Ensure all generic parameters are WinRT types. if (isProjectedType && type is INamedTypeSymbol namedType && namedType.IsGenericType && !namedType.IsDefinition) { - isProjectedType = namedType.TypeArguments.All(IsWinRTType); + isProjectedType = namedType.TypeArguments.All(type => IsWinRTType(type, mapper)); } return isProjectedType; } @@ -262,7 +262,7 @@ private static string GetAbiTypeForFundamentalType(ISymbol type) return type.ToDisplayString(); } - public static bool IsBlittableValueType(ITypeSymbol type) + public static bool IsBlittableValueType(ITypeSymbol type, TypeMapper typeMapper) { if (!type.IsValueType) { @@ -292,9 +292,9 @@ public static bool IsBlittableValueType(ITypeSymbol type) } string customTypeMapKey = string.Join(".", type.ContainingNamespace.ToDisplayString(), type.MetadataName); - if (MappedCSharpTypes.ContainsKey(customTypeMapKey)) + if (typeMapper.HasMappingForType(customTypeMapKey)) { - return MappedCSharpTypes[customTypeMapKey].IsBlittable(); + return typeMapper.GetMappedType(customTypeMapKey).IsBlittable(); } if (type.TypeKind == TypeKind.Enum) @@ -306,7 +306,7 @@ public static bool IsBlittableValueType(ITypeSymbol type) { foreach (var typeMember in type.GetMembers()) { - if (typeMember is IFieldSymbol field && !IsBlittableValueType(field.Type)) + if (typeMember is IFieldSymbol field && !IsBlittableValueType(field.Type, typeMapper)) { return false; } @@ -315,7 +315,7 @@ public static bool IsBlittableValueType(ITypeSymbol type) return true; } - public static string GetAbiType(ITypeSymbol type) + public static string GetAbiType(ITypeSymbol type, TypeMapper mapper) { if (IsFundamentalType(type)) { @@ -335,9 +335,9 @@ public static string GetAbiType(ITypeSymbol type) if (type.IsValueType) { string customTypeMapKey = string.Join(".", type.ContainingNamespace.ToDisplayString(), type.MetadataName); - if (MappedCSharpTypes.ContainsKey(customTypeMapKey)) + if (mapper.HasMappingForType(customTypeMapKey)) { - string prefix = MappedCSharpTypes[customTypeMapKey].IsBlittable() ? "" : "ABI."; + string prefix = mapper.GetMappedType(customTypeMapKey).IsBlittable() ? "" : "ABI."; return prefix + typeStr; } @@ -352,7 +352,7 @@ public static string GetAbiType(ITypeSymbol type) // Handling authoring scenario where Impl type has the attributes and // if the current component is the one being authored, it may not be // generated yet to check given it is the same compilation. - else if (!IsBlittableValueType(type)) + else if (!IsBlittableValueType(type, mapper)) { return "ABI." + typeStr; } @@ -698,65 +698,5 @@ public bool IsBlittable() return isValueType && isBlittable; } } - - // Based on whether System.Type is used in an attribute declaration or elsewhere, we need to choose the correct custom mapping - // as attributes don't use the TypeName mapping. - internal static (string, string, string, bool, bool) GetSystemTypeCustomMapping(ISymbol containingSymbol) - { - bool isDefinedInAttribute = - containingSymbol != null && - string.CompareOrdinal((containingSymbol as INamedTypeSymbol).BaseType?.ToString(), "System.Attribute") == 0; - return isDefinedInAttribute ? - ("System", "Type", "mscorlib", true, false) : - ("Windows.UI.Xaml.Interop", "TypeName", "Windows.Foundation.UniversalApiContract", false, true); - } - - // This should be in sync with the reverse mapping from WinRT.Runtime/Projections.cs and cswinrt/helpers.h. - // TODO-WuxMux: Update this table to respect a property the defines WUX vs MUX projections. - // Additionally, output a module initializer that validates the MUX/WUX projection mode to ensure that things don't get out of sync. - public static readonly Dictionary MappedCSharpTypes = new(StringComparer.Ordinal) - { - { "System.DateTimeOffset", new MappedType("Windows.Foundation", "DateTime", "Windows.Foundation.FoundationContract", true, false) }, - { "System.Exception", new MappedType("Windows.Foundation", "HResult", "Windows.Foundation.FoundationContract", true, false) }, - { "System.EventHandler`1", new MappedType("Windows.Foundation", "EventHandler`1", "Windows.Foundation.FoundationContract") }, - { "System.FlagsAttribute", new MappedType("System", "FlagsAttribute", "mscorlib" ) }, - { "System.IDisposable", new MappedType("Windows.Foundation", "IClosable", "Windows.Foundation.FoundationContract") }, - { "System.IServiceProvider", new MappedType("Microsoft.UI.Xaml", "IXamlServiceProvider", "Microsoft.UI") }, - { "System.Nullable`1", new MappedType("Windows.Foundation", "IReference`1", "Windows.Foundation.FoundationContract" ) }, - { "System.Object", new MappedType("System", "Object", "mscorlib" ) }, - { "System.TimeSpan", new MappedType("Windows.Foundation", "TimeSpan", "Windows.Foundation.FoundationContract", true, false) }, - { "System.Uri", new MappedType("Windows.Foundation", "Uri", "Windows.Foundation.FoundationContract") }, - { "System.ComponentModel.DataErrorsChangedEventArgs", new MappedType("Microsoft.UI.Xaml.Data", "DataErrorsChangedEventArgs", "Microsoft.UI") }, - { "System.ComponentModel.INotifyDataErrorInfo", new MappedType("Microsoft.UI.Xaml.Data", "INotifyDataErrorInfo", "Microsoft.UI") }, - { "System.ComponentModel.INotifyPropertyChanged", new MappedType("Microsoft.UI.Xaml.Data", "INotifyPropertyChanged", "Microsoft.UI") }, - { "System.ComponentModel.PropertyChangedEventArgs", new MappedType("Microsoft.UI.Xaml.Data", "PropertyChangedEventArgs", "Microsoft.UI") }, - { "System.ComponentModel.PropertyChangedEventHandler", new MappedType("Microsoft.UI.Xaml.Data", "PropertyChangedEventHandler", "Microsoft.UI") }, - { "System.Windows.Input.ICommand", new MappedType("Microsoft.UI.Xaml.Input", "ICommand", "Microsoft.UI") }, - { "System.Collections.IEnumerable", new MappedType("Microsoft.UI.Xaml.Interop", "IBindableIterable", "Microsoft.UI") }, - { "System.Collections.IList", new MappedType("Microsoft.UI.Xaml.Interop", "IBindableVector", "Microsoft.UI") }, - { "System.Collections.Specialized.INotifyCollectionChanged", new MappedType("Microsoft.UI.Xaml.Interop", "INotifyCollectionChanged", "Microsoft.UI") }, - { "System.Collections.Specialized.NotifyCollectionChangedAction", new MappedType("Microsoft.UI.Xaml.Interop", "NotifyCollectionChangedAction", "Microsoft.UI") }, - { "System.Collections.Specialized.NotifyCollectionChangedEventArgs", new MappedType("Microsoft.UI.Xaml.Interop", "NotifyCollectionChangedEventArgs", "Microsoft.UI") }, - { "System.Collections.Specialized.NotifyCollectionChangedEventHandler", new MappedType("Microsoft.UI.Xaml.Interop", "NotifyCollectionChangedEventHandler", "Microsoft.UI") }, - { "WinRT.EventRegistrationToken", new MappedType("Windows.Foundation", "EventRegistrationToken", "Windows.Foundation.FoundationContract", true, true) }, - { "System.AttributeTargets", new MappedType("Windows.Foundation.Metadata", "AttributeTargets", "Windows.Foundation.FoundationContract", true, true) }, - { "System.AttributeUsageAttribute", new MappedType("Windows.Foundation.Metadata", "AttributeUsageAttribute", "Windows.Foundation.FoundationContract") }, - { "System.Numerics.Matrix3x2", new MappedType("Windows.Foundation.Numerics", "Matrix3x2", "Windows.Foundation.FoundationContract", true, true) }, - { "System.Numerics.Matrix4x4", new MappedType("Windows.Foundation.Numerics", "Matrix4x4", "Windows.Foundation.FoundationContract", true, true) }, - { "System.Numerics.Plane", new MappedType("Windows.Foundation.Numerics", "Plane", "Windows.Foundation.FoundationContract", true, true) }, - { "System.Numerics.Quaternion", new MappedType("Windows.Foundation.Numerics", "Quaternion", "Windows.Foundation.FoundationContract", true, true) }, - { "System.Numerics.Vector2", new MappedType("Windows.Foundation.Numerics", "Vector2", "Windows.Foundation.FoundationContract", true, true) }, - { "System.Numerics.Vector3", new MappedType("Windows.Foundation.Numerics", "Vector3", "Windows.Foundation.FoundationContract", true, true) }, - { "System.Numerics.Vector4", new MappedType("Windows.Foundation.Numerics", "Vector4", "Windows.Foundation.FoundationContract", true, true) }, - { "System.Type", new MappedType(GetSystemTypeCustomMapping) }, - { "System.Collections.Generic.IEnumerable`1", new MappedType("Windows.Foundation.Collections", "IIterable`1", "Windows.Foundation.FoundationContract") }, - { "System.Collections.Generic.IEnumerator`1", new MappedType("Windows.Foundation.Collections", "IIterator`1", "Windows.Foundation.FoundationContract") }, - { "System.Collections.Generic.KeyValuePair`2", new MappedType("Windows.Foundation.Collections", "IKeyValuePair`2", "Windows.Foundation.FoundationContract") }, - { "System.Collections.Generic.IReadOnlyDictionary`2", new MappedType("Windows.Foundation.Collections", "IMapView`2", "Windows.Foundation.FoundationContract") }, - { "System.Collections.Generic.IDictionary`2", new MappedType("Windows.Foundation.Collections", "IMap`2", "Windows.Foundation.FoundationContract") }, - { "System.Collections.Generic.IReadOnlyList`1", new MappedType("Windows.Foundation.Collections", "IVectorView`1", "Windows.Foundation.FoundationContract") }, - { "System.Collections.Generic.IList`1", new MappedType("Windows.Foundation.Collections", "IVector`1", "Windows.Foundation.FoundationContract") }, - { "Windows.UI.Color", new MappedType("Windows.UI", "Color", "Windows.Foundation.UniversalApiContract", true, true) }, - }; } } diff --git a/src/Authoring/WinRT.SourceGenerator/TypeMapper.cs b/src/Authoring/WinRT.SourceGenerator/TypeMapper.cs new file mode 100644 index 000000000..e35ccc63e --- /dev/null +++ b/src/Authoring/WinRT.SourceGenerator/TypeMapper.cs @@ -0,0 +1,125 @@ +using Microsoft.CodeAnalysis; +using System; +using System.Collections.Generic; +using System.Text; +using static Generator.GeneratorHelper; + +namespace Generator +{ + internal sealed class TypeMapper + { + private readonly Dictionary typeMapping; + + // Based on whether System.Type is used in an attribute declaration or elsewhere, we need to choose the correct custom mapping + // as attributes don't use the TypeName mapping. + private static (string, string, string, bool, bool) GetSystemTypeCustomMapping(ISymbol containingSymbol) + { + bool isDefinedInAttribute = + containingSymbol != null && + string.CompareOrdinal((containingSymbol as INamedTypeSymbol).BaseType?.ToString(), "System.Attribute") == 0; + return isDefinedInAttribute ? + ("System", "Type", "mscorlib", true, false) : + ("Windows.UI.Xaml.Interop", "TypeName", "Windows.Foundation.UniversalApiContract", false, true); + } + + public TypeMapper(UiXamlMode xamlMode) + { + // This should be in sync with the reverse mapping from WinRT.Runtime/Projections.cs and cswinrt/helpers.h. + if (xamlMode == UiXamlMode.WindowsUiXaml) + { + typeMapping = new(StringComparer.Ordinal) + { + { "System.DateTimeOffset", new MappedType("Windows.Foundation", "DateTime", "Windows.Foundation.FoundationContract", true, false) }, + { "System.Exception", new MappedType("Windows.Foundation", "HResult", "Windows.Foundation.FoundationContract", true, false) }, + { "System.EventHandler`1", new MappedType("Windows.Foundation", "EventHandler`1", "Windows.Foundation.FoundationContract") }, + { "System.FlagsAttribute", new MappedType("System", "FlagsAttribute", "mscorlib" ) }, + { "System.IDisposable", new MappedType("Windows.Foundation", "IClosable", "Windows.Foundation.FoundationContract") }, + { "System.Nullable`1", new MappedType("Windows.Foundation", "IReference`1", "Windows.Foundation.FoundationContract" ) }, + { "System.Object", new MappedType("System", "Object", "mscorlib" ) }, + { "System.TimeSpan", new MappedType("Windows.Foundation", "TimeSpan", "Windows.Foundation.FoundationContract", true, false) }, + { "System.Uri", new MappedType("Windows.Foundation", "Uri", "Windows.Foundation.FoundationContract") }, + { "System.ComponentModel.INotifyPropertyChanged", new MappedType("Windows.UI.Xaml.Data", "INotifyPropertyChanged", "Windows.UI.Xaml") }, + { "System.ComponentModel.PropertyChangedEventArgs", new MappedType("Windows.UI.Xaml.Data", "PropertyChangedEventArgs", "Windows.UI.Xaml") }, + { "System.ComponentModel.PropertyChangedEventHandler", new MappedType("Windows.UI.Xaml.Data", "PropertyChangedEventHandler", "Windows.UI.Xaml") }, + { "System.Windows.Input.ICommand", new MappedType("Windows.UI.Xaml.Input", "ICommand", "Windows.UI.Xaml") }, + { "System.Collections.IEnumerable", new MappedType("Windows.UI.Xaml.Interop", "IBindableIterable", "Windows.UI.Xaml") }, + { "System.Collections.IList", new MappedType("Windows.UI.Xaml.Interop", "IBindableVector", "Windows.UI.Xaml") }, + { "System.Collections.Specialized.INotifyCollectionChanged", new MappedType("Windows.UI.Xaml.Interop", "INotifyCollectionChanged", "Windows.UI.Xaml") }, + { "System.Collections.Specialized.NotifyCollectionChangedAction", new MappedType("Windows.UI.Xaml.Interop", "NotifyCollectionChangedAction", "Windows.UI.Xaml") }, + { "System.Collections.Specialized.NotifyCollectionChangedEventArgs", new MappedType("Windows.UI.Xaml.Interop", "NotifyCollectionChangedEventArgs", "Windows.UI.Xaml") }, + { "System.Collections.Specialized.NotifyCollectionChangedEventHandler", new MappedType("Windows.UI.Xaml.Interop", "NotifyCollectionChangedEventHandler", "Windows.UI.Xaml") }, + { "WinRT.EventRegistrationToken", new MappedType("Windows.Foundation", "EventRegistrationToken", "Windows.Foundation.FoundationContract", true, true) }, + { "System.AttributeTargets", new MappedType("Windows.Foundation.Metadata", "AttributeTargets", "Windows.Foundation.FoundationContract", true, true) }, + { "System.AttributeUsageAttribute", new MappedType("Windows.Foundation.Metadata", "AttributeUsageAttribute", "Windows.Foundation.FoundationContract") }, + { "System.Numerics.Matrix3x2", new MappedType("Windows.Foundation.Numerics", "Matrix3x2", "Windows.Foundation.FoundationContract", true, true) }, + { "System.Numerics.Matrix4x4", new MappedType("Windows.Foundation.Numerics", "Matrix4x4", "Windows.Foundation.FoundationContract", true, true) }, + { "System.Numerics.Plane", new MappedType("Windows.Foundation.Numerics", "Plane", "Windows.Foundation.FoundationContract", true, true) }, + { "System.Numerics.Quaternion", new MappedType("Windows.Foundation.Numerics", "Quaternion", "Windows.Foundation.FoundationContract", true, true) }, + { "System.Numerics.Vector2", new MappedType("Windows.Foundation.Numerics", "Vector2", "Windows.Foundation.FoundationContract", true, true) }, + { "System.Numerics.Vector3", new MappedType("Windows.Foundation.Numerics", "Vector3", "Windows.Foundation.FoundationContract", true, true) }, + { "System.Numerics.Vector4", new MappedType("Windows.Foundation.Numerics", "Vector4", "Windows.Foundation.FoundationContract", true, true) }, + { "System.Type", new MappedType(GetSystemTypeCustomMapping) }, + { "System.Collections.Generic.IEnumerable`1", new MappedType("Windows.Foundation.Collections", "IIterable`1", "Windows.Foundation.FoundationContract") }, + { "System.Collections.Generic.IEnumerator`1", new MappedType("Windows.Foundation.Collections", "IIterator`1", "Windows.Foundation.FoundationContract") }, + { "System.Collections.Generic.KeyValuePair`2", new MappedType("Windows.Foundation.Collections", "IKeyValuePair`2", "Windows.Foundation.FoundationContract") }, + { "System.Collections.Generic.IReadOnlyDictionary`2", new MappedType("Windows.Foundation.Collections", "IMapView`2", "Windows.Foundation.FoundationContract") }, + { "System.Collections.Generic.IDictionary`2", new MappedType("Windows.Foundation.Collections", "IMap`2", "Windows.Foundation.FoundationContract") }, + { "System.Collections.Generic.IReadOnlyList`1", new MappedType("Windows.Foundation.Collections", "IVectorView`1", "Windows.Foundation.FoundationContract") }, + { "System.Collections.Generic.IList`1", new MappedType("Windows.Foundation.Collections", "IVector`1", "Windows.Foundation.FoundationContract") }, + { "Windows.UI.Color", new MappedType("Windows.UI", "Color", "Windows.Foundation.UniversalApiContract", true, true) }, + }; + } + else + { + typeMapping = new(StringComparer.Ordinal) + { + { "System.DateTimeOffset", new MappedType("Windows.Foundation", "DateTime", "Windows.Foundation.FoundationContract", true, false) }, + { "System.Exception", new MappedType("Windows.Foundation", "HResult", "Windows.Foundation.FoundationContract", true, false) }, + { "System.EventHandler`1", new MappedType("Windows.Foundation", "EventHandler`1", "Windows.Foundation.FoundationContract") }, + { "System.FlagsAttribute", new MappedType("System", "FlagsAttribute", "mscorlib" ) }, + { "System.IDisposable", new MappedType("Windows.Foundation", "IClosable", "Windows.Foundation.FoundationContract") }, + { "System.IServiceProvider", new MappedType("Microsoft.UI.Xaml", "IXamlServiceProvider", "Microsoft.UI") }, + { "System.Nullable`1", new MappedType("Windows.Foundation", "IReference`1", "Windows.Foundation.FoundationContract" ) }, + { "System.Object", new MappedType("System", "Object", "mscorlib" ) }, + { "System.TimeSpan", new MappedType("Windows.Foundation", "TimeSpan", "Windows.Foundation.FoundationContract", true, false) }, + { "System.Uri", new MappedType("Windows.Foundation", "Uri", "Windows.Foundation.FoundationContract") }, + { "System.ComponentModel.DataErrorsChangedEventArgs", new MappedType("Microsoft.UI.Xaml.Data", "DataErrorsChangedEventArgs", "Microsoft.UI") }, + { "System.ComponentModel.INotifyDataErrorInfo", new MappedType("Microsoft.UI.Xaml.Data", "INotifyDataErrorInfo", "Microsoft.UI") }, + { "System.ComponentModel.INotifyPropertyChanged", new MappedType("Microsoft.UI.Xaml.Data", "INotifyPropertyChanged", "Microsoft.UI") }, + { "System.ComponentModel.PropertyChangedEventArgs", new MappedType("Microsoft.UI.Xaml.Data", "PropertyChangedEventArgs", "Microsoft.UI") }, + { "System.ComponentModel.PropertyChangedEventHandler", new MappedType("Microsoft.UI.Xaml.Data", "PropertyChangedEventHandler", "Microsoft.UI") }, + { "System.Windows.Input.ICommand", new MappedType("Microsoft.UI.Xaml.Input", "ICommand", "Microsoft.UI") }, + { "System.Collections.IEnumerable", new MappedType("Microsoft.UI.Xaml.Interop", "IBindableIterable", "Microsoft.UI") }, + { "System.Collections.IList", new MappedType("Microsoft.UI.Xaml.Interop", "IBindableVector", "Microsoft.UI") }, + { "System.Collections.Specialized.INotifyCollectionChanged", new MappedType("Microsoft.UI.Xaml.Interop", "INotifyCollectionChanged", "Microsoft.UI") }, + { "System.Collections.Specialized.NotifyCollectionChangedAction", new MappedType("Microsoft.UI.Xaml.Interop", "NotifyCollectionChangedAction", "Microsoft.UI") }, + { "System.Collections.Specialized.NotifyCollectionChangedEventArgs", new MappedType("Microsoft.UI.Xaml.Interop", "NotifyCollectionChangedEventArgs", "Microsoft.UI") }, + { "System.Collections.Specialized.NotifyCollectionChangedEventHandler", new MappedType("Microsoft.UI.Xaml.Interop", "NotifyCollectionChangedEventHandler", "Microsoft.UI") }, + { "WinRT.EventRegistrationToken", new MappedType("Windows.Foundation", "EventRegistrationToken", "Windows.Foundation.FoundationContract", true, true) }, + { "System.AttributeTargets", new MappedType("Windows.Foundation.Metadata", "AttributeTargets", "Windows.Foundation.FoundationContract", true, true) }, + { "System.AttributeUsageAttribute", new MappedType("Windows.Foundation.Metadata", "AttributeUsageAttribute", "Windows.Foundation.FoundationContract") }, + { "System.Numerics.Matrix3x2", new MappedType("Windows.Foundation.Numerics", "Matrix3x2", "Windows.Foundation.FoundationContract", true, true) }, + { "System.Numerics.Matrix4x4", new MappedType("Windows.Foundation.Numerics", "Matrix4x4", "Windows.Foundation.FoundationContract", true, true) }, + { "System.Numerics.Plane", new MappedType("Windows.Foundation.Numerics", "Plane", "Windows.Foundation.FoundationContract", true, true) }, + { "System.Numerics.Quaternion", new MappedType("Windows.Foundation.Numerics", "Quaternion", "Windows.Foundation.FoundationContract", true, true) }, + { "System.Numerics.Vector2", new MappedType("Windows.Foundation.Numerics", "Vector2", "Windows.Foundation.FoundationContract", true, true) }, + { "System.Numerics.Vector3", new MappedType("Windows.Foundation.Numerics", "Vector3", "Windows.Foundation.FoundationContract", true, true) }, + { "System.Numerics.Vector4", new MappedType("Windows.Foundation.Numerics", "Vector4", "Windows.Foundation.FoundationContract", true, true) }, + { "System.Type", new MappedType(GetSystemTypeCustomMapping) }, + { "System.Collections.Generic.IEnumerable`1", new MappedType("Windows.Foundation.Collections", "IIterable`1", "Windows.Foundation.FoundationContract") }, + { "System.Collections.Generic.IEnumerator`1", new MappedType("Windows.Foundation.Collections", "IIterator`1", "Windows.Foundation.FoundationContract") }, + { "System.Collections.Generic.KeyValuePair`2", new MappedType("Windows.Foundation.Collections", "IKeyValuePair`2", "Windows.Foundation.FoundationContract") }, + { "System.Collections.Generic.IReadOnlyDictionary`2", new MappedType("Windows.Foundation.Collections", "IMapView`2", "Windows.Foundation.FoundationContract") }, + { "System.Collections.Generic.IDictionary`2", new MappedType("Windows.Foundation.Collections", "IMap`2", "Windows.Foundation.FoundationContract") }, + { "System.Collections.Generic.IReadOnlyList`1", new MappedType("Windows.Foundation.Collections", "IVectorView`1", "Windows.Foundation.FoundationContract") }, + { "System.Collections.Generic.IList`1", new MappedType("Windows.Foundation.Collections", "IVector`1", "Windows.Foundation.FoundationContract") }, + { "Windows.UI.Color", new MappedType("Windows.UI", "Color", "Windows.Foundation.UniversalApiContract", true, true) }, + }; + } + } + + public bool HasMappingForType(string typeName) => typeMapping.ContainsKey(typeName); + + public MappedType GetMappedType(string typeName) => typeMapping[typeName]; + } +} diff --git a/src/Authoring/WinRT.SourceGenerator/UiXamlMode.cs b/src/Authoring/WinRT.SourceGenerator/UiXamlMode.cs new file mode 100644 index 000000000..7432a1075 --- /dev/null +++ b/src/Authoring/WinRT.SourceGenerator/UiXamlMode.cs @@ -0,0 +1,26 @@ +using Microsoft.CodeAnalysis.Diagnostics; +using System; +using System.Collections.Generic; +using System.Text; + +namespace Generator +{ + internal enum UiXamlMode + { + MicrosoftUiXaml, + WindowsUiXaml, + } + + internal static class OptionsHelper + { + public static UiXamlMode GetUiXamlMode(this AnalyzerConfigOptions options) + { + if (options.TryGetValue("build_property.CsWinRTUiXamlMode", out var value) && Enum.TryParse(value, out UiXamlMode mode)) + { + return mode; + } + + return UiXamlMode.MicrosoftUiXaml; + } + } +} diff --git a/src/Authoring/WinRT.SourceGenerator/WinRTTypeWriter.cs b/src/Authoring/WinRT.SourceGenerator/WinRTTypeWriter.cs index 3a64b1e8b..686320671 100644 --- a/src/Authoring/WinRT.SourceGenerator/WinRTTypeWriter.cs +++ b/src/Authoring/WinRT.SourceGenerator/WinRTTypeWriter.cs @@ -265,7 +265,7 @@ class WinRTTypeWriter : CSharpSyntaxWalker private readonly Dictionary typeReferenceMapping; private readonly Dictionary assemblyReferenceMapping; private readonly MetadataBuilder metadataBuilder; - + private readonly TypeMapper mapper; private readonly Dictionary typeDefinitionMapping; private TypeDeclaration currentTypeDeclaration; @@ -275,12 +275,14 @@ public WinRTTypeWriter( string assembly, string version, MetadataBuilder metadataBuilder, - Logger logger) + Logger logger, + TypeMapper mapper) { this.assembly = assembly; this.version = version; this.metadataBuilder = metadataBuilder; Logger = logger; + this.mapper = mapper; typeReferenceMapping = new Dictionary(StringComparer.Ordinal); assemblyReferenceMapping = new Dictionary(StringComparer.Ordinal); typeDefinitionMapping = new Dictionary(StringComparer.Ordinal); @@ -435,9 +437,9 @@ private EntityHandle GetTypeReference(ISymbol symbol) var assembly = GetAssemblyForWinRTType(symbol); if (assembly == null) { - if (GeneratorHelper.MappedCSharpTypes.ContainsKey(fullType)) + if (mapper.HasMappingForType(fullType)) { - (@namespace, name, assembly, _, _) = GeneratorHelper.MappedCSharpTypes[fullType].GetMapping(currentTypeDeclaration.Node); + (@namespace, name, assembly, _, _) = mapper.GetMappedType(fullType).GetMapping(currentTypeDeclaration.Node); Logger.Log("custom mapping " + fullType + " to " + QualifiedName(@namespace, name) + " from " + assembly); } else @@ -520,9 +522,9 @@ private void EncodeSymbol(Symbol symbol, SignatureTypeEncoder typeEncoder) else { bool isValueType = symbol.Type.TypeKind == TypeKind.Enum || symbol.Type.TypeKind == TypeKind.Struct; - if (GeneratorHelper.MappedCSharpTypes.ContainsKey(QualifiedName(symbol.Type))) + if (mapper.HasMappingForType(QualifiedName(symbol.Type))) { - (_, _, _, _, isValueType) = GeneratorHelper.MappedCSharpTypes[QualifiedName(symbol.Type)].GetMapping(currentTypeDeclaration.Node); + (_, _, _, _, isValueType) = mapper.GetMappedType(QualifiedName(symbol.Type)).GetMapping(currentTypeDeclaration.Node); } typeEncoder.Type(GetTypeReference(symbol.Type), isValueType); } @@ -804,7 +806,7 @@ private void ProcessCustomMappedInterfaces(INamedTypeSymbol classSymbol) // Mark custom mapped interface members for removal later. // Note we want to also mark members from interfaces without mappings. foreach (var implementedInterface in GetInterfaces(classSymbol, true). - Where(symbol => GeneratorHelper.MappedCSharpTypes.ContainsKey(QualifiedName(symbol)) || + Where(symbol => mapper.HasMappingForType(QualifiedName(symbol)) || ImplementedInterfacesWithoutMapping.Contains(QualifiedName(symbol)))) { bool isPubliclyImplemented = false; @@ -825,7 +827,7 @@ private void ProcessCustomMappedInterfaces(INamedTypeSymbol classSymbol) } foreach (var implementedInterface in GetInterfaces(classSymbol) - .Where(symbol => GeneratorHelper.MappedCSharpTypes.ContainsKey(QualifiedName(symbol)))) + .Where(symbol => mapper.HasMappingForType(QualifiedName(symbol)))) { WriteCustomMappedTypeMembers(implementedInterface, true, isPublicImplementation[implementedInterface]); } @@ -853,9 +855,9 @@ INamedTypeSymbol GetTypeByMetadataName(string metadataName) private string GetMappedQualifiedTypeName(ITypeSymbol symbol) { string qualifiedName = QualifiedName(symbol); - if (GeneratorHelper.MappedCSharpTypes.ContainsKey(qualifiedName)) + if (mapper.HasMappingForType(qualifiedName)) { - var (@namespace, mappedTypeName, _, _, _) = GeneratorHelper.MappedCSharpTypes[qualifiedName].GetMapping(currentTypeDeclaration.Node); + var (@namespace, mappedTypeName, _, _, _) = mapper.GetMappedType(qualifiedName).GetMapping(currentTypeDeclaration.Node); qualifiedName = QualifiedName(@namespace, mappedTypeName); if (symbol is INamedTypeSymbol namedType && namedType.TypeArguments.Length > 0) { @@ -874,7 +876,7 @@ private string GetMappedQualifiedTypeName(ITypeSymbol symbol) private void WriteCustomMappedTypeMembers(INamedTypeSymbol symbol, bool isDefinition, bool isPublic = true) { - var (_, mappedTypeName, _, _, _) = GeneratorHelper.MappedCSharpTypes[QualifiedName(symbol)].GetMapping(currentTypeDeclaration.Node); + var (_, mappedTypeName, _, _, _) = mapper.GetMappedType(QualifiedName(symbol)).GetMapping(currentTypeDeclaration.Node); string qualifiedName = GetMappedQualifiedTypeName(symbol); Logger.Log("writing custom mapped type members for " + mappedTypeName + " public: " + isPublic + " qualified name: " + qualifiedName); @@ -1233,7 +1235,7 @@ void GatherPubliclyAccessibleInterfaces(ITypeSymbol symbol) GatherPubliclyAccessibleInterfaces(symbol); var baseType = symbol.BaseType; - while (baseType != null && !GeneratorHelper.IsWinRTType(baseType)) + while (baseType != null && !GeneratorHelper.IsWinRTType(baseType, mapper)) { GatherPubliclyAccessibleInterfaces(baseType); @@ -2438,9 +2440,9 @@ void AddType(INamedTypeSymbol type, bool treatAsProjectedType = false) { AddProjectedType(type); } - else if (GeneratorHelper.MappedCSharpTypes.ContainsKey(qualifiedName)) + else if (mapper.HasMappingForType(qualifiedName)) { - var (@namespace, name, assembly, isSystemType, _) = GeneratorHelper.MappedCSharpTypes[qualifiedName].GetMapping(); + var (@namespace, name, assembly, isSystemType, _) = mapper.GetMappedType(qualifiedName).GetMapping(); if (isSystemType) { var projectedType = Model.Compilation.GetTypeByMetadataName(QualifiedName(@namespace, name)); @@ -2532,7 +2534,7 @@ public void FinalizeGeneration() Logger.Log("finalizing interface " + implementedInterfaceQualifiedNameWithGenerics); var interfaceTypeDeclaration = typeDefinitionMapping[implementedInterfaceQualifiedNameWithGenerics]; - if (GeneratorHelper.MappedCSharpTypes.ContainsKey(QualifiedName(implementedInterface))) + if (mapper.HasMappingForType(QualifiedName(implementedInterface))) { Logger.Log("adding MethodImpls for custom mapped interface"); foreach (var interfaceMember in interfaceTypeDeclaration.MethodReferences) @@ -2663,7 +2665,7 @@ public void FinalizeGeneration() public void GenerateWinRTExposedClassAttributes(GeneratorExecutionContext context) { - static bool IsWinRTType(ISymbol symbol) + static bool IsWinRTType(ISymbol symbol, TypeMapper mapper) { if (symbol is INamedTypeSymbol namedType) { @@ -2694,7 +2696,7 @@ typeDeclaration.Node is INamedTypeSymbol symbol && symbol.TypeKind == TypeKind.Class && !symbol.IsStatic) { - vtableAttributesToAdd.Add(WinRTAotSourceGenerator.GetVtableAttributeToAdd(symbol, IsWinRTType, context.Compilation.Assembly, true, typeDeclaration.DefaultInterface)); + vtableAttributesToAdd.Add(WinRTAotSourceGenerator.GetVtableAttributeToAdd(symbol, IsWinRTType, mapper, context.Compilation.Assembly, true, typeDeclaration.DefaultInterface)); } } diff --git a/src/Perf/IIDOptimizer/GuidPatcher.cs b/src/Perf/IIDOptimizer/GuidPatcher.cs index bd200dfd6..e12723150 100644 --- a/src/Perf/IIDOptimizer/GuidPatcher.cs +++ b/src/Perf/IIDOptimizer/GuidPatcher.cs @@ -72,12 +72,14 @@ public GuidPatcher(AssemblyDefinition winRTRuntime, AssemblyDefinition targetAss guidGeneratorType = null; TypeDefinition? typeExtensionsType = null; + TypeDefinition? wuxMuxProjectedInterfaceAttributeType = null; // Use the type definition if we are patching WinRT.Runtime, otherwise lookup the types as references if (string.CompareOrdinal(assembly.Name.Name, "WinRT.Runtime") == 0) { - guidGeneratorType = winRTRuntimeAssembly.MainModule.Types.Where(typeDef => string.CompareOrdinal(typeDef.Name, "GuidGenerator") == 0).First(); - typeExtensionsType = winRTRuntimeAssembly.MainModule.Types.Where(typeDef => string.CompareOrdinal(typeDef.Name, "TypeExtensions") == 0).First(); + guidGeneratorType = winRTRuntimeAssembly.MainModule.Types.Where(typeDef => string.Equals(typeDef.Name, "GuidGenerator", StringComparison.Ordinal)).First(); + typeExtensionsType = winRTRuntimeAssembly.MainModule.Types.Where(typeDef => string.Equals(typeDef.Name, "TypeExtensions", StringComparison.Ordinal)).First(); + wuxMuxProjectedInterfaceAttributeType = winRTRuntimeAssembly.MainModule.Types.Where(typedef => string.Equals(typedef.Name, "WuxMuxProjectedInterfaceAttribute", StringComparison.Ordinal)).First(); } foreach (var asm in assembly.MainModule.AssemblyReferences) @@ -87,6 +89,7 @@ public GuidPatcher(AssemblyDefinition winRTRuntime, AssemblyDefinition targetAss guidGeneratorType = new TypeReference("WinRT", "GuidGenerator", assembly.MainModule, asm).Resolve(); typeExtensionsType = new TypeReference("WinRT", "TypeExtensions", assembly.MainModule, asm).Resolve(); + wuxMuxProjectedInterfaceAttributeType = new TypeReference("WinRT", "WuxMuxProjectedInterfaceAttribute", assembly.MainModule, asm).Resolve(); } else if (string.CompareOrdinal(asm.Name, "System.Runtime.InteropServices") == 0) { @@ -101,7 +104,7 @@ public GuidPatcher(AssemblyDefinition winRTRuntime, AssemblyDefinition targetAss getHelperTypeMethod = typeExtensionsType.Methods.First(m => String.CompareOrdinal(m.Name, "GetHelperType") == 0); } - signatureGenerator = new SignatureGenerator(assembly, guidAttributeType!, winRTRuntimeAssembly); + signatureGenerator = new SignatureGenerator(assembly, guidAttributeType!, wuxMuxProjectedInterfaceAttributeType!, winRTRuntimeAssembly); methodCache = new Dictionary(); } diff --git a/src/Perf/IIDOptimizer/SignatureGenerator.cs b/src/Perf/IIDOptimizer/SignatureGenerator.cs index 819bcabaa..2f9d3cfbf 100644 --- a/src/Perf/IIDOptimizer/SignatureGenerator.cs +++ b/src/Perf/IIDOptimizer/SignatureGenerator.cs @@ -55,12 +55,14 @@ sealed class SignatureGenerator { private readonly AssemblyDefinition assembly; private readonly TypeDefinition guidAttributeType; + private readonly TypeDefinition wuxMuxProjectedInterfaceAttributeType; private readonly AssemblyDefinition winRTRuntimeAssembly; - public SignatureGenerator(AssemblyDefinition assembly, TypeDefinition guidAttributeType, AssemblyDefinition runtimeAssembly) + public SignatureGenerator(AssemblyDefinition assembly, TypeDefinition guidAttributeType, TypeDefinition wuxMuxProjectedInterfaceAttributeType, AssemblyDefinition runtimeAssembly) { this.assembly = assembly; this.guidAttributeType = guidAttributeType; + this.wuxMuxProjectedInterfaceAttributeType = wuxMuxProjectedInterfaceAttributeType; this.winRTRuntimeAssembly = runtimeAssembly; } @@ -73,9 +75,9 @@ public SignaturePart GetSignatureParts(TypeReference type) var typeDef = type.Resolve(); - var helperType = new TypeReference($"ABI.{typeDef.Namespace}", typeDef.Name, typeDef.Module, assembly.MainModule); + TypeReference helperType = type.GetCswinrtAbiTypeDefinition(winRTRuntimeAssembly); - if (helperType.Resolve() is not null) + if (helperType is not null) { if (type.IsGenericInstance) { @@ -167,9 +169,25 @@ public SignaturePart GetSignatureParts(TypeReference type) return new RuntimeClassSignature(type, GetSignatureParts(iface)); } - // TODO-WuxMux: We need to intercept the WUX/MUX types here and do one of the following options: - // - Take an option in the IID optimizer to hard-code for one or the other (for OutputType Exe or for libraries that are one flavor only, this is reasonable) - // - Fall back to runtime-based IID lookup for the type (works for everything, less efficient) + // For types projected from WUX or MUX into .NET, we'll need to do a runtime lookup for the IID. + // TODO-WuxMux: We can instead take an option in the IID optimizer to hard-code the lookup for WUX or MUX when specified, which would be more efficient for scenarios where this is possible. + if (helperType?.Resolve().CustomAttributes.Any(attr => attr.AttributeType.Resolve() == wuxMuxProjectedInterfaceAttributeType) == true) + { + var getGuidSignatureMethod = new MethodReference("GetGuidSignature", assembly.MainModule.TypeSystem.String, helperType) + { + HasThis = false + }; + + if (getGuidSignatureMethod.Resolve() is not null) + { + return new CustomSignatureMethod(assembly.MainModule.ImportReference(getGuidSignatureMethod)); + } + else + { + throw new InvalidOperationException($"Unable to resolve GetGuidSignature method for type projected into .NET from WUX/MUX: {type.FullName}."); + } + } + Guid? guidAttributeValue = type.ReadGuidFromAttribute(guidAttributeType, winRTRuntimeAssembly); if (guidAttributeValue == null) { diff --git a/src/WinRT.Runtime/GuidGenerator.cs b/src/WinRT.Runtime/GuidGenerator.cs index 066536625..246238ad8 100644 --- a/src/WinRT.Runtime/GuidGenerator.cs +++ b/src/WinRT.Runtime/GuidGenerator.cs @@ -7,6 +7,7 @@ using System.Reflection; using System.Security.Cryptography; using System.Text; +using WinRT.Interop; namespace WinRT { @@ -28,11 +29,11 @@ public static Guid GetIID( #endif Type type) { - if (Projections.FindCustomIIDForAbiType(type) is Guid customIID) + type = type.GetGuidType(); + if (type.IsDefined(typeof(WuxMuxProjectedTypeAttribute))) { - return customIID; + return Guid.Parse(GetSignature(type)); } - type = type.GetGuidType(); if (!type.IsGenericType) { return type.GUID; diff --git a/src/WinRT.Runtime/Interop/WuxMuxProjectedInterfaceAttribute.cs b/src/WinRT.Runtime/Interop/WuxMuxProjectedInterfaceAttribute.cs new file mode 100644 index 000000000..10b746ebd --- /dev/null +++ b/src/WinRT.Runtime/Interop/WuxMuxProjectedInterfaceAttribute.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace WinRT.Interop +{ + /// + /// This type signals that the type it is applied to is projected into .NET from either a Windows.UI.Xaml type or a Microsoft.UI.Xaml type. + /// For this type, the GuidAttribute is not used and instead the GetGuidSignature method must be called to get the IID or generic IID signature part of the type. + /// + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] + internal sealed class WuxMuxProjectedTypeAttribute : Attribute + { + } +} diff --git a/src/WinRT.Runtime/Projections.cs b/src/WinRT.Runtime/Projections.cs index 0ee03e99d..fab580b15 100644 --- a/src/WinRT.Runtime/Projections.cs +++ b/src/WinRT.Runtime/Projections.cs @@ -25,14 +25,28 @@ namespace WinRT #endif static class Projections { - private enum UiXamlMode + internal enum UiXamlMode { - Unsupported, MicrosoftUiXaml, WindowsUiXaml } - private static UiXamlMode UiXamlMode { get; } = AppContext.GetData("CsWinRT.UiXamlMode") is string str && Enum.TryParse(str, out var mode) ? mode : UiXamlMode.Unsupported; + private static UiXamlMode GetUIXamlModeSetting() + { + if (AppContext.GetData("CsWinRT.UiXamlMode") is string str && Enum.TryParse(str, out var mode)) + { +#if !NET5_0_OR_GREATER + if (mode == UiXamlMode.WindowsUiXaml) + { + throw new NotSupportedException("Windows.UI.Xaml is not supported before .NET 5. Please use built-in WinRT interop for Windows.UI.Xaml experiences"); + } +#endif + return mode; + } + return UiXamlMode.MicrosoftUiXaml; // We default to MUX for back-compat with existing projects. + } + + internal static UiXamlMode UiXamlModeSetting { get; } = GetUIXamlModeSetting(); private static readonly ReaderWriterLockSlim rwlock = new ReaderWriterLockSlim(); @@ -46,7 +60,7 @@ private enum UiXamlMode static Projections() { - // This should be in sync with cswinrt/helpers.h and the reverse mapping from WinRT.SourceGenerator/WinRTTypeWriter.cs. + // This should be in sync with cswinrt/helpers.h and the reverse mapping from WinRT.SourceGenerator/TypeMapper.cs. RegisterCustomAbiTypeMappingNoLock(typeof(bool), typeof(ABI.System.Boolean), "Boolean"); RegisterCustomAbiTypeMappingNoLock(typeof(char), typeof(ABI.System.Char), "Char"); RegisterCustomAbiTypeMappingNoLock(typeof(EventRegistrationToken), typeof(ABI.WinRT.EventRegistrationToken), "Windows.Foundation.EventRegistrationToken"); @@ -73,7 +87,7 @@ static Projections() RegisterCustomAbiTypeMappingNoLock(typeof(TimeSpan), typeof(ABI.System.TimeSpan), "Windows.Foundation.TimeSpan"); RegisterCustomAbiTypeMappingNoLock(typeof(Uri), typeof(ABI.System.Uri), "Windows.Foundation.Uri", isRuntimeClass: true); - if (UiXamlMode == UiXamlMode.MicrosoftUiXaml) + if (UiXamlModeSetting == UiXamlMode.MicrosoftUiXaml) { RegisterCustomAbiTypeMappingNoLock(typeof(DataErrorsChangedEventArgs), typeof(ABI.System.ComponentModel.DataErrorsChangedEventArgs), "Microsoft.UI.Xaml.Data.DataErrorsChangedEventArgs", isRuntimeClass: true); RegisterCustomAbiTypeMappingNoLock(typeof(PropertyChangedEventArgs), typeof(ABI.System.ComponentModel.PropertyChangedEventArgs), "Microsoft.UI.Xaml.Data.PropertyChangedEventArgs", isRuntimeClass: true); @@ -89,18 +103,14 @@ static Projections() RegisterCustomAbiTypeMappingNoLock(typeof(NotifyCollectionChangedEventArgs), typeof(ABI.System.Collections.Specialized.NotifyCollectionChangedEventArgs), "Microsoft.UI.Xaml.Interop.NotifyCollectionChangedEventArgs", isRuntimeClass: true); RegisterCustomAbiTypeMappingNoLock(typeof(NotifyCollectionChangedEventHandler), typeof(ABI.System.Collections.Specialized.NotifyCollectionChangedEventHandler), "Microsoft.UI.Xaml.Interop.NotifyCollectionChangedEventHandler"); CustomTypeToHelperTypeMappings.Add(typeof(Microsoft.UI.Xaml.Interop.IBindableVector), typeof(ABI.System.Collections.IList)); - - // TODO-WuxMux: Add custom IIDs to the IID lookup } - else if (UiXamlMode == UiXamlMode.WindowsUiXaml) +#if NET5_0_OR_GREATER + else if (UiXamlModeSetting == UiXamlMode.WindowsUiXaml) { - RegisterCustomAbiTypeMappingNoLock(typeof(DataErrorsChangedEventArgs), typeof(ABI.System.ComponentModel.DataErrorsChangedEventArgs), "Windows.UI.Xaml.Data.DataErrorsChangedEventArgs", isRuntimeClass: true); RegisterCustomAbiTypeMappingNoLock(typeof(PropertyChangedEventArgs), typeof(ABI.System.ComponentModel.PropertyChangedEventArgs), "Windows.UI.Xaml.Data.PropertyChangedEventArgs", isRuntimeClass: true); RegisterCustomAbiTypeMappingNoLock(typeof(PropertyChangedEventHandler), typeof(ABI.System.ComponentModel.PropertyChangedEventHandler), "Windows.UI.Xaml.Data.PropertyChangedEventHandler"); - RegisterCustomAbiTypeMappingNoLock(typeof(INotifyDataErrorInfo), typeof(ABI.System.ComponentModel.INotifyDataErrorInfo), "Windows.UI.Xaml.Data.INotifyDataErrorInfo"); RegisterCustomAbiTypeMappingNoLock(typeof(INotifyPropertyChanged), typeof(ABI.System.ComponentModel.INotifyPropertyChanged), "Windows.UI.Xaml.Data.INotifyPropertyChanged"); RegisterCustomAbiTypeMappingNoLock(typeof(ICommand), typeof(ABI.System.Windows.Input.ICommand), "Windows.UI.Xaml.Interop.ICommand"); - RegisterCustomAbiTypeMappingNoLock(typeof(IServiceProvider), typeof(ABI.System.IServiceProvider), "Windows.UI.Xaml.IXamlServiceProvider"); RegisterCustomAbiTypeMappingNoLock(typeof(IEnumerable), typeof(ABI.System.Collections.IEnumerable), "Windows.UI.Xaml.Interop.IBindableIterable"); RegisterCustomAbiTypeMappingNoLock(typeof(IList), typeof(ABI.System.Collections.IList), "Windows.UI.Xaml.Interop.IBindableVector"); RegisterCustomAbiTypeMappingNoLock(typeof(INotifyCollectionChanged), typeof(ABI.System.Collections.Specialized.INotifyCollectionChanged), "Windows.UI.Xaml.Interop.INotifyCollectionChanged"); @@ -108,9 +118,8 @@ static Projections() RegisterCustomAbiTypeMappingNoLock(typeof(NotifyCollectionChangedEventArgs), typeof(ABI.System.Collections.Specialized.NotifyCollectionChangedEventArgs), "Windows.UI.Xaml.Interop.NotifyCollectionChangedEventArgs", isRuntimeClass: true); RegisterCustomAbiTypeMappingNoLock(typeof(NotifyCollectionChangedEventHandler), typeof(ABI.System.Collections.Specialized.NotifyCollectionChangedEventHandler), "Windows.UI.Xaml.Interop.NotifyCollectionChangedEventHandler"); CustomTypeToHelperTypeMappings.Add(typeof(Windows.UI.Xaml.Interop.IBindableVector), typeof(ABI.System.Collections.IList)); - - // TODO-WuxMux: Add custom IIDs to the IID lookup } +#endif RegisterCustomAbiTypeMappingNoLock(typeof(EventHandler<>), typeof(ABI.System.EventHandler<>), "Windows.Foundation.EventHandler`1"); diff --git a/src/WinRT.Runtime/Projections/Bindable.net5.cs b/src/WinRT.Runtime/Projections/Bindable.net5.cs index 2b31c540d..809c4eadd 100644 --- a/src/WinRT.Runtime/Projections/Bindable.net5.cs +++ b/src/WinRT.Runtime/Projections/Bindable.net5.cs @@ -1,101 +1,162 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -using System; -using System.Collections; -using System.Collections.Generic; +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +using System; +using System.Collections; +using System.Collections.Generic; using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using WinRT; +using System.Runtime.InteropServices; +using WinRT; using WinRT.Interop; -#pragma warning disable 0169 // warning CS0169: The field '...' is never used -#pragma warning disable 0649 // warning CS0169: Field '...' is never assigned to - -namespace Microsoft.UI.Xaml.Interop -{ - [global::WinRT.WindowsRuntimeType] - [Guid("036D2C08-DF29-41AF-8AA2-D774BE62BA6F")] - [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Microsoft.UI.Xaml.Interop.IBindableIterable))] - internal interface IBindableIterable - { - IBindableIterator First(); - } - [global::WinRT.WindowsRuntimeType] - [Guid("6A1D6C07-076D-49F2-8314-F52C9C9A8331")] - [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Microsoft.UI.Xaml.Interop.IBindableIterator))] - internal interface IBindableIterator - { - bool MoveNext(); - // GetMany is not implemented by IBindableIterator, but it is here - // for compat purposes with WinUI where there are scenarios they do - // reinterpret_cast from IBindableIterator to IIterable. It is - // the last function in the vftable and shouldn't be called by anyone. - // If called, it will return NotImplementedException. - uint GetMany(ref object[] items); - object Current { get; } - bool HasCurrent { get; } - } - [global::WinRT.WindowsRuntimeType] - [Guid("393DE7DE-6FD0-4C0D-BB71-47244A113E93")] - internal interface IBindableVector : IEnumerable - { - object GetAt(uint index); - IBindableVectorView GetView(); - bool IndexOf(object value, out uint index); - void SetAt(uint index, object value); - void InsertAt(uint index, object value); - void RemoveAt(uint index); - void Append(object value); - void RemoveAtEnd(); - void Clear(); - uint Size { get; } - } - [global::WinRT.WindowsRuntimeType] - [Guid("346DD6E7-976E-4BC3-815D-ECE243BC0F33")] - [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Microsoft.UI.Xaml.Interop.IBindableVectorView))] - internal interface IBindableVectorView : IEnumerable - { - object GetAt(uint index); - bool IndexOf(object value, out uint index); - uint Size { get; } - } -} - -namespace ABI.Microsoft.UI.Xaml.Interop -{ - [DynamicInterfaceCastableImplementation] - [Guid("036D2C08-DF29-41AF-8AA2-D774BE62BA6F")] - internal unsafe interface IBindableIterable : global::Microsoft.UI.Xaml.Interop.IBindableIterable, ABI.System.Collections.IEnumerable - { - - } - - [DynamicInterfaceCastableImplementation] - [Guid("6A1D6C07-076D-49F2-8314-F52C9C9A8331")] - internal unsafe interface IBindableIterator : global::Microsoft.UI.Xaml.Interop.IBindableIterator +#pragma warning disable 0169 // warning CS0169: The field '...' is never used +#pragma warning disable 0649 // warning CS0169: Field '...' is never assigned to + +namespace ABI.System.Collections +{ + using WUX = global::Windows.UI.Xaml.Interop; + using MUX = global::Microsoft.UI.Xaml.Interop; + using global::System; + using global::System.Runtime.CompilerServices; + using global::System.Diagnostics.CodeAnalysis; + +#if EMBED + internal +#else + public +#endif + static class IEnumerableMethods + { + public static global::System.Guid IID { get; } = new Guid(new global::System.ReadOnlySpan(new byte[] { 0x08, 0x2C, 0x6D, 0x03, 0x29, 0xDF, 0xAF, 0x41, 0x8A, 0xA2, 0xD7, 0x74, 0xBE, 0x62, 0xBA, 0x6F })); + + public static IntPtr AbiToProjectionVftablePtr => IEnumerable.AbiToProjectionVftablePtr; + } + + [DynamicInterfaceCastableImplementation] + [Guid("036D2C08-DF29-41AF-8AA2-D774BE62BA6F")] + internal unsafe interface IEnumerable : global::System.Collections.IEnumerable, WUX.IBindableIterable, MUX.IBindableIterable { - public static readonly IntPtr AbiToProjectionVftablePtr; - static IBindableIterator() + public static string GetGuidSignature() => GuidGenerator.GetSignature(typeof(IEnumerable)); + + public sealed class AdaptiveFromAbiHelper : global::System.Collections.IEnumerable { - AbiToProjectionVftablePtr = ComWrappersSupport.AllocateVtableMemory(typeof(IBindableIterator), sizeof(IInspectable.Vftbl) + sizeof(IntPtr) * 4); - *(IInspectable.Vftbl*)AbiToProjectionVftablePtr = IInspectable.Vftbl.AbiToProjectionVftable; - ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[6] = &Do_Abi_get_Current_0; - ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[7] = &Do_Abi_get_HasCurrent_1; - ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[8] = &Do_Abi_MoveNext_2; - ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[9] = &Do_Abi_GetMany_3; + private readonly Func _enumerator; + private readonly IWinRTObject _winRTObject; + + [DynamicDependency(DynamicallyAccessedMemberTypes.PublicMethods, typeof(IEnumerable<>))] + [SuppressMessage("Trimming", "IL2070:'this' argument does not satisfy 'DynamicallyAccessedMembersAttribute' in call to target method. The parameter of method does not have matching annotations.", Justification = "We explicitly preserve the type we're looking for with the DynamicDependency attribute.")] + [SuppressMessage("Trimming", "IL2075:'this' argument does not satisfy 'DynamicallyAccessedMembersAttribute' in call to target method. The return value of the source method does not have matching annotations.", Justification = "We can't annotate this case (GetMethod on a type returned from GetInterface), so we use DynamicDependency to keep alive the one type we care about's public methods.")] + public AdaptiveFromAbiHelper( + Type runtimeType, IWinRTObject winRTObject) + : this(winRTObject) + { + Type enumGenericType = (runtimeType.IsGenericType && runtimeType.GetGenericTypeDefinition() == typeof(IEnumerable<>)) ? + runtimeType : runtimeType.GetInterface("System.Collections.Generic.IEnumerable`1"); + if(enumGenericType != null) + { + var getEnumerator = enumGenericType.GetMethod("GetEnumerator"); + _enumerator = (IWinRTObject obj) => (IEnumerator)getEnumerator.Invoke(obj, null); + } + } + + public AdaptiveFromAbiHelper(IWinRTObject winRTObject) + { + _winRTObject = winRTObject; + if (winRTObject is WUX.IBindableIterable) + { + _enumerator = (IWinRTObject obj) => new Generic.FromAbiEnumerator(new NonGenericToGenericWuxIterator(((WUX.IBindableIterable)obj).First())); + } + else if (winRTObject is MUX.IBindableIterable) + { + _enumerator = (IWinRTObject obj) => new Generic.FromAbiEnumerator(new NonGenericToGenericMuxIterator(((MUX.IBindableIterable)obj).First())); + } + } + + public IEnumerator GetEnumerator() => _enumerator(_winRTObject); + + private sealed class NonGenericToGenericWuxIterator : global::Windows.Foundation.Collections.IIterator + { + private readonly WUX.IBindableIterator iterator; + + public NonGenericToGenericWuxIterator(WUX.IBindableIterator iterator) => this.iterator = iterator; + + public object _Current => iterator.Current; + public bool HasCurrent => iterator.HasCurrent; + public bool _MoveNext() { return iterator.MoveNext(); } + public uint GetMany(ref object[] items) => throw new NotSupportedException(); + } + + private sealed class NonGenericToGenericMuxIterator : global::Windows.Foundation.Collections.IIterator + { + private readonly MUX.IBindableIterator iterator; + + public NonGenericToGenericMuxIterator(MUX.IBindableIterator iterator) => this.iterator = iterator; + + public object _Current => iterator.Current; + public bool HasCurrent => iterator.HasCurrent; + public bool _MoveNext() { return iterator.MoveNext(); } + public uint GetMany(ref object[] items) => throw new NotSupportedException(); + } + } + + private sealed class ToWuxAbiHelper : WUX.IBindableIterable + { + private readonly IEnumerable m_enumerable; + + internal ToWuxAbiHelper(IEnumerable enumerable) => m_enumerable = enumerable; + + WUX.IBindableIterator WUX.IBindableIterable.First() => MakeBindableIterator(m_enumerable.GetEnumerator()); + + internal static WUX.IBindableIterator MakeBindableIterator(IEnumerator enumerator) => + new Generic.IEnumerator.ToAbiHelper(new NonGenericToGenericEnumerator(enumerator)); + + private sealed class NonGenericToGenericEnumerator : IEnumerator + { + private readonly IEnumerator enumerator; + + public NonGenericToGenericEnumerator(IEnumerator enumerator) => this.enumerator = enumerator; + + public object Current => enumerator.Current; + public bool MoveNext() { return enumerator.MoveNext(); } + public void Reset() { enumerator.Reset(); } + public void Dispose() { } + } } - [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] - private static unsafe int Do_Abi_MoveNext_2(IntPtr thisPtr, byte* result) + private sealed class ToMuxAbiHelper(IEnumerable enumerable) : MUX.IBindableIterable + { + MUX.IBindableIterator MUX.IBindableIterable.First() => MakeBindableIterator(enumerable.GetEnumerator()); + + internal static MUX.IBindableIterator MakeBindableIterator(IEnumerator enumerator) => + new Generic.IEnumerator.ToAbiHelper(new NonGenericToGenericEnumerator(enumerator)); + + private sealed class NonGenericToGenericEnumerator(IEnumerator enumerator) : IEnumerator + { + public object Current => enumerator.Current; + public bool MoveNext() { return enumerator.MoveNext(); } + public void Reset() { enumerator.Reset(); } + public void Dispose() { } + } + } + + public static readonly IntPtr AbiToProjectionVftablePtr; + static IEnumerable() + { + AbiToProjectionVftablePtr = ComWrappersSupport.AllocateVtableMemory(typeof(IEnumerable), sizeof(IInspectable.Vftbl) + sizeof(IntPtr) * 1); + *(IInspectable.Vftbl*)AbiToProjectionVftablePtr = IInspectable.Vftbl.AbiToProjectionVftable; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[6] = Projections.UiXamlModeSetting is Projections.UiXamlMode.WindowsUiXaml ? &Do_Wux_Abi_First_0 : &Do_Mux_Abi_First_0; + } + + [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] + private static unsafe int Do_Wux_Abi_First_0(IntPtr thisPtr, IntPtr* result) { - bool __result = default; *result = default; try { - __result = global::WinRT.ComWrappersSupport.FindObject(thisPtr).MoveNext(); - *result = (byte)(__result ? 1 : 0); + var __this = global::WinRT.ComWrappersSupport.FindObject(thisPtr); + var iterator = ToWuxAbiHelper.MakeBindableIterator(__this.GetEnumerator()); + *result = MarshalInterface.FromManaged(iterator); } catch (Exception __exception__) { @@ -105,907 +166,620 @@ private static unsafe int Do_Abi_MoveNext_2(IntPtr thisPtr, byte* result) return 0; } - [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] - private static unsafe int Do_Abi_GetMany_3(IntPtr thisPtr, int __itemsSize, IntPtr items, uint* result) + [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] + private static unsafe int Do_Mux_Abi_First_0(IntPtr thisPtr, IntPtr* result) { *result = default; - try { - // Should never be called. - throw new NotImplementedException(); + var __this = global::WinRT.ComWrappersSupport.FindObject(thisPtr); + var iterator = ToMuxAbiHelper.MakeBindableIterator(__this.GetEnumerator()); + *result = MarshalInterface.FromManaged(iterator); } catch (Exception __exception__) { global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); } + return 0; } - [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] - private static unsafe int Do_Abi_get_Current_0(IntPtr thisPtr, IntPtr* value) + internal static ObjectReference ObjRefFromAbi(IntPtr thisPtr) { - object __value = default; - *value = default; + if (thisPtr == IntPtr.Zero) + { + return null; + } + return ObjectReference.FromAbi(thisPtr); + } + + private static AdaptiveFromAbiHelper _AbiHelper(IWinRTObject _this) + { + return (AdaptiveFromAbiHelper)_this.GetOrCreateTypeHelperData(typeof(global::System.Collections.IEnumerable).TypeHandle, + () => new AdaptiveFromAbiHelper(_this)); + } + + unsafe WUX.IBindableIterator WUX.IBindableIterable.First() + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IEnumerable).TypeHandle); + var ThisPtr = _obj.ThisPtr; + IntPtr __retval = default; try { - __value = global::WinRT.ComWrappersSupport.FindObject(thisPtr).Current; - *value = MarshalInspectable.FromManaged(__value); + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[6](ThisPtr, &__retval)); + return MarshalInterface.FromAbi(__retval); } - catch (Exception __exception__) + finally { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + MarshalInterface.DisposeAbi(__retval); } - return 0; } - [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] - private static unsafe int Do_Abi_get_HasCurrent_1(IntPtr thisPtr, byte* value) + unsafe MUX.IBindableIterator MUX.IBindableIterable.First() { - bool __value = default; - *value = default; + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IEnumerable).TypeHandle); + var ThisPtr = _obj.ThisPtr; + IntPtr __retval = default; try { - __value = global::WinRT.ComWrappersSupport.FindObject(thisPtr).HasCurrent; - *value = (byte)(__value ? 1 : 0); + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[6](ThisPtr, &__retval)); + return MarshalInterface.FromAbi(__retval); } - catch (Exception __exception__) + finally { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + MarshalInterface.DisposeAbi(__retval); } - return 0; - } - - internal static ObjectReference FromAbi(IntPtr thisPtr) => ObjectReference.FromAbi(thisPtr); - - unsafe bool global::Microsoft.UI.Xaml.Interop.IBindableIterator.MoveNext() - { - var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::Microsoft.UI.Xaml.Interop.IBindableIterator).TypeHandle); - var ThisPtr = _obj.ThisPtr; - byte __retval = default; - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[8](ThisPtr, &__retval)); - return __retval != 0; - } - - unsafe uint global::Microsoft.UI.Xaml.Interop.IBindableIterator.GetMany(ref object[] items) - { - // Should never be called. - throw new NotImplementedException(); - } - - unsafe object global::Microsoft.UI.Xaml.Interop.IBindableIterator.Current - { - get - { - var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::Microsoft.UI.Xaml.Interop.IBindableIterator).TypeHandle); - var ThisPtr = _obj.ThisPtr; - IntPtr __retval = default; - try - { - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[6](ThisPtr, &__retval)); - return MarshalInspectable.FromAbi(__retval); - } - finally - { - MarshalInspectable.DisposeAbi(__retval); - } - } - } - - unsafe bool global::Microsoft.UI.Xaml.Interop.IBindableIterator.HasCurrent - { - get - { - var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::Microsoft.UI.Xaml.Interop.IBindableIterator).TypeHandle); - var ThisPtr = _obj.ThisPtr; - byte __retval = default; - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[7](ThisPtr, &__retval)); - return __retval != 0; - } - } - - } - [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] - internal static class IBindableIterator_Delegates - { - public unsafe delegate int get_Current_0(IntPtr thisPtr, IntPtr* result); - public unsafe delegate int get_HasCurrent_1(IntPtr thisPtr, byte* result); - public unsafe delegate int MoveNext_2(IntPtr thisPtr, byte* result); - public unsafe delegate int GetMany_3(IntPtr thisPtr, int itemSize, IntPtr items, uint* result); - } - - [DynamicInterfaceCastableImplementation] - [Guid("346DD6E7-976E-4BC3-815D-ECE243BC0F33")] - internal unsafe interface IBindableVectorView : global::Microsoft.UI.Xaml.Interop.IBindableVectorView + } + + IEnumerator global::System.Collections.IEnumerable.GetEnumerator() + { + return _AbiHelper((IWinRTObject)this).GetEnumerator(); + } + } + + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] +#if EMBED + internal +#else + public +#endif + static class IEnumerable_Delegates + { + public unsafe delegate int First_0(IntPtr thisPtr, IntPtr* result); + } + +#if EMBED + internal +#else + public +#endif + static class IListMethods { - public static readonly IntPtr AbiToProjectionVftablePtr; - static IBindableVectorView() + public static Guid IID { get; } = new Guid(new global::System.ReadOnlySpan(new byte[] { 0xDE, 0xE7, 0x3D, 0x39, 0xD0, 0x6F, 0x0D, 0x4C, 0xBB, 0x71, 0x47, 0x24, 0x4A, 0x11, 0x3E, 0x93 })); + + public static IntPtr AbiToProjectionVftablePtr => IList.AbiToProjectionVftablePtr; + } + + [DynamicInterfaceCastableImplementation] + [Guid("393DE7DE-6FD0-4C0D-BB71-47244A113E93")] + internal unsafe interface IList : global::System.Collections.IList, global::Windows.UI.Xaml.Interop.IBindableVector + { + public static string GetGuidSignature() => GuidGenerator.GetSignature(typeof(IList)); + + public interface IBindableVectorAdapter { - AbiToProjectionVftablePtr = ComWrappersSupport.AllocateVtableMemory(typeof(IBindableVectorView), sizeof(IInspectable.Vftbl) + sizeof(IntPtr) * 3); - *(IInspectable.Vftbl*)AbiToProjectionVftablePtr = IInspectable.Vftbl.AbiToProjectionVftable; - ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[6] = &Do_Abi_GetAt_0; - ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[7] = &Do_Abi_get_Size_1; - ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[8] = &Do_Abi_IndexOf_2; + object GetAt(uint index); + IBindableVectorViewAdapter GetView(); + bool IndexOf(object value, out uint index); + void SetAt(uint index, object value); + void InsertAt(uint index, object value); + void RemoveAt(uint index); + void Append(object value); + void RemoveAtEnd(); + void Clear(); + uint Size { get; } } - [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] - private static unsafe int Do_Abi_GetAt_0(IntPtr thisPtr, uint index, IntPtr* result) + public interface IBindableVectorViewAdapter { - object __result = default; + object GetAt(uint index); + bool IndexOf(object value, out uint index); + uint Size { get; } + } - try - { - __result = global::WinRT.ComWrappersSupport.FindObject(thisPtr).GetAt(index); - *result = MarshalInspectable.FromManaged(__result); + private sealed class WuxBindableVectorAdapter(WUX.IBindableVector vector) : IBindableVectorAdapter + { + public object GetAt(uint index) => vector.GetAt(index); + public IBindableVectorViewAdapter GetView() => new WuxBindableVectorViewAdapter(vector.GetView()); + public bool IndexOf(object value, out uint index) => vector.IndexOf(value, out index); + public void SetAt(uint index, object value) => vector.SetAt(index, value); + public void InsertAt(uint index, object value) => vector.InsertAt(index, value); + public void RemoveAt(uint index) => vector.RemoveAt(index); + public void Append(object value) => vector.Append(value); + public void RemoveAtEnd() => vector.RemoveAtEnd(); + public void Clear() => vector.Clear(); + public uint Size => vector.Size; + private sealed class WuxBindableVectorViewAdapter(WUX.IBindableVectorView vectorView) : IBindableVectorViewAdapter + { + public object GetAt(uint index) => vectorView.GetAt(index); + public bool IndexOf(object value, out uint index) => vectorView.IndexOf(value, out index); + public uint Size => vectorView.Size; } - catch (Exception __exception__) + } + + private sealed class MuxBindableVectorAdapter(MUX.IBindableVector vector) : IBindableVectorAdapter + { + public object GetAt(uint index) => vector.GetAt(index); + public IBindableVectorViewAdapter GetView() => new WuxBindableVectorViewAdapter(vector.GetView()); + public bool IndexOf(object value, out uint index) => vector.IndexOf(value, out index); + public void SetAt(uint index, object value) => vector.SetAt(index, value); + public void InsertAt(uint index, object value) => vector.InsertAt(index, value); + public void RemoveAt(uint index) => vector.RemoveAt(index); + public void Append(object value) => vector.Append(value); + public void RemoveAtEnd() => vector.RemoveAtEnd(); + public void Clear() => vector.Clear(); + public uint Size => vector.Size; + + private sealed class WuxBindableVectorViewAdapter(MUX.IBindableVectorView vectorView) : IBindableVectorViewAdapter { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + public object GetAt(uint index) => vectorView.GetAt(index); + public bool IndexOf(object value, out uint index) => vectorView.IndexOf(value, out index); + public uint Size => vectorView.Size; } - return 0; } - [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] - private static unsafe int Do_Abi_IndexOf_2(IntPtr thisPtr, IntPtr value, uint* index, byte* returnValue) + public sealed class FromAbiHelper : global::System.Collections.IList { - bool __returnValue = default; + private readonly IBindableVectorAdapter _vector; - *index = default; - *returnValue = default; - uint __index = default; + public FromAbiHelper(IBindableVectorAdapter vector) + { + _vector = vector; + } - try + public bool IsSynchronized => false; + + public object SyncRoot { get => this; } + + public int Count { - __returnValue = global::WinRT.ComWrappersSupport.FindObject(thisPtr).IndexOf(MarshalInspectable.FromAbi(value), out __index); - *index = __index; - *returnValue = (byte)(__returnValue ? 1 : 0); + get + { + uint size = _vector.Size; + if (((uint)int.MaxValue) < size) + { + throw new InvalidOperationException(WinRTRuntimeErrorStrings.InvalidOperation_CollectionBackingListTooLarge); + } + return (int)size; + } } - catch (Exception __exception__) + + public void CopyTo(Array array, int arrayIndex) { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + if (array == null) + throw new ArgumentNullException(nameof(array)); + + // ICollection expects the destination array to be single-dimensional. + if (array.Rank != 1) + throw new ArgumentException(WinRTRuntimeErrorStrings.Arg_RankMultiDimNotSupported); + + int destLB = array.GetLowerBound(0); + int srcLen = Count; + int destLen = array.GetLength(0); + + if (arrayIndex < destLB) + throw new ArgumentOutOfRangeException(nameof(arrayIndex)); + + // Does the dimension in question have sufficient space to copy the expected number of entries? + // We perform this check before valid index check to ensure the exception message is in sync with + // the following snippet that uses regular framework code: + // + // ArrayList list = new ArrayList(); + // list.Add(1); + // Array items = Array.CreateInstance(typeof(object), new int[] { 1 }, new int[] { -1 }); + // list.CopyTo(items, 0); + + if (srcLen > (destLen - (arrayIndex - destLB))) + throw new ArgumentException(WinRTRuntimeErrorStrings.Argument_InsufficientSpaceToCopyCollection); + + if (arrayIndex - destLB > destLen) + throw new ArgumentException(WinRTRuntimeErrorStrings.Argument_IndexOutOfArrayBounds); + + // We need to verify the index as we; + for (uint i = 0; i < srcLen; i++) + { + array.SetValue(_vector.GetAt(i), i + arrayIndex); + } } - return 0; - } - [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] - private static unsafe int Do_Abi_get_Size_1(IntPtr thisPtr, uint* value) - { - uint __value = default; + public object this[int index] + { + get => Indexer_Get(index); + set => Indexer_Set(index, value); + } - *value = default; + internal object Indexer_Get(int index) + { + if (index < 0) + throw new ArgumentOutOfRangeException(nameof(index)); - try + return GetAt(_vector, (uint)index); + } + + internal void Indexer_Set(int index, object value) { - __value = global::WinRT.ComWrappersSupport.FindObject(thisPtr).Size; - *value = __value; + if (index < 0) + throw new ArgumentOutOfRangeException(nameof(index)); + SetAt(_vector, (uint)index, value); } - catch (Exception __exception__) + + public int Add(object value) { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + _vector.Append(value); + + uint size = _vector.Size; + if (((uint)int.MaxValue) < size) + { + throw new InvalidOperationException(WinRTRuntimeErrorStrings.InvalidOperation_CollectionBackingListTooLarge); + } + + return (int)(size - 1); } - return 0; - } - - internal static ObjectReference FromAbi(IntPtr thisPtr) => ObjectReference.FromAbi(thisPtr); - - private static readonly global::System.Runtime.CompilerServices.ConditionalWeakTable _helperTable = new(); - - unsafe object global::Microsoft.UI.Xaml.Interop.IBindableVectorView.GetAt(uint index) - { - var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::Microsoft.UI.Xaml.Interop.IBindableIterator).TypeHandle); - var ThisPtr = _obj.ThisPtr; - IntPtr __retval = default; - try - { - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[6](ThisPtr, index, &__retval)); - return MarshalInspectable.FromAbi(__retval); - } - finally - { - MarshalInspectable.DisposeAbi(__retval); - } - } - - unsafe bool global::Microsoft.UI.Xaml.Interop.IBindableVectorView.IndexOf(object value, out uint index) - { - var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::Microsoft.UI.Xaml.Interop.IBindableIterator).TypeHandle); - var ThisPtr = _obj.ThisPtr; - ObjectReferenceValue __value = default; - uint __index = default; - byte __retval = default; - try - { - __value = MarshalInspectable.CreateMarshaler2(value); - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[8]( - ThisPtr, - MarshalInspectable.GetAbi(__value), - &__index, - &__retval)); - index = __index; - return __retval != 0; - } - finally - { - MarshalInspectable.DisposeMarshaler(__value); - } - } - - unsafe uint global::Microsoft.UI.Xaml.Interop.IBindableVectorView.Size - { - get - { - var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::Microsoft.UI.Xaml.Interop.IBindableIterator).TypeHandle); - var ThisPtr = _obj.ThisPtr; - uint __retval = default; - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[7](ThisPtr, &__retval)); - return __retval; - } - } - - IEnumerator IEnumerable.GetEnumerator() - { - return _helperTable.GetValue((IWinRTObject)this, - (enumerable) => new ABI.System.Collections.IEnumerable.FromAbiHelper((global::System.Collections.IEnumerable)(IWinRTObject)enumerable) - ).GetEnumerator(); - } - } - [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] - internal static class IBindableVectorView_Delegates - { - public unsafe delegate int GetAt_0(IntPtr thisPtr, uint index, IntPtr* result); - public unsafe delegate int get_Size_1(IntPtr thisPtr, uint* result); - public unsafe delegate int IndexOf_2(IntPtr thisPtr, IntPtr value, uint* index, byte* returnValue); - } -} - -namespace ABI.System.Collections -{ - using global::Microsoft.UI.Xaml.Interop; - using global::System; - using global::System.Runtime.CompilerServices; -#if EMBED - internal -#else - public -#endif - static class IEnumerableMethods - { - public static global::System.Guid IID { get; } = new Guid(new global::System.ReadOnlySpan(new byte[] { 0x08, 0x2C, 0x6D, 0x03, 0x29, 0xDF, 0xAF, 0x41, 0x8A, 0xA2, 0xD7, 0x74, 0xBE, 0x62, 0xBA, 0x6F })); + public bool Contains(object item) + { + return _vector.IndexOf(item, out _); + } - public static IntPtr AbiToProjectionVftablePtr => IEnumerable.AbiToProjectionVftablePtr; - } - - [DynamicInterfaceCastableImplementation] - [Guid("036D2C08-DF29-41AF-8AA2-D774BE62BA6F")] - internal unsafe interface IEnumerable : global::System.Collections.IEnumerable, global::Microsoft.UI.Xaml.Interop.IBindableIterable - { - public static string GetGuidSignature() => GuidGenerator.GetSignature(typeof(IEnumerable)); - - public sealed class AdaptiveFromAbiHelper : FromAbiHelper, global::System.Collections.IEnumerable - { - private readonly Func _enumerator; - - public AdaptiveFromAbiHelper(Type runtimeType, IWinRTObject winRTObject) - :base(winRTObject) - { - Type enumGenericType = (runtimeType.IsGenericType && runtimeType.GetGenericTypeDefinition() == typeof(global::System.Collections.Generic.IEnumerable<>)) ? - runtimeType : runtimeType.GetInterface("System.Collections.Generic.IEnumerable`1"); - if(enumGenericType != null) - { - var getEnumerator = enumGenericType.GetMethod("GetEnumerator"); - _enumerator = (IWinRTObject obj) => (global::System.Collections.IEnumerator)getEnumerator.Invoke(obj, null); - } - } - - public override global::System.Collections.IEnumerator GetEnumerator() => _enumerator != null ? _enumerator(_winrtObject) : base.GetEnumerator(); - } - - public class FromAbiHelper : global::System.Collections.IEnumerable - { - private readonly global::System.Collections.IEnumerable _iterable; - protected readonly IWinRTObject _winrtObject; - - public FromAbiHelper(global::System.Collections.IEnumerable iterable) - { - _iterable = iterable; - } - - protected FromAbiHelper(IWinRTObject winrtObject) - { - _iterable = null; - _winrtObject = winrtObject; - } - - private IWinRTObject GetIterable() - { - return (IWinRTObject)_iterable ?? _winrtObject; - } - - public virtual global::System.Collections.IEnumerator GetEnumerator() => - new Generic.FromAbiEnumerator(new NonGenericToGenericIterator(((global::Microsoft.UI.Xaml.Interop.IBindableIterable) GetIterable()).First())); - - private sealed class NonGenericToGenericIterator : global::Windows.Foundation.Collections.IIterator - { - private readonly IBindableIterator iterator; - - public NonGenericToGenericIterator(IBindableIterator iterator) => this.iterator = iterator; - - public object _Current => iterator.Current; - public bool HasCurrent => iterator.HasCurrent; - public bool _MoveNext() { return iterator.MoveNext(); } - public uint GetMany(ref object[] items) => throw new NotSupportedException(); - } - } - - public sealed class ToAbiHelper : IBindableIterable - { - private readonly IEnumerable m_enumerable; - - internal ToAbiHelper(IEnumerable enumerable) => m_enumerable = enumerable; - - IBindableIterator IBindableIterable.First() => MakeBindableIterator(m_enumerable.GetEnumerator()); - - internal static IBindableIterator MakeBindableIterator(IEnumerator enumerator) => - new Generic.IEnumerator.ToAbiHelper(new NonGenericToGenericEnumerator(enumerator)); - - private sealed class NonGenericToGenericEnumerator : IEnumerator - { - private readonly IEnumerator enumerator; - - public NonGenericToGenericEnumerator(IEnumerator enumerator) => this.enumerator = enumerator; - - public object Current => enumerator.Current; - public bool MoveNext() { return enumerator.MoveNext(); } - public void Reset() { enumerator.Reset(); } - public void Dispose() { } - } - } + public void Clear() + { + _vector.Clear(); + } - public static readonly IntPtr AbiToProjectionVftablePtr; - static IEnumerable() - { - AbiToProjectionVftablePtr = ComWrappersSupport.AllocateVtableMemory(typeof(IEnumerable), sizeof(IInspectable.Vftbl) + sizeof(IntPtr) * 1); - *(IInspectable.Vftbl*)AbiToProjectionVftablePtr = IInspectable.Vftbl.AbiToProjectionVftable; - ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[6] = &Do_Abi_First_0; + public bool IsFixedSize { get => false; } + + public bool IsReadOnly { get => false; } + + public int IndexOf(object item) + { + uint index; + bool exists = _vector.IndexOf(item, out index); + + if (!exists) + return -1; + + if (((uint)int.MaxValue) < index) + { + throw new InvalidOperationException(WinRTRuntimeErrorStrings.InvalidOperation_CollectionBackingListTooLarge); + } + + return (int)index; + } + + public void Insert(int index, object item) + { + if (index < 0) + throw new ArgumentOutOfRangeException(nameof(index)); + + InsertAtHelper(_vector, (uint)index, item); + } + + public void Remove(object item) + { + uint index; + bool exists = _vector.IndexOf(item, out index); + + if (exists) + { + if (((uint)int.MaxValue) < index) + { + throw new InvalidOperationException(WinRTRuntimeErrorStrings.InvalidOperation_CollectionBackingListTooLarge); + } + + RemoveAtHelper(_vector, index); + } + } + + public void RemoveAt(int index) + { + if (index < 0) + throw new ArgumentOutOfRangeException(nameof(index)); + + RemoveAtHelper(_vector, (uint)index); + } + + private static object GetAt(IBindableVectorAdapter _this, uint index) + { + try + { + return _this.GetAt(index); + + // We delegate bounds checking to the underlying collection and if it detected a fault, + // we translate it to the right exception: + } + catch (Exception ex) + { + if (ExceptionHelpers.E_BOUNDS == ex.HResult) + throw new ArgumentOutOfRangeException(nameof(index)); + throw; + } + } + + private static void SetAt(IBindableVectorAdapter _this, uint index, object value) + { + try + { + _this.SetAt(index, value); + + // We delegate bounds checking to the underlying collection and if it detected a fault, + // we translate it to the right exception: + } + catch (Exception ex) + { + if (ExceptionHelpers.E_BOUNDS == ex.HResult) + throw new ArgumentOutOfRangeException(nameof(index)); + throw; + } + } + + private static void InsertAtHelper(IBindableVectorAdapter _this, uint index, object item) + { + try + { + _this.InsertAt(index, item); + + // We delegate bounds checking to the underlying collection and if it detected a fault, + // we translate it to the right exception: + } + catch (Exception ex) + { + if (ExceptionHelpers.E_BOUNDS == ex.HResult) + throw new ArgumentOutOfRangeException(nameof(index)); + throw; + } + } + + private static void RemoveAtHelper(IBindableVectorAdapter _this, uint index) + { + try + { + _this.RemoveAt(index); + + // We delegate bounds checking to the underlying collection and if it detected a fault, + // we translate it to the right exception: + } + catch (Exception ex) + { + if (ExceptionHelpers.E_BOUNDS == ex.HResult) + throw new ArgumentOutOfRangeException(nameof(index)); + throw; + } + } + + public IEnumerator GetEnumerator() + { + return ((IEnumerable)(IWinRTObject)_vector).GetEnumerator(); + } } - [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] - private static unsafe int Do_Abi_First_0(IntPtr thisPtr, IntPtr* result) + public sealed class ToAbiHelper : WUX.IBindableVector, MUX.IBindableVector, IBindableVectorAdapter { - *result = default; - try + private global::System.Collections.IList _list; + + public ToAbiHelper(global::System.Collections.IList list) => _list = list; + + public object GetAt(uint index) { - var __this = global::WinRT.ComWrappersSupport.FindObject(thisPtr); - var iterator = ToAbiHelper.MakeBindableIterator(__this.GetEnumerator()); - *result = MarshalInterface.FromManaged(iterator); + EnsureIndexInt32(index, _list.Count); + + try + { + return _list[(int)index]; + } + catch (ArgumentOutOfRangeException ex) + { + throw ex.GetExceptionForHR(ExceptionHelpers.E_BOUNDS, WinRTRuntimeErrorStrings.ArgumentOutOfRange_Index); + } } - catch (Exception __exception__) + + public uint Size { get => (uint)_list.Count; } + + IBindableVectorViewAdapter IBindableVectorAdapter.GetView() { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + return new ListToBindableVectorViewAdapter(_list); } - return 0; - } - - internal static ObjectReference ObjRefFromAbi(IntPtr thisPtr) - { - if (thisPtr == IntPtr.Zero) - { - return null; - } - return ObjectReference.FromAbi(thisPtr); - } - - private static FromAbiHelper _AbiHelper(IWinRTObject _this) - { - return (FromAbiHelper)_this.GetOrCreateTypeHelperData(typeof(global::System.Collections.IEnumerable).TypeHandle, - () => new FromAbiHelper((global::System.Collections.IEnumerable)_this)); - } - - unsafe global::Microsoft.UI.Xaml.Interop.IBindableIterator global::Microsoft.UI.Xaml.Interop.IBindableIterable.First() - { - var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IEnumerable).TypeHandle); - var ThisPtr = _obj.ThisPtr; - IntPtr __retval = default; - try - { - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[6](ThisPtr, &__retval)); - return MarshalInterface.FromAbi(__retval); - } - finally - { - MarshalInterface.DisposeAbi(__retval); - } - } - - IEnumerator global::System.Collections.IEnumerable.GetEnumerator() - { - return _AbiHelper((IWinRTObject)this).GetEnumerator(); - } - } - - [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] -#if EMBED - internal -#else - public -#endif - static class IEnumerable_Delegates - { - public unsafe delegate int First_0(IntPtr thisPtr, IntPtr* result); - } -#if EMBED - internal -#else - public -#endif - static class IListMethods - { - public static Guid IID { get; } = new Guid(new global::System.ReadOnlySpan(new byte[] { 0xDE, 0xE7, 0x3D, 0x39, 0xD0, 0x6F, 0x0D, 0x4C, 0xBB, 0x71, 0x47, 0x24, 0x4A, 0x11, 0x3E, 0x93 })); + WUX.IBindableVectorView WUX.IBindableVector.GetView() + { + return new ListToBindableVectorViewAdapter(_list); + } - public static IntPtr AbiToProjectionVftablePtr => IList.AbiToProjectionVftablePtr; - } + MUX.IBindableVectorView MUX.IBindableVector.GetView() + { + return new ListToBindableVectorViewAdapter(_list); + } + + public bool IndexOf(object value, out uint index) + { + int ind = _list.IndexOf(value); + + if (-1 == ind) + { + index = 0; + return false; + } - [DynamicInterfaceCastableImplementation] - [Guid("393DE7DE-6FD0-4C0D-BB71-47244A113E93")] - internal unsafe interface IList : global::System.Collections.IList, global::Microsoft.UI.Xaml.Interop.IBindableVector - { - public static string GetGuidSignature() => GuidGenerator.GetSignature(typeof(IList)); - - public sealed class FromAbiHelper : global::System.Collections.IList - { - private readonly global::Microsoft.UI.Xaml.Interop.IBindableVector _vector; - - public FromAbiHelper(global::Microsoft.UI.Xaml.Interop.IBindableVector vector) - { - _vector = vector; - } - - public bool IsSynchronized => false; - - public object SyncRoot { get => this; } - - public int Count - { - get - { - uint size = _vector.Size; - if (((uint)int.MaxValue) < size) - { - throw new InvalidOperationException(WinRTRuntimeErrorStrings.InvalidOperation_CollectionBackingListTooLarge); - } - - return (int)size; - } - } - - public void CopyTo(Array array, int arrayIndex) - { - if (array == null) - throw new ArgumentNullException(nameof(array)); - - // ICollection expects the destination array to be single-dimensional. - if (array.Rank != 1) - throw new ArgumentException(WinRTRuntimeErrorStrings.Arg_RankMultiDimNotSupported); - - int destLB = array.GetLowerBound(0); - int srcLen = Count; - int destLen = array.GetLength(0); - - if (arrayIndex < destLB) - throw new ArgumentOutOfRangeException(nameof(arrayIndex)); - - // Does the dimension in question have sufficient space to copy the expected number of entries? - // We perform this check before valid index check to ensure the exception message is in sync with - // the following snippet that uses regular framework code: - // - // ArrayList list = new ArrayList(); - // list.Add(1); - // Array items = Array.CreateInstance(typeof(object), new int[] { 1 }, new int[] { -1 }); - // list.CopyTo(items, 0); - - if (srcLen > (destLen - (arrayIndex - destLB))) - throw new ArgumentException(WinRTRuntimeErrorStrings.Argument_InsufficientSpaceToCopyCollection); - - if (arrayIndex - destLB > destLen) - throw new ArgumentException(WinRTRuntimeErrorStrings.Argument_IndexOutOfArrayBounds); - - // We need to verify the index as we; - for (uint i = 0; i < srcLen; i++) - { - array.SetValue(_vector.GetAt(i), i + arrayIndex); - } - } - - public object this[int index] - { - get => Indexer_Get(index); - set => Indexer_Set(index, value); - } - - internal object Indexer_Get(int index) - { - if (index < 0) - throw new ArgumentOutOfRangeException(nameof(index)); - - return GetAt(_vector, (uint)index); - } - - internal void Indexer_Set(int index, object value) - { - if (index < 0) - throw new ArgumentOutOfRangeException(nameof(index)); - - SetAt(_vector, (uint)index, value); - } - - public int Add(object value) - { - _vector.Append(value); - - uint size = _vector.Size; - if (((uint)int.MaxValue) < size) - { - throw new InvalidOperationException(WinRTRuntimeErrorStrings.InvalidOperation_CollectionBackingListTooLarge); - } - - return (int)(size - 1); - } - - public bool Contains(object item) - { - return _vector.IndexOf(item, out _); - } - - public void Clear() - { - _vector.Clear(); - } - - public bool IsFixedSize { get => false; } - - public bool IsReadOnly { get => false; } - - public int IndexOf(object item) - { - uint index; - bool exists = _vector.IndexOf(item, out index); - - if (!exists) - return -1; - - if (((uint)int.MaxValue) < index) - { - throw new InvalidOperationException(WinRTRuntimeErrorStrings.InvalidOperation_CollectionBackingListTooLarge); - } - - return (int)index; - } - - public void Insert(int index, object item) - { - if (index < 0) - throw new ArgumentOutOfRangeException(nameof(index)); - - InsertAtHelper(_vector, (uint)index, item); - } - - public void Remove(object item) - { - uint index; - bool exists = _vector.IndexOf(item, out index); - - if (exists) - { - if (((uint)int.MaxValue) < index) - { - throw new InvalidOperationException(WinRTRuntimeErrorStrings.InvalidOperation_CollectionBackingListTooLarge); - } - - RemoveAtHelper(_vector, index); - } - } - - public void RemoveAt(int index) - { - if (index < 0) - throw new ArgumentOutOfRangeException(nameof(index)); - - RemoveAtHelper(_vector, (uint)index); - } - - private static object GetAt(global::Microsoft.UI.Xaml.Interop.IBindableVector _this, uint index) - { - try - { - return _this.GetAt(index); - - // We delegate bounds checking to the underlying collection and if it detected a fault, - // we translate it to the right exception: - } - catch (Exception ex) - { - if (ExceptionHelpers.E_BOUNDS == ex.HResult) - throw new ArgumentOutOfRangeException(nameof(index)); - throw; - } - } - - private static void SetAt(global::Microsoft.UI.Xaml.Interop.IBindableVector _this, uint index, object value) - { - try - { - _this.SetAt(index, value); - - // We delegate bounds checking to the underlying collection and if it detected a fault, - // we translate it to the right exception: - } - catch (Exception ex) - { - if (ExceptionHelpers.E_BOUNDS == ex.HResult) - throw new ArgumentOutOfRangeException(nameof(index)); - throw; - } - } - - private static void InsertAtHelper(global::Microsoft.UI.Xaml.Interop.IBindableVector _this, uint index, object item) - { - try - { - _this.InsertAt(index, item); - - // We delegate bounds checking to the underlying collection and if it detected a fault, - // we translate it to the right exception: - } - catch (Exception ex) - { - if (ExceptionHelpers.E_BOUNDS == ex.HResult) - throw new ArgumentOutOfRangeException(nameof(index)); - throw; - } - } - - private static void RemoveAtHelper(global::Microsoft.UI.Xaml.Interop.IBindableVector _this, uint index) - { - try - { - _this.RemoveAt(index); - - // We delegate bounds checking to the underlying collection and if it detected a fault, - // we translate it to the right exception: - } - catch (Exception ex) - { - if (ExceptionHelpers.E_BOUNDS == ex.HResult) - throw new ArgumentOutOfRangeException(nameof(index)); - throw; - } - } - - public IEnumerator GetEnumerator() - { - return ((IEnumerable)(IWinRTObject)_vector).GetEnumerator(); - } - } - - public sealed class ToAbiHelper : IBindableVector - { - private global::System.Collections.IList _list; - - public ToAbiHelper(global::System.Collections.IList list) => _list = list; - - public object GetAt(uint index) - { - EnsureIndexInt32(index, _list.Count); - - try - { - return _list[(int)index]; - } - catch (ArgumentOutOfRangeException ex) - { - throw ex.GetExceptionForHR(ExceptionHelpers.E_BOUNDS, WinRTRuntimeErrorStrings.ArgumentOutOfRange_Index); - } - } - - public uint Size { get => (uint)_list.Count; } - - IBindableVectorView IBindableVector.GetView() - { - return new ListToBindableVectorViewAdapter(_list); - } - - public bool IndexOf(object value, out uint index) - { - int ind = _list.IndexOf(value); - - if (-1 == ind) - { - index = 0; - return false; - } - - index = (uint)ind; - return true; - } - - public void SetAt(uint index, object value) - { - EnsureIndexInt32(index, _list.Count); - - try - { - _list[(int)index] = value; - } - catch (ArgumentOutOfRangeException ex) - { - throw ex.GetExceptionForHR(ExceptionHelpers.E_BOUNDS, WinRTRuntimeErrorStrings.ArgumentOutOfRange_Index); - } - } - - public void InsertAt(uint index, object value) - { - // Inserting at an index one past the end of the list is equivalent to appending - // so we need to ensure that we're within (0, count + 1). - EnsureIndexInt32(index, _list.Count + 1); - - try - { - _list.Insert((int)index, value); - } - catch (ArgumentOutOfRangeException ex) - { - // Change error code to match what WinRT expects - ex.SetHResult(ExceptionHelpers.E_BOUNDS); - throw; - } - } - - public void RemoveAt(uint index) - { - EnsureIndexInt32(index, _list.Count); - - try - { - _list.RemoveAt((int)index); - } - catch (ArgumentOutOfRangeException ex) - { - // Change error code to match what WinRT expects - ex.SetHResult(ExceptionHelpers.E_BOUNDS); - throw; - } - } - - public void Append(object value) - { - _list.Add(value); - } - - public void RemoveAtEnd() - { - if (_list.Count == 0) - { - Exception e = new InvalidOperationException(WinRTRuntimeErrorStrings.InvalidOperation_CannotRemoveLastFromEmptyCollection); - e.SetHResult(ExceptionHelpers.E_BOUNDS); - throw e; - } - - uint size = (uint)_list.Count; - RemoveAt(size - 1); - } - - public void Clear() - { - _list.Clear(); - } - - private static void EnsureIndexInt32(uint index, int listCapacity) - { - // We use '<=' and not '<' becasue int.MaxValue == index would imply - // that Size > int.MaxValue: - if (((uint)int.MaxValue) <= index || index >= (uint)listCapacity) - { - Exception e = new ArgumentOutOfRangeException(nameof(index), WinRTRuntimeErrorStrings.ArgumentOutOfRange_IndexLargerThanMaxValue); - e.SetHResult(ExceptionHelpers.E_BOUNDS); - throw e; - } - } - - public IEnumerator GetEnumerator() => _list.GetEnumerator(); - - /// A Windows Runtime IBindableVectorView implementation that wraps around a managed IList exposing - /// it to Windows runtime interop. - internal sealed class ListToBindableVectorViewAdapter : IBindableVectorView - { - private readonly global::System.Collections.IList list; - - internal ListToBindableVectorViewAdapter(global::System.Collections.IList list) - { - if (list == null) - throw new ArgumentNullException(nameof(list)); - this.list = list; - } - - private static void EnsureIndexInt32(uint index, int listCapacity) - { - // We use '<=' and not '<' becasue int.MaxValue == index would imply - // that Size > int.MaxValue: - if (((uint)int.MaxValue) <= index || index >= (uint)listCapacity) - { - Exception e = new ArgumentOutOfRangeException(nameof(index), WinRTRuntimeErrorStrings.ArgumentOutOfRange_IndexLargerThanMaxValue); - e.SetHResult(ExceptionHelpers.E_BOUNDS); - throw e; - } - } - - public IBindableIterator First() => - IEnumerable.ToAbiHelper.MakeBindableIterator(list.GetEnumerator()); - - public object GetAt(uint index) - { - EnsureIndexInt32(index, list.Count); - - try - { - return list[(int)index]; - } - catch (ArgumentOutOfRangeException ex) - { - throw ex.GetExceptionForHR(ExceptionHelpers.E_BOUNDS, WinRTRuntimeErrorStrings.ArgumentOutOfRange_Index); - } - } - - public uint Size => (uint)list.Count; - - public bool IndexOf(object value, out uint index) - { - int ind = list.IndexOf(value); - - if (-1 == ind) - { - index = 0; - return false; - } - - index = (uint)ind; - return true; - } - - public IEnumerator GetEnumerator() => list.GetEnumerator(); - } + index = (uint)ind; + return true; + } + + public void SetAt(uint index, object value) + { + EnsureIndexInt32(index, _list.Count); + + try + { + _list[(int)index] = value; + } + catch (ArgumentOutOfRangeException ex) + { + throw ex.GetExceptionForHR(ExceptionHelpers.E_BOUNDS, WinRTRuntimeErrorStrings.ArgumentOutOfRange_Index); + } + } + + public void InsertAt(uint index, object value) + { + // Inserting at an index one past the end of the list is equivalent to appending + // so we need to ensure that we're within (0, count + 1). + EnsureIndexInt32(index, _list.Count + 1); + + try + { + _list.Insert((int)index, value); + } + catch (ArgumentOutOfRangeException ex) + { + // Change error code to match what WinRT expects + ex.SetHResult(ExceptionHelpers.E_BOUNDS); + throw; + } + } + + public void RemoveAt(uint index) + { + EnsureIndexInt32(index, _list.Count); + + try + { + _list.RemoveAt((int)index); + } + catch (ArgumentOutOfRangeException ex) + { + // Change error code to match what WinRT expects + ex.SetHResult(ExceptionHelpers.E_BOUNDS); + throw; + } + } + + public void Append(object value) + { + _list.Add(value); + } + + public void RemoveAtEnd() + { + if (_list.Count == 0) + { + Exception e = new InvalidOperationException(WinRTRuntimeErrorStrings.InvalidOperation_CannotRemoveLastFromEmptyCollection); + e.SetHResult(ExceptionHelpers.E_BOUNDS); + throw e; + } + + uint size = (uint)_list.Count; + RemoveAt(size - 1); + } + + public void Clear() + { + _list.Clear(); + } + + private static void EnsureIndexInt32(uint index, int listCapacity) + { + // We use '<=' and not '<' becasue int.MaxValue == index would imply + // that Size > int.MaxValue: + if (((uint)int.MaxValue) <= index || index >= (uint)listCapacity) + { + Exception e = new ArgumentOutOfRangeException(nameof(index), WinRTRuntimeErrorStrings.ArgumentOutOfRange_IndexLargerThanMaxValue); + e.SetHResult(ExceptionHelpers.E_BOUNDS); + throw e; + } + } + + public IEnumerator GetEnumerator() => _list.GetEnumerator(); + + /// A Windows Runtime IBindableVectorView implementation that wraps around a managed IList exposing + /// it to Windows runtime interop. + internal sealed class ListToBindableVectorViewAdapter : WUX.IBindableVectorView, MUX.IBindableVectorView, IBindableVectorViewAdapter + { + private readonly global::System.Collections.IList list; + + internal ListToBindableVectorViewAdapter(global::System.Collections.IList list) + { + if (list == null) + throw new ArgumentNullException(nameof(list)); + this.list = list; + } + + private static void EnsureIndexInt32(uint index, int listCapacity) + { + // We use '<=' and not '<' becasue int.MaxValue == index would imply + // that Size > int.MaxValue: + if (((uint)int.MaxValue) <= index || index >= (uint)listCapacity) + { + Exception e = new ArgumentOutOfRangeException(nameof(index), WinRTRuntimeErrorStrings.ArgumentOutOfRange_IndexLargerThanMaxValue); + e.SetHResult(ExceptionHelpers.E_BOUNDS); + throw e; + } + } + + public object GetAt(uint index) + { + EnsureIndexInt32(index, list.Count); + + try + { + return list[(int)index]; + } + catch (ArgumentOutOfRangeException ex) + { + throw ex.GetExceptionForHR(ExceptionHelpers.E_BOUNDS, WinRTRuntimeErrorStrings.ArgumentOutOfRange_Index); + } + } + + public uint Size => (uint)list.Count; + + public bool IndexOf(object value, out uint index) + { + int ind = list.IndexOf(value); + + if (-1 == ind) + { + index = 0; + return false; + } + + index = (uint)ind; + return true; + } + + public IEnumerator GetEnumerator() => list.GetEnumerator(); + } } - public static readonly IntPtr AbiToProjectionVftablePtr; + public static readonly IntPtr AbiToProjectionVftablePtr; static IList() { - AbiToProjectionVftablePtr = ComWrappersSupport.AllocateVtableMemory(typeof(IList), sizeof(IInspectable.Vftbl) + sizeof(IntPtr) * 10); - *(IInspectable.Vftbl*)AbiToProjectionVftablePtr = IInspectable.Vftbl.AbiToProjectionVftable; + AbiToProjectionVftablePtr = ComWrappersSupport.AllocateVtableMemory(typeof(IList), sizeof(IInspectable.Vftbl) + sizeof(IntPtr) * 10); + *(IInspectable.Vftbl*)AbiToProjectionVftablePtr = IInspectable.Vftbl.AbiToProjectionVftable; ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[6] = &Do_Abi_GetAt_0; - ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[7] = &Do_Abi_get_Size_1; - ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[8] = &Do_Abi_GetView_2; - ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[9] = &Do_Abi_IndexOf_3; - ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[10] = &Do_Abi_SetAt_4; - ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[11] = &Do_Abi_InsertAt_5; - ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[12] = &Do_Abi_RemoveAt_6; - ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[13] = &Do_Abi_Append_7; - ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[14] = &Do_Abi_RemoveAtEnd_8; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[7] = &Do_Abi_get_Size_1; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[8] = Projections.UiXamlModeSetting is Projections.UiXamlMode.WindowsUiXaml ? &Do_Wux_Abi_GetView_2 : &Do_Mux_Abi_GetView_2; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[9] = &Do_Abi_IndexOf_3; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[10] = &Do_Abi_SetAt_4; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[11] = &Do_Abi_InsertAt_5; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[12] = &Do_Abi_RemoveAt_6; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[13] = &Do_Abi_Append_7; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[14] = &Do_Abi_RemoveAtEnd_8; ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[15] = &Do_Abi_Clear_9; } private static readonly ConditionalWeakTable _adapterTable = new(); - private static IBindableVector FindAdapter(IntPtr thisPtr) + private static IBindableVectorAdapter FindAdapter(IntPtr thisPtr) { var __this = global::WinRT.ComWrappersSupport.FindObject(thisPtr); return _adapterTable.GetValue(__this, (list) => new ToAbiHelper(list)); @@ -1031,14 +805,32 @@ private static unsafe int Do_Abi_GetAt_0(IntPtr thisPtr, uint index, IntPtr* res } [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] - private static unsafe int Do_Abi_GetView_2(IntPtr thisPtr, IntPtr* result) + private static unsafe int Do_Wux_Abi_GetView_2(IntPtr thisPtr, IntPtr* result) { - global::Microsoft.UI.Xaml.Interop.IBindableVectorView __result = default; + IBindableVectorViewAdapter __result = default; *result = default; try { __result = FindAdapter(thisPtr).GetView(); - *result = MarshalInterface.FromManaged(__result); + *result = MarshalInterface.FromManaged((WUX.IBindableVectorView)__result); + } + catch (Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + + [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] + private static unsafe int Do_Mux_Abi_GetView_2(IntPtr thisPtr, IntPtr* result) + { + IBindableVectorViewAdapter __result = default; + *result = default; + try + { + __result = FindAdapter(thisPtr).GetView(); + *result = MarshalInterface.FromManaged((MUX.IBindableVectorView)__result); } catch (Exception __exception__) { @@ -1177,202 +969,211 @@ private static unsafe int Do_Abi_get_Size_1(IntPtr thisPtr, uint* value) return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); } return 0; - } - - internal static ObjectReference ObjRefFromAbi(IntPtr thisPtr) - { - if (thisPtr == IntPtr.Zero) - { - return null; - } - return ObjectReference.FromAbi(thisPtr); - } - - internal static FromAbiHelper _VectorToList(IWinRTObject _this) - { - return (FromAbiHelper)_this.GetOrCreateTypeHelperData(typeof(global::System.Collections.IList).TypeHandle, - () => new FromAbiHelper((global::Microsoft.UI.Xaml.Interop.IBindableVector)_this)); - } - - unsafe object global::Microsoft.UI.Xaml.Interop.IBindableVector.GetAt(uint index) - { - var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); - var ThisPtr = _obj.ThisPtr; - IntPtr __retval = default; - try - { - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[6](ThisPtr, index, &__retval)); - return MarshalInspectable.FromAbi(__retval); - } - finally - { - MarshalInspectable.DisposeAbi(__retval); - } - } - - unsafe global::Microsoft.UI.Xaml.Interop.IBindableVectorView global::Microsoft.UI.Xaml.Interop.IBindableVector.GetView() - { - var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); - var ThisPtr = _obj.ThisPtr; - IntPtr __retval = default; - try - { - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[8](ThisPtr, &__retval)); - return MarshalInterface.FromAbi(__retval); - } - finally - { - MarshalInterface.DisposeAbi(__retval); - } - } - - unsafe bool global::Microsoft.UI.Xaml.Interop.IBindableVector.IndexOf(object value, out uint index) - { - var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); - var ThisPtr = _obj.ThisPtr; - ObjectReferenceValue __value = default; - uint __index = default; - byte __retval = default; - try - { + } + + internal static ObjectReference ObjRefFromAbi(IntPtr thisPtr) + { + if (thisPtr == IntPtr.Zero) + { + return null; + } + return ObjectReference.FromAbi(thisPtr); + } + + internal static FromAbiHelper _VectorToList(IWinRTObject _this) + { + IBindableVectorAdapter adapter = null; + if (Projections.UiXamlModeSetting is Projections.UiXamlMode.WindowsUiXaml) + { + adapter = new WuxBindableVectorAdapter((WUX.IBindableVector)_this); + } + else + { + adapter = new MuxBindableVectorAdapter((MUX.IBindableVector)_this); + } + return (FromAbiHelper)_this.GetOrCreateTypeHelperData(typeof(global::System.Collections.IList).TypeHandle, + () => new FromAbiHelper(adapter)); + } + + unsafe object global::Windows.UI.Xaml.Interop.IBindableVector.GetAt(uint index) + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); + var ThisPtr = _obj.ThisPtr; + IntPtr __retval = default; + try + { + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[6](ThisPtr, index, &__retval)); + return MarshalInspectable.FromAbi(__retval); + } + finally + { + MarshalInspectable.DisposeAbi(__retval); + } + } + + unsafe global::Windows.UI.Xaml.Interop.IBindableVectorView global::Windows.UI.Xaml.Interop.IBindableVector.GetView() + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); + var ThisPtr = _obj.ThisPtr; + IntPtr __retval = default; + try + { + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[8](ThisPtr, &__retval)); + return MarshalInterface.FromAbi(__retval); + } + finally + { + MarshalInterface.DisposeAbi(__retval); + } + } + + unsafe bool global::Windows.UI.Xaml.Interop.IBindableVector.IndexOf(object value, out uint index) + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); + var ThisPtr = _obj.ThisPtr; + ObjectReferenceValue __value = default; + uint __index = default; + byte __retval = default; + try + { __value = MarshalInspectable.CreateMarshaler2(value); - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[9](ThisPtr, MarshalInspectable.GetAbi(__value), &__index, &__retval)); - index = __index; - return __retval != 0; - } - finally - { - MarshalInspectable.DisposeMarshaler(__value); - } - } - - unsafe void global::Microsoft.UI.Xaml.Interop.IBindableVector.SetAt(uint index, object value) - { - var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); - var ThisPtr = _obj.ThisPtr; - ObjectReferenceValue __value = default; - try - { + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[9](ThisPtr, MarshalInspectable.GetAbi(__value), &__index, &__retval)); + index = __index; + return __retval != 0; + } + finally + { + MarshalInspectable.DisposeMarshaler(__value); + } + } + + unsafe void global::Windows.UI.Xaml.Interop.IBindableVector.SetAt(uint index, object value) + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); + var ThisPtr = _obj.ThisPtr; + ObjectReferenceValue __value = default; + try + { __value = MarshalInspectable.CreateMarshaler2(value); - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[10](ThisPtr, index, MarshalInspectable.GetAbi(__value))); - } - finally - { - MarshalInspectable.DisposeMarshaler(__value); - } - } - - unsafe void global::Microsoft.UI.Xaml.Interop.IBindableVector.InsertAt(uint index, object value) - { - var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); - var ThisPtr = _obj.ThisPtr; - ObjectReferenceValue __value = default; - try - { + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[10](ThisPtr, index, MarshalInspectable.GetAbi(__value))); + } + finally + { + MarshalInspectable.DisposeMarshaler(__value); + } + } + + unsafe void global::Windows.UI.Xaml.Interop.IBindableVector.InsertAt(uint index, object value) + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); + var ThisPtr = _obj.ThisPtr; + ObjectReferenceValue __value = default; + try + { __value = MarshalInspectable.CreateMarshaler2(value); - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[11](ThisPtr, index, MarshalInspectable.GetAbi(__value))); - } - finally - { - MarshalInspectable.DisposeMarshaler(__value); - } - } - - unsafe void global::Microsoft.UI.Xaml.Interop.IBindableVector.RemoveAt(uint index) - { - var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[11](ThisPtr, index, MarshalInspectable.GetAbi(__value))); + } + finally + { + MarshalInspectable.DisposeMarshaler(__value); + } + } + + unsafe void global::Windows.UI.Xaml.Interop.IBindableVector.RemoveAt(uint index) + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); + var ThisPtr = _obj.ThisPtr; + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[12](ThisPtr, index)); + } + + unsafe void global::Windows.UI.Xaml.Interop.IBindableVector.Append(object value) + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); var ThisPtr = _obj.ThisPtr; - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[12](ThisPtr, index)); - } - - unsafe void global::Microsoft.UI.Xaml.Interop.IBindableVector.Append(object value) - { - var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); - var ThisPtr = _obj.ThisPtr; - ObjectReferenceValue __value = default; - try - { + ObjectReferenceValue __value = default; + try + { __value = MarshalInspectable.CreateMarshaler2(value); - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[13](ThisPtr, MarshalInspectable.GetAbi(__value))); - } - finally - { - MarshalInspectable.DisposeMarshaler(__value); - } - } - - unsafe void global::Microsoft.UI.Xaml.Interop.IBindableVector.RemoveAtEnd() - { - var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[13](ThisPtr, MarshalInspectable.GetAbi(__value))); + } + finally + { + MarshalInspectable.DisposeMarshaler(__value); + } + } + + unsafe void global::Windows.UI.Xaml.Interop.IBindableVector.RemoveAtEnd() + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); var ThisPtr = _obj.ThisPtr; - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[14](ThisPtr)); - } - - unsafe void global::Microsoft.UI.Xaml.Interop.IBindableVector.Clear() - { - var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[14](ThisPtr)); + } + + unsafe void global::Windows.UI.Xaml.Interop.IBindableVector.Clear() + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); var ThisPtr = _obj.ThisPtr; - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[15](ThisPtr)); - } - - unsafe uint global::Microsoft.UI.Xaml.Interop.IBindableVector.Size - { - get - { - var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); - var ThisPtr = _obj.ThisPtr; + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[15](ThisPtr)); + } + + unsafe uint global::Windows.UI.Xaml.Interop.IBindableVector.Size + { + get + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); + var ThisPtr = _obj.ThisPtr; uint __retval = default; - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[7](ThisPtr, &__retval)); - return __retval; - } - } - - object global::System.Collections.IList.this[int index] - { - get => _VectorToList((IWinRTObject)this)[index]; - - set => _VectorToList((IWinRTObject)this)[index] = value; - } - - bool global::System.Collections.IList.IsFixedSize => _VectorToList((IWinRTObject)this).IsFixedSize; - - bool global::System.Collections.IList.IsReadOnly => _VectorToList((IWinRTObject)this).IsReadOnly; - - int global::System.Collections.ICollection.Count => _VectorToList((IWinRTObject)this).Count; - - bool global::System.Collections.ICollection.IsSynchronized => _VectorToList((IWinRTObject)this).IsSynchronized; - - object global::System.Collections.ICollection.SyncRoot => _VectorToList((IWinRTObject)this).SyncRoot; - - int global::System.Collections.IList.Add(object value) => _VectorToList((IWinRTObject)this).Add(value); - - void global::System.Collections.IList.Clear() => _VectorToList((IWinRTObject)this).Clear(); - - bool global::System.Collections.IList.Contains(object value) => _VectorToList((IWinRTObject)this).Contains(value); - - int global::System.Collections.IList.IndexOf(object value) => _VectorToList((IWinRTObject)this).IndexOf(value); - - void global::System.Collections.IList.Insert(int index, object value) => _VectorToList((IWinRTObject)this).Insert(index, value); - - void global::System.Collections.IList.Remove(object value) => _VectorToList((IWinRTObject)this).Remove(value); - - void global::System.Collections.IList.RemoveAt(int index) => _VectorToList((IWinRTObject)this).RemoveAt(index); - - void global::System.Collections.ICollection.CopyTo(Array array, int index) => _VectorToList((IWinRTObject)this).CopyTo(array, index); - - IEnumerator global::System.Collections.IEnumerable.GetEnumerator() => _VectorToList((IWinRTObject)this).GetEnumerator(); - } - internal static class IList_Delegates - { - public unsafe delegate int GetAt_0(IntPtr thisPtr, uint index, IntPtr* result); - public unsafe delegate int get_Size_1(IntPtr thisPtr, uint* result); - public unsafe delegate int GetView_2(IntPtr thisPtr, IntPtr* result); - public unsafe delegate int IndexOf_3(IntPtr thisPtr, IntPtr value, uint* index, byte* returnValue); - public unsafe delegate int SetAt_4(IntPtr thisPtr, uint index, IntPtr value); - public unsafe delegate int InsertAt_5(IntPtr thisPtr, uint index, IntPtr value); - public unsafe delegate int RemoveAt_6(IntPtr thisPtr, uint index); - public unsafe delegate int Append_7(IntPtr thisPtr, IntPtr value); - public unsafe delegate int RemoveAtEnd_8(IntPtr thisPtr); - public unsafe delegate int Clear_9(IntPtr thisPtr); - } -} + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[7](ThisPtr, &__retval)); + return __retval; + } + } + + object global::System.Collections.IList.this[int index] + { + get => _VectorToList((IWinRTObject)this)[index]; + + set => _VectorToList((IWinRTObject)this)[index] = value; + } + + bool global::System.Collections.IList.IsFixedSize => _VectorToList((IWinRTObject)this).IsFixedSize; + + bool global::System.Collections.IList.IsReadOnly => _VectorToList((IWinRTObject)this).IsReadOnly; + + int global::System.Collections.ICollection.Count => _VectorToList((IWinRTObject)this).Count; + + bool global::System.Collections.ICollection.IsSynchronized => _VectorToList((IWinRTObject)this).IsSynchronized; + + object global::System.Collections.ICollection.SyncRoot => _VectorToList((IWinRTObject)this).SyncRoot; + + int global::System.Collections.IList.Add(object value) => _VectorToList((IWinRTObject)this).Add(value); + + void global::System.Collections.IList.Clear() => _VectorToList((IWinRTObject)this).Clear(); + + bool global::System.Collections.IList.Contains(object value) => _VectorToList((IWinRTObject)this).Contains(value); + + int global::System.Collections.IList.IndexOf(object value) => _VectorToList((IWinRTObject)this).IndexOf(value); + + void global::System.Collections.IList.Insert(int index, object value) => _VectorToList((IWinRTObject)this).Insert(index, value); + + void global::System.Collections.IList.Remove(object value) => _VectorToList((IWinRTObject)this).Remove(value); + + void global::System.Collections.IList.RemoveAt(int index) => _VectorToList((IWinRTObject)this).RemoveAt(index); + + void global::System.Collections.ICollection.CopyTo(Array array, int index) => _VectorToList((IWinRTObject)this).CopyTo(array, index); + + IEnumerator global::System.Collections.IEnumerable.GetEnumerator() => _VectorToList((IWinRTObject)this).GetEnumerator(); + } + internal static class IList_Delegates + { + public unsafe delegate int GetAt_0(IntPtr thisPtr, uint index, IntPtr* result); + public unsafe delegate int get_Size_1(IntPtr thisPtr, uint* result); + public unsafe delegate int GetView_2(IntPtr thisPtr, IntPtr* result); + public unsafe delegate int IndexOf_3(IntPtr thisPtr, IntPtr value, uint* index, byte* returnValue); + public unsafe delegate int SetAt_4(IntPtr thisPtr, uint index, IntPtr value); + public unsafe delegate int InsertAt_5(IntPtr thisPtr, uint index, IntPtr value); + public unsafe delegate int RemoveAt_6(IntPtr thisPtr, uint index); + public unsafe delegate int Append_7(IntPtr thisPtr, IntPtr value); + public unsafe delegate int RemoveAtEnd_8(IntPtr thisPtr); + public unsafe delegate int Clear_9(IntPtr thisPtr); + } +} diff --git a/src/WinRT.Runtime/Projections/ICommand.net5.cs b/src/WinRT.Runtime/Projections/ICommand.net5.cs index 8f6ca008a..1f4c89b8c 100644 --- a/src/WinRT.Runtime/Projections/ICommand.net5.cs +++ b/src/WinRT.Runtime/Projections/ICommand.net5.cs @@ -20,6 +20,7 @@ static class ICommandMethods public static IntPtr AbiToProjectionVftablePtr => ICommand.Vftbl.AbiToProjectionVftablePtr; } + // ICommand has the same IID for both Windows.UI.Xaml.Input.ICommand and Microsoft.UI.Xaml.Input.ICommand, so we can use one interface definition for both without marking it as a WUX/MUX type. [EditorBrowsable(EditorBrowsableState.Never)] [Guid("E5AF3542-CA67-4081-995B-709DD13792DF")] [DynamicInterfaceCastableImplementation] diff --git a/src/WinRT.Runtime/Projections/ICustomPropertyProvider.net5.cs b/src/WinRT.Runtime/Projections/ICustomPropertyProvider.net5.cs index ca33a3457..0684e4cf5 100644 --- a/src/WinRT.Runtime/Projections/ICustomPropertyProvider.net5.cs +++ b/src/WinRT.Runtime/Projections/ICustomPropertyProvider.net5.cs @@ -6,6 +6,8 @@ using System.Runtime.InteropServices; using WinRT; +// These types have the same GUIDs in both Microsoft.UI.Xaml and Windows.UI.Xaml, +// so we don't need to duplicate them for the internal usage here as they can be transparently used by both WUX and MUX. namespace Microsoft.UI.Xaml.Data { [global::WinRT.WindowsRuntimeType] diff --git a/src/WinRT.Runtime/Projections/IEnumerable.net5.cs b/src/WinRT.Runtime/Projections/IEnumerable.net5.cs index 7e7626a86..5b1f2467c 100644 --- a/src/WinRT.Runtime/Projections/IEnumerable.net5.cs +++ b/src/WinRT.Runtime/Projections/IEnumerable.net5.cs @@ -907,7 +907,7 @@ public static void DisposeAbi(IntPtr abi) => // In IEnumerator<> scenarios, we use this as a helper for the implementation and don't actually use it to // create a CCW. [global::WinRT.WinRTExposedType(typeof(IBindableIteratorTypeDetails))] - public sealed class ToAbiHelper : global::Windows.Foundation.Collections.IIterator, global::Microsoft.UI.Xaml.Interop.IBindableIterator + public sealed class ToAbiHelper : global::Windows.Foundation.Collections.IIterator, global::Microsoft.UI.Xaml.Interop.IBindableIterator, global::Windows.UI.Xaml.Interop.IBindableIterator { private readonly global::System.Collections.Generic.IEnumerator m_enumerator; private bool m_firstItem = true; @@ -998,6 +998,11 @@ public uint GetMany(ref T[] items) public bool MoveNext() => _MoveNext(); uint global::Microsoft.UI.Xaml.Interop.IBindableIterator.GetMany(ref object[] items) + { + // Should not be called. + throw new NotImplementedException(); + } + uint global::Windows.UI.Xaml.Interop.IBindableIterator.GetMany(ref object[] items) { // Should not be called. throw new NotImplementedException(); diff --git a/src/WinRT.Runtime/Projections/INotifyCollectionChanged.net5.cs b/src/WinRT.Runtime/Projections/INotifyCollectionChanged.net5.cs index 7c0d94350..3d7334c5c 100644 --- a/src/WinRT.Runtime/Projections/INotifyCollectionChanged.net5.cs +++ b/src/WinRT.Runtime/Projections/INotifyCollectionChanged.net5.cs @@ -5,6 +5,7 @@ using System.ComponentModel; using System.Runtime.InteropServices; using WinRT; +using WinRT.Interop; namespace ABI.System.Collections.Specialized { @@ -45,11 +46,21 @@ public static unsafe (Action Projections.UiXamlModeSetting == Projections.UiXamlMode.WindowsUiXaml + ? "{CF75D69C-F2F4-486B-B302-BB4C09BAEBFA}" + : typeof(INotifyCollectionChanged).GUID.ToString("B"); + + [Guid("530155E1-28A5-5693-87CE-30724D95A06D")] + [WuxMuxProjectedType] public struct Vftbl - { + { + public static string GetGuidSignature() + => INotifyCollectionChanged.GetGuidSignature(); + internal IInspectable.Vftbl IInspectableVftbl; private delegate* unmanaged _add_CollectionChanged_0; diff --git a/src/WinRT.Runtime/Projections/INotifyPropertyChanged.net5.cs b/src/WinRT.Runtime/Projections/INotifyPropertyChanged.net5.cs index 576c284f8..dd5322408 100644 --- a/src/WinRT.Runtime/Projections/INotifyPropertyChanged.net5.cs +++ b/src/WinRT.Runtime/Projections/INotifyPropertyChanged.net5.cs @@ -4,6 +4,7 @@ using System; using System.Runtime.InteropServices; using WinRT; +using WinRT.Interop; namespace ABI.System.ComponentModel { @@ -21,12 +22,22 @@ static class INotifyPropertyChangedMethods [DynamicInterfaceCastableImplementation] [Guid("90B17601-B065-586E-83D9-9ADC3A695284")] + [WuxMuxProjectedType] internal unsafe interface INotifyPropertyChanged : global::System.ComponentModel.INotifyPropertyChanged { + public static string GetGuidSignature() + => Projections.UiXamlModeSetting == Projections.UiXamlMode.WindowsUiXaml + ? "{cf75d69c-f2f4-486b-b302-bb4c09baebfa}" + : typeof(INotifyPropertyChanged).GUID.ToString("B"); + [Guid("90B17601-B065-586E-83D9-9ADC3A695284")] - [StructLayout(LayoutKind.Sequential)] + [StructLayout(LayoutKind.Sequential)] + [WuxMuxProjectedType] public struct Vftbl - { + { + public static string GetGuidSignature() + => INotifyPropertyChanged.GetGuidSignature(); + internal IInspectable.Vftbl IInspectableVftbl; private delegate* unmanaged _add_PropertyChanged_0; diff --git a/src/WinRT.Runtime/Projections/Microsoft.UI.Xaml.Bindable.net5.cs b/src/WinRT.Runtime/Projections/Microsoft.UI.Xaml.Bindable.net5.cs new file mode 100644 index 000000000..95397bad6 --- /dev/null +++ b/src/WinRT.Runtime/Projections/Microsoft.UI.Xaml.Bindable.net5.cs @@ -0,0 +1,367 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using WinRT; +using WinRT.Interop; + + +#pragma warning disable 0169 // warning CS0169: The field '...' is never used +#pragma warning disable 0649 // warning CS0169: Field '...' is never assigned to + +namespace Microsoft.UI.Xaml.Interop +{ + [global::WinRT.WindowsRuntimeType] + [Guid("036D2C08-DF29-41AF-8AA2-D774BE62BA6F")] + [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Microsoft.UI.Xaml.Interop.IBindableIterable))] + internal interface IBindableIterable + { + IBindableIterator First(); + } + [global::WinRT.WindowsRuntimeType] + [Guid("6A1D6C07-076D-49F2-8314-F52C9C9A8331")] + [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Microsoft.UI.Xaml.Interop.IBindableIterator))] + internal interface IBindableIterator + { + bool MoveNext(); + // GetMany is not implemented by IBindableIterator, but it is here + // for compat purposes with WinUI where there are scenarios they do + // reinterpret_cast from IBindableIterator to IIterable. It is + // the last function in the vftable and shouldn't be called by anyone. + // If called, it will return NotImplementedException. + uint GetMany(ref object[] items); + object Current { get; } + bool HasCurrent { get; } + } + [global::WinRT.WindowsRuntimeType] + [Guid("393DE7DE-6FD0-4C0D-BB71-47244A113E93")] + internal interface IBindableVector : IEnumerable + { + object GetAt(uint index); + IBindableVectorView GetView(); + bool IndexOf(object value, out uint index); + void SetAt(uint index, object value); + void InsertAt(uint index, object value); + void RemoveAt(uint index); + void Append(object value); + void RemoveAtEnd(); + void Clear(); + uint Size { get; } + } + [global::WinRT.WindowsRuntimeType] + [Guid("346DD6E7-976E-4BC3-815D-ECE243BC0F33")] + [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Microsoft.UI.Xaml.Interop.IBindableVectorView))] + internal interface IBindableVectorView : IEnumerable + { + object GetAt(uint index); + bool IndexOf(object value, out uint index); + uint Size { get; } + } +} + +namespace ABI.Microsoft.UI.Xaml.Interop +{ + [DynamicInterfaceCastableImplementation] + [Guid("036D2C08-DF29-41AF-8AA2-D774BE62BA6F")] + internal unsafe interface IBindableIterable : global::Microsoft.UI.Xaml.Interop.IBindableIterable, ABI.System.Collections.IEnumerable + { + + } + + [DynamicInterfaceCastableImplementation] + [Guid("6A1D6C07-076D-49F2-8314-F52C9C9A8331")] + internal unsafe interface IBindableIterator : global::Microsoft.UI.Xaml.Interop.IBindableIterator + { + public static readonly IntPtr AbiToProjectionVftablePtr; + static IBindableIterator() + { + AbiToProjectionVftablePtr = ComWrappersSupport.AllocateVtableMemory(typeof(IBindableIterator), sizeof(IInspectable.Vftbl) + sizeof(IntPtr) * 4); + *(IInspectable.Vftbl*)AbiToProjectionVftablePtr = IInspectable.Vftbl.AbiToProjectionVftable; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[6] = &Do_Abi_get_Current_0; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[7] = &Do_Abi_get_HasCurrent_1; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[8] = &Do_Abi_MoveNext_2; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[9] = &Do_Abi_GetMany_3; + } + + [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] + private static unsafe int Do_Abi_MoveNext_2(IntPtr thisPtr, byte* result) + { + bool __result = default; + *result = default; + try + { + __result = global::WinRT.ComWrappersSupport.FindObject(thisPtr).MoveNext(); + *result = (byte)(__result ? 1 : 0); + } + catch (Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + + [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] + private static unsafe int Do_Abi_GetMany_3(IntPtr thisPtr, int __itemsSize, IntPtr items, uint* result) + { + *result = default; + + try + { + // Should never be called. + throw new NotImplementedException(); + } + catch (Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + } + + [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] + private static unsafe int Do_Abi_get_Current_0(IntPtr thisPtr, IntPtr* value) + { + object __value = default; + *value = default; + try + { + __value = global::WinRT.ComWrappersSupport.FindObject(thisPtr).Current; + *value = MarshalInspectable.FromManaged(__value); + } + catch (Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + + [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] + private static unsafe int Do_Abi_get_HasCurrent_1(IntPtr thisPtr, byte* value) + { + bool __value = default; + *value = default; + try + { + __value = global::WinRT.ComWrappersSupport.FindObject(thisPtr).HasCurrent; + *value = (byte)(__value ? 1 : 0); + } + catch (Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + + internal static ObjectReference FromAbi(IntPtr thisPtr) => ObjectReference.FromAbi(thisPtr); + + unsafe bool global::Microsoft.UI.Xaml.Interop.IBindableIterator.MoveNext() + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::Microsoft.UI.Xaml.Interop.IBindableIterator).TypeHandle); + var ThisPtr = _obj.ThisPtr; + byte __retval = default; + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[8](ThisPtr, &__retval)); + return __retval != 0; + } + + unsafe uint global::Microsoft.UI.Xaml.Interop.IBindableIterator.GetMany(ref object[] items) + { + // Should never be called. + throw new NotImplementedException(); + } + + unsafe object global::Microsoft.UI.Xaml.Interop.IBindableIterator.Current + { + get + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::Microsoft.UI.Xaml.Interop.IBindableIterator).TypeHandle); + var ThisPtr = _obj.ThisPtr; + IntPtr __retval = default; + try + { + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[6](ThisPtr, &__retval)); + return MarshalInspectable.FromAbi(__retval); + } + finally + { + MarshalInspectable.DisposeAbi(__retval); + } + } + } + + unsafe bool global::Microsoft.UI.Xaml.Interop.IBindableIterator.HasCurrent + { + get + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::Microsoft.UI.Xaml.Interop.IBindableIterator).TypeHandle); + var ThisPtr = _obj.ThisPtr; + byte __retval = default; + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[7](ThisPtr, &__retval)); + return __retval != 0; + } + } + + } + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + internal static class IBindableIterator_Delegates + { + public unsafe delegate int get_Current_0(IntPtr thisPtr, IntPtr* result); + public unsafe delegate int get_HasCurrent_1(IntPtr thisPtr, byte* result); + public unsafe delegate int MoveNext_2(IntPtr thisPtr, byte* result); + public unsafe delegate int GetMany_3(IntPtr thisPtr, int itemSize, IntPtr items, uint* result); + } + + [DynamicInterfaceCastableImplementation] + [Guid("346DD6E7-976E-4BC3-815D-ECE243BC0F33")] + internal unsafe interface IBindableVectorView : global::Microsoft.UI.Xaml.Interop.IBindableVectorView + { + public static readonly IntPtr AbiToProjectionVftablePtr; + static IBindableVectorView() + { + AbiToProjectionVftablePtr = ComWrappersSupport.AllocateVtableMemory(typeof(IBindableVectorView), sizeof(IInspectable.Vftbl) + sizeof(IntPtr) * 3); + *(IInspectable.Vftbl*)AbiToProjectionVftablePtr = IInspectable.Vftbl.AbiToProjectionVftable; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[6] = &Do_Abi_GetAt_0; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[7] = &Do_Abi_get_Size_1; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[8] = &Do_Abi_IndexOf_2; + } + + [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] + private static unsafe int Do_Abi_GetAt_0(IntPtr thisPtr, uint index, IntPtr* result) + { + object __result = default; + + try + { + __result = global::WinRT.ComWrappersSupport.FindObject(thisPtr).GetAt(index); + *result = MarshalInspectable.FromManaged(__result); + + } + catch (Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + + [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] + private static unsafe int Do_Abi_IndexOf_2(IntPtr thisPtr, IntPtr value, uint* index, byte* returnValue) + { + bool __returnValue = default; + + *index = default; + *returnValue = default; + uint __index = default; + + try + { + __returnValue = global::WinRT.ComWrappersSupport.FindObject(thisPtr).IndexOf(MarshalInspectable.FromAbi(value), out __index); + *index = __index; + *returnValue = (byte)(__returnValue ? 1 : 0); + + } + catch (Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + + [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] + private static unsafe int Do_Abi_get_Size_1(IntPtr thisPtr, uint* value) + { + uint __value = default; + + *value = default; + + try + { + __value = global::WinRT.ComWrappersSupport.FindObject(thisPtr).Size; + *value = __value; + + } + catch (Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + + internal static ObjectReference FromAbi(IntPtr thisPtr) => ObjectReference.FromAbi(thisPtr); + + private static readonly global::System.Runtime.CompilerServices.ConditionalWeakTable _helperTable = new(); + + unsafe object global::Microsoft.UI.Xaml.Interop.IBindableVectorView.GetAt(uint index) + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::Microsoft.UI.Xaml.Interop.IBindableIterator).TypeHandle); + var ThisPtr = _obj.ThisPtr; + IntPtr __retval = default; + try + { + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[6](ThisPtr, index, &__retval)); + return MarshalInspectable.FromAbi(__retval); + } + finally + { + MarshalInspectable.DisposeAbi(__retval); + } + } + + unsafe bool global::Microsoft.UI.Xaml.Interop.IBindableVectorView.IndexOf(object value, out uint index) + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::Microsoft.UI.Xaml.Interop.IBindableIterator).TypeHandle); + var ThisPtr = _obj.ThisPtr; + ObjectReferenceValue __value = default; + uint __index = default; + byte __retval = default; + try + { + __value = MarshalInspectable.CreateMarshaler2(value); + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[8]( + ThisPtr, + MarshalInspectable.GetAbi(__value), + &__index, + &__retval)); + index = __index; + return __retval != 0; + } + finally + { + MarshalInspectable.DisposeMarshaler(__value); + } + } + + unsafe uint global::Microsoft.UI.Xaml.Interop.IBindableVectorView.Size + { + get + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::Microsoft.UI.Xaml.Interop.IBindableIterator).TypeHandle); + var ThisPtr = _obj.ThisPtr; + uint __retval = default; + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[7](ThisPtr, &__retval)); + return __retval; + } + } + + IEnumerator IEnumerable.GetEnumerator() + { + return _helperTable.GetValue((IWinRTObject)this, + (enumerable) => new ABI.System.Collections.IEnumerable.AdaptiveFromAbiHelper(enumerable) + ).GetEnumerator(); + } + } + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + internal static class IBindableVectorView_Delegates + { + public unsafe delegate int GetAt_0(IntPtr thisPtr, uint index, IntPtr* result); + public unsafe delegate int get_Size_1(IntPtr thisPtr, uint* result); + public unsafe delegate int IndexOf_2(IntPtr thisPtr, IntPtr value, uint* index, byte* returnValue); + } +} diff --git a/src/WinRT.Runtime/Projections/Bindable.netstandard2.0.cs b/src/WinRT.Runtime/Projections/Microsoft.UI.Xaml.Bindable.netstandard2.0.cs similarity index 100% rename from src/WinRT.Runtime/Projections/Bindable.netstandard2.0.cs rename to src/WinRT.Runtime/Projections/Microsoft.UI.Xaml.Bindable.netstandard2.0.cs diff --git a/src/WinRT.Runtime/Projections/NotifyCollectionChangedAction.cs b/src/WinRT.Runtime/Projections/NotifyCollectionChangedAction.cs index b6ccf1bc7..62d5af9f4 100644 --- a/src/WinRT.Runtime/Projections/NotifyCollectionChangedAction.cs +++ b/src/WinRT.Runtime/Projections/NotifyCollectionChangedAction.cs @@ -1,10 +1,15 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. +using WinRT; + namespace ABI.System.Collections.Specialized { static class NotifyCollectionChangedAction { - public static string GetGuidSignature() => "enum(Microsoft.UI.Xaml.Interop.NotifyCollectionChangedAction;i4)"; + public static string GetGuidSignature() => + Projections.UiXamlModeSetting == Projections.UiXamlMode.WindowsUiXaml + ? "enum(Windows.UI.Xaml.Interop.NotifyCollectionChangedAction;i4)" + : "enum(Microsoft.UI.Xaml.Interop.NotifyCollectionChangedAction;i4)"; } } diff --git a/src/WinRT.Runtime/Projections/NotifyCollectionChangedEventArgs.cs b/src/WinRT.Runtime/Projections/NotifyCollectionChangedEventArgs.cs index 2cc04a771..e0000593c 100644 --- a/src/WinRT.Runtime/Projections/NotifyCollectionChangedEventArgs.cs +++ b/src/WinRT.Runtime/Projections/NotifyCollectionChangedEventArgs.cs @@ -1,279 +1,376 @@ // Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -using ABI.Microsoft.UI.Xaml.Interop; -using System; -using System.ComponentModel; -using System.Runtime.InteropServices; -using WinRT; -using WinRT.Interop; - -namespace ABI.Microsoft.UI.Xaml.Interop -{ - [global::WinRT.ObjectReferenceWrapper(nameof(_obj))] - [Guid("DA049FF2-D2E0-5FE8-8C7B-F87F26060B6F")] - internal sealed unsafe class INotifyCollectionChangedEventArgs - { - [Guid("DA049FF2-D2E0-5FE8-8C7B-F87F26060B6F")] - [StructLayout(LayoutKind.Sequential)] - public struct Vftbl - { - internal IInspectable.Vftbl IInspectableVftbl; - private void* _get_Action_0; - public delegate* unmanaged[Stdcall] get_Action_0 => (delegate* unmanaged[Stdcall])_get_Action_0; - private void* _get_NewItems_1; - public delegate* unmanaged[Stdcall] get_NewItems_1 => (delegate* unmanaged[Stdcall])_get_NewItems_1; - private void* _get_OldItems_2; - public delegate* unmanaged[Stdcall] get_OldItems_2 => (delegate* unmanaged[Stdcall])_get_OldItems_2; - private void* _get_NewStartingIndex_3; - public delegate* unmanaged[Stdcall] get_NewStartingIndex_3 => (delegate* unmanaged[Stdcall])_get_NewStartingIndex_3; - private void* _get_OldStartingIndex_4; - public delegate* unmanaged[Stdcall] get_OldStartingIndex_4 => (delegate* unmanaged[Stdcall])_get_OldStartingIndex_4; - } - internal static ObjectReference FromAbi(IntPtr thisPtr) => ObjectReference.FromAbi(thisPtr); - - public static implicit operator INotifyCollectionChangedEventArgs(IObjectReference obj) => (obj != null) ? new INotifyCollectionChangedEventArgs(obj) : null; - private readonly ObjectReference _obj; - public IObjectReference ObjRef { get => _obj; } - public IntPtr ThisPtr => _obj.ThisPtr; - public ObjectReference AsInterface() => _obj.As(); - public A As() => _obj.AsType(); - public INotifyCollectionChangedEventArgs(IObjectReference obj) : this(obj.As()) { } - internal INotifyCollectionChangedEventArgs(ObjectReference obj) - { - _obj = obj; - } - - public unsafe global::System.Collections.Specialized.NotifyCollectionChangedAction Action - { - get - { - global::System.Collections.Specialized.NotifyCollectionChangedAction __retval = default; - global::WinRT.ExceptionHelpers.ThrowExceptionForHR(_obj.Vftbl.get_Action_0(ThisPtr, &__retval)); - return __retval; - } - } - - public unsafe global::System.Collections.IList NewItems - { - get - { - IntPtr __retval = default; - try - { - global::WinRT.ExceptionHelpers.ThrowExceptionForHR(_obj.Vftbl.get_NewItems_1(ThisPtr, &__retval)); - return MarshalInterface.FromAbi(__retval); - } - finally - { - MarshalInterface.DisposeAbi(__retval); - } - } - } - - public unsafe int NewStartingIndex - { - get - { - int __retval = default; - global::WinRT.ExceptionHelpers.ThrowExceptionForHR(_obj.Vftbl.get_NewStartingIndex_3(ThisPtr, &__retval)); - return __retval; - } - } - - public unsafe global::System.Collections.IList OldItems - { - get - { - IntPtr __retval = default; - try - { - global::WinRT.ExceptionHelpers.ThrowExceptionForHR(_obj.Vftbl.get_OldItems_2(ThisPtr, &__retval)); - return MarshalInterface.FromAbi(__retval); - } - finally - { - MarshalInterface.DisposeAbi(__retval); - } - } - } - - public unsafe int OldStartingIndex - { - get - { - int __retval = default; - global::WinRT.ExceptionHelpers.ThrowExceptionForHR(_obj.Vftbl.get_OldStartingIndex_4(ThisPtr, &__retval)); - return __retval; - } - } - } - - [global::WinRT.ObjectReferenceWrapper(nameof(_obj))] - [Guid("5108EBA4-4892-5A20-8374-A96815E0FD27")] - internal sealed unsafe class WinRTNotifyCollectionChangedEventArgsRuntimeClassFactory - { - [Guid("5108EBA4-4892-5A20-8374-A96815E0FD27")] - [StructLayout(LayoutKind.Sequential)] - public struct Vftbl - { - internal IInspectable.Vftbl IInspectableVftbl; - private void* _CreateInstanceWithAllParameters_0; - public delegate* unmanaged[Stdcall] CreateInstanceWithAllParameters_0 => (delegate* unmanaged[Stdcall])_CreateInstanceWithAllParameters_0; - } - public static ObjectReference FromAbi(IntPtr thisPtr) => ObjectReference.FromAbi(thisPtr); - - public static implicit operator WinRTNotifyCollectionChangedEventArgsRuntimeClassFactory(IObjectReference obj) => (obj != null) ? new WinRTNotifyCollectionChangedEventArgsRuntimeClassFactory(obj) : null; - public static implicit operator WinRTNotifyCollectionChangedEventArgsRuntimeClassFactory(ObjectReference obj) => (obj != null) ? new WinRTNotifyCollectionChangedEventArgsRuntimeClassFactory(obj) : null; - private readonly ObjectReference _obj; - public IntPtr ThisPtr => _obj.ThisPtr; - public ObjectReference AsInterface() => _obj.As(); - public A As() => _obj.AsType(); - public WinRTNotifyCollectionChangedEventArgsRuntimeClassFactory(IObjectReference obj) : this(obj.As()) { } - public WinRTNotifyCollectionChangedEventArgsRuntimeClassFactory(ObjectReference obj) - { - _obj = obj; - } - - public unsafe IObjectReference CreateInstanceWithAllParameters(global::System.Collections.Specialized.NotifyCollectionChangedAction action, global::System.Collections.IList newItems, global::System.Collections.IList oldItems, int newIndex, int oldIndex, object baseInterface, out IObjectReference innerInterface) - { - ObjectReferenceValue __newItems = default; - ObjectReferenceValue __oldItems = default; - ObjectReferenceValue __baseInterface = default; - IntPtr __innerInterface = default; - IntPtr __retval = default; - try - { - __newItems = MarshalInterface.CreateMarshaler2(newItems); - __oldItems = MarshalInterface.CreateMarshaler2(oldItems); - __baseInterface = MarshalInspectable.CreateMarshaler2(baseInterface); - global::WinRT.ExceptionHelpers.ThrowExceptionForHR(_obj.Vftbl.CreateInstanceWithAllParameters_0(ThisPtr, action, MarshalInterface.GetAbi(__newItems), MarshalInterface.GetAbi(__oldItems), newIndex, oldIndex, MarshalInspectable.GetAbi(__baseInterface), &__innerInterface, &__retval)); - innerInterface = ObjectReference.FromAbi(__innerInterface); - return ObjectReference.FromAbi(__retval); - } - finally - { - MarshalInterface.DisposeMarshaler(__newItems); - MarshalInterface.DisposeMarshaler(__oldItems); - MarshalInspectable.DisposeMarshaler(__baseInterface); - MarshalInspectable.DisposeAbi(__innerInterface); - MarshalInspectable.DisposeAbi(__retval); - } +// Licensed under the MIT License. + +using ABI.Microsoft.UI.Xaml.Interop; +using System; +using System.ComponentModel; +using System.Runtime.InteropServices; +using WinRT; +using WinRT.Interop; + +namespace ABI.Microsoft.UI.Xaml.Interop +{ + [global::WinRT.ObjectReferenceWrapper(nameof(_obj))] + [Guid("DA049FF2-D2E0-5FE8-8C7B-F87F26060B6F")] + [WuxMuxProjectedType] + internal sealed unsafe class INotifyCollectionChangedEventArgs + { + public static string GetGuidSignature() + => Projections.UiXamlModeSetting == Projections.UiXamlMode.WindowsUiXaml + ? "{4cf68d33-e3f2-4964-b85e-945b4f7e2f21}" + : typeof(INotifyCollectionChangedEventArgs).GUID.ToString("B"); + + [Guid("DA049FF2-D2E0-5FE8-8C7B-F87F26060B6F")] + [StructLayout(LayoutKind.Sequential)] + [WuxMuxProjectedType] + public struct Vftbl + { + public static string GetGuidSignature() + => INotifyCollectionChangedEventArgs.GetGuidSignature(); + + internal IInspectable.Vftbl IInspectableVftbl; + private void* _get_Action_0; + public delegate* unmanaged[Stdcall] get_Action_0 => (delegate* unmanaged[Stdcall])_get_Action_0; + private void* _get_NewItems_1; + public delegate* unmanaged[Stdcall] get_NewItems_1 => (delegate* unmanaged[Stdcall])_get_NewItems_1; + private void* _get_OldItems_2; + public delegate* unmanaged[Stdcall] get_OldItems_2 => (delegate* unmanaged[Stdcall])_get_OldItems_2; + private void* _get_NewStartingIndex_3; + public delegate* unmanaged[Stdcall] get_NewStartingIndex_3 => (delegate* unmanaged[Stdcall])_get_NewStartingIndex_3; + private void* _get_OldStartingIndex_4; + public delegate* unmanaged[Stdcall] get_OldStartingIndex_4 => (delegate* unmanaged[Stdcall])_get_OldStartingIndex_4; + } + internal static ObjectReference FromAbi(IntPtr thisPtr) => ObjectReference.FromAbi(thisPtr); + + public static implicit operator INotifyCollectionChangedEventArgs(IObjectReference obj) => (obj != null) ? new INotifyCollectionChangedEventArgs(obj) : null; + private readonly ObjectReference _obj; + public IObjectReference ObjRef { get => _obj; } + public IntPtr ThisPtr => _obj.ThisPtr; + public ObjectReference AsInterface() => _obj.As(); + public A As() => _obj.AsType(); + public INotifyCollectionChangedEventArgs(IObjectReference obj) : this(obj.As()) { } + internal INotifyCollectionChangedEventArgs(ObjectReference obj) + { + _obj = obj; } - public unsafe ObjectReferenceValue CreateInstanceWithAllParameters(global::System.Collections.Specialized.NotifyCollectionChangedAction action, global::System.Collections.IList newItems, global::System.Collections.IList oldItems, int newIndex, int oldIndex) - { - ObjectReferenceValue __newItems = default; - ObjectReferenceValue __oldItems = default; - IntPtr __innerInterface = default; - IntPtr __retval = default; - try - { - __newItems = MarshalInterface.CreateMarshaler2(newItems); - __oldItems = MarshalInterface.CreateMarshaler2(oldItems); - global::WinRT.ExceptionHelpers.ThrowExceptionForHR(_obj.Vftbl.CreateInstanceWithAllParameters_0(ThisPtr, action, MarshalInterface.GetAbi(__newItems), MarshalInterface.GetAbi(__oldItems), newIndex, oldIndex, IntPtr.Zero, &__innerInterface, &__retval)); - return new ObjectReferenceValue(__retval); - } - finally - { - __newItems.Dispose(); - __oldItems.Dispose(); - MarshalInspectable.DisposeAbi(__innerInterface); - } - } - } -} - -namespace ABI.System.Collections.Specialized -{ - [EditorBrowsable(EditorBrowsableState.Never)] - [StructLayout(LayoutKind.Sequential)] -#if EMBED - internal -#else - public -#endif - struct NotifyCollectionChangedEventArgs + public unsafe global::System.Collections.Specialized.NotifyCollectionChangedAction Action + { + get + { + global::System.Collections.Specialized.NotifyCollectionChangedAction __retval = default; + global::WinRT.ExceptionHelpers.ThrowExceptionForHR(_obj.Vftbl.get_Action_0(ThisPtr, &__retval)); + return __retval; + } + } + + public unsafe global::System.Collections.IList NewItems + { + get + { + IntPtr __retval = default; + try + { + global::WinRT.ExceptionHelpers.ThrowExceptionForHR(_obj.Vftbl.get_NewItems_1(ThisPtr, &__retval)); + return MarshalInterface.FromAbi(__retval); + } + finally + { + MarshalInterface.DisposeAbi(__retval); + } + } + } + + public unsafe int NewStartingIndex + { + get + { + int __retval = default; + global::WinRT.ExceptionHelpers.ThrowExceptionForHR(_obj.Vftbl.get_NewStartingIndex_3(ThisPtr, &__retval)); + return __retval; + } + } + + public unsafe global::System.Collections.IList OldItems + { + get + { + IntPtr __retval = default; + try + { + global::WinRT.ExceptionHelpers.ThrowExceptionForHR(_obj.Vftbl.get_OldItems_2(ThisPtr, &__retval)); + return MarshalInterface.FromAbi(__retval); + } + finally + { + MarshalInterface.DisposeAbi(__retval); + } + } + } + + public unsafe int OldStartingIndex + { + get + { + int __retval = default; + global::WinRT.ExceptionHelpers.ThrowExceptionForHR(_obj.Vftbl.get_OldStartingIndex_4(ThisPtr, &__retval)); + return __retval; + } + } + } + + internal interface IWinRTNotifyCollectionChangedEventArgsRuntimeClassFactory { - private static WinRTNotifyCollectionChangedEventArgsRuntimeClassFactory Instance = ActivationFactory.Get("Microsoft.UI.Xaml.Interop.NotifyCollectionChangedEventArgs"); - - public static IObjectReference CreateMarshaler(global::System.Collections.Specialized.NotifyCollectionChangedEventArgs value) - { - if (value is null) - { - return null; - } - - return Instance.CreateInstanceWithAllParameters(value.Action, value.NewItems, value.OldItems, value.NewStartingIndex, value.OldStartingIndex, null, out _); + IObjectReference CreateInstanceWithAllParameters(global::System.Collections.Specialized.NotifyCollectionChangedAction action, global::System.Collections.IList newItems, global::System.Collections.IList oldItems, int newIndex, int oldIndex, object baseInterface, out IObjectReference innerInterface); + ObjectReferenceValue CreateInstanceWithAllParameters(global::System.Collections.Specialized.NotifyCollectionChangedAction action, global::System.Collections.IList newItems, global::System.Collections.IList oldItems, int newIndex, int oldIndex); + } + + [global::WinRT.ObjectReferenceWrapper(nameof(_obj))] + [Guid("5108EBA4-4892-5A20-8374-A96815E0FD27")] + internal sealed unsafe class MUXNotifyCollectionChangedEventArgsRuntimeClassFactory : IWinRTNotifyCollectionChangedEventArgsRuntimeClassFactory + { + [Guid("5108EBA4-4892-5A20-8374-A96815E0FD27")] + [StructLayout(LayoutKind.Sequential)] + public struct Vftbl + { + internal IInspectable.Vftbl IInspectableVftbl; + private void* _CreateInstanceWithAllParameters_0; + public delegate* unmanaged[Stdcall] CreateInstanceWithAllParameters_0 => (delegate* unmanaged[Stdcall])_CreateInstanceWithAllParameters_0; + } + public static ObjectReference FromAbi(IntPtr thisPtr) => ObjectReference.FromAbi(thisPtr); + + public static implicit operator MUXNotifyCollectionChangedEventArgsRuntimeClassFactory(IObjectReference obj) => (obj != null) ? new MUXNotifyCollectionChangedEventArgsRuntimeClassFactory(obj) : null; + public static implicit operator MUXNotifyCollectionChangedEventArgsRuntimeClassFactory(ObjectReference obj) => (obj != null) ? new MUXNotifyCollectionChangedEventArgsRuntimeClassFactory(obj) : null; + private readonly ObjectReference _obj; + public IntPtr ThisPtr => _obj.ThisPtr; + public ObjectReference AsInterface() => _obj.As(); + public A As() => _obj.AsType(); + public MUXNotifyCollectionChangedEventArgsRuntimeClassFactory(IObjectReference obj) : this(obj.As()) { } + public MUXNotifyCollectionChangedEventArgsRuntimeClassFactory(ObjectReference obj) + { + _obj = obj; } - public static ObjectReferenceValue CreateMarshaler2(global::System.Collections.Specialized.NotifyCollectionChangedEventArgs value) - { - if (value is null) - { - return new ObjectReferenceValue(); - } - - return Instance.CreateInstanceWithAllParameters(value.Action, value.NewItems, value.OldItems, value.NewStartingIndex, value.OldStartingIndex); - } - - public static IntPtr GetAbi(IObjectReference m) => m?.ThisPtr ?? IntPtr.Zero; - - public static global::System.Collections.Specialized.NotifyCollectionChangedEventArgs FromAbi(IntPtr ptr) - { - if (ptr == IntPtr.Zero) - { - return null; - } - - INotifyCollectionChangedEventArgs args = INotifyCollectionChangedEventArgs.FromAbi(ptr); - return CreateNotifyCollectionChangedEventArgs(args.Action, args.NewItems, args.OldItems, args.NewStartingIndex, args.OldStartingIndex); - } - - private static global::System.Collections.Specialized.NotifyCollectionChangedEventArgs CreateNotifyCollectionChangedEventArgs( - global::System.Collections.Specialized.NotifyCollectionChangedAction action, - global::System.Collections.IList newItems, - global::System.Collections.IList oldItems, - int newStartingIndex, - int oldStartingIndex) => - action switch - { - global::System.Collections.Specialized.NotifyCollectionChangedAction.Add => new global::System.Collections.Specialized.NotifyCollectionChangedEventArgs(action, newItems, newStartingIndex), - global::System.Collections.Specialized.NotifyCollectionChangedAction.Remove => new global::System.Collections.Specialized.NotifyCollectionChangedEventArgs(action, oldItems, oldStartingIndex), - global::System.Collections.Specialized.NotifyCollectionChangedAction.Replace => new global::System.Collections.Specialized.NotifyCollectionChangedEventArgs(action, newItems, oldItems, newStartingIndex), - global::System.Collections.Specialized.NotifyCollectionChangedAction.Move => new global::System.Collections.Specialized.NotifyCollectionChangedEventArgs(action, newItems, newStartingIndex, oldStartingIndex), - global::System.Collections.Specialized.NotifyCollectionChangedAction.Reset => new global::System.Collections.Specialized.NotifyCollectionChangedEventArgs(global::System.Collections.Specialized.NotifyCollectionChangedAction.Reset), - _ => throw new ArgumentException(), - }; - - public static unsafe void CopyManaged(global::System.Collections.Specialized.NotifyCollectionChangedEventArgs o, IntPtr dest) - { - *(IntPtr*)dest.ToPointer() = CreateMarshaler2(o).Detach(); - } - - public static IntPtr FromManaged(global::System.Collections.Specialized.NotifyCollectionChangedEventArgs value) - { - if (value is null) - { - return IntPtr.Zero; - } - return CreateMarshaler2(value).Detach(); - } - - public static void DisposeMarshaler(IObjectReference m) { m?.Dispose(); } + public unsafe IObjectReference CreateInstanceWithAllParameters(global::System.Collections.Specialized.NotifyCollectionChangedAction action, global::System.Collections.IList newItems, global::System.Collections.IList oldItems, int newIndex, int oldIndex, object baseInterface, out IObjectReference innerInterface) + { + ObjectReferenceValue __newItems = default; + ObjectReferenceValue __oldItems = default; + ObjectReferenceValue __baseInterface = default; + IntPtr __innerInterface = default; + IntPtr __retval = default; + try + { + __newItems = MarshalInterface.CreateMarshaler2(newItems); + __oldItems = MarshalInterface.CreateMarshaler2(oldItems); + __baseInterface = MarshalInspectable.CreateMarshaler2(baseInterface); + global::WinRT.ExceptionHelpers.ThrowExceptionForHR(_obj.Vftbl.CreateInstanceWithAllParameters_0(ThisPtr, action, MarshalInterface.GetAbi(__newItems), MarshalInterface.GetAbi(__oldItems), newIndex, oldIndex, MarshalInspectable.GetAbi(__baseInterface), &__innerInterface, &__retval)); + innerInterface = ObjectReference.FromAbi(__innerInterface); + return ObjectReference.FromAbi(__retval); + } + finally + { + MarshalInterface.DisposeMarshaler(__newItems); + MarshalInterface.DisposeMarshaler(__oldItems); + MarshalInspectable.DisposeMarshaler(__baseInterface); + MarshalInspectable.DisposeAbi(__innerInterface); + MarshalInspectable.DisposeAbi(__retval); + } + } + + public unsafe ObjectReferenceValue CreateInstanceWithAllParameters(global::System.Collections.Specialized.NotifyCollectionChangedAction action, global::System.Collections.IList newItems, global::System.Collections.IList oldItems, int newIndex, int oldIndex) + { + ObjectReferenceValue __newItems = default; + ObjectReferenceValue __oldItems = default; + IntPtr __innerInterface = default; + IntPtr __retval = default; + try + { + __newItems = MarshalInterface.CreateMarshaler2(newItems); + __oldItems = MarshalInterface.CreateMarshaler2(oldItems); + global::WinRT.ExceptionHelpers.ThrowExceptionForHR(_obj.Vftbl.CreateInstanceWithAllParameters_0(ThisPtr, action, MarshalInterface.GetAbi(__newItems), MarshalInterface.GetAbi(__oldItems), newIndex, oldIndex, IntPtr.Zero, &__innerInterface, &__retval)); + return new ObjectReferenceValue(__retval); + } + finally + { + __newItems.Dispose(); + __oldItems.Dispose(); + MarshalInspectable.DisposeAbi(__innerInterface); + } + } + } + + [global::WinRT.ObjectReferenceWrapper(nameof(_obj))] + [Guid("b30c3e3a-df8d-44a5-9a38-7ac0d08ce63d")] + internal sealed unsafe class WUXNotifyCollectionChangedEventArgsRuntimeClassFactory : IWinRTNotifyCollectionChangedEventArgsRuntimeClassFactory + { + [Guid("b30c3e3a-df8d-44a5-9a38-7ac0d08ce63d")] + [StructLayout(LayoutKind.Sequential)] + public struct Vftbl + { + internal IInspectable.Vftbl IInspectableVftbl; + private void* _CreateInstanceWithAllParameters_0; + public delegate* unmanaged[Stdcall] CreateInstanceWithAllParameters_0 => (delegate* unmanaged[Stdcall])_CreateInstanceWithAllParameters_0; + } + public static ObjectReference FromAbi(IntPtr thisPtr) => ObjectReference.FromAbi(thisPtr); + + public static implicit operator WUXNotifyCollectionChangedEventArgsRuntimeClassFactory(IObjectReference obj) => (obj != null) ? new WUXNotifyCollectionChangedEventArgsRuntimeClassFactory(obj) : null; + public static implicit operator WUXNotifyCollectionChangedEventArgsRuntimeClassFactory(ObjectReference obj) => (obj != null) ? new WUXNotifyCollectionChangedEventArgsRuntimeClassFactory(obj) : null; + private readonly ObjectReference _obj; + public IntPtr ThisPtr => _obj.ThisPtr; + public ObjectReference AsInterface() => _obj.As(); + public A As() => _obj.AsType(); + public WUXNotifyCollectionChangedEventArgsRuntimeClassFactory(IObjectReference obj) : this(obj.As()) { } + public WUXNotifyCollectionChangedEventArgsRuntimeClassFactory(ObjectReference obj) + { + _obj = obj; + } + + public unsafe IObjectReference CreateInstanceWithAllParameters(global::System.Collections.Specialized.NotifyCollectionChangedAction action, global::System.Collections.IList newItems, global::System.Collections.IList oldItems, int newIndex, int oldIndex, object baseInterface, out IObjectReference innerInterface) + { + ObjectReferenceValue __newItems = default; + ObjectReferenceValue __oldItems = default; + ObjectReferenceValue __baseInterface = default; + IntPtr __innerInterface = default; + IntPtr __retval = default; + try + { + __newItems = MarshalInterface.CreateMarshaler2(newItems); + __oldItems = MarshalInterface.CreateMarshaler2(oldItems); + __baseInterface = MarshalInspectable.CreateMarshaler2(baseInterface); + global::WinRT.ExceptionHelpers.ThrowExceptionForHR(_obj.Vftbl.CreateInstanceWithAllParameters_0(ThisPtr, action, MarshalInterface.GetAbi(__newItems), MarshalInterface.GetAbi(__oldItems), newIndex, oldIndex, MarshalInspectable.GetAbi(__baseInterface), &__innerInterface, &__retval)); + innerInterface = ObjectReference.FromAbi(__innerInterface); + return ObjectReference.FromAbi(__retval); + } + finally + { + MarshalInterface.DisposeMarshaler(__newItems); + MarshalInterface.DisposeMarshaler(__oldItems); + MarshalInspectable.DisposeMarshaler(__baseInterface); + MarshalInspectable.DisposeAbi(__innerInterface); + MarshalInspectable.DisposeAbi(__retval); + } + } + + public unsafe ObjectReferenceValue CreateInstanceWithAllParameters(global::System.Collections.Specialized.NotifyCollectionChangedAction action, global::System.Collections.IList newItems, global::System.Collections.IList oldItems, int newIndex, int oldIndex) + { + ObjectReferenceValue __newItems = default; + ObjectReferenceValue __oldItems = default; + IntPtr __innerInterface = default; + IntPtr __retval = default; + try + { + __newItems = MarshalInterface.CreateMarshaler2(newItems); + __oldItems = MarshalInterface.CreateMarshaler2(oldItems); + global::WinRT.ExceptionHelpers.ThrowExceptionForHR(_obj.Vftbl.CreateInstanceWithAllParameters_0(ThisPtr, action, MarshalInterface.GetAbi(__newItems), MarshalInterface.GetAbi(__oldItems), newIndex, oldIndex, IntPtr.Zero, &__innerInterface, &__retval)); + return new ObjectReferenceValue(__retval); + } + finally + { + __newItems.Dispose(); + __oldItems.Dispose(); + MarshalInspectable.DisposeAbi(__innerInterface); + } + } + } +} + +namespace ABI.System.Collections.Specialized +{ + [EditorBrowsable(EditorBrowsableState.Never)] + [StructLayout(LayoutKind.Sequential)] +#if EMBED + internal +#else + public +#endif + struct NotifyCollectionChangedEventArgs + { + private static IWinRTNotifyCollectionChangedEventArgsRuntimeClassFactory Instance = + Projections.UiXamlModeSetting == Projections.UiXamlMode.WindowsUiXaml + ? new WUXNotifyCollectionChangedEventArgsRuntimeClassFactory(ActivationFactory.Get("Windows.UI.Xaml.Interop.NotifyCollectionChangedEventArgs")) + : new MUXNotifyCollectionChangedEventArgsRuntimeClassFactory(ActivationFactory.Get("Microsoft.UI.Xaml.Interop.NotifyCollectionChangedEventArgs")); + + public static IObjectReference CreateMarshaler(global::System.Collections.Specialized.NotifyCollectionChangedEventArgs value) + { + if (value is null) + { + return null; + } + + return Instance.CreateInstanceWithAllParameters(value.Action, value.NewItems, value.OldItems, value.NewStartingIndex, value.OldStartingIndex, null, out _); + } + + public static ObjectReferenceValue CreateMarshaler2(global::System.Collections.Specialized.NotifyCollectionChangedEventArgs value) + { + if (value is null) + { + return new ObjectReferenceValue(); + } + + return Instance.CreateInstanceWithAllParameters(value.Action, value.NewItems, value.OldItems, value.NewStartingIndex, value.OldStartingIndex); + } + + public static IntPtr GetAbi(IObjectReference m) => m?.ThisPtr ?? IntPtr.Zero; + + public static global::System.Collections.Specialized.NotifyCollectionChangedEventArgs FromAbi(IntPtr ptr) + { + if (ptr == IntPtr.Zero) + { + return null; + } + + INotifyCollectionChangedEventArgs args = INotifyCollectionChangedEventArgs.FromAbi(ptr); + return CreateNotifyCollectionChangedEventArgs(args.Action, args.NewItems, args.OldItems, args.NewStartingIndex, args.OldStartingIndex); + } + + private static global::System.Collections.Specialized.NotifyCollectionChangedEventArgs CreateNotifyCollectionChangedEventArgs( + global::System.Collections.Specialized.NotifyCollectionChangedAction action, + global::System.Collections.IList newItems, + global::System.Collections.IList oldItems, + int newStartingIndex, + int oldStartingIndex) => + action switch + { + global::System.Collections.Specialized.NotifyCollectionChangedAction.Add => new global::System.Collections.Specialized.NotifyCollectionChangedEventArgs(action, newItems, newStartingIndex), + global::System.Collections.Specialized.NotifyCollectionChangedAction.Remove => new global::System.Collections.Specialized.NotifyCollectionChangedEventArgs(action, oldItems, oldStartingIndex), + global::System.Collections.Specialized.NotifyCollectionChangedAction.Replace => new global::System.Collections.Specialized.NotifyCollectionChangedEventArgs(action, newItems, oldItems, newStartingIndex), + global::System.Collections.Specialized.NotifyCollectionChangedAction.Move => new global::System.Collections.Specialized.NotifyCollectionChangedEventArgs(action, newItems, newStartingIndex, oldStartingIndex), + global::System.Collections.Specialized.NotifyCollectionChangedAction.Reset => new global::System.Collections.Specialized.NotifyCollectionChangedEventArgs(global::System.Collections.Specialized.NotifyCollectionChangedAction.Reset), + _ => throw new ArgumentException(), + }; + + public static unsafe void CopyManaged(global::System.Collections.Specialized.NotifyCollectionChangedEventArgs o, IntPtr dest) + { + *(IntPtr*)dest.ToPointer() = CreateMarshaler2(o).Detach(); + } + + public static IntPtr FromManaged(global::System.Collections.Specialized.NotifyCollectionChangedEventArgs value) + { + if (value is null) + { + return IntPtr.Zero; + } + return CreateMarshaler2(value).Detach(); + } + + public static void DisposeMarshaler(IObjectReference m) { m?.Dispose(); } public static void DisposeAbi(IntPtr abi) { MarshalInspectable.DisposeAbi(abi); } - public static unsafe MarshalInterfaceHelper.MarshalerArray CreateMarshalerArray(global::System.Collections.Specialized.NotifyCollectionChangedEventArgs[] array) => MarshalInterfaceHelper.CreateMarshalerArray2(array, CreateMarshaler2); - public static (int length, IntPtr data) GetAbiArray(object box) => MarshalInterfaceHelper.GetAbiArray(box); - public static unsafe global::System.Collections.Specialized.NotifyCollectionChangedEventArgs[] FromAbiArray(object box) => MarshalInterfaceHelper.FromAbiArray(box, FromAbi); - public static void CopyAbiArray(global::System.Collections.Specialized.NotifyCollectionChangedEventArgs[] array, object box) => MarshalInterfaceHelper.CopyAbiArray(array, box, FromAbi); - public static (int length, IntPtr data) FromManagedArray(global::System.Collections.Specialized.NotifyCollectionChangedEventArgs[] array) => MarshalInterfaceHelper.FromManagedArray(array, FromManaged); - public static void DisposeMarshalerArray(MarshalInterfaceHelper.MarshalerArray array) => MarshalInterfaceHelper.DisposeMarshalerArray(array); - public static unsafe void DisposeAbiArray(object box) => MarshalInspectable.DisposeAbiArray(box); - - public static string GetGuidSignature() - { - return "rc(Microsoft.UI.Xaml.Interop.NotifyCollectionChangedEventArgs;{4cf68d33-e3f2-4964-b85e-945b4f7e2f21})"; - } - } -} + public static unsafe MarshalInterfaceHelper.MarshalerArray CreateMarshalerArray(global::System.Collections.Specialized.NotifyCollectionChangedEventArgs[] array) => MarshalInterfaceHelper.CreateMarshalerArray2(array, CreateMarshaler2); + public static (int length, IntPtr data) GetAbiArray(object box) => MarshalInterfaceHelper.GetAbiArray(box); + public static unsafe global::System.Collections.Specialized.NotifyCollectionChangedEventArgs[] FromAbiArray(object box) => MarshalInterfaceHelper.FromAbiArray(box, FromAbi); + public static void CopyAbiArray(global::System.Collections.Specialized.NotifyCollectionChangedEventArgs[] array, object box) => MarshalInterfaceHelper.CopyAbiArray(array, box, FromAbi); + public static (int length, IntPtr data) FromManagedArray(global::System.Collections.Specialized.NotifyCollectionChangedEventArgs[] array) => MarshalInterfaceHelper.FromManagedArray(array, FromManaged); + public static void DisposeMarshalerArray(MarshalInterfaceHelper.MarshalerArray array) => MarshalInterfaceHelper.DisposeMarshalerArray(array); + public static unsafe void DisposeAbiArray(object box) => MarshalInspectable.DisposeAbiArray(box); + + public static string GetGuidSignature() + { + if (Projections.UiXamlModeSetting == Projections.UiXamlMode.WindowsUiXaml) + { + return "rc(Windows.UI.Xaml.Interop.NotifyCollectionChangedEventArgs;{4cf68d33-e3f2-4964-b85e-945b4f7e2f21})"; + } + return "rc(Microsoft.UI.Xaml.Interop.NotifyCollectionChangedEventArgs;{4cf68d33-e3f2-4964-b85e-945b4f7e2f21})"; + } + } +} diff --git a/src/WinRT.Runtime/Projections/NotifyCollectionChangedEventHandler.cs b/src/WinRT.Runtime/Projections/NotifyCollectionChangedEventHandler.cs index 1d39d310d..aaf4f8181 100644 --- a/src/WinRT.Runtime/Projections/NotifyCollectionChangedEventHandler.cs +++ b/src/WinRT.Runtime/Projections/NotifyCollectionChangedEventHandler.cs @@ -41,11 +41,15 @@ static unsafe NotifyCollectionChangedEventHandler() var nativeVftbl = ComWrappersSupport.AllocateVtableMemory(typeof(NotifyCollectionChangedEventHandler), Marshal.SizeOf()); Marshal.StructureToPtr(AbiToProjectionVftable, nativeVftbl, false); AbiToProjectionVftablePtr = nativeVftbl; + + IID = Projections.UiXamlModeSetting == Projections.UiXamlMode.WindowsUiXaml + ? Guid.Parse("ca10b37c-f382-4591-8557-5e24965279b0") + : typeof(global::ABI.System.Collections.Specialized.NotifyCollectionChangedEventHandler).GUID; } public static global::System.Delegate AbiInvokeDelegate { get; } - private static readonly Guid IID = new(0x8B0909DC, 0x2005, 0x5D93, 0xBF, 0x8A, 0x72, 0x5F, 0x01, 0x7B, 0xAA, 0x8D); + private static readonly Guid IID; public static unsafe IObjectReference CreateMarshaler(global::System.Collections.Specialized.NotifyCollectionChangedEventHandler managedDelegate) => managedDelegate is null ? null : MarshalDelegate.CreateMarshaler(managedDelegate, IID); diff --git a/src/WinRT.Runtime/Projections/PropertyChangedEventArgs.cs b/src/WinRT.Runtime/Projections/PropertyChangedEventArgs.cs index 4529aff6c..86586a85c 100644 --- a/src/WinRT.Runtime/Projections/PropertyChangedEventArgs.cs +++ b/src/WinRT.Runtime/Projections/PropertyChangedEventArgs.cs @@ -18,10 +18,15 @@ internal unsafe struct IPropertyChangedEventArgsVftbl public delegate* unmanaged[Stdcall] get_PropertyName_0 => (delegate* unmanaged[Stdcall])_get_PropertyName_0; } + internal interface IWinRTPropertyChangedEventArgsRuntimeClassFactory + { + IObjectReference CreateInstance(string name, object baseInterface, out IObjectReference innerInterface); + ObjectReferenceValue CreateInstance(string name); + } [global::WinRT.ObjectReferenceWrapper(nameof(_obj))] [Guid("7C0C27A8-0B41-5070-B160-FC9AE960A36C")] - internal sealed unsafe class WinRTPropertyChangedEventArgsRuntimeClassFactory + internal sealed unsafe class MUXPropertyChangedEventArgsRuntimeClassFactory : IWinRTPropertyChangedEventArgsRuntimeClassFactory { [Guid("7C0C27A8-0B41-5070-B160-FC9AE960A36C")] [StructLayout(LayoutKind.Sequential)] @@ -33,14 +38,14 @@ public struct Vftbl } public static ObjectReference FromAbi(IntPtr thisPtr) => ObjectReference.FromAbi(thisPtr); - public static implicit operator WinRTPropertyChangedEventArgsRuntimeClassFactory(IObjectReference obj) => (obj != null) ? new WinRTPropertyChangedEventArgsRuntimeClassFactory(obj) : null; - public static implicit operator WinRTPropertyChangedEventArgsRuntimeClassFactory(ObjectReference obj) => (obj != null) ? new WinRTPropertyChangedEventArgsRuntimeClassFactory(obj) : null; + public static implicit operator MUXPropertyChangedEventArgsRuntimeClassFactory(IObjectReference obj) => (obj != null) ? new MUXPropertyChangedEventArgsRuntimeClassFactory(obj) : null; + public static implicit operator MUXPropertyChangedEventArgsRuntimeClassFactory(ObjectReference obj) => (obj != null) ? new MUXPropertyChangedEventArgsRuntimeClassFactory(obj) : null; private readonly ObjectReference _obj; public IntPtr ThisPtr => _obj.ThisPtr; public ObjectReference AsInterface() => _obj.As(); public A As() => _obj.AsType(); - public WinRTPropertyChangedEventArgsRuntimeClassFactory(IObjectReference obj) : this(obj.As()) { } - public WinRTPropertyChangedEventArgsRuntimeClassFactory(ObjectReference obj) + public MUXPropertyChangedEventArgsRuntimeClassFactory(IObjectReference obj) : this(obj.As()) { } + public MUXPropertyChangedEventArgsRuntimeClassFactory(ObjectReference obj) { _obj = obj; } @@ -87,7 +92,78 @@ public unsafe ObjectReferenceValue CreateInstance(string name) MarshalInspectable.DisposeAbi(__innerInterface); } } + } + + + + [global::WinRT.ObjectReferenceWrapper(nameof(_obj))] + [Guid("4f33a9a0-5cf4-47a4-b16f-d7faaf17457e")] + internal sealed unsafe class WUXPropertyChangedEventArgsRuntimeClassFactory : IWinRTPropertyChangedEventArgsRuntimeClassFactory + { + [Guid("4f33a9a0-5cf4-47a4-b16f-d7faaf17457e")] + [StructLayout(LayoutKind.Sequential)] + public struct Vftbl + { + internal IInspectable.Vftbl IInspectableVftbl; + private void* _CreateInstance_0; + public delegate* unmanaged[Stdcall] CreateInstance_0 => (delegate* unmanaged[Stdcall])_CreateInstance_0; + } + public static ObjectReference FromAbi(IntPtr thisPtr) => ObjectReference.FromAbi(thisPtr); + public static implicit operator WUXPropertyChangedEventArgsRuntimeClassFactory(IObjectReference obj) => (obj != null) ? new WUXPropertyChangedEventArgsRuntimeClassFactory(obj) : null; + public static implicit operator WUXPropertyChangedEventArgsRuntimeClassFactory(ObjectReference obj) => (obj != null) ? new WUXPropertyChangedEventArgsRuntimeClassFactory(obj) : null; + private readonly ObjectReference _obj; + public IntPtr ThisPtr => _obj.ThisPtr; + public ObjectReference AsInterface() => _obj.As(); + public A As() => _obj.AsType(); + public WUXPropertyChangedEventArgsRuntimeClassFactory(IObjectReference obj) : this(obj.As()) { } + public WUXPropertyChangedEventArgsRuntimeClassFactory(ObjectReference obj) + { + _obj = obj; + } + + public unsafe IObjectReference CreateInstance(string name, object baseInterface, out IObjectReference innerInterface) + { + IObjectReference __baseInterface = default; + IntPtr __innerInterface = default; + IntPtr __retval = default; + try + { + MarshalString.Pinnable __name = new(name); + fixed (void* ___name = __name) + { + __baseInterface = MarshalInspectable.CreateMarshaler(baseInterface); + global::WinRT.ExceptionHelpers.ThrowExceptionForHR(_obj.Vftbl.CreateInstance_0(ThisPtr, MarshalString.GetAbi(ref __name), MarshalInspectable.GetAbi(__baseInterface), &__innerInterface, &__retval)); + innerInterface = ObjectReference.FromAbi(__innerInterface); + return ObjectReference.Attach(ref __retval); + } + } + finally + { + MarshalInspectable.DisposeMarshaler(__baseInterface); + MarshalInspectable.DisposeAbi(__innerInterface); + MarshalInspectable.DisposeAbi(__retval); + } + } + + public unsafe ObjectReferenceValue CreateInstance(string name) + { + IntPtr __innerInterface = default; + IntPtr __retval = default; + try + { + MarshalString.Pinnable __name = new(name); + fixed (void* ___name = __name) + { + global::WinRT.ExceptionHelpers.ThrowExceptionForHR(_obj.Vftbl.CreateInstance_0(ThisPtr, MarshalString.GetAbi(ref __name), IntPtr.Zero, &__innerInterface, &__retval)); + return new ObjectReferenceValue(__retval); + } + } + finally + { + MarshalInspectable.DisposeAbi(__innerInterface); + } + } } } @@ -102,7 +178,10 @@ namespace ABI.System.ComponentModel #endif unsafe struct PropertyChangedEventArgs { - private static ABI.Microsoft.UI.Xaml.Data.WinRTPropertyChangedEventArgsRuntimeClassFactory Instance = ActivationFactory.Get("Microsoft.UI.Xaml.Data.PropertyChangedEventArgs"); + private static ABI.Microsoft.UI.Xaml.Data.IWinRTPropertyChangedEventArgsRuntimeClassFactory Instance = + Projections.UiXamlModeSetting == Projections.UiXamlMode.WindowsUiXaml + ? new ABI.Microsoft.UI.Xaml.Data.WUXPropertyChangedEventArgsRuntimeClassFactory(ActivationFactory.Get("Windows.UI.Xaml.Data.PropertyChangedEventArgs")) + : new ABI.Microsoft.UI.Xaml.Data.MUXPropertyChangedEventArgsRuntimeClassFactory(ActivationFactory.Get("Microsoft.UI.Xaml.Data.PropertyChangedEventArgs")); public static IObjectReference CreateMarshaler(global::System.ComponentModel.PropertyChangedEventArgs value) { @@ -136,6 +215,8 @@ public static ObjectReferenceValue CreateMarshaler2(global::System.ComponentMode IntPtr propertyName = IntPtr.Zero; try { + // We can use the Microsoft.UI.Xaml.Data.IPropertyChangedEventArgsVftbl here in both WUX and MUX because the vtables are laid out the same and we know + // that we have either a MUX or WUX IPropertyChangedEventArgs pointer in ptr. ExceptionHelpers.ThrowExceptionForHR((**(ABI.Microsoft.UI.Xaml.Data.IPropertyChangedEventArgsVftbl**)ptr).get_PropertyName_0(ptr, &propertyName)); return new global::System.ComponentModel.PropertyChangedEventArgs(MarshalString.FromAbi(propertyName)); } @@ -172,6 +253,11 @@ public static IntPtr FromManaged(global::System.ComponentModel.PropertyChangedEv public static string GetGuidSignature() { + if (Projections.UiXamlModeSetting == Projections.UiXamlMode.WindowsUiXaml) + { + return "rc(Windows.UI.Xaml.Data.NotifyPropertyChangedEventArgs;{4f33a9a0-5cf4-47a4-b16f-d7faaf17457e})"; + } + return "rc(Microsoft.UI.Xaml.Data.NotifyPropertyChangedEventArgs;{4f33a9a0-5cf4-47a4-b16f-d7faaf17457e})"; } } diff --git a/src/WinRT.Runtime/Projections/PropertyChangedEventHandler.cs b/src/WinRT.Runtime/Projections/PropertyChangedEventHandler.cs index 28334aadd..2faf769a7 100644 --- a/src/WinRT.Runtime/Projections/PropertyChangedEventHandler.cs +++ b/src/WinRT.Runtime/Projections/PropertyChangedEventHandler.cs @@ -40,11 +40,14 @@ static unsafe PropertyChangedEventHandler() var nativeVftbl = ComWrappersSupport.AllocateVtableMemory(typeof(PropertyChangedEventHandler), Marshal.SizeOf()); Marshal.StructureToPtr(AbiToProjectionVftable, nativeVftbl, false); AbiToProjectionVftablePtr = nativeVftbl; + IID = Projections.UiXamlModeSetting == Projections.UiXamlMode.WindowsUiXaml + ? Guid.Parse("50f19c16-0a22-4d8e-a089-1ea9951657d2") + : typeof(global::System.ComponentModel.PropertyChangedEventHandler).GUID; } public static global::System.Delegate AbiInvokeDelegate { get; } - private static readonly Guid IID = new(0xE3DE52F6, 0x1E32, 0x5DA6, 0xBB, 0x2D, 0xB5, 0xB6, 0x09, 0x6C, 0x96, 0x2D); + private static readonly Guid IID; public static unsafe IObjectReference CreateMarshaler(global::System.ComponentModel.PropertyChangedEventHandler managedDelegate) => managedDelegate is null ? null : MarshalDelegate.CreateMarshaler(managedDelegate, IID); diff --git a/src/WinRT.Runtime/Projections/Windows.UI.Xaml.Bindable.net5.cs b/src/WinRT.Runtime/Projections/Windows.UI.Xaml.Bindable.net5.cs new file mode 100644 index 000000000..7f54e9b25 --- /dev/null +++ b/src/WinRT.Runtime/Projections/Windows.UI.Xaml.Bindable.net5.cs @@ -0,0 +1,367 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using WinRT; +using WinRT.Interop; + + +#pragma warning disable 0169 // warning CS0169: The field '...' is never used +#pragma warning disable 0649 // warning CS0169: Field '...' is never assigned to + +namespace Windows.UI.Xaml.Interop +{ + [global::WinRT.WindowsRuntimeType] + [Guid("036D2C08-DF29-41AF-8AA2-D774BE62BA6F")] + [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Windows.UI.Xaml.Interop.IBindableIterable))] + internal interface IBindableIterable + { + IBindableIterator First(); + } + [global::WinRT.WindowsRuntimeType] + [Guid("6A1D6C07-076D-49F2-8314-F52C9C9A8331")] + [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Windows.UI.Xaml.Interop.IBindableIterator))] + internal interface IBindableIterator + { + bool MoveNext(); + // GetMany is not implemented by IBindableIterator, but it is here + // for compat purposes with WinUI where there are scenarios they do + // reinterpret_cast from IBindableIterator to IIterable. It is + // the last function in the vftable and shouldn't be called by anyone. + // If called, it will return NotImplementedException. + uint GetMany(ref object[] items); + object Current { get; } + bool HasCurrent { get; } + } + [global::WinRT.WindowsRuntimeType] + [Guid("393DE7DE-6FD0-4C0D-BB71-47244A113E93")] + internal interface IBindableVector : IEnumerable + { + object GetAt(uint index); + IBindableVectorView GetView(); + bool IndexOf(object value, out uint index); + void SetAt(uint index, object value); + void InsertAt(uint index, object value); + void RemoveAt(uint index); + void Append(object value); + void RemoveAtEnd(); + void Clear(); + uint Size { get; } + } + [global::WinRT.WindowsRuntimeType] + [Guid("346DD6E7-976E-4BC3-815D-ECE243BC0F33")] + [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Windows.UI.Xaml.Interop.IBindableVectorView))] + internal interface IBindableVectorView : IEnumerable + { + object GetAt(uint index); + bool IndexOf(object value, out uint index); + uint Size { get; } + } +} + +namespace ABI.Windows.UI.Xaml.Interop +{ + [DynamicInterfaceCastableImplementation] + [Guid("036D2C08-DF29-41AF-8AA2-D774BE62BA6F")] + internal unsafe interface IBindableIterable : global::Windows.UI.Xaml.Interop.IBindableIterable, ABI.System.Collections.IEnumerable + { + + } + + [DynamicInterfaceCastableImplementation] + [Guid("6A1D6C07-076D-49F2-8314-F52C9C9A8331")] + internal unsafe interface IBindableIterator : global::Windows.UI.Xaml.Interop.IBindableIterator + { + public static readonly IntPtr AbiToProjectionVftablePtr; + static IBindableIterator() + { + AbiToProjectionVftablePtr = ComWrappersSupport.AllocateVtableMemory(typeof(IBindableIterator), sizeof(IInspectable.Vftbl) + sizeof(IntPtr) * 4); + *(IInspectable.Vftbl*)AbiToProjectionVftablePtr = IInspectable.Vftbl.AbiToProjectionVftable; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[6] = &Do_Abi_get_Current_0; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[7] = &Do_Abi_get_HasCurrent_1; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[8] = &Do_Abi_MoveNext_2; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[9] = &Do_Abi_GetMany_3; + } + + [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] + private static unsafe int Do_Abi_MoveNext_2(IntPtr thisPtr, byte* result) + { + bool __result = default; + *result = default; + try + { + __result = global::WinRT.ComWrappersSupport.FindObject(thisPtr).MoveNext(); + *result = (byte)(__result ? 1 : 0); + } + catch (Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + + [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] + private static unsafe int Do_Abi_GetMany_3(IntPtr thisPtr, int __itemsSize, IntPtr items, uint* result) + { + *result = default; + + try + { + // Should never be called. + throw new NotImplementedException(); + } + catch (Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + } + + [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] + private static unsafe int Do_Abi_get_Current_0(IntPtr thisPtr, IntPtr* value) + { + object __value = default; + *value = default; + try + { + __value = global::WinRT.ComWrappersSupport.FindObject(thisPtr).Current; + *value = MarshalInspectable.FromManaged(__value); + } + catch (Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + + [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] + private static unsafe int Do_Abi_get_HasCurrent_1(IntPtr thisPtr, byte* value) + { + bool __value = default; + *value = default; + try + { + __value = global::WinRT.ComWrappersSupport.FindObject(thisPtr).HasCurrent; + *value = (byte)(__value ? 1 : 0); + } + catch (Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + + internal static ObjectReference FromAbi(IntPtr thisPtr) => ObjectReference.FromAbi(thisPtr); + + unsafe bool global::Windows.UI.Xaml.Interop.IBindableIterator.MoveNext() + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::Windows.UI.Xaml.Interop.IBindableIterator).TypeHandle); + var ThisPtr = _obj.ThisPtr; + byte __retval = default; + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[8](ThisPtr, &__retval)); + return __retval != 0; + } + + unsafe uint global::Windows.UI.Xaml.Interop.IBindableIterator.GetMany(ref object[] items) + { + // Should never be called. + throw new NotImplementedException(); + } + + unsafe object global::Windows.UI.Xaml.Interop.IBindableIterator.Current + { + get + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::Windows.UI.Xaml.Interop.IBindableIterator).TypeHandle); + var ThisPtr = _obj.ThisPtr; + IntPtr __retval = default; + try + { + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[6](ThisPtr, &__retval)); + return MarshalInspectable.FromAbi(__retval); + } + finally + { + MarshalInspectable.DisposeAbi(__retval); + } + } + } + + unsafe bool global::Windows.UI.Xaml.Interop.IBindableIterator.HasCurrent + { + get + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::Windows.UI.Xaml.Interop.IBindableIterator).TypeHandle); + var ThisPtr = _obj.ThisPtr; + byte __retval = default; + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[7](ThisPtr, &__retval)); + return __retval != 0; + } + } + + } + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + internal static class IBindableIterator_Delegates + { + public unsafe delegate int get_Current_0(IntPtr thisPtr, IntPtr* result); + public unsafe delegate int get_HasCurrent_1(IntPtr thisPtr, byte* result); + public unsafe delegate int MoveNext_2(IntPtr thisPtr, byte* result); + public unsafe delegate int GetMany_3(IntPtr thisPtr, int itemSize, IntPtr items, uint* result); + } + + [DynamicInterfaceCastableImplementation] + [Guid("346DD6E7-976E-4BC3-815D-ECE243BC0F33")] + internal unsafe interface IBindableVectorView : global::Windows.UI.Xaml.Interop.IBindableVectorView + { + public static readonly IntPtr AbiToProjectionVftablePtr; + static IBindableVectorView() + { + AbiToProjectionVftablePtr = ComWrappersSupport.AllocateVtableMemory(typeof(IBindableVectorView), sizeof(IInspectable.Vftbl) + sizeof(IntPtr) * 3); + *(IInspectable.Vftbl*)AbiToProjectionVftablePtr = IInspectable.Vftbl.AbiToProjectionVftable; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[6] = &Do_Abi_GetAt_0; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[7] = &Do_Abi_get_Size_1; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[8] = &Do_Abi_IndexOf_2; + } + + [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] + private static unsafe int Do_Abi_GetAt_0(IntPtr thisPtr, uint index, IntPtr* result) + { + object __result = default; + + try + { + __result = global::WinRT.ComWrappersSupport.FindObject(thisPtr).GetAt(index); + *result = MarshalInspectable.FromManaged(__result); + + } + catch (Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + + [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] + private static unsafe int Do_Abi_IndexOf_2(IntPtr thisPtr, IntPtr value, uint* index, byte* returnValue) + { + bool __returnValue = default; + + *index = default; + *returnValue = default; + uint __index = default; + + try + { + __returnValue = global::WinRT.ComWrappersSupport.FindObject(thisPtr).IndexOf(MarshalInspectable.FromAbi(value), out __index); + *index = __index; + *returnValue = (byte)(__returnValue ? 1 : 0); + + } + catch (Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + + [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] + private static unsafe int Do_Abi_get_Size_1(IntPtr thisPtr, uint* value) + { + uint __value = default; + + *value = default; + + try + { + __value = global::WinRT.ComWrappersSupport.FindObject(thisPtr).Size; + *value = __value; + + } + catch (Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + + internal static ObjectReference FromAbi(IntPtr thisPtr) => ObjectReference.FromAbi(thisPtr); + + private static readonly global::System.Runtime.CompilerServices.ConditionalWeakTable _helperTable = new(); + + unsafe object global::Windows.UI.Xaml.Interop.IBindableVectorView.GetAt(uint index) + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::Windows.UI.Xaml.Interop.IBindableIterator).TypeHandle); + var ThisPtr = _obj.ThisPtr; + IntPtr __retval = default; + try + { + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[6](ThisPtr, index, &__retval)); + return MarshalInspectable.FromAbi(__retval); + } + finally + { + MarshalInspectable.DisposeAbi(__retval); + } + } + + unsafe bool global::Windows.UI.Xaml.Interop.IBindableVectorView.IndexOf(object value, out uint index) + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::Windows.UI.Xaml.Interop.IBindableIterator).TypeHandle); + var ThisPtr = _obj.ThisPtr; + ObjectReferenceValue __value = default; + uint __index = default; + byte __retval = default; + try + { + __value = MarshalInspectable.CreateMarshaler2(value); + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[8]( + ThisPtr, + MarshalInspectable.GetAbi(__value), + &__index, + &__retval)); + index = __index; + return __retval != 0; + } + finally + { + MarshalInspectable.DisposeMarshaler(__value); + } + } + + unsafe uint global::Windows.UI.Xaml.Interop.IBindableVectorView.Size + { + get + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::Windows.UI.Xaml.Interop.IBindableIterator).TypeHandle); + var ThisPtr = _obj.ThisPtr; + uint __retval = default; + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[7](ThisPtr, &__retval)); + return __retval; + } + } + + IEnumerator IEnumerable.GetEnumerator() + { + return _helperTable.GetValue((IWinRTObject)this, + (enumerable) => new ABI.System.Collections.IEnumerable.AdaptiveFromAbiHelper(enumerable) + ).GetEnumerator(); + } + } + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + internal static class IBindableVectorView_Delegates + { + public unsafe delegate int GetAt_0(IntPtr thisPtr, uint index, IntPtr* result); + public unsafe delegate int get_Size_1(IntPtr thisPtr, uint* result); + public unsafe delegate int IndexOf_2(IntPtr thisPtr, IntPtr value, uint* index, byte* returnValue); + } +} diff --git a/src/cswinrt/cswinrt.vcxproj.filters b/src/cswinrt/cswinrt.vcxproj.filters index 57e31721d..b06989e5d 100644 --- a/src/cswinrt/cswinrt.vcxproj.filters +++ b/src/cswinrt/cswinrt.vcxproj.filters @@ -51,6 +51,21 @@ {369a6d8a-43e6-48af-82c1-bb2e555909a4} + + {22aeef74-f4df-40f4-a18f-8053ac54f966} + + + {bb545b29-ba72-4949-b044-790f57ba17a5} + + + {8451fa83-9750-4aec-ae8c-a4149c4b98a6} + + + {98453be9-888b-4032-b5cd-4034b17197c9} + + + {03980bb6-f657-4c07-a456-5b4774de5773} + @@ -174,6 +189,24 @@ strings + + strings\additions\Windows.UI.Xaml.Controls.Primitives + + + strings\additions\Windows.UI.Xaml.Media.Animation + + + strings\additions\Windows.UI.Xaml.Media.Media3D + + + strings\additions\Windows.UI.Xaml.Media + + + strings\additions\Windows.UI.Xaml + + + strings\additions\Windows.UI.Xaml + diff --git a/src/cswinrt/helpers.h b/src/cswinrt/helpers.h index 8e43f270f..93b1ce916 100644 --- a/src/cswinrt/helpers.h +++ b/src/cswinrt/helpers.h @@ -670,7 +670,7 @@ namespace cswinrt } mapped_types[] = { // Make sure to keep this table consistent with the registrations in WinRT.Runtime/Projections.cs - // and the reverse mapping in WinRT.SourceGenerator/WinRTTypeWriter.cs. + // and the reverse mapping in WinRT.SourceGenerator/TypeMapper.cs. // This table can include both the MUX and WUX types as only one will be selected at runtime. // NOTE: Must keep namespaces sorted (outer) and abi type names sorted (inner) { "Microsoft.UI.Xaml", diff --git a/src/cswinrt/strings/additions/Windows.UI.Xaml.Controls/Windows.UI.Xaml.Controls.Primitives.cs b/src/cswinrt/strings/additions/Windows.UI.Xaml.Controls/Windows.UI.Xaml.Controls.Primitives.cs index 8326013d9..ec28e9295 100644 --- a/src/cswinrt/strings/additions/Windows.UI.Xaml.Controls/Windows.UI.Xaml.Controls.Primitives.cs +++ b/src/cswinrt/strings/additions/Windows.UI.Xaml.Controls/Windows.UI.Xaml.Controls.Primitives.cs @@ -3,7 +3,7 @@ namespace Windows.UI.Xaml.Controls.Primitives { using global::Windows.Foundation; - [global::WinRT.WindowsRuntimeType("Microsoft.UI")] + [global::WinRT.WindowsRuntimeType("Windows.UI.Xaml")] [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Windows.UI.Xaml.Controls.Primitives.GeneratorPosition))] [StructLayout(LayoutKind.Sequential)] #if EMBED diff --git a/src/cswinrt/strings/additions/Windows.UI.Xaml.Media.Animation/Windows.UI.Xaml.Media.Animation.cs b/src/cswinrt/strings/additions/Windows.UI.Xaml.Media.Animation/Windows.UI.Xaml.Media.Animation.cs index 789928089..259898959 100644 --- a/src/cswinrt/strings/additions/Windows.UI.Xaml.Media.Animation/Windows.UI.Xaml.Media.Animation.cs +++ b/src/cswinrt/strings/additions/Windows.UI.Xaml.Media.Animation/Windows.UI.Xaml.Media.Animation.cs @@ -3,7 +3,7 @@ namespace Windows.UI.Xaml.Media.Animation { using global::Windows.Foundation; - [global::WinRT.WindowsRuntimeType("Microsoft.UI")] + [global::WinRT.WindowsRuntimeType("Windows.UI.Xaml")] [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Windows.UI.Xaml.Media.Animation.KeyTime))] [StructLayout(LayoutKind.Sequential)] #if EMBED @@ -78,7 +78,7 @@ public TimeSpan TimeSpan } } - [global::WinRT.WindowsRuntimeType("Microsoft.UI")] + [global::WinRT.WindowsRuntimeType("Windows.UI.Xaml")] #if EMBED internal #else @@ -91,7 +91,7 @@ enum RepeatBehaviorType Forever } - [global::WinRT.WindowsRuntimeType("Microsoft.UI")] + [global::WinRT.WindowsRuntimeType("Windows.UI.Xaml")] [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Windows.UI.Xaml.Media.Animation.RepeatBehavior))] [StructLayout(LayoutKind.Sequential)] #if EMBED diff --git a/src/cswinrt/strings/additions/Windows.UI.Xaml.Media.Media3D/Windows.UI.Xaml.Media.Media3D.cs b/src/cswinrt/strings/additions/Windows.UI.Xaml.Media.Media3D/Windows.UI.Xaml.Media.Media3D.cs index 84e3837ff..98dfb069e 100644 --- a/src/cswinrt/strings/additions/Windows.UI.Xaml.Media.Media3D/Windows.UI.Xaml.Media.Media3D.cs +++ b/src/cswinrt/strings/additions/Windows.UI.Xaml.Media.Media3D/Windows.UI.Xaml.Media.Media3D.cs @@ -3,7 +3,7 @@ namespace Windows.UI.Xaml.Media.Media3D { using global::Windows.Foundation; - [global::WinRT.WindowsRuntimeType("Microsoft.UI")] + [global::WinRT.WindowsRuntimeType("Windows.UI.Xaml")] [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Windows.UI.Xaml.Media.Media3D.Matrix3D))] [StructLayout(LayoutKind.Sequential)] #if EMBED diff --git a/src/cswinrt/strings/additions/Windows.UI.Xaml.Media/Windows.UI.Xaml.Media.cs b/src/cswinrt/strings/additions/Windows.UI.Xaml.Media/Windows.UI.Xaml.Media.cs index a731d74fb..b156e5104 100644 --- a/src/cswinrt/strings/additions/Windows.UI.Xaml.Media/Windows.UI.Xaml.Media.cs +++ b/src/cswinrt/strings/additions/Windows.UI.Xaml.Media/Windows.UI.Xaml.Media.cs @@ -3,7 +3,7 @@ namespace Windows.UI.Xaml.Media { using global::Windows.Foundation; - [global::WinRT.WindowsRuntimeType("Microsoft.UI")] + [global::WinRT.WindowsRuntimeType("Windows.UI.Xaml")] [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Windows.UI.Xaml.Media.Matrix))] [StructLayout(LayoutKind.Sequential)] #if EMBED diff --git a/src/cswinrt/strings/additions/Windows.UI.Xaml/Windows.UI.Xaml.cs b/src/cswinrt/strings/additions/Windows.UI.Xaml/Windows.UI.Xaml.cs index 1ec6ea03d..341d016d6 100644 --- a/src/cswinrt/strings/additions/Windows.UI.Xaml/Windows.UI.Xaml.cs +++ b/src/cswinrt/strings/additions/Windows.UI.Xaml/Windows.UI.Xaml.cs @@ -3,7 +3,7 @@ namespace Windows.UI.Xaml { using global::Windows.Foundation; - [global::WinRT.WindowsRuntimeType("Microsoft.UI")] + [global::WinRT.WindowsRuntimeType("Windows.UI.Xaml")] [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Windows.UI.Xaml.CornerRadius))] [StructLayout(LayoutKind.Sequential)] #if EMBED @@ -151,7 +151,7 @@ public double BottomLeft } } - [global::WinRT.WindowsRuntimeType("Microsoft.UI")] + [global::WinRT.WindowsRuntimeType("Windows.UI.Xaml")] #if EMBED internal #else @@ -164,7 +164,7 @@ enum GridUnitType Star, } - [global::WinRT.WindowsRuntimeType("Microsoft.UI")] + [global::WinRT.WindowsRuntimeType("Windows.UI.Xaml")] [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Windows.UI.Xaml.GridLength))] [StructLayout(LayoutKind.Sequential)] #if EMBED @@ -282,7 +282,7 @@ internal string ToString(global::System.Globalization.CultureInfo cultureInfo) } } - [global::WinRT.WindowsRuntimeType("Microsoft.UI")] + [global::WinRT.WindowsRuntimeType("Windows.UI.Xaml")] [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Windows.UI.Xaml.Thickness))] [StructLayout(LayoutKind.Sequential)] #if EMBED @@ -396,7 +396,7 @@ public override int GetHashCode() } } - [global::WinRT.WindowsRuntimeType("Microsoft.UI")] + [global::WinRT.WindowsRuntimeType("Windows.UI.Xaml")] #if EMBED internal #else @@ -409,7 +409,7 @@ enum DurationType Forever } - [global::WinRT.WindowsRuntimeType("Microsoft.UI")] + [global::WinRT.WindowsRuntimeType("Windows.UI.Xaml")] [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Windows.UI.Xaml.Duration))] [StructLayout(LayoutKind.Sequential)] #if EMBED From 0195eaf496c0d92e6f287e9969197e75f6049d25 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Mon, 18 Dec 2023 14:32:30 -0800 Subject: [PATCH 03/46] Add WUX test projection and fix bug with ICommand special-casing. --- src/Directory.Build.props | 2 ++ src/Projections/Windows.UI.Xaml/Module.cs | 3 +++ .../Windows.UI.Xaml/Windows.UI.Xaml.csproj | 26 +++++++++++++++++++ src/cswinrt.sln | 19 ++++++++++++++ src/cswinrt/code_writers.h | 2 +- 5 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 src/Projections/Windows.UI.Xaml/Module.cs create mode 100644 src/Projections/Windows.UI.Xaml/Windows.UI.Xaml.csproj diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 5a1370dc5..caef79a59 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -30,6 +30,8 @@ netcoreapp3.1;net6.0;net8.0 netstandard2.0;net6.0;net8.0 netstandard2.0;net6.0;net8.0 + net6.0;net8.0 + net6.0;net8.0 net6.0-windows10.0.19041.0;net7.0-windows10.0.19041.0 net6.0-windows10.0.19041.0 net6.0;net8.0 diff --git a/src/Projections/Windows.UI.Xaml/Module.cs b/src/Projections/Windows.UI.Xaml/Module.cs new file mode 100644 index 000000000..636144eed --- /dev/null +++ b/src/Projections/Windows.UI.Xaml/Module.cs @@ -0,0 +1,3 @@ +#if NET +[assembly: global::System.Runtime.Versioning.SupportedOSPlatform("Windows")] +#endif diff --git a/src/Projections/Windows.UI.Xaml/Windows.UI.Xaml.csproj b/src/Projections/Windows.UI.Xaml/Windows.UI.Xaml.csproj new file mode 100644 index 000000000..79d80d607 --- /dev/null +++ b/src/Projections/Windows.UI.Xaml/Windows.UI.Xaml.csproj @@ -0,0 +1,26 @@ + + + + $(LibBuildTFMsNoNetStandard) + x64;x86 + Microsoft.Windows.UI.Xaml + true + + + + + + + + + + + + + +-exclude Windows +-include Windows.UI.Xaml + + + + \ No newline at end of file diff --git a/src/cswinrt.sln b/src/cswinrt.sln index 50184b3ca..c958debde 100644 --- a/src/cswinrt.sln +++ b/src/cswinrt.sln @@ -163,6 +163,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WinAppSDK", "Projections\Wi EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestLibrary", "Tests\FunctionalTests\TestLibrary\TestLibrary.csproj", "{335D51AC-1DCF-4487-A2BD-34CE2F17B3C4}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Windows.UI.Xaml", "Projections\Windows.UI.Xaml\Windows.UI.Xaml.csproj", "{E85F3614-79B6-4652-BDB0-64AF68874CE0}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|ARM = Debug|ARM @@ -735,6 +737,22 @@ Global {335D51AC-1DCF-4487-A2BD-34CE2F17B3C4}.Release|x64.Build.0 = Release|x64 {335D51AC-1DCF-4487-A2BD-34CE2F17B3C4}.Release|x86.ActiveCfg = Release|x86 {335D51AC-1DCF-4487-A2BD-34CE2F17B3C4}.Release|x86.Build.0 = Release|x86 + {E85F3614-79B6-4652-BDB0-64AF68874CE0}.Debug|ARM.ActiveCfg = Debug|x64 + {E85F3614-79B6-4652-BDB0-64AF68874CE0}.Debug|ARM.Build.0 = Debug|x64 + {E85F3614-79B6-4652-BDB0-64AF68874CE0}.Debug|ARM64.ActiveCfg = Debug|x64 + {E85F3614-79B6-4652-BDB0-64AF68874CE0}.Debug|ARM64.Build.0 = Debug|x64 + {E85F3614-79B6-4652-BDB0-64AF68874CE0}.Debug|x64.ActiveCfg = Debug|x64 + {E85F3614-79B6-4652-BDB0-64AF68874CE0}.Debug|x64.Build.0 = Debug|x64 + {E85F3614-79B6-4652-BDB0-64AF68874CE0}.Debug|x86.ActiveCfg = Debug|x86 + {E85F3614-79B6-4652-BDB0-64AF68874CE0}.Debug|x86.Build.0 = Debug|x86 + {E85F3614-79B6-4652-BDB0-64AF68874CE0}.Release|ARM.ActiveCfg = Release|x64 + {E85F3614-79B6-4652-BDB0-64AF68874CE0}.Release|ARM.Build.0 = Release|x64 + {E85F3614-79B6-4652-BDB0-64AF68874CE0}.Release|ARM64.ActiveCfg = Release|x64 + {E85F3614-79B6-4652-BDB0-64AF68874CE0}.Release|ARM64.Build.0 = Release|x64 + {E85F3614-79B6-4652-BDB0-64AF68874CE0}.Release|x64.ActiveCfg = Release|x64 + {E85F3614-79B6-4652-BDB0-64AF68874CE0}.Release|x64.Build.0 = Release|x64 + {E85F3614-79B6-4652-BDB0-64AF68874CE0}.Release|x86.ActiveCfg = Release|x86 + {E85F3614-79B6-4652-BDB0-64AF68874CE0}.Release|x86.Build.0 = Release|x86 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -780,6 +798,7 @@ Global {C44DB047-5DF0-4732-98F4-A181D3AD8A7F} = {5ECC38F0-16FD-47E1-B8DC-8C474008AD55} {7B803846-91AE-4B98-AC93-D3FCFB2DE5AA} = {6D41796B-9904-40B8-BBCB-40B2D1BAE44B} {335D51AC-1DCF-4487-A2BD-34CE2F17B3C4} = {5ECC38F0-16FD-47E1-B8DC-8C474008AD55} + {E85F3614-79B6-4652-BDB0-64AF68874CE0} = {6D41796B-9904-40B8-BBCB-40B2D1BAE44B} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {5AE8C9D7-2613-4E1A-A4F2-579BAC28D0A2} diff --git a/src/cswinrt/code_writers.h b/src/cswinrt/code_writers.h index 045b91981..2ee67716c 100644 --- a/src/cswinrt/code_writers.h +++ b/src/cswinrt/code_writers.h @@ -1440,7 +1440,7 @@ private % Make_%() if (event.Name() == "CanExecuteChanged" && event_type == "global::System.EventHandler") { auto parent_type = w.write_temp("%", bind(event.Parent(), typedef_name_type::NonProjected, true)); - if (parent_type == "Microsoft.UI.Xaml.Input.ICommand") + if (parent_type == "Microsoft.UI.Xaml.Input.ICommand" || parent_type == "Windows.UI.Xaml.Input.ICommand") { event_type = "global::System.EventHandler"; } From 4de7abc8e360e2ea913d5aa1eaed70113f2cd2ea Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Mon, 18 Dec 2023 14:40:05 -0800 Subject: [PATCH 04/46] Inline MUX guids. --- src/WinRT.Runtime/Projections/INotifyCollectionChanged.net5.cs | 2 +- src/WinRT.Runtime/Projections/INotifyPropertyChanged.net5.cs | 2 +- .../Projections/NotifyCollectionChangedEventArgs.cs | 2 +- .../Projections/NotifyCollectionChangedEventHandler.cs | 2 +- src/WinRT.Runtime/Projections/PropertyChangedEventHandler.cs | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/WinRT.Runtime/Projections/INotifyCollectionChanged.net5.cs b/src/WinRT.Runtime/Projections/INotifyCollectionChanged.net5.cs index 3d7334c5c..84ca24e2d 100644 --- a/src/WinRT.Runtime/Projections/INotifyCollectionChanged.net5.cs +++ b/src/WinRT.Runtime/Projections/INotifyCollectionChanged.net5.cs @@ -52,7 +52,7 @@ internal unsafe interface INotifyCollectionChanged : global::System.Collections. public static string GetGuidSignature() => Projections.UiXamlModeSetting == Projections.UiXamlMode.WindowsUiXaml ? "{CF75D69C-F2F4-486B-B302-BB4C09BAEBFA}" - : typeof(INotifyCollectionChanged).GUID.ToString("B"); + : "{530155E1-28A5-5693-87CE-30724D95A06D}"; [Guid("530155E1-28A5-5693-87CE-30724D95A06D")] [WuxMuxProjectedType] diff --git a/src/WinRT.Runtime/Projections/INotifyPropertyChanged.net5.cs b/src/WinRT.Runtime/Projections/INotifyPropertyChanged.net5.cs index dd5322408..0bff679c1 100644 --- a/src/WinRT.Runtime/Projections/INotifyPropertyChanged.net5.cs +++ b/src/WinRT.Runtime/Projections/INotifyPropertyChanged.net5.cs @@ -28,7 +28,7 @@ internal unsafe interface INotifyPropertyChanged : global::System.ComponentModel public static string GetGuidSignature() => Projections.UiXamlModeSetting == Projections.UiXamlMode.WindowsUiXaml ? "{cf75d69c-f2f4-486b-b302-bb4c09baebfa}" - : typeof(INotifyPropertyChanged).GUID.ToString("B"); + : "{90B17601-B065-586E-83D9-9ADC3A695284}"; [Guid("90B17601-B065-586E-83D9-9ADC3A695284")] [StructLayout(LayoutKind.Sequential)] diff --git a/src/WinRT.Runtime/Projections/NotifyCollectionChangedEventArgs.cs b/src/WinRT.Runtime/Projections/NotifyCollectionChangedEventArgs.cs index e0000593c..081ca31a3 100644 --- a/src/WinRT.Runtime/Projections/NotifyCollectionChangedEventArgs.cs +++ b/src/WinRT.Runtime/Projections/NotifyCollectionChangedEventArgs.cs @@ -18,7 +18,7 @@ internal sealed unsafe class INotifyCollectionChangedEventArgs public static string GetGuidSignature() => Projections.UiXamlModeSetting == Projections.UiXamlMode.WindowsUiXaml ? "{4cf68d33-e3f2-4964-b85e-945b4f7e2f21}" - : typeof(INotifyCollectionChangedEventArgs).GUID.ToString("B"); + : "{DA049FF2-D2E0-5FE8-8C7B-F87F26060B6F}"; [Guid("DA049FF2-D2E0-5FE8-8C7B-F87F26060B6F")] [StructLayout(LayoutKind.Sequential)] diff --git a/src/WinRT.Runtime/Projections/NotifyCollectionChangedEventHandler.cs b/src/WinRT.Runtime/Projections/NotifyCollectionChangedEventHandler.cs index aaf4f8181..5d6976853 100644 --- a/src/WinRT.Runtime/Projections/NotifyCollectionChangedEventHandler.cs +++ b/src/WinRT.Runtime/Projections/NotifyCollectionChangedEventHandler.cs @@ -44,7 +44,7 @@ static unsafe NotifyCollectionChangedEventHandler() IID = Projections.UiXamlModeSetting == Projections.UiXamlMode.WindowsUiXaml ? Guid.Parse("ca10b37c-f382-4591-8557-5e24965279b0") - : typeof(global::ABI.System.Collections.Specialized.NotifyCollectionChangedEventHandler).GUID; + : Guid.Parse("8B0909DC-2005-5D93-BF8A-725F017BAA8D"); } public static global::System.Delegate AbiInvokeDelegate { get; } diff --git a/src/WinRT.Runtime/Projections/PropertyChangedEventHandler.cs b/src/WinRT.Runtime/Projections/PropertyChangedEventHandler.cs index 2faf769a7..053bb27a3 100644 --- a/src/WinRT.Runtime/Projections/PropertyChangedEventHandler.cs +++ b/src/WinRT.Runtime/Projections/PropertyChangedEventHandler.cs @@ -42,7 +42,7 @@ static unsafe PropertyChangedEventHandler() AbiToProjectionVftablePtr = nativeVftbl; IID = Projections.UiXamlModeSetting == Projections.UiXamlMode.WindowsUiXaml ? Guid.Parse("50f19c16-0a22-4d8e-a089-1ea9951657d2") - : typeof(global::System.ComponentModel.PropertyChangedEventHandler).GUID; + : Guid.Parse("E3DE52F6-1E32-5DA6-BB2D-B5B6096C962D"); } public static global::System.Delegate AbiInvokeDelegate { get; } From a2e8df24f1580e13d23c53a490da3bf98d85e728 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Mon, 18 Dec 2023 14:56:01 -0800 Subject: [PATCH 05/46] Add CsWinRT SDK support --- nuget/Microsoft.Windows.CsWinRT.Authoring.targets | 1 + nuget/Microsoft.Windows.CsWinRT.targets | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/nuget/Microsoft.Windows.CsWinRT.Authoring.targets b/nuget/Microsoft.Windows.CsWinRT.Authoring.targets index 6a6a99805..efb3c1eee 100644 --- a/nuget/Microsoft.Windows.CsWinRT.Authoring.targets +++ b/nuget/Microsoft.Windows.CsWinRT.Authoring.targets @@ -31,6 +31,7 @@ Copyright (C) Microsoft Corporation. All rights reserved. + diff --git a/nuget/Microsoft.Windows.CsWinRT.targets b/nuget/Microsoft.Windows.CsWinRT.targets index ae67f35eb..c98cf11f3 100644 --- a/nuget/Microsoft.Windows.CsWinRT.targets +++ b/nuget/Microsoft.Windows.CsWinRT.targets @@ -220,6 +220,13 @@ $(CsWinRTInternalProjection) + + + $(CsWinRTUiXamlMode) + true + + + From 0d88207a67437cd128bd40ea930f930dd956f37c Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Mon, 18 Dec 2023 16:58:33 -0800 Subject: [PATCH 06/46] Add tests for authoring components with WUX APIs (also validates some of the consumption logic in the process) --- .../Windows.UI.Xaml/Windows.UI.Xaml.csproj | 5 +- .../AuthoringWuxConsumptionTest.exe.manifest | 22 ++ .../AuthoringWuxConsumptionTest.vcxproj | 212 ++++++++++++++++++ ...uthoringWuxConsumptionTest.vcxproj.filters | 39 ++++ .../Directory.Build.targets | 16 ++ .../DoNotImport_MsAppxPackageTargets.targets | 5 + .../WinRT.Host.runtimeconfig.json | 13 ++ .../packages.config | 7 + src/Tests/AuthoringWuxConsumptionTest/pch.cpp | 1 + src/Tests/AuthoringWuxConsumptionTest/pch.h | 25 +++ .../AuthoringWuxConsumptionTest/test.cpp | 67 ++++++ .../AuthoringWuxTest/AuthoringWuxTest.csproj | 22 ++ .../AuthoringWuxTest/Directory.Build.props | 9 + .../AuthoringWuxTest/Directory.Build.targets | 5 + src/Tests/AuthoringWuxTest/Module.cs | 3 + src/Tests/AuthoringWuxTest/Program.cs | 176 +++++++++++++++ .../Properties/launchSettings.json | 8 + src/WinRT.Runtime/Projections.cs | 2 + .../INotifyCollectionChanged.net5.cs | 3 +- .../INotifyPropertyChanged.net5.cs | 2 +- src/cswinrt.sln | 38 ++++ 21 files changed, 676 insertions(+), 4 deletions(-) create mode 100644 src/Tests/AuthoringWuxConsumptionTest/AuthoringWuxConsumptionTest.exe.manifest create mode 100644 src/Tests/AuthoringWuxConsumptionTest/AuthoringWuxConsumptionTest.vcxproj create mode 100644 src/Tests/AuthoringWuxConsumptionTest/AuthoringWuxConsumptionTest.vcxproj.filters create mode 100644 src/Tests/AuthoringWuxConsumptionTest/Directory.Build.targets create mode 100644 src/Tests/AuthoringWuxConsumptionTest/DoNotImport_MsAppxPackageTargets.targets create mode 100644 src/Tests/AuthoringWuxConsumptionTest/WinRT.Host.runtimeconfig.json create mode 100644 src/Tests/AuthoringWuxConsumptionTest/packages.config create mode 100644 src/Tests/AuthoringWuxConsumptionTest/pch.cpp create mode 100644 src/Tests/AuthoringWuxConsumptionTest/pch.h create mode 100644 src/Tests/AuthoringWuxConsumptionTest/test.cpp create mode 100644 src/Tests/AuthoringWuxTest/AuthoringWuxTest.csproj create mode 100644 src/Tests/AuthoringWuxTest/Directory.Build.props create mode 100644 src/Tests/AuthoringWuxTest/Directory.Build.targets create mode 100644 src/Tests/AuthoringWuxTest/Module.cs create mode 100644 src/Tests/AuthoringWuxTest/Program.cs create mode 100644 src/Tests/AuthoringWuxTest/Properties/launchSettings.json diff --git a/src/Projections/Windows.UI.Xaml/Windows.UI.Xaml.csproj b/src/Projections/Windows.UI.Xaml/Windows.UI.Xaml.csproj index 79d80d607..5bd3796fa 100644 --- a/src/Projections/Windows.UI.Xaml/Windows.UI.Xaml.csproj +++ b/src/Projections/Windows.UI.Xaml/Windows.UI.Xaml.csproj @@ -19,7 +19,10 @@ -exclude Windows --include Windows.UI.Xaml +-include Windows.UI.Xaml +-exclude Windows.UI.Xaml.Media.Animation.ConditionallyIndependentlyAnimatableAttribute +-exclude Windows.UI.Xaml.Media.Animation.KeyTime +-exclude Windows.UI.Xaml.Media.Animation.RepeatBehavior diff --git a/src/Tests/AuthoringWuxConsumptionTest/AuthoringWuxConsumptionTest.exe.manifest b/src/Tests/AuthoringWuxConsumptionTest/AuthoringWuxConsumptionTest.exe.manifest new file mode 100644 index 000000000..4af3eb765 --- /dev/null +++ b/src/Tests/AuthoringWuxConsumptionTest/AuthoringWuxConsumptionTest.exe.manifest @@ -0,0 +1,22 @@ + + + + + + + + + + \ No newline at end of file diff --git a/src/Tests/AuthoringWuxConsumptionTest/AuthoringWuxConsumptionTest.vcxproj b/src/Tests/AuthoringWuxConsumptionTest/AuthoringWuxConsumptionTest.vcxproj new file mode 100644 index 000000000..cd4340fe9 --- /dev/null +++ b/src/Tests/AuthoringWuxConsumptionTest/AuthoringWuxConsumptionTest.vcxproj @@ -0,0 +1,212 @@ + + + + + + + Debug + ARM64 + + + Debug + Win32 + + + Release + ARM64 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + {A04A0416-5E35-4DD0-8226-63D941B28467} + Win32Proj + AuthoringConsumptionTest + Application + v143 + v142 + Unicode + <_WinMDPlatform>$(Platform) + <_WinMDPlatform Condition="'$(Platform)' == 'Win32'">x86 + false + + + + + + + + + + + + + + Create + + + + + + + + true + true + true + true + + + + + {ffa9a78b-f53f-43ee-af87-24a80f4c330a} + TargetFramework=net6.0 + + + {0bb8f82d-874e-45aa-bca3-20ce0562164a} + TargetFramework=net6.0 + + + {7e33bcb7-19c5-4061-981d-ba695322708a} + + + {25244ced-966e-45f2-9711-1f51e951ff89} + TargetFramework=net6.0 + + + {d60cfcad-4a13-4047-91c8-9d7df4753493} + TargetFramework=net6.0 + + + + + ..\AuthoringWuxTest\bin\$(_WinMDPlatform)\$(Configuration)\net6.0\AuthoringWuxTest.winmd + true + + + + + + + + + + + + + + + Use + pch.h + Disabled + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + Level3 + + + true + Console + + + + + Use + pch.h + Disabled + X64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + Level3 + + + DebugFull + Console + + + + + Use + pch.h + Disabled + X64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + Level3 + + + DebugFull + Console + + + + + Use + pch.h + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + MultiThreadedDLL + Level3 + ProgramDatabase + + + true + Console + true + true + + + + + Use + pch.h + X64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + MultiThreadedDLL + Level3 + ProgramDatabase + + + true + Console + true + true + + + + + Use + pch.h + X64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + MultiThreadedDLL + Level3 + ProgramDatabase + + + true + Console + true + true + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + + + + + + \ No newline at end of file diff --git a/src/Tests/AuthoringWuxConsumptionTest/AuthoringWuxConsumptionTest.vcxproj.filters b/src/Tests/AuthoringWuxConsumptionTest/AuthoringWuxConsumptionTest.vcxproj.filters new file mode 100644 index 000000000..44172eb24 --- /dev/null +++ b/src/Tests/AuthoringWuxConsumptionTest/AuthoringWuxConsumptionTest.vcxproj.filters @@ -0,0 +1,39 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Header Files + + + + + Source Files + + + Source Files + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Tests/AuthoringWuxConsumptionTest/Directory.Build.targets b/src/Tests/AuthoringWuxConsumptionTest/Directory.Build.targets new file mode 100644 index 000000000..623267b30 --- /dev/null +++ b/src/Tests/AuthoringWuxConsumptionTest/Directory.Build.targets @@ -0,0 +1,16 @@ + + + + $(MSBuildProjectDirectory)/DoNotImport_MsAppxPackageTargets.targets + CopyTestAssets;$(PrepareForRunDependsOn) + + + + + + + + + diff --git a/src/Tests/AuthoringWuxConsumptionTest/DoNotImport_MsAppxPackageTargets.targets b/src/Tests/AuthoringWuxConsumptionTest/DoNotImport_MsAppxPackageTargets.targets new file mode 100644 index 000000000..bcb335b80 --- /dev/null +++ b/src/Tests/AuthoringWuxConsumptionTest/DoNotImport_MsAppxPackageTargets.targets @@ -0,0 +1,5 @@ + + + + + diff --git a/src/Tests/AuthoringWuxConsumptionTest/WinRT.Host.runtimeconfig.json b/src/Tests/AuthoringWuxConsumptionTest/WinRT.Host.runtimeconfig.json new file mode 100644 index 000000000..89437eff9 --- /dev/null +++ b/src/Tests/AuthoringWuxConsumptionTest/WinRT.Host.runtimeconfig.json @@ -0,0 +1,13 @@ +{ + "runtimeOptions": { + "tfm": "net6.0", + "rollForward": "LatestMinor", + "framework": { + "name": "Microsoft.NETCore.App", + "version": "6.0.0" + }, + "configProperties": { + "CsWinRT.UiXamlMode": "WindowsUiXaml" + } + } +} \ No newline at end of file diff --git a/src/Tests/AuthoringWuxConsumptionTest/packages.config b/src/Tests/AuthoringWuxConsumptionTest/packages.config new file mode 100644 index 000000000..98b40a750 --- /dev/null +++ b/src/Tests/AuthoringWuxConsumptionTest/packages.config @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/src/Tests/AuthoringWuxConsumptionTest/pch.cpp b/src/Tests/AuthoringWuxConsumptionTest/pch.cpp new file mode 100644 index 000000000..bcb5590be --- /dev/null +++ b/src/Tests/AuthoringWuxConsumptionTest/pch.cpp @@ -0,0 +1 @@ +#include "pch.h" diff --git a/src/Tests/AuthoringWuxConsumptionTest/pch.h b/src/Tests/AuthoringWuxConsumptionTest/pch.h new file mode 100644 index 000000000..fac3012ea --- /dev/null +++ b/src/Tests/AuthoringWuxConsumptionTest/pch.h @@ -0,0 +1,25 @@ +#pragma once + +// Undefine GetCurrentTime macro to prevent +// conflict with Storyboard::GetCurrentTime +#undef GetCurrentTime + +#include +#include +#include + +#pragma push_macro("X86") +#pragma push_macro("X64") +#undef X86 +#undef X64 +#include "winrt/Windows.System.h" +#pragma pop_macro("X64") +#pragma pop_macro("X86") + +#include +#include +#include + +#include + +#include "gtest/gtest.h" diff --git a/src/Tests/AuthoringWuxConsumptionTest/test.cpp b/src/Tests/AuthoringWuxConsumptionTest/test.cpp new file mode 100644 index 000000000..604468c8d --- /dev/null +++ b/src/Tests/AuthoringWuxConsumptionTest/test.cpp @@ -0,0 +1,67 @@ +#include "pch.h" + +using namespace winrt; +using namespace Windows::Foundation; +using namespace AuthoringWuxTest; + +TEST(AuthoringWuxTest, Collections) +{ + DisposableClass; + + DisposableClass disposed; + disposed.Close(); + MultipleInterfaceMappingClass multipleInterfaces; + Windows::UI::Xaml::Interop::IBindableIterable bindable = multipleInterfaces; + Windows::Foundation::Collections::IVector vector = multipleInterfaces; + Windows::UI::Xaml::Interop::IBindableVector bindableVector = multipleInterfaces; + EXPECT_EQ(vector.Size(), 0); + EXPECT_EQ(bindableVector.Size(), 0); + vector.Append(DisposableClass()); + vector.Append(DisposableClass()); + vector.Append(disposed); + bindableVector.Append(DisposableClass()); + EXPECT_EQ(vector.Size(), 4); + EXPECT_EQ(bindableVector.Size(), 4); + + auto first = vector.First(); + EXPECT_TRUE(first.HasCurrent()); + EXPECT_FALSE(first.Current().IsDisposed()); + auto bindableFirst = bindable.First(); + EXPECT_TRUE(bindableFirst.HasCurrent()); + EXPECT_FALSE(bindableFirst.Current().as().IsDisposed()); + bindableFirst.Current().as().Close(); + EXPECT_TRUE(first.Current().IsDisposed()); + EXPECT_FALSE(vector.GetAt(1).IsDisposed()); + EXPECT_TRUE(vector.GetAt(2).IsDisposed()); + EXPECT_TRUE(bindableVector.First().Current().as().IsDisposed()); + EXPECT_FALSE(bindableVector.GetAt(3).as().IsDisposed()); + EXPECT_TRUE(bindableVector.GetAt(2).as().IsDisposed()); + for (auto obj : vector.GetView()) + { + obj.Close(); + } + + std::array view{}; + EXPECT_EQ(vector.GetMany(1, view), 2); + EXPECT_EQ(view.size(), 2); + for (auto& obj : view) + { + EXPECT_TRUE(obj.IsDisposed()); + } +} + +TEST(AuthoringWuxTest, PropertyChanged) +{ + CustomNotifyPropertyChanged customNotifyPropertyChanged; + Windows::UI::Xaml::Data::INotifyPropertyChanged propChanged = customNotifyPropertyChanged; + winrt::hstring propName = L"Number"; + bool eventTriggered = false; + auto token = propChanged.PropertyChanged(auto_revoke, [&eventTriggered, &propName](IInspectable sender, Windows::UI::Xaml::Data::PropertyChangedEventArgs args) + { + eventTriggered = (args.PropertyName() == propName); + }); + + customNotifyPropertyChanged.RaisePropertyChanged(propName); + + EXPECT_TRUE(eventTriggered); +} \ No newline at end of file diff --git a/src/Tests/AuthoringWuxTest/AuthoringWuxTest.csproj b/src/Tests/AuthoringWuxTest/AuthoringWuxTest.csproj new file mode 100644 index 000000000..a00cb2c58 --- /dev/null +++ b/src/Tests/AuthoringWuxTest/AuthoringWuxTest.csproj @@ -0,0 +1,22 @@ + + + + net6.0 + x64;x86 + true + true + WindowsUiXaml + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Tests/AuthoringWuxTest/Directory.Build.props b/src/Tests/AuthoringWuxTest/Directory.Build.props new file mode 100644 index 000000000..4cf186e3d --- /dev/null +++ b/src/Tests/AuthoringWuxTest/Directory.Build.props @@ -0,0 +1,9 @@ + + + + true + + + + + diff --git a/src/Tests/AuthoringWuxTest/Directory.Build.targets b/src/Tests/AuthoringWuxTest/Directory.Build.targets new file mode 100644 index 000000000..8dde12d1b --- /dev/null +++ b/src/Tests/AuthoringWuxTest/Directory.Build.targets @@ -0,0 +1,5 @@ + + + + + diff --git a/src/Tests/AuthoringWuxTest/Module.cs b/src/Tests/AuthoringWuxTest/Module.cs new file mode 100644 index 000000000..636144eed --- /dev/null +++ b/src/Tests/AuthoringWuxTest/Module.cs @@ -0,0 +1,3 @@ +#if NET +[assembly: global::System.Runtime.Versioning.SupportedOSPlatform("Windows")] +#endif diff --git a/src/Tests/AuthoringWuxTest/Program.cs b/src/Tests/AuthoringWuxTest/Program.cs new file mode 100644 index 000000000..858ae1d4c --- /dev/null +++ b/src/Tests/AuthoringWuxTest/Program.cs @@ -0,0 +1,176 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.ComponentModel; + +#pragma warning disable CA1416 + +namespace AuthoringWuxTest +{ + public sealed class DisposableClass : IDisposable + { + public bool IsDisposed { get; set; } + + public DisposableClass() + { + IsDisposed = false; + } + + public void Dispose() + { + IsDisposed = true; + } + } + public sealed class CustomNotifyPropertyChanged : INotifyPropertyChanged + { + public CustomNotifyPropertyChanged() + { + System.Diagnostics.Debugger.Launch(); + } + + public event PropertyChangedEventHandler PropertyChanged; + + public void RaisePropertyChanged(string propertyName) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + } + + public sealed class CustomNotifyCollectionChanged : INotifyCollectionChanged + { + public event NotifyCollectionChangedEventHandler CollectionChanged; + + public void RaiseCollectionChanged(NotifyCollectionChangedEventArgs args) + { + CollectionChanged?.Invoke(this, args); + } + } + + public sealed class CustomEnumerable : IEnumerable + { + private IEnumerable _enumerable; + + public CustomEnumerable(IEnumerable enumerable) + { + _enumerable = enumerable; + } + + public IEnumerator GetEnumerator() + { + return _enumerable.GetEnumerator(); + } + } + + public sealed class MultipleInterfaceMappingClass : IList, IList + { + private List _list = new List(); + + DisposableClass IList.this[int index] { get => _list[index]; set => _list[index] = value; } + object IList.this[int index] { get => _list[index]; set => ((IList)_list) [index] = value; } + + int ICollection.Count => _list.Count; + + int ICollection.Count => _list.Count; + + bool ICollection.IsReadOnly => true; + + bool IList.IsReadOnly => true; + + bool IList.IsFixedSize => false; + + bool ICollection.IsSynchronized => true; + + object ICollection.SyncRoot => ((ICollection) _list).SyncRoot; + + void ICollection.Add(DisposableClass item) + { + _list.Add(item); + } + + int IList.Add(object value) + { + return ((IList) _list).Add(value); + } + + void ICollection.Clear() + { + _list.Clear(); + } + + void IList.Clear() + { + _list.Clear(); + } + + bool ICollection.Contains(DisposableClass item) + { + return _list.Contains(item); + } + + bool IList.Contains(object value) + { + return ((IList) _list).Contains(value); + } + + void ICollection.CopyTo(DisposableClass[] array, int arrayIndex) + { + _list.CopyTo(array, arrayIndex); + } + + void ICollection.CopyTo(Array array, int index) + { + ((ICollection) _list).CopyTo(array, index); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return _list.GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return _list.GetEnumerator(); + } + + int IList.IndexOf(DisposableClass item) + { + return _list.IndexOf(item); + } + + int IList.IndexOf(object value) + { + return ((IList) _list).IndexOf(value); + } + + void IList.Insert(int index, DisposableClass item) + { + _list.Insert(index, item); + } + + void IList.Insert(int index, object value) + { + ((IList) _list).Insert(index, value); + } + + bool ICollection.Remove(DisposableClass item) + { + return _list.Remove(item); + } + + void IList.Remove(object value) + { + ((IList) _list).Remove(value); + } + + void IList.RemoveAt(int index) + { + _list.RemoveAt(index); + } + + void IList.RemoveAt(int index) + { + _list.RemoveAt(index); + } + } +} diff --git a/src/Tests/AuthoringWuxTest/Properties/launchSettings.json b/src/Tests/AuthoringWuxTest/Properties/launchSettings.json new file mode 100644 index 000000000..c05aeebf5 --- /dev/null +++ b/src/Tests/AuthoringWuxTest/Properties/launchSettings.json @@ -0,0 +1,8 @@ +{ + "profiles": { + "AuthoringSample": { + "commandName": "Project", + "nativeDebugging": true + } + } +} \ No newline at end of file diff --git a/src/WinRT.Runtime/Projections.cs b/src/WinRT.Runtime/Projections.cs index fab580b15..09ded64e3 100644 --- a/src/WinRT.Runtime/Projections.cs +++ b/src/WinRT.Runtime/Projections.cs @@ -33,6 +33,8 @@ internal enum UiXamlMode private static UiXamlMode GetUIXamlModeSetting() { + System.Diagnostics.Debugger.Launch(); + System.Diagnostics.Debugger.Break(); if (AppContext.GetData("CsWinRT.UiXamlMode") is string str && Enum.TryParse(str, out var mode)) { #if !NET5_0_OR_GREATER diff --git a/src/WinRT.Runtime/Projections/INotifyCollectionChanged.net5.cs b/src/WinRT.Runtime/Projections/INotifyCollectionChanged.net5.cs index 84ca24e2d..85dd32233 100644 --- a/src/WinRT.Runtime/Projections/INotifyCollectionChanged.net5.cs +++ b/src/WinRT.Runtime/Projections/INotifyCollectionChanged.net5.cs @@ -38,8 +38,7 @@ public static unsafe (Action(new byte[] { 0xE1, 0x55, 0x01, 0x53, 0xA5, 0x28, 0x93, 0x56, 0x87, 0xCE, 0x30, 0x72, 0x4D, 0x95, 0xA0, 0x6D })); - + public static global::System.Guid IID { get; } = Guid.Parse(INotifyCollectionChanged.Vftbl.GetGuidSignature()); public static IntPtr AbiToProjectionVftablePtr => INotifyCollectionChanged.Vftbl.AbiToProjectionVftablePtr; } diff --git a/src/WinRT.Runtime/Projections/INotifyPropertyChanged.net5.cs b/src/WinRT.Runtime/Projections/INotifyPropertyChanged.net5.cs index 0bff679c1..d1e2db48b 100644 --- a/src/WinRT.Runtime/Projections/INotifyPropertyChanged.net5.cs +++ b/src/WinRT.Runtime/Projections/INotifyPropertyChanged.net5.cs @@ -15,7 +15,7 @@ namespace ABI.System.ComponentModel #endif static class INotifyPropertyChangedMethods { - public static global::System.Guid IID { get; } = new Guid(new global::System.ReadOnlySpan(new byte[] { 0x01, 0x76, 0xB1, 0x90, 0x65, 0xB0, 0x6E, 0x58, 0x83, 0xD9, 0x9A, 0xDC, 0x3A, 0x69, 0x52, 0x84 })); + public static global::System.Guid IID { get; } = Guid.Parse(INotifyPropertyChanged.Vftbl.GetGuidSignature()); public static IntPtr AbiToProjectionVftablePtr => INotifyPropertyChanged.Vftbl.AbiToProjectionVftablePtr; } diff --git a/src/cswinrt.sln b/src/cswinrt.sln index c958debde..a254d2277 100644 --- a/src/cswinrt.sln +++ b/src/cswinrt.sln @@ -165,6 +165,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestLibrary", "Tests\Functi EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Windows.UI.Xaml", "Projections\Windows.UI.Xaml\Windows.UI.Xaml.csproj", "{E85F3614-79B6-4652-BDB0-64AF68874CE0}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AuthoringWuxTest", "Tests\AuthoringWuxTest\AuthoringWuxTest.csproj", "{D60CFCAD-4A13-4047-91C8-9D7DF4753493}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AuthoringWuxConsumptionTest", "Tests\AuthoringWuxConsumptionTest\AuthoringWuxConsumptionTest.vcxproj", "{A04A0416-5E35-4DD0-8226-63D941B28467}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|ARM = Debug|ARM @@ -753,6 +757,38 @@ Global {E85F3614-79B6-4652-BDB0-64AF68874CE0}.Release|x64.Build.0 = Release|x64 {E85F3614-79B6-4652-BDB0-64AF68874CE0}.Release|x86.ActiveCfg = Release|x86 {E85F3614-79B6-4652-BDB0-64AF68874CE0}.Release|x86.Build.0 = Release|x86 + {D60CFCAD-4A13-4047-91C8-9D7DF4753493}.Debug|ARM.ActiveCfg = Debug|x64 + {D60CFCAD-4A13-4047-91C8-9D7DF4753493}.Debug|ARM.Build.0 = Debug|x64 + {D60CFCAD-4A13-4047-91C8-9D7DF4753493}.Debug|ARM64.ActiveCfg = Debug|x64 + {D60CFCAD-4A13-4047-91C8-9D7DF4753493}.Debug|ARM64.Build.0 = Debug|x64 + {D60CFCAD-4A13-4047-91C8-9D7DF4753493}.Debug|x64.ActiveCfg = Debug|x64 + {D60CFCAD-4A13-4047-91C8-9D7DF4753493}.Debug|x64.Build.0 = Debug|x64 + {D60CFCAD-4A13-4047-91C8-9D7DF4753493}.Debug|x86.ActiveCfg = Debug|x86 + {D60CFCAD-4A13-4047-91C8-9D7DF4753493}.Debug|x86.Build.0 = Debug|x86 + {D60CFCAD-4A13-4047-91C8-9D7DF4753493}.Release|ARM.ActiveCfg = Release|x64 + {D60CFCAD-4A13-4047-91C8-9D7DF4753493}.Release|ARM.Build.0 = Release|x64 + {D60CFCAD-4A13-4047-91C8-9D7DF4753493}.Release|ARM64.ActiveCfg = Release|x64 + {D60CFCAD-4A13-4047-91C8-9D7DF4753493}.Release|ARM64.Build.0 = Release|x64 + {D60CFCAD-4A13-4047-91C8-9D7DF4753493}.Release|x64.ActiveCfg = Release|x64 + {D60CFCAD-4A13-4047-91C8-9D7DF4753493}.Release|x64.Build.0 = Release|x64 + {D60CFCAD-4A13-4047-91C8-9D7DF4753493}.Release|x86.ActiveCfg = Release|x86 + {D60CFCAD-4A13-4047-91C8-9D7DF4753493}.Release|x86.Build.0 = Release|x86 + {A04A0416-5E35-4DD0-8226-63D941B28467}.Debug|ARM.ActiveCfg = Debug|x64 + {A04A0416-5E35-4DD0-8226-63D941B28467}.Debug|ARM.Build.0 = Debug|x64 + {A04A0416-5E35-4DD0-8226-63D941B28467}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {A04A0416-5E35-4DD0-8226-63D941B28467}.Debug|ARM64.Build.0 = Debug|ARM64 + {A04A0416-5E35-4DD0-8226-63D941B28467}.Debug|x64.ActiveCfg = Debug|x64 + {A04A0416-5E35-4DD0-8226-63D941B28467}.Debug|x64.Build.0 = Debug|x64 + {A04A0416-5E35-4DD0-8226-63D941B28467}.Debug|x86.ActiveCfg = Debug|Win32 + {A04A0416-5E35-4DD0-8226-63D941B28467}.Debug|x86.Build.0 = Debug|Win32 + {A04A0416-5E35-4DD0-8226-63D941B28467}.Release|ARM.ActiveCfg = Release|x64 + {A04A0416-5E35-4DD0-8226-63D941B28467}.Release|ARM.Build.0 = Release|x64 + {A04A0416-5E35-4DD0-8226-63D941B28467}.Release|ARM64.ActiveCfg = Release|ARM64 + {A04A0416-5E35-4DD0-8226-63D941B28467}.Release|ARM64.Build.0 = Release|ARM64 + {A04A0416-5E35-4DD0-8226-63D941B28467}.Release|x64.ActiveCfg = Release|x64 + {A04A0416-5E35-4DD0-8226-63D941B28467}.Release|x64.Build.0 = Release|x64 + {A04A0416-5E35-4DD0-8226-63D941B28467}.Release|x86.ActiveCfg = Release|Win32 + {A04A0416-5E35-4DD0-8226-63D941B28467}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -799,6 +835,8 @@ Global {7B803846-91AE-4B98-AC93-D3FCFB2DE5AA} = {6D41796B-9904-40B8-BBCB-40B2D1BAE44B} {335D51AC-1DCF-4487-A2BD-34CE2F17B3C4} = {5ECC38F0-16FD-47E1-B8DC-8C474008AD55} {E85F3614-79B6-4652-BDB0-64AF68874CE0} = {6D41796B-9904-40B8-BBCB-40B2D1BAE44B} + {D60CFCAD-4A13-4047-91C8-9D7DF4753493} = {CFB651EC-DAA4-4A11-ABCD-C77F90602EB5} + {A04A0416-5E35-4DD0-8226-63D941B28467} = {CFB651EC-DAA4-4A11-ABCD-C77F90602EB5} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {5AE8C9D7-2613-4E1A-A4F2-579BAC28D0A2} From ee4dce09f2ecb0c19abebc6d3ad28206fb9418f0 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Mon, 18 Dec 2023 17:16:32 -0800 Subject: [PATCH 07/46] Remove Debug.Breaks --- .../AuthoringWuxConsumptionTest.vcxproj | 2 +- .../AuthoringWuxConsumptionTest.vcxproj.filters | 2 +- src/Tests/AuthoringWuxConsumptionTest/test.cpp | 2 -- src/Tests/AuthoringWuxTest/Program.cs | 5 ----- src/WinRT.Runtime/Projections.cs | 2 -- 5 files changed, 2 insertions(+), 11 deletions(-) diff --git a/src/Tests/AuthoringWuxConsumptionTest/AuthoringWuxConsumptionTest.vcxproj b/src/Tests/AuthoringWuxConsumptionTest/AuthoringWuxConsumptionTest.vcxproj index cd4340fe9..64c641b2f 100644 --- a/src/Tests/AuthoringWuxConsumptionTest/AuthoringWuxConsumptionTest.vcxproj +++ b/src/Tests/AuthoringWuxConsumptionTest/AuthoringWuxConsumptionTest.vcxproj @@ -94,7 +94,7 @@ - + diff --git a/src/Tests/AuthoringWuxConsumptionTest/AuthoringWuxConsumptionTest.vcxproj.filters b/src/Tests/AuthoringWuxConsumptionTest/AuthoringWuxConsumptionTest.vcxproj.filters index 44172eb24..1332cff35 100644 --- a/src/Tests/AuthoringWuxConsumptionTest/AuthoringWuxConsumptionTest.vcxproj.filters +++ b/src/Tests/AuthoringWuxConsumptionTest/AuthoringWuxConsumptionTest.vcxproj.filters @@ -34,6 +34,6 @@ - + \ No newline at end of file diff --git a/src/Tests/AuthoringWuxConsumptionTest/test.cpp b/src/Tests/AuthoringWuxConsumptionTest/test.cpp index 604468c8d..eca0007cc 100644 --- a/src/Tests/AuthoringWuxConsumptionTest/test.cpp +++ b/src/Tests/AuthoringWuxConsumptionTest/test.cpp @@ -6,8 +6,6 @@ using namespace AuthoringWuxTest; TEST(AuthoringWuxTest, Collections) { - DisposableClass; - DisposableClass disposed; disposed.Close(); MultipleInterfaceMappingClass multipleInterfaces; diff --git a/src/Tests/AuthoringWuxTest/Program.cs b/src/Tests/AuthoringWuxTest/Program.cs index 858ae1d4c..004a3cb23 100644 --- a/src/Tests/AuthoringWuxTest/Program.cs +++ b/src/Tests/AuthoringWuxTest/Program.cs @@ -24,11 +24,6 @@ public void Dispose() } public sealed class CustomNotifyPropertyChanged : INotifyPropertyChanged { - public CustomNotifyPropertyChanged() - { - System.Diagnostics.Debugger.Launch(); - } - public event PropertyChangedEventHandler PropertyChanged; public void RaisePropertyChanged(string propertyName) diff --git a/src/WinRT.Runtime/Projections.cs b/src/WinRT.Runtime/Projections.cs index 09ded64e3..fab580b15 100644 --- a/src/WinRT.Runtime/Projections.cs +++ b/src/WinRT.Runtime/Projections.cs @@ -33,8 +33,6 @@ internal enum UiXamlMode private static UiXamlMode GetUIXamlModeSetting() { - System.Diagnostics.Debugger.Launch(); - System.Diagnostics.Debugger.Break(); if (AppContext.GetData("CsWinRT.UiXamlMode") is string str && Enum.TryParse(str, out var mode)) { #if !NET5_0_OR_GREATER From 5e38d0a8b3fcd95135401dd1298b8efbde3c5e8d Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Tue, 19 Dec 2023 13:22:39 -0800 Subject: [PATCH 08/46] Change approach so WUX/MUX works for delegates --- src/WinRT.Runtime/GuidGenerator.cs | 21 ++++++- .../WuxMuxProjectedInterfaceAttribute.cs | 5 +- .../MatchingRefApiCompatBaseline.txt | 2 + .../INotifyCollectionChanged.net5.cs | 55 ++++++++---------- .../INotifyPropertyChanged.net5.cs | 23 +++----- .../NotifyCollectionChangedEventArgs.cs | 12 +--- .../NotifyCollectionChangedEventHandler.cs | 25 +++++---- .../Projections/PropertyChangedEventArgs.cs | 56 +++++++++---------- .../PropertyChangedEventHandler.cs | 31 +++++----- 9 files changed, 116 insertions(+), 114 deletions(-) diff --git a/src/WinRT.Runtime/GuidGenerator.cs b/src/WinRT.Runtime/GuidGenerator.cs index 246238ad8..237351db7 100644 --- a/src/WinRT.Runtime/GuidGenerator.cs +++ b/src/WinRT.Runtime/GuidGenerator.cs @@ -20,7 +20,12 @@ static class GuidGenerator { public static Guid GetGUID(Type type) { - return type.GetGuidType().GUID; + type = type.GetGuidType(); + if (type.GetCustomAttribute() is {} wuxMuxAttribute) + { + return GetWuxMuxIID(wuxMuxAttribute); + } + return type.GUID; } public static Guid GetIID( @@ -30,9 +35,9 @@ public static Guid GetIID( Type type) { type = type.GetGuidType(); - if (type.IsDefined(typeof(WuxMuxProjectedTypeAttribute))) + if (type.GetCustomAttribute() is {} wuxMuxAttribute) { - return Guid.Parse(GetSignature(type)); + return GetWuxMuxIID(wuxMuxAttribute); } if (!type.IsGenericType) { @@ -41,6 +46,16 @@ public static Guid GetIID( return (Guid)type.GetField("PIID").GetValue(null); } + internal static Guid GetWuxMuxIID(WuxMuxProjectedTypeAttribute wuxMuxAttribute) + { + return Projections.UiXamlModeSetting switch + { + Projections.UiXamlMode.WindowsUiXaml => wuxMuxAttribute.WuxIID, + Projections.UiXamlMode.MicrosoftUiXaml => wuxMuxAttribute.MuxIID, + _ => throw new InvalidOperationException("Invalid UI XAML mode") + }; + } + public static string GetSignature( #if NET [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] diff --git a/src/WinRT.Runtime/Interop/WuxMuxProjectedInterfaceAttribute.cs b/src/WinRT.Runtime/Interop/WuxMuxProjectedInterfaceAttribute.cs index 10b746ebd..16b051cac 100644 --- a/src/WinRT.Runtime/Interop/WuxMuxProjectedInterfaceAttribute.cs +++ b/src/WinRT.Runtime/Interop/WuxMuxProjectedInterfaceAttribute.cs @@ -9,7 +9,10 @@ namespace WinRT.Interop /// For this type, the GuidAttribute is not used and instead the GetGuidSignature method must be called to get the IID or generic IID signature part of the type. /// [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] - internal sealed class WuxMuxProjectedTypeAttribute : Attribute + internal sealed class WuxMuxProjectedTypeAttribute(string wuxIID, string muxIID) : Attribute { + public Guid WuxIID { get; } = Guid.Parse(wuxIID); + + public Guid MuxIID { get; } = Guid.Parse(muxIID); } } diff --git a/src/WinRT.Runtime/MatchingRefApiCompatBaseline.txt b/src/WinRT.Runtime/MatchingRefApiCompatBaseline.txt index b2b3c6b21..7faef7862 100644 --- a/src/WinRT.Runtime/MatchingRefApiCompatBaseline.txt +++ b/src/WinRT.Runtime/MatchingRefApiCompatBaseline.txt @@ -123,4 +123,6 @@ TypesMustExist : Type 'WinRT.WinRTExposedTypeAttribute' does not exist in the re MembersMustExist : Member 'public System.Boolean WinRT.ComWrappersSupport.RegisterDelegateFactory(System.Type, System.Func)' does not exist in the reference but it does exist in the implementation. MembersMustExist : Member 'public void WinRT.ComWrappersSupport.RegisterComInterfaceEntries(System.Type, System.Runtime.InteropServices.ComWrappers.ComInterfaceEntry[])' does not exist in the reference but it does exist in the implementation. MembersMustExist : Member 'public System.ReadOnlySpan WinRT.MarshalString.FromAbiUnsafe(System.IntPtr)' does not exist in the reference but it does exist in the implementation. +CannotRemoveAttribute : Attribute 'WinRT.Interop.WuxMuxProjectedTypeAttribute' exists on 'ABI.System.Collections.Specialized.NotifyCollectionChangedEventHandler' in the implementation but not the reference. +CannotRemoveAttribute : Attribute 'WinRT.Interop.WuxMuxProjectedTypeAttribute' exists on 'ABI.System.ComponentModel.PropertyChangedEventHandler' in the implementation but not the reference. Total Issues: 124 diff --git a/src/WinRT.Runtime/Projections/INotifyCollectionChanged.net5.cs b/src/WinRT.Runtime/Projections/INotifyCollectionChanged.net5.cs index 85dd32233..161d7cf8e 100644 --- a/src/WinRT.Runtime/Projections/INotifyCollectionChanged.net5.cs +++ b/src/WinRT.Runtime/Projections/INotifyCollectionChanged.net5.cs @@ -1,21 +1,22 @@ -// Copyright (c) Microsoft Corporation. +// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. using System; using System.ComponentModel; +using System.Reflection; using System.Runtime.InteropServices; using WinRT; using WinRT.Interop; namespace ABI.System.Collections.Specialized -{ +{ #if EMBED - internal + internal #else public #endif - static class INotifyCollectionChangedMethods - { + static class INotifyCollectionChangedMethods + { private volatile static global::System.Runtime.CompilerServices.ConditionalWeakTable _CollectionChanged; private static global::System.Runtime.CompilerServices.ConditionalWeakTable MakeCollectionChangedTable() { @@ -24,7 +25,7 @@ static class INotifyCollectionChangedMethods } private static global::System.Runtime.CompilerServices.ConditionalWeakTable CollectionChanged => _CollectionChanged ?? MakeCollectionChangedTable(); - + public static unsafe (Action, Action) Get_CollectionChanged(IObjectReference obj, object thisObj) { var eventSource = _CollectionChanged.GetValue(thisObj, (key) => @@ -36,30 +37,22 @@ public static unsafe (Action**)ThisPtr)[7]); }); return eventSource.EventActions; - } - - public static global::System.Guid IID { get; } = Guid.Parse(INotifyCollectionChanged.Vftbl.GetGuidSignature()); - public static IntPtr AbiToProjectionVftablePtr => INotifyCollectionChanged.Vftbl.AbiToProjectionVftablePtr; + } + + public static global::System.Guid IID { get; } = GuidGenerator.GetWuxMuxIID(typeof(INotifyCollectionChanged).GetCustomAttribute()); + public static IntPtr AbiToProjectionVftablePtr => INotifyCollectionChanged.Vftbl.AbiToProjectionVftablePtr; } [DynamicInterfaceCastableImplementation] [EditorBrowsable(EditorBrowsableState.Never)] - [Guid("530155E1-28A5-5693-87CE-30724D95A06D")] - [WuxMuxProjectedType] + [Guid("530155E1-28A5-5693-87CE-30724D95A06D")] + [WuxMuxProjectedType(wuxIID: "CF75D69C-F2F4-486B-B302-BB4C09BAEBFA", muxIID: "530155E1-28A5-5693-87CE-30724D95A06D")] internal unsafe interface INotifyCollectionChanged : global::System.Collections.Specialized.INotifyCollectionChanged { - public static string GetGuidSignature() - => Projections.UiXamlModeSetting == Projections.UiXamlMode.WindowsUiXaml - ? "{CF75D69C-F2F4-486B-B302-BB4C09BAEBFA}" - : "{530155E1-28A5-5693-87CE-30724D95A06D}"; - - [Guid("530155E1-28A5-5693-87CE-30724D95A06D")] - [WuxMuxProjectedType] + [Guid("530155E1-28A5-5693-87CE-30724D95A06D")] + [WuxMuxProjectedType(wuxIID: "CF75D69C-F2F4-486B-B302-BB4C09BAEBFA", muxIID: "530155E1-28A5-5693-87CE-30724D95A06D")] public struct Vftbl - { - public static string GetGuidSignature() - => INotifyCollectionChanged.GetGuidSignature(); - + { internal IInspectable.Vftbl IInspectableVftbl; private delegate* unmanaged _add_CollectionChanged_0; @@ -86,15 +79,15 @@ static unsafe Vftbl() } private volatile static global::System.Runtime.CompilerServices.ConditionalWeakTable> _collectionChanged_TokenTables; - - private static global::System.Runtime.CompilerServices.ConditionalWeakTable> MakeConditionalWeakTable() - { - global::System.Threading.Interlocked.CompareExchange(ref _collectionChanged_TokenTables, new(), null); - return _collectionChanged_TokenTables; + + private static global::System.Runtime.CompilerServices.ConditionalWeakTable> MakeConditionalWeakTable() + { + global::System.Threading.Interlocked.CompareExchange(ref _collectionChanged_TokenTables, new(), null); + return _collectionChanged_TokenTables; } - private static global::System.Runtime.CompilerServices.ConditionalWeakTable> _CollectionChanged_TokenTables => _collectionChanged_TokenTables ?? MakeConditionalWeakTable(); - + private static global::System.Runtime.CompilerServices.ConditionalWeakTable> _CollectionChanged_TokenTables => _collectionChanged_TokenTables ?? MakeConditionalWeakTable(); + [UnmanagedCallersOnly] private static unsafe int Do_Abi_add_CollectionChanged_0(IntPtr thisPtr, IntPtr handler, global::WinRT.EventRegistrationToken* token) { @@ -144,5 +137,5 @@ private static (Action _CollectionChanged((IWinRTObject)this).Item1(value); remove => _CollectionChanged((IWinRTObject)this).Item2(value); } - } + } } diff --git a/src/WinRT.Runtime/Projections/INotifyPropertyChanged.net5.cs b/src/WinRT.Runtime/Projections/INotifyPropertyChanged.net5.cs index d1e2db48b..302678f9f 100644 --- a/src/WinRT.Runtime/Projections/INotifyPropertyChanged.net5.cs +++ b/src/WinRT.Runtime/Projections/INotifyPropertyChanged.net5.cs @@ -2,41 +2,35 @@ // Licensed under the MIT License. using System; +using System.Reflection; using System.Runtime.InteropServices; using WinRT; using WinRT.Interop; namespace ABI.System.ComponentModel -{ +{ #if EMBED internal #else public #endif static class INotifyPropertyChangedMethods - { - public static global::System.Guid IID { get; } = Guid.Parse(INotifyPropertyChanged.Vftbl.GetGuidSignature()); + { + public static global::System.Guid IID { get; } = GuidGenerator.GetWuxMuxIID(typeof(INotifyPropertyChanged).GetCustomAttribute()); public static IntPtr AbiToProjectionVftablePtr => INotifyPropertyChanged.Vftbl.AbiToProjectionVftablePtr; } [DynamicInterfaceCastableImplementation] [Guid("90B17601-B065-586E-83D9-9ADC3A695284")] - [WuxMuxProjectedType] + [WuxMuxProjectedType(wuxIID: "cf75d69c-f2f4-486b-b302-bb4c09baebfa", muxIID: "90B17601-B065-586E-83D9-9ADC3A695284")] internal unsafe interface INotifyPropertyChanged : global::System.ComponentModel.INotifyPropertyChanged { - public static string GetGuidSignature() - => Projections.UiXamlModeSetting == Projections.UiXamlMode.WindowsUiXaml - ? "{cf75d69c-f2f4-486b-b302-bb4c09baebfa}" - : "{90B17601-B065-586E-83D9-9ADC3A695284}"; - [Guid("90B17601-B065-586E-83D9-9ADC3A695284")] - [StructLayout(LayoutKind.Sequential)] - [WuxMuxProjectedType] + [StructLayout(LayoutKind.Sequential)] + [WuxMuxProjectedType(wuxIID: "cf75d69c-f2f4-486b-b302-bb4c09baebfa", muxIID: "90B17601-B065-586E-83D9-9ADC3A695284")] public struct Vftbl - { - public static string GetGuidSignature() - => INotifyPropertyChanged.GetGuidSignature(); + { internal IInspectable.Vftbl IInspectableVftbl; @@ -78,6 +72,7 @@ private static unsafe int Do_Abi_add_PropertyChanged_0(IntPtr thisPtr, IntPtr ha *token = default; try { + global::System.Diagnostics.Debugger.Launch(); var __this = global::WinRT.ComWrappersSupport.FindObject(thisPtr); var __handler = global::ABI.System.ComponentModel.PropertyChangedEventHandler.FromAbi(handler); *token = _PropertyChanged_TokenTables.GetOrCreateValue(__this).AddEventHandler(__handler); diff --git a/src/WinRT.Runtime/Projections/NotifyCollectionChangedEventArgs.cs b/src/WinRT.Runtime/Projections/NotifyCollectionChangedEventArgs.cs index 081ca31a3..20aa46a52 100644 --- a/src/WinRT.Runtime/Projections/NotifyCollectionChangedEventArgs.cs +++ b/src/WinRT.Runtime/Projections/NotifyCollectionChangedEventArgs.cs @@ -12,22 +12,14 @@ namespace ABI.Microsoft.UI.Xaml.Interop { [global::WinRT.ObjectReferenceWrapper(nameof(_obj))] [Guid("DA049FF2-D2E0-5FE8-8C7B-F87F26060B6F")] - [WuxMuxProjectedType] + [WuxMuxProjectedType(wuxIID: "4cf68d33-e3f2-4964-b85e-945b4f7e2f21", muxIID: "DA049FF2-D2E0-5FE8-8C7B-F87F26060B6F")] internal sealed unsafe class INotifyCollectionChangedEventArgs { - public static string GetGuidSignature() - => Projections.UiXamlModeSetting == Projections.UiXamlMode.WindowsUiXaml - ? "{4cf68d33-e3f2-4964-b85e-945b4f7e2f21}" - : "{DA049FF2-D2E0-5FE8-8C7B-F87F26060B6F}"; - [Guid("DA049FF2-D2E0-5FE8-8C7B-F87F26060B6F")] [StructLayout(LayoutKind.Sequential)] - [WuxMuxProjectedType] + [WuxMuxProjectedType(wuxIID: "4cf68d33-e3f2-4964-b85e-945b4f7e2f21", muxIID: "DA049FF2-D2E0-5FE8-8C7B-F87F26060B6F")] public struct Vftbl { - public static string GetGuidSignature() - => INotifyCollectionChangedEventArgs.GetGuidSignature(); - internal IInspectable.Vftbl IInspectableVftbl; private void* _get_Action_0; public delegate* unmanaged[Stdcall] get_Action_0 => (delegate* unmanaged[Stdcall])_get_Action_0; diff --git a/src/WinRT.Runtime/Projections/NotifyCollectionChangedEventHandler.cs b/src/WinRT.Runtime/Projections/NotifyCollectionChangedEventHandler.cs index 5d6976853..22c48c661 100644 --- a/src/WinRT.Runtime/Projections/NotifyCollectionChangedEventHandler.cs +++ b/src/WinRT.Runtime/Projections/NotifyCollectionChangedEventHandler.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. +// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. using System; @@ -13,6 +13,7 @@ namespace ABI.System.Collections.Specialized [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] [Guid("8B0909DC-2005-5D93-BF8A-725F017BAA8D")] + [WuxMuxProjectedType(wuxIID: "ca10b37c-f382-4591-8557-5e24965279b0", muxIID: "8B0909DC-2005-5D93-BF8A-725F017BAA8D")] #if EMBED internal #else @@ -52,21 +53,21 @@ static unsafe NotifyCollectionChangedEventHandler() private static readonly Guid IID; public static unsafe IObjectReference CreateMarshaler(global::System.Collections.Specialized.NotifyCollectionChangedEventHandler managedDelegate) => - managedDelegate is null ? null : MarshalDelegate.CreateMarshaler(managedDelegate, IID); - + managedDelegate is null ? null : MarshalDelegate.CreateMarshaler(managedDelegate, IID); + public static unsafe ObjectReferenceValue CreateMarshaler2(global::System.Collections.Specialized.NotifyCollectionChangedEventHandler managedDelegate) => MarshalDelegate.CreateMarshaler2(managedDelegate, IID); public static IntPtr GetAbi(IObjectReference value) => MarshalInterfaceHelper.GetAbi(value); public static unsafe global::System.Collections.Specialized.NotifyCollectionChangedEventHandler FromAbi(IntPtr nativeDelegate) - { + { return MarshalDelegate.FromAbi(nativeDelegate); } - public static global::System.Collections.Specialized.NotifyCollectionChangedEventHandler CreateRcw(IntPtr ptr) - { - return new global::System.Collections.Specialized.NotifyCollectionChangedEventHandler(new NativeDelegateWrapper(ComWrappersSupport.GetObjectReferenceForInterface(ptr, IID)).Invoke); + public static global::System.Collections.Specialized.NotifyCollectionChangedEventHandler CreateRcw(IntPtr ptr) + { + return new global::System.Collections.Specialized.NotifyCollectionChangedEventHandler(new NativeDelegateWrapper(ComWrappersSupport.GetObjectReferenceForInterface(ptr, IID)).Invoke); } [global::WinRT.ObjectReferenceWrapper(nameof(_nativeDelegate))] @@ -133,8 +134,8 @@ public static IntPtr FromManaged(global::System.Collections.Specialized.NotifyCo public static void DisposeMarshaler(IObjectReference value) => MarshalInterfaceHelper.DisposeMarshaler(value); - public static void DisposeAbi(IntPtr abi) => MarshalInterfaceHelper.DisposeAbi(abi); - + public static void DisposeAbi(IntPtr abi) => MarshalInterfaceHelper.DisposeAbi(abi); + public static unsafe MarshalInterfaceHelper.MarshalerArray CreateMarshalerArray(global::System.Collections.Specialized.NotifyCollectionChangedEventHandler[] array) => MarshalInterfaceHelper.CreateMarshalerArray2(array, CreateMarshaler2); public static (int length, IntPtr data) GetAbiArray(object box) => MarshalInterfaceHelper.GetAbiArray(box); public static unsafe global::System.Collections.Specialized.NotifyCollectionChangedEventHandler[] FromAbiArray(object box) => MarshalInterfaceHelper.FromAbiArray(box, FromAbi); @@ -149,7 +150,7 @@ public static IntPtr FromManaged(global::System.Collections.Specialized.NotifyCo private static unsafe int Do_Abi_Invoke(IntPtr thisPtr, IntPtr sender, IntPtr e) { try - { + { #if NET var invoke = ComWrappersSupport.FindObject(thisPtr); invoke.Invoke(MarshalInspectable.FromAbi(sender), global::ABI.System.Collections.Specialized.NotifyCollectionChangedEventArgs.FromAbi(e)); @@ -171,9 +172,9 @@ private static unsafe int Do_Abi_Invoke(IntPtr thisPtr, IntPtr sender, IntPtr e) internal sealed unsafe class NotifyCollectionChangedEventSource : EventSource { - internal NotifyCollectionChangedEventSource(IObjectReference obj, + internal NotifyCollectionChangedEventSource(IObjectReference obj, #if NET - delegate* unmanaged[Stdcall] addHandler, + delegate* unmanaged[Stdcall] addHandler, #else delegate* unmanaged[Stdcall] addHandler, #endif diff --git a/src/WinRT.Runtime/Projections/PropertyChangedEventArgs.cs b/src/WinRT.Runtime/Projections/PropertyChangedEventArgs.cs index 86586a85c..9ba9f9ae3 100644 --- a/src/WinRT.Runtime/Projections/PropertyChangedEventArgs.cs +++ b/src/WinRT.Runtime/Projections/PropertyChangedEventArgs.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. +// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. using System; @@ -18,10 +18,10 @@ internal unsafe struct IPropertyChangedEventArgsVftbl public delegate* unmanaged[Stdcall] get_PropertyName_0 => (delegate* unmanaged[Stdcall])_get_PropertyName_0; } - internal interface IWinRTPropertyChangedEventArgsRuntimeClassFactory - { - IObjectReference CreateInstance(string name, object baseInterface, out IObjectReference innerInterface); - ObjectReferenceValue CreateInstance(string name); + internal interface IWinRTPropertyChangedEventArgsRuntimeClassFactory + { + IObjectReference CreateInstance(string name, object baseInterface, out IObjectReference innerInterface); + ObjectReferenceValue CreateInstance(string name); } [global::WinRT.ObjectReferenceWrapper(nameof(_obj))] @@ -59,11 +59,11 @@ public unsafe IObjectReference CreateInstance(string name, object baseInterface, { MarshalString.Pinnable __name = new(name); fixed (void* ___name = __name) - { + { __baseInterface = MarshalInspectable.CreateMarshaler(baseInterface); global::WinRT.ExceptionHelpers.ThrowExceptionForHR(_obj.Vftbl.CreateInstance_0(ThisPtr, MarshalString.GetAbi(ref __name), MarshalInspectable.GetAbi(__baseInterface), &__innerInterface, &__retval)); innerInterface = ObjectReference.FromAbi(__innerInterface); - return ObjectReference.Attach(ref __retval); + return ObjectReference.Attach(ref __retval); } } finally @@ -72,8 +72,8 @@ public unsafe IObjectReference CreateInstance(string name, object baseInterface, MarshalInspectable.DisposeAbi(__innerInterface); MarshalInspectable.DisposeAbi(__retval); } - } - + } + public unsafe ObjectReferenceValue CreateInstance(string name) { IntPtr __innerInterface = default; @@ -82,7 +82,7 @@ public unsafe ObjectReferenceValue CreateInstance(string name) { MarshalString.Pinnable __name = new(name); fixed (void* ___name = __name) - { + { global::WinRT.ExceptionHelpers.ThrowExceptionForHR(_obj.Vftbl.CreateInstance_0(ThisPtr, MarshalString.GetAbi(ref __name), IntPtr.Zero, &__innerInterface, &__retval)); return new ObjectReferenceValue(__retval); } @@ -92,15 +92,15 @@ public unsafe ObjectReferenceValue CreateInstance(string name) MarshalInspectable.DisposeAbi(__innerInterface); } } - } - - - + } + + + [global::WinRT.ObjectReferenceWrapper(nameof(_obj))] - [Guid("4f33a9a0-5cf4-47a4-b16f-d7faaf17457e")] + [Guid("6dcc9c03-e0c7-4eee-8ea9-37e3406eeb1c")] internal sealed unsafe class WUXPropertyChangedEventArgsRuntimeClassFactory : IWinRTPropertyChangedEventArgsRuntimeClassFactory { - [Guid("4f33a9a0-5cf4-47a4-b16f-d7faaf17457e")] + [Guid("6dcc9c03-e0c7-4eee-8ea9-37e3406eeb1c")] [StructLayout(LayoutKind.Sequential)] public struct Vftbl { @@ -131,11 +131,11 @@ public unsafe IObjectReference CreateInstance(string name, object baseInterface, { MarshalString.Pinnable __name = new(name); fixed (void* ___name = __name) - { + { __baseInterface = MarshalInspectable.CreateMarshaler(baseInterface); global::WinRT.ExceptionHelpers.ThrowExceptionForHR(_obj.Vftbl.CreateInstance_0(ThisPtr, MarshalString.GetAbi(ref __name), MarshalInspectable.GetAbi(__baseInterface), &__innerInterface, &__retval)); innerInterface = ObjectReference.FromAbi(__innerInterface); - return ObjectReference.Attach(ref __retval); + return ObjectReference.Attach(ref __retval); } } finally @@ -144,8 +144,8 @@ public unsafe IObjectReference CreateInstance(string name, object baseInterface, MarshalInspectable.DisposeAbi(__innerInterface); MarshalInspectable.DisposeAbi(__retval); } - } - + } + public unsafe ObjectReferenceValue CreateInstance(string name) { IntPtr __innerInterface = default; @@ -154,7 +154,7 @@ public unsafe ObjectReferenceValue CreateInstance(string name) { MarshalString.Pinnable __name = new(name); fixed (void* ___name = __name) - { + { global::WinRT.ExceptionHelpers.ThrowExceptionForHR(_obj.Vftbl.CreateInstance_0(ThisPtr, MarshalString.GetAbi(ref __name), IntPtr.Zero, &__innerInterface, &__retval)); return new ObjectReferenceValue(__retval); } @@ -191,8 +191,8 @@ public static IObjectReference CreateMarshaler(global::System.ComponentModel.Pro } return Instance.CreateInstance(value.PropertyName, null, out _); - } - + } + public static ObjectReferenceValue CreateMarshaler2(global::System.ComponentModel.PropertyChangedEventArgs value) { if (value is null) @@ -241,8 +241,8 @@ public static IntPtr FromManaged(global::System.ComponentModel.PropertyChangedEv } public static void DisposeMarshaler(IObjectReference m) { m?.Dispose(); } - public static void DisposeAbi(IntPtr abi) { MarshalInspectable.DisposeAbi(abi); } - + public static void DisposeAbi(IntPtr abi) { MarshalInspectable.DisposeAbi(abi); } + public static unsafe MarshalInterfaceHelper.MarshalerArray CreateMarshalerArray(global::System.ComponentModel.PropertyChangedEventArgs[] array) => MarshalInterfaceHelper.CreateMarshalerArray2(array, CreateMarshaler2); public static (int length, IntPtr data) GetAbiArray(object box) => MarshalInterfaceHelper.GetAbiArray(box); public static unsafe global::System.ComponentModel.PropertyChangedEventArgs[] FromAbiArray(object box) => MarshalInterfaceHelper.FromAbiArray(box, FromAbi); @@ -253,9 +253,9 @@ public static IntPtr FromManaged(global::System.ComponentModel.PropertyChangedEv public static string GetGuidSignature() { - if (Projections.UiXamlModeSetting == Projections.UiXamlMode.WindowsUiXaml) - { - return "rc(Windows.UI.Xaml.Data.NotifyPropertyChangedEventArgs;{4f33a9a0-5cf4-47a4-b16f-d7faaf17457e})"; + if (Projections.UiXamlModeSetting == Projections.UiXamlMode.WindowsUiXaml) + { + return "rc(Windows.UI.Xaml.Data.NotifyPropertyChangedEventArgs;{4f33a9a0-5cf4-47a4-b16f-d7faaf17457e})"; } return "rc(Microsoft.UI.Xaml.Data.NotifyPropertyChangedEventArgs;{4f33a9a0-5cf4-47a4-b16f-d7faaf17457e})"; diff --git a/src/WinRT.Runtime/Projections/PropertyChangedEventHandler.cs b/src/WinRT.Runtime/Projections/PropertyChangedEventHandler.cs index 053bb27a3..4d74c3bae 100644 --- a/src/WinRT.Runtime/Projections/PropertyChangedEventHandler.cs +++ b/src/WinRT.Runtime/Projections/PropertyChangedEventHandler.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. +// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. using System; @@ -12,6 +12,7 @@ namespace ABI.System.ComponentModel { [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] [Guid("E3DE52F6-1E32-5DA6-BB2D-B5B6096C962D")] + [WuxMuxProjectedType(wuxIID: "50f19c16-0a22-4d8e-a089-1ea9951657d2", muxIID: "E3DE52F6-1E32-5DA6-BB2D-B5B6096C962D")] #if EMBED internal #else @@ -45,26 +46,26 @@ static unsafe PropertyChangedEventHandler() : Guid.Parse("E3DE52F6-1E32-5DA6-BB2D-B5B6096C962D"); } - public static global::System.Delegate AbiInvokeDelegate { get; } - + public static global::System.Delegate AbiInvokeDelegate { get; } + private static readonly Guid IID; public static unsafe IObjectReference CreateMarshaler(global::System.ComponentModel.PropertyChangedEventHandler managedDelegate) => - managedDelegate is null ? null : MarshalDelegate.CreateMarshaler(managedDelegate, IID); - + managedDelegate is null ? null : MarshalDelegate.CreateMarshaler(managedDelegate, IID); + public static unsafe ObjectReferenceValue CreateMarshaler2(global::System.ComponentModel.PropertyChangedEventHandler managedDelegate) => MarshalDelegate.CreateMarshaler2(managedDelegate, IID); public static IntPtr GetAbi(IObjectReference value) => MarshalInterfaceHelper.GetAbi(value); public static unsafe global::System.ComponentModel.PropertyChangedEventHandler FromAbi(IntPtr nativeDelegate) - { + { return MarshalDelegate.FromAbi(nativeDelegate); - } - - public static global::System.ComponentModel.PropertyChangedEventHandler CreateRcw(IntPtr ptr) - { - return new global::System.ComponentModel.PropertyChangedEventHandler(new NativeDelegateWrapper(ComWrappersSupport.GetObjectReferenceForInterface(ptr, IID)).Invoke); + } + + public static global::System.ComponentModel.PropertyChangedEventHandler CreateRcw(IntPtr ptr) + { + return new global::System.ComponentModel.PropertyChangedEventHandler(new NativeDelegateWrapper(ComWrappersSupport.GetObjectReferenceForInterface(ptr, IID)).Invoke); } [global::WinRT.ObjectReferenceWrapper(nameof(_nativeDelegate))] @@ -130,8 +131,8 @@ public static IntPtr FromManaged(global::System.ComponentModel.PropertyChangedEv public static void DisposeMarshaler(IObjectReference value) => MarshalInterfaceHelper.DisposeMarshaler(value); - public static void DisposeAbi(IntPtr abi) => MarshalInterfaceHelper.DisposeAbi(abi); - + public static void DisposeAbi(IntPtr abi) => MarshalInterfaceHelper.DisposeAbi(abi); + public static unsafe MarshalInterfaceHelper.MarshalerArray CreateMarshalerArray(global::System.ComponentModel.PropertyChangedEventHandler[] array) => MarshalInterfaceHelper.CreateMarshalerArray2(array, CreateMarshaler2); public static (int length, IntPtr data) GetAbiArray(object box) => MarshalInterfaceHelper.GetAbiArray(box); public static unsafe global::System.ComponentModel.PropertyChangedEventHandler[] FromAbiArray(object box) => MarshalInterfaceHelper.FromAbiArray(box, FromAbi); @@ -146,7 +147,7 @@ public static IntPtr FromManaged(global::System.ComponentModel.PropertyChangedEv private static unsafe int Do_Abi_Invoke(IntPtr thisPtr, IntPtr sender, IntPtr e) { try - { + { #if NET var invoke = ComWrappersSupport.FindObject(thisPtr); invoke.Invoke(MarshalInspectable.FromAbi(sender), global::ABI.System.ComponentModel.PropertyChangedEventArgs.FromAbi(e)); @@ -170,7 +171,7 @@ internal sealed unsafe class PropertyChangedEventSource : EventSource addHandler, + delegate* unmanaged[Stdcall] addHandler, #else delegate* unmanaged[Stdcall] addHandler, #endif From e63e3d1870f1bdfb20a8ac852b2477bf095f0bab Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Tue, 19 Dec 2023 13:37:12 -0800 Subject: [PATCH 09/46] Use Xaml Islands and a custom main to enable writing GTest tests with INPC and types that need the XAML engine initialized on the thread. --- .../AuthoringWuxConsumptionTest.exe.manifest | 37 +++++++++++-------- src/Tests/AuthoringWuxConsumptionTest/pch.h | 1 + .../AuthoringWuxConsumptionTest/test.cpp | 10 +++++ 3 files changed, 32 insertions(+), 16 deletions(-) diff --git a/src/Tests/AuthoringWuxConsumptionTest/AuthoringWuxConsumptionTest.exe.manifest b/src/Tests/AuthoringWuxConsumptionTest/AuthoringWuxConsumptionTest.exe.manifest index 4af3eb765..3d69fa84a 100644 --- a/src/Tests/AuthoringWuxConsumptionTest/AuthoringWuxConsumptionTest.exe.manifest +++ b/src/Tests/AuthoringWuxConsumptionTest/AuthoringWuxConsumptionTest.exe.manifest @@ -2,21 +2,26 @@ - - - - + + + + + + + + + \ No newline at end of file diff --git a/src/Tests/AuthoringWuxConsumptionTest/pch.h b/src/Tests/AuthoringWuxConsumptionTest/pch.h index fac3012ea..db3c5d270 100644 --- a/src/Tests/AuthoringWuxConsumptionTest/pch.h +++ b/src/Tests/AuthoringWuxConsumptionTest/pch.h @@ -19,6 +19,7 @@ #include #include #include +#include #include diff --git a/src/Tests/AuthoringWuxConsumptionTest/test.cpp b/src/Tests/AuthoringWuxConsumptionTest/test.cpp index eca0007cc..b182b935c 100644 --- a/src/Tests/AuthoringWuxConsumptionTest/test.cpp +++ b/src/Tests/AuthoringWuxConsumptionTest/test.cpp @@ -62,4 +62,14 @@ TEST(AuthoringWuxTest, PropertyChanged) customNotifyPropertyChanged.RaisePropertyChanged(propName); EXPECT_TRUE(eventTriggered); +} + +int main(int argc, char** argv) +{ + ::testing::InitGoogleTest(&argc, argv); + winrt::init_apartment(winrt::apartment_type::single_threaded); + auto manager = winrt::Windows::UI::Xaml::Hosting::WindowsXamlManager::InitializeForCurrentThread(); + int result = RUN_ALL_TESTS(); + manager.Close(); + return result; } \ No newline at end of file From 21b99e59a56091bb3dbac33366f67a66f16b8c40 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Fri, 18 Aug 2023 11:36:53 -0700 Subject: [PATCH 10/46] Start prototype with TODOs on supporting build-time/runtime-startup selected WUX vs MUX mode. Implement the base TODO-WuxMux items that must be completed to support a runtime configuration WUX/MUX switch. Add WUX test projection and fix bug with ICommand special-casing. Inline MUX guids. Add CsWinRT SDK support Add tests for authoring components with WUX APIs (also validates some of the consumption logic in the process) Remove Debug.Breaks Change approach so WUX/MUX works for delegates Use Xaml Islands and a custom main to enable writing GTest tests with INPC and types that need the XAML engine initialized on the thread. Add AuthoringWuxComsumptionTest to the CI Change IIDOptimizer to fall back to GuidGenerator for WUX/MUX types. Fix IList ABI type to implement WUX and MUX Add breaks PR feedback and fix unit test failures. Fix configurations for new projects. Fix configuration for Windows.UI.Xaml projection --- .../CsWinRT-BuildAndTest-Stage.yml | 12 + ...icrosoft.Windows.CsWinRT.Authoring.targets | 1 + nuget/Microsoft.Windows.CsWinRT.targets | 7 + .../WinRT.SourceGenerator/AotOptimizer.cs | 103 +- .../WinRT.SourceGenerator/DiagnosticUtils.cs | 9 +- .../WinRT.SourceGenerator/Generator.cs | 8 +- src/Authoring/WinRT.SourceGenerator/Helper.cs | 386 ++- .../WinRT.SourceGenerator/TypeMapper.cs | 125 + .../WinRT.SourceGenerator/UiXamlMode.cs | 26 + .../WinRT.SourceGenerator/WinRTTypeWriter.cs | 40 +- src/Directory.Build.props | 2 + src/Perf/IIDOptimizer/GuidPatcher.cs | 14 +- src/Perf/IIDOptimizer/SignatureEmitter.cs | 31 + src/Perf/IIDOptimizer/SignatureGenerator.cs | 13 +- src/Projections/Windows.UI.Xaml/Module.cs | 3 + .../Windows.UI.Xaml/Windows.UI.Xaml.csproj | 28 + .../AuthoringWuxConsumptionTest.exe.manifest | 27 + .../AuthoringWuxConsumptionTest.vcxproj | 212 ++ ...uthoringWuxConsumptionTest.vcxproj.filters | 39 + .../Directory.Build.targets | 16 + .../DoNotImport_MsAppxPackageTargets.targets | 5 + .../WinRT.Host.runtimeconfig.json | 13 + .../packages.config | 7 + src/Tests/AuthoringWuxConsumptionTest/pch.cpp | 1 + src/Tests/AuthoringWuxConsumptionTest/pch.h | 26 + .../AuthoringWuxConsumptionTest/test.cpp | 75 + .../AuthoringWuxTest/AuthoringWuxTest.csproj | 22 + .../AuthoringWuxTest/Directory.Build.props | 9 + .../AuthoringWuxTest/Directory.Build.targets | 5 + src/Tests/AuthoringWuxTest/Module.cs | 3 + src/Tests/AuthoringWuxTest/Program.cs | 171 ++ .../Properties/launchSettings.json | 8 + src/WinRT.Runtime/GuidGenerator.cs | 88 +- .../WuxMuxProjectedInterfaceAttribute.cs | 24 + .../MatchingRefApiCompatBaseline.txt | 7 +- src/WinRT.Runtime/Projections.cs | 80 +- .../Projections/Bindable.net5.cs | 2156 ++++++++--------- .../Projections/ICommand.net5.cs | 1 + .../ICustomPropertyProvider.net5.cs | 2 + .../Projections/IEnumerable.net5.cs | 7 +- .../INotifyCollectionChanged.net5.cs | 43 +- .../INotifyPropertyChanged.net5.cs | 12 +- .../Microsoft.UI.Xaml.Bindable.net5.cs | 367 +++ ...rosoft.UI.Xaml.Bindable.netstandard2.0.cs} | 0 .../NotifyCollectionChangedAction.cs | 7 +- .../NotifyCollectionChangedEventArgs.cs | 631 ++--- .../NotifyCollectionChangedEventHandler.cs | 31 +- .../Projections/PropertyChangedEventArgs.cs | 118 +- .../PropertyChangedEventHandler.cs | 36 +- .../Windows.UI.Xaml.Bindable.net5.cs | 367 +++ src/cswinrt.sln | 57 + src/cswinrt/code_writers.h | 2 +- src/cswinrt/cswinrt.vcxproj | 6 + src/cswinrt/cswinrt.vcxproj.filters | 33 + src/cswinrt/helpers.h | 84 +- .../Windows.UI.Xaml.Controls.Primitives.cs | 73 + .../Windows.UI.Xaml.Media.Animation.cs | 326 +++ .../Windows.UI.Xaml.Media.Media3D.cs | 711 ++++++ .../Windows.UI.Xaml.Media.cs | 263 ++ .../Windows.UI.Xaml/Windows.UI.Xaml.SR.cs | 17 + .../Windows.UI.Xaml/Windows.UI.Xaml.cs | 774 ++++++ 61 files changed, 5957 insertions(+), 1813 deletions(-) create mode 100644 src/Authoring/WinRT.SourceGenerator/TypeMapper.cs create mode 100644 src/Authoring/WinRT.SourceGenerator/UiXamlMode.cs create mode 100644 src/Projections/Windows.UI.Xaml/Module.cs create mode 100644 src/Projections/Windows.UI.Xaml/Windows.UI.Xaml.csproj create mode 100644 src/Tests/AuthoringWuxConsumptionTest/AuthoringWuxConsumptionTest.exe.manifest create mode 100644 src/Tests/AuthoringWuxConsumptionTest/AuthoringWuxConsumptionTest.vcxproj create mode 100644 src/Tests/AuthoringWuxConsumptionTest/AuthoringWuxConsumptionTest.vcxproj.filters create mode 100644 src/Tests/AuthoringWuxConsumptionTest/Directory.Build.targets create mode 100644 src/Tests/AuthoringWuxConsumptionTest/DoNotImport_MsAppxPackageTargets.targets create mode 100644 src/Tests/AuthoringWuxConsumptionTest/WinRT.Host.runtimeconfig.json create mode 100644 src/Tests/AuthoringWuxConsumptionTest/packages.config create mode 100644 src/Tests/AuthoringWuxConsumptionTest/pch.cpp create mode 100644 src/Tests/AuthoringWuxConsumptionTest/pch.h create mode 100644 src/Tests/AuthoringWuxConsumptionTest/test.cpp create mode 100644 src/Tests/AuthoringWuxTest/AuthoringWuxTest.csproj create mode 100644 src/Tests/AuthoringWuxTest/Directory.Build.props create mode 100644 src/Tests/AuthoringWuxTest/Directory.Build.targets create mode 100644 src/Tests/AuthoringWuxTest/Module.cs create mode 100644 src/Tests/AuthoringWuxTest/Program.cs create mode 100644 src/Tests/AuthoringWuxTest/Properties/launchSettings.json create mode 100644 src/WinRT.Runtime/Interop/WuxMuxProjectedInterfaceAttribute.cs create mode 100644 src/WinRT.Runtime/Projections/Microsoft.UI.Xaml.Bindable.net5.cs rename src/WinRT.Runtime/Projections/{Bindable.netstandard2.0.cs => Microsoft.UI.Xaml.Bindable.netstandard2.0.cs} (100%) create mode 100644 src/WinRT.Runtime/Projections/Windows.UI.Xaml.Bindable.net5.cs create mode 100644 src/cswinrt/strings/additions/Windows.UI.Xaml.Controls/Windows.UI.Xaml.Controls.Primitives.cs create mode 100644 src/cswinrt/strings/additions/Windows.UI.Xaml.Media.Animation/Windows.UI.Xaml.Media.Animation.cs create mode 100644 src/cswinrt/strings/additions/Windows.UI.Xaml.Media.Media3D/Windows.UI.Xaml.Media.Media3D.cs create mode 100644 src/cswinrt/strings/additions/Windows.UI.Xaml.Media/Windows.UI.Xaml.Media.cs create mode 100644 src/cswinrt/strings/additions/Windows.UI.Xaml/Windows.UI.Xaml.SR.cs create mode 100644 src/cswinrt/strings/additions/Windows.UI.Xaml/Windows.UI.Xaml.cs diff --git a/build/AzurePipelineTemplates/CsWinRT-BuildAndTest-Stage.yml b/build/AzurePipelineTemplates/CsWinRT-BuildAndTest-Stage.yml index 6017ac7c0..1c040cf2c 100644 --- a/build/AzurePipelineTemplates/CsWinRT-BuildAndTest-Stage.yml +++ b/build/AzurePipelineTemplates/CsWinRT-BuildAndTest-Stage.yml @@ -111,6 +111,18 @@ stages: script: | dir _build\$(BuildPlatform)\$(BuildConfiguration)\AuthoringConsumptionTest\bin _build\$(BuildPlatform)\$(BuildConfiguration)\AuthoringConsumptionTest\bin\AuthoringConsumptionTest.exe --gtest_output=xml:AUTHORINGTEST-$(Build.BuildNumber).xml + exit /b 0 + +# Run WUX Tests + - task: CmdLine@2 + displayName: Run WUX Tests + condition: and(succeeded(), or(eq(variables['BuildPlatform'], 'x86'), eq(variables['BuildPlatform'], 'x64'))) + continueOnError: True + inputs: + workingDirectory: $(Build.SourcesDirectory)\src + script: | + dir _build\$(BuildPlatform)\$(BuildConfiguration)\AuthoringWuxConsumptionTest\bin + _build\$(BuildPlatform)\$(BuildConfiguration)\AuthoringWuxConsumptionTest\bin\AuthoringWuxConsumptionTest.exe --gtest_output=xml:AUTHORINGWUXTEST-$(Build.BuildNumber).xml exit /b 0 # Run Functional Tests diff --git a/nuget/Microsoft.Windows.CsWinRT.Authoring.targets b/nuget/Microsoft.Windows.CsWinRT.Authoring.targets index 608746067..bb3ae3f19 100644 --- a/nuget/Microsoft.Windows.CsWinRT.Authoring.targets +++ b/nuget/Microsoft.Windows.CsWinRT.Authoring.targets @@ -31,6 +31,7 @@ Copyright (C) Microsoft Corporation. All rights reserved. + diff --git a/nuget/Microsoft.Windows.CsWinRT.targets b/nuget/Microsoft.Windows.CsWinRT.targets index f9b18979d..03c1d284a 100644 --- a/nuget/Microsoft.Windows.CsWinRT.targets +++ b/nuget/Microsoft.Windows.CsWinRT.targets @@ -230,6 +230,13 @@ $(CsWinRTInternalProjection) + + + $(CsWinRTUiXamlMode) + true + + + diff --git a/src/Authoring/WinRT.SourceGenerator/AotOptimizer.cs b/src/Authoring/WinRT.SourceGenerator/AotOptimizer.cs index 13501d1e1..f6996659d 100644 --- a/src/Authoring/WinRT.SourceGenerator/AotOptimizer.cs +++ b/src/Authoring/WinRT.SourceGenerator/AotOptimizer.cs @@ -20,17 +20,28 @@ public void Initialize(IncrementalGeneratorInitializationContext context) { var properties = context.AnalyzerConfigOptionsProvider.Select(static (provider, _) => (provider.IsCsWinRTAotOptimizerEnabled(), provider.IsCsWinRTComponent())); - var vtableAttributesToAdd = context.SyntaxProvider.CreateSyntaxProvider( + var typeMapper = context.AnalyzerConfigOptionsProvider.Select((options, ct) => options.GlobalOptions.GetUiXamlMode()).Select((mode, ct) => new TypeMapper(mode)); + + var possibleVtableAttributesToAdd = context.SyntaxProvider.CreateSyntaxProvider( static (n, _) => NeedVtableAttribute(n), - static (n, _) => GetVtableAttributeToAdd(n) - ).Where(vtableAttribute => vtableAttribute != null); + static (n, _) => n + ); + + var vtableAttributesToAdd = possibleVtableAttributesToAdd + .Combine(typeMapper) + .Select((data, ct) => GetVtableAttributeToAdd(data.Left, data.Right)) + .Where(n => n is not null); context.RegisterImplementationSourceOutput(vtableAttributesToAdd.Collect().Combine(properties), GenerateVtableAttributes); - var vtablesToAddOnLookupTable = context.SyntaxProvider.CreateSyntaxProvider( + var possibleVtablesToAddOnLookupTable = context.SyntaxProvider.CreateSyntaxProvider( static (n, _) => NeedVtableOnLookupTable(n), - static (n, _) => GetVtableAttributesToAddOnLookupTable(n) - ).Where(vtableAttribute => vtableAttribute != null); + static (n, _) => n); + + var vtablesToAddOnLookupTable = possibleVtablesToAddOnLookupTable + .Combine(typeMapper) + .Select((data, ct) => GetVtableAttributesToAddOnLookupTable(data.Left, data.Right)) + .Where(vtableAttribute => vtableAttribute != null); var genericInterfacesFromVtableAttribute = vtableAttributesToAdd.SelectMany(static (vtableAttribute, _) => vtableAttribute.GenericInterfaces).Collect(); var genericInterfacesFromVtableLookupTable = vtablesToAddOnLookupTable.SelectMany(static (vtable, _) => vtable.SelectMany(v => v.GenericInterfaces)).Collect(); @@ -52,10 +63,10 @@ private static bool NeedVtableAttribute(SyntaxNode node) !GeneratorHelper.IsWinRTType(declaration); // Making sure it isn't an RCW we are projecting. } - private static VtableAttribute GetVtableAttributeToAdd(GeneratorSyntaxContext context) + private static VtableAttribute GetVtableAttributeToAdd(GeneratorSyntaxContext context, TypeMapper typeMapper) { var symbol = context.SemanticModel.GetDeclaredSymbol(context.Node as ClassDeclarationSyntax); - return GetVtableAttributeToAdd(symbol, GeneratorHelper.IsWinRTType, context.SemanticModel.Compilation.Assembly, false); + return GetVtableAttributeToAdd(symbol, GeneratorHelper.IsWinRTType, typeMapper, context.SemanticModel.Compilation.Assembly, false); } private static string ToFullyQualifiedString(ISymbol symbol) @@ -88,7 +99,7 @@ private static string ToVtableLookupString(ISymbol symbol) } } - internal static VtableAttribute GetVtableAttributeToAdd(ITypeSymbol symbol, Func isWinRTType, IAssemblySymbol assemblySymbol, bool isAuthoring, string authoringDefaultInterface = "") + internal static VtableAttribute GetVtableAttributeToAdd(ITypeSymbol symbol, Func isWinRTType, TypeMapper mapper, IAssemblySymbol assemblySymbol, bool isAuthoring, string authoringDefaultInterface = "") { if (GeneratorHelper.HasNonInstantiatedWinRTGeneric(symbol) || GeneratorHelper.HasPrivateclass(symbol)) { @@ -105,13 +116,13 @@ internal static VtableAttribute GetVtableAttributeToAdd(ITypeSymbol symbol, Func foreach (var iface in symbol.AllInterfaces) { - if (isWinRTType(iface)) + if (isWinRTType(iface, mapper)) { interfacesToAddToVtable.Add(ToFullyQualifiedString(iface)); AddGenericInterfaceInstantiation(iface); } - if (iface.IsGenericType && TryGetCompatibleWindowsRuntimeTypesForVariantType(iface, null, isWinRTType, out var compatibleIfaces)) + if (iface.IsGenericType && TryGetCompatibleWindowsRuntimeTypesForVariantType(iface, mapper, null, isWinRTType, out var compatibleIfaces)) { foreach (var compatibleIface in compatibleIfaces) { @@ -189,7 +200,7 @@ void AddGenericInterfaceInstantiation(INamedTypeSymbol iface) genericParameters.Add(new GenericParameter( ToFullyQualifiedString(genericParameter), - GeneratorHelper.GetAbiType(genericParameter), + GeneratorHelper.GetAbiType(genericParameter, mapper), genericParameter.TypeKind)); } @@ -207,7 +218,7 @@ bool IsExternalInternalInterface(INamedTypeSymbol iface) } } - private static bool TryGetCompatibleWindowsRuntimeTypesForVariantType(INamedTypeSymbol type, Stack typeStack, Func isWinRTType, out IList compatibleTypes) + private static bool TryGetCompatibleWindowsRuntimeTypesForVariantType(INamedTypeSymbol type, TypeMapper mapper, Stack typeStack, Func isWinRTType, out IList compatibleTypes) { compatibleTypes = null; @@ -220,7 +231,7 @@ private static bool TryGetCompatibleWindowsRuntimeTypesForVariantType(INamedType } var definition = type.OriginalDefinition; - if (!isWinRTType(definition)) + if (!isWinRTType(definition, mapper)) { return false; } @@ -240,20 +251,20 @@ private static bool TryGetCompatibleWindowsRuntimeTypesForVariantType(INamedType HashSet compatibleTypesForGeneric = new(SymbolEqualityComparer.Default); - if (isWinRTType(type.TypeArguments[0])) + if (isWinRTType(type.TypeArguments[0], mapper)) { compatibleTypesForGeneric.Add(type.TypeArguments[0]); } foreach (var iface in type.TypeArguments[0].AllInterfaces) { - if (isWinRTType(iface)) + if (isWinRTType(iface, mapper)) { compatibleTypesForGeneric.Add(iface); } if (iface.IsGenericType - && TryGetCompatibleWindowsRuntimeTypesForVariantType(iface, typeStack, isWinRTType, out var compatibleIfaces)) + && TryGetCompatibleWindowsRuntimeTypesForVariantType(iface, mapper, typeStack, isWinRTType, out var compatibleIfaces)) { compatibleTypesForGeneric.UnionWith(compatibleIfaces); } @@ -262,7 +273,7 @@ private static bool TryGetCompatibleWindowsRuntimeTypesForVariantType(INamedType var baseType = type.TypeArguments[0].BaseType; while (baseType != null) { - if (isWinRTType(baseType)) + if (isWinRTType(baseType, mapper)) { compatibleTypesForGeneric.Add(baseType); } @@ -503,7 +514,7 @@ private static bool NeedVtableOnLookupTable(SyntaxNode node) node is AssignmentExpressionSyntax; } - private static List GetVtableAttributesToAddOnLookupTable(GeneratorSyntaxContext context) + private static List GetVtableAttributesToAddOnLookupTable(GeneratorSyntaxContext context, TypeMapper mapper) { HashSet vtableAttributes = new(); @@ -511,7 +522,7 @@ private static List GetVtableAttributesToAddOnLookupTable(Gener { var invocationSymbol = context.SemanticModel.GetSymbolInfo(invocation.Expression).Symbol; // Check if function is within a CsWinRT projected class or interface. - if (invocationSymbol is IMethodSymbol methodSymbol && GeneratorHelper.IsWinRTType(methodSymbol.ContainingSymbol)) + if (invocationSymbol is IMethodSymbol methodSymbol && GeneratorHelper.IsWinRTType(methodSymbol.ContainingSymbol, mapper)) { // Get the concrete types directly from the argument rather than // using what the method accepts, which might just be an interface, so @@ -530,14 +541,14 @@ private static List GetVtableAttributesToAddOnLookupTable(Gener { if (methodSymbol.Parameters[paramsIdx].Type is not IArrayTypeSymbol) { - var vtableAtribute = GetVtableAttributeToAdd(arrayType, GeneratorHelper.IsWinRTType, context.SemanticModel.Compilation.Assembly, false); + var vtableAtribute = GetVtableAttributeToAdd(arrayType, GeneratorHelper.IsWinRTType, mapper, context.SemanticModel.Compilation.Assembly, false); if (vtableAtribute != default) { vtableAttributes.Add(vtableAtribute); } // Also add the enumerator type to the lookup table as the native caller may call it. - AddEnumeratorAdapterForType(arrayType.ElementType, context.SemanticModel.Compilation, GeneratorHelper.IsWinRTType, vtableAttributes); + AddEnumeratorAdapterForType(arrayType.ElementType, mapper, context.SemanticModel.Compilation, GeneratorHelper.IsWinRTType, vtableAttributes); } } else if (argumentType.Type is not null) @@ -552,11 +563,11 @@ private static List GetVtableAttributesToAddOnLookupTable(Gener // information is available. if (argumentClassTypeSymbol.TypeKind == TypeKind.Delegate && argumentClassTypeSymbol.MetadataName.Contains("`") && - GeneratorHelper.IsWinRTType(argumentClassTypeSymbol) && + GeneratorHelper.IsWinRTType(argumentClassTypeSymbol, mapper) && methodSymbol.Parameters[paramsIdx].Type.SpecialType == SpecialType.System_Object) { var argumentClassNamedTypeSymbol = argumentClassTypeSymbol as INamedTypeSymbol; - vtableAttributes.Add(GetVtableAttributeToAdd(argumentClassTypeSymbol, GeneratorHelper.IsWinRTType, context.SemanticModel.Compilation.Assembly, false)); + vtableAttributes.Add(GetVtableAttributeToAdd(argumentClassTypeSymbol, GeneratorHelper.IsWinRTType, mapper, context.SemanticModel.Compilation.Assembly, false)); } // This handles the case where the source generator wasn't able to run @@ -569,19 +580,19 @@ private static List GetVtableAttributesToAddOnLookupTable(Gener // we handle it here. if (argumentClassTypeSymbol.TypeKind == TypeKind.Class && (argumentClassTypeSymbol.MetadataName.Contains("`") || - (!GeneratorHelper.IsWinRTType(argumentClassTypeSymbol) && + (!GeneratorHelper.IsWinRTType(argumentClassTypeSymbol, mapper) && !GeneratorHelper.HasWinRTExposedTypeAttribute(argumentClassTypeSymbol) && // If the type is defined in the same assembly as what the source generator is running on, // we let the WinRTExposedType attribute generator handle it. !SymbolEqualityComparer.Default.Equals(argumentClassTypeSymbol.ContainingAssembly, context.SemanticModel.Compilation.Assembly)))) { - var vtableAtribute = GetVtableAttributeToAdd(argumentClassTypeSymbol, GeneratorHelper.IsWinRTType, context.SemanticModel.Compilation.Assembly, false); + var vtableAtribute = GetVtableAttributeToAdd(argumentClassTypeSymbol, GeneratorHelper.IsWinRTType, mapper, context.SemanticModel.Compilation.Assembly, false); if (vtableAtribute != default) { vtableAttributes.Add(vtableAtribute); } - AddEnumeratorAdapterForEnumerableInterface(argumentClassTypeSymbol, context.SemanticModel.Compilation, GeneratorHelper.IsWinRTType, vtableAttributes); + AddEnumeratorAdapterForEnumerableInterface(argumentClassTypeSymbol, mapper, context.SemanticModel.Compilation, GeneratorHelper.IsWinRTType, vtableAttributes); } } } @@ -602,7 +613,7 @@ private static List GetVtableAttributesToAddOnLookupTable(Gener // Check if property being assigned to is within a CsWinRT projected class or interface. if (leftSymbol is IPropertySymbol propertySymbol && - GeneratorHelper.IsWinRTType(propertySymbol.ContainingSymbol)) + GeneratorHelper.IsWinRTType(propertySymbol.ContainingSymbol, mapper)) { var argumentType = context.SemanticModel.GetTypeInfo(assignment.Right); @@ -613,14 +624,14 @@ private static List GetVtableAttributesToAddOnLookupTable(Gener { if (propertySymbol.Type is not IArrayTypeSymbol) { - var vtableAtribute = GetVtableAttributeToAdd(arrayType, GeneratorHelper.IsWinRTType, context.SemanticModel.Compilation.Assembly, false); + var vtableAtribute = GetVtableAttributeToAdd(arrayType, GeneratorHelper.IsWinRTType, mapper, context.SemanticModel.Compilation.Assembly, false); if (vtableAtribute != default) { vtableAttributes.Add(vtableAtribute); } // Also add the enumerator type to the lookup table as the native caller can call it. - AddEnumeratorAdapterForType(arrayType.ElementType, context.SemanticModel.Compilation, GeneratorHelper.IsWinRTType, vtableAttributes); + AddEnumeratorAdapterForType(arrayType.ElementType, mapper, context.SemanticModel.Compilation, GeneratorHelper.IsWinRTType, vtableAttributes); } } else if (argumentType.Type is not null || argumentType.ConvertedType is not null) @@ -635,28 +646,28 @@ private static List GetVtableAttributesToAddOnLookupTable(Gener // assignment to object, it is not known, and that is handled here. if (argumentClassTypeSymbol.TypeKind == TypeKind.Delegate && argumentClassTypeSymbol.MetadataName.Contains("`") && - GeneratorHelper.IsWinRTType(argumentClassTypeSymbol) && + GeneratorHelper.IsWinRTType(argumentClassTypeSymbol, mapper) && propertySymbol.Type.SpecialType == SpecialType.System_Object) { var argumentClassNamedTypeSymbol = argumentClassTypeSymbol as INamedTypeSymbol; - vtableAttributes.Add(GetVtableAttributeToAdd(argumentClassTypeSymbol, GeneratorHelper.IsWinRTType, context.SemanticModel.Compilation.Assembly, false)); + vtableAttributes.Add(GetVtableAttributeToAdd(argumentClassTypeSymbol, GeneratorHelper.IsWinRTType, mapper, context.SemanticModel.Compilation.Assembly, false)); } if (argumentClassTypeSymbol.TypeKind == TypeKind.Class && (argumentClassTypeSymbol.MetadataName.Contains("`") || - (!GeneratorHelper.IsWinRTType(argumentClassTypeSymbol) && + (!GeneratorHelper.IsWinRTType(argumentClassTypeSymbol, mapper) && !GeneratorHelper.HasWinRTExposedTypeAttribute(argumentClassTypeSymbol) && // If the type is defined in the same assembly as what the source generator is running on, // we let the WinRTExposedType attribute generator handle it. !SymbolEqualityComparer.Default.Equals(argumentClassTypeSymbol.ContainingAssembly, context.SemanticModel.Compilation.Assembly)))) { - var vtableAtribute = GetVtableAttributeToAdd(argumentClassTypeSymbol, GeneratorHelper.IsWinRTType, context.SemanticModel.Compilation.Assembly, false); + var vtableAtribute = GetVtableAttributeToAdd(argumentClassTypeSymbol, GeneratorHelper.IsWinRTType, mapper, context.SemanticModel.Compilation.Assembly, false); if (vtableAtribute != default) { vtableAttributes.Add(vtableAtribute); } - AddEnumeratorAdapterForEnumerableInterface(argumentClassTypeSymbol, context.SemanticModel.Compilation, GeneratorHelper.IsWinRTType, vtableAttributes); + AddEnumeratorAdapterForEnumerableInterface(argumentClassTypeSymbol, mapper, context.SemanticModel.Compilation, GeneratorHelper.IsWinRTType, vtableAttributes); } } } @@ -668,11 +679,11 @@ private static List GetVtableAttributesToAddOnLookupTable(Gener // Any of the IEnumerable interfaces on the vtable can be used to get the enumerator. Given IEnumerable is // a covariant interface, it means that we can end up getting an instance of the enumerable adapter for any one // of those covariant interfaces and thereby need vtable lookup entries for all of them. - private static void AddEnumeratorAdapterForType(ITypeSymbol type, Compilation compilation, Func isWinRTType, HashSet vtableAttributes) + private static void AddEnumeratorAdapterForType(ITypeSymbol type, TypeMapper mapper, Compilation compilation, Func isWinRTType, HashSet vtableAttributes) { var enumerableType = compilation.GetTypeByMetadataName("System.Collections.Generic.IEnumerable`1"). Construct(type); - if (TryGetCompatibleWindowsRuntimeTypesForVariantType(enumerableType, null, isWinRTType, out var compatibleIfaces)) + if (TryGetCompatibleWindowsRuntimeTypesForVariantType(enumerableType, mapper, null, isWinRTType, out var compatibleIfaces)) { foreach (var compatibleIface in compatibleIfaces) { @@ -681,51 +692,51 @@ private static void AddEnumeratorAdapterForType(ITypeSymbol type, Compilation co { var enumeratorAdapterType = compilation.GetTypeByMetadataName("ABI.System.Collections.Generic.ToAbiEnumeratorAdapter`1"). Construct(compatibleIface.TypeArguments[0]); - vtableAttributes.Add(GetVtableAttributeToAdd(enumeratorAdapterType, isWinRTType, compilation.Assembly, false)); + vtableAttributes.Add(GetVtableAttributeToAdd(enumeratorAdapterType, isWinRTType, mapper, compilation.Assembly, false)); } } } } - internal static void AddEnumeratorAdapterForEnumerableInterface(ITypeSymbol classType, Compilation compilation, Func isWinRTType, HashSet vtableAttributes) + internal static void AddEnumeratorAdapterForEnumerableInterface(ITypeSymbol classType, TypeMapper mapper, Compilation compilation, Func isWinRTType, HashSet vtableAttributes) { // Type may implement multiple unique IEnumerable interfaces. foreach (var iface in classType.AllInterfaces) { if (iface.MetadataName == "IEnumerable`1") { - AddEnumeratorAdapterForType(iface.TypeArguments[0], compilation, isWinRTType, vtableAttributes); + AddEnumeratorAdapterForType(iface.TypeArguments[0], mapper, compilation, isWinRTType, vtableAttributes); } } } - internal static void AddVtableAdapterTypeForKnownInterface(ITypeSymbol classType, Compilation compilation, Func isWinRTType, HashSet vtableAttributes) + internal static void AddVtableAdapterTypeForKnownInterface(ITypeSymbol classType, Compilation compilation, Func isWinRTType, TypeMapper mapper, HashSet vtableAttributes) { foreach (var iface in classType.AllInterfaces) { if (iface.MetadataName == "IEnumerable`1") { - AddEnumeratorAdapterForType(iface.TypeArguments[0], compilation, isWinRTType, vtableAttributes); + AddEnumeratorAdapterForType(iface.TypeArguments[0], mapper, compilation, isWinRTType, vtableAttributes); } else if (iface.MetadataName == "IDictionary`2") { var readOnlyDictionaryType = compilation.GetTypeByMetadataName("System.Collections.ObjectModel.ReadOnlyDictionary`2"). Construct([.. iface.TypeArguments]); - vtableAttributes.Add(GetVtableAttributeToAdd(readOnlyDictionaryType, isWinRTType, compilation.Assembly, false)); + vtableAttributes.Add(GetVtableAttributeToAdd(readOnlyDictionaryType, isWinRTType, mapper, compilation.Assembly, false)); var keyValuePairType = compilation.GetTypeByMetadataName("System.Collections.Generic.KeyValuePair`2"). Construct([.. iface.TypeArguments]); - vtableAttributes.Add(GetVtableAttributeToAdd(keyValuePairType, isWinRTType, compilation.Assembly, false)); + vtableAttributes.Add(GetVtableAttributeToAdd(keyValuePairType, isWinRTType, mapper, compilation.Assembly, false)); var constantSplittableMapType = compilation.GetTypeByMetadataName("ABI.System.Collections.Generic.ConstantSplittableMap`2"). Construct([.. iface.TypeArguments]); - vtableAttributes.Add(GetVtableAttributeToAdd(constantSplittableMapType, isWinRTType, compilation.Assembly, false)); + vtableAttributes.Add(GetVtableAttributeToAdd(constantSplittableMapType, isWinRTType, mapper, compilation.Assembly, false)); } else if (iface.MetadataName == "IList`1") { var readOnlyCollectionType = compilation.GetTypeByMetadataName("System.Collections.ObjectModel.ReadOnlyCollection`1"). Construct([.. iface.TypeArguments]); - vtableAttributes.Add(GetVtableAttributeToAdd(readOnlyCollectionType, isWinRTType, compilation.Assembly, false)); + vtableAttributes.Add(GetVtableAttributeToAdd(readOnlyCollectionType, isWinRTType, mapper, compilation.Assembly, false)); } } } diff --git a/src/Authoring/WinRT.SourceGenerator/DiagnosticUtils.cs b/src/Authoring/WinRT.SourceGenerator/DiagnosticUtils.cs index 9c2215de1..528bd1598 100644 --- a/src/Authoring/WinRT.SourceGenerator/DiagnosticUtils.cs +++ b/src/Authoring/WinRT.SourceGenerator/DiagnosticUtils.cs @@ -16,11 +16,13 @@ public WinRTComponentScanner(GeneratorExecutionContext context, string assemblyN _assemblyName = assemblyName; _context = context; _flag = false; + _typeMapper = new TypeMapper(context.AnalyzerConfigOptions.GlobalOptions.GetUiXamlMode()); } private readonly string _assemblyName; private readonly GeneratorExecutionContext _context; private bool _flag; + private readonly TypeMapper _typeMapper; public bool Found() { return _flag; } @@ -105,7 +107,7 @@ private void CheckDeclarations() var props = @class.DescendantNodes().OfType().Where(IsPublic); // filter out methods and properties that will be replaced with our custom type mappings - IgnoreCustomTypeMappings(classSymbol, ref publicMethods, ref props); + IgnoreCustomTypeMappings(classSymbol, _typeMapper, ref publicMethods, ref props); if (!classSymbol.IsSealed && !classSymbol.IsStatic) { @@ -137,7 +139,7 @@ private void CheckDeclarations() var props = @interface.DescendantNodes().OfType().Where(IsPublic); // filter out methods and properties that will be replaced with our custom type mappings - IgnoreCustomTypeMappings(interfaceSym, ref methods, ref props); + IgnoreCustomTypeMappings(interfaceSym, _typeMapper, ref methods, ref props); if (interfaceSym.IsGenericType) { @@ -206,6 +208,7 @@ private bool IsMethodImpl(IMethodSymbol m, IMethodSymbol interfaceMethod) } private void IgnoreCustomTypeMappings(INamedTypeSymbol typeSymbol, + TypeMapper typeMapper, ref IEnumerable methods, ref IEnumerable properties) { @@ -217,7 +220,7 @@ string QualifiedName(INamedTypeSymbol sym) HashSet classMethods = new(); foreach (var @interface in typeSymbol.AllInterfaces. - Where(symbol => GeneratorHelper.MappedCSharpTypes.ContainsKey(QualifiedName(symbol)) || + Where(symbol => typeMapper.HasMappingForType(QualifiedName(symbol)) || WinRTTypeWriter.ImplementedInterfacesWithoutMapping.Contains(QualifiedName(symbol)))) { foreach (var interfaceMember in @interface.GetMembers()) diff --git a/src/Authoring/WinRT.SourceGenerator/Generator.cs b/src/Authoring/WinRT.SourceGenerator/Generator.cs index baf75519b..303051597 100644 --- a/src/Authoring/WinRT.SourceGenerator/Generator.cs +++ b/src/Authoring/WinRT.SourceGenerator/Generator.cs @@ -1,4 +1,4 @@ -using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Text; @@ -20,11 +20,14 @@ public class ComponentGenerator private Logger Logger { get; } private readonly GeneratorExecutionContext context; private string tempFolder; + private readonly TypeMapper mapper; public ComponentGenerator(GeneratorExecutionContext context) { this.context = context; Logger = new Logger(context); + mapper = new(context.AnalyzerConfigOptions.GlobalOptions.GetUiXamlMode()); + // TODO-WuxMux: output a module initializer that validates the MUX/WUX projection mode to ensure that things don't get out of sync. } private string GetTempFolder(bool clearSourceFilesFromFolder = false) @@ -152,7 +155,8 @@ public void Generate() assembly, version, metadataBuilder, - Logger); + Logger, + mapper); WinRTSyntaxReceiver syntaxReceiver = (WinRTSyntaxReceiver)context.SyntaxReceiver; Logger.Log("Found " + syntaxReceiver.Declarations.Count + " types"); diff --git a/src/Authoring/WinRT.SourceGenerator/Helper.cs b/src/Authoring/WinRT.SourceGenerator/Helper.cs index 1cd7f89ab..55c699c19 100644 --- a/src/Authoring/WinRT.SourceGenerator/Helper.cs +++ b/src/Authoring/WinRT.SourceGenerator/Helper.cs @@ -1,117 +1,117 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. - -using Microsoft.CodeAnalysis; + +using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Diagnostics; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; using System.Text.RegularExpressions; -namespace Generator -{ - public static class Helper - { - public static Guid EncodeGuid(byte[] data) - { - if (BitConverter.IsLittleEndian) - { - // swap bytes of int a - byte t = data[0]; - data[0] = data[3]; - data[3] = t; - t = data[1]; - data[1] = data[2]; - data[2] = t; - // swap bytes of short b - t = data[4]; - data[4] = data[5]; - data[5] = t; - // swap bytes of short c and encode rfc time/version field - t = data[6]; - data[6] = data[7]; - data[7] = (byte)((t & 0x0f) | (5 << 4)); - // encode rfc clock/reserved field - data[8] = (byte)((data[8] & 0x3f) | 0x80); - } - return new Guid(data.Take(16).ToArray()); - } - } - - class AttributeDataComparer : IEqualityComparer - { - public bool Equals(AttributeData x, AttributeData y) - { - return string.CompareOrdinal(x.ToString(), y.ToString()) == 0; - } - - public int GetHashCode(AttributeData obj) - { - return obj.ToString().GetHashCode(); - } - } - - static class GeneratorExecutionContextHelper - { - public static string GetAssemblyName(this GeneratorExecutionContext context) - { - context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.AssemblyName", out var assemblyName); - return assemblyName; - } - - public static string GetAssemblyVersion(this GeneratorExecutionContext context) - { - context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.AssemblyVersion", out var assemblyVersion); - return assemblyVersion; - } - - public static string GetGeneratedFilesDir(this GeneratorExecutionContext context) - { - context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.CsWinRTGeneratedFilesDir", out var generatedFilesDir); - Directory.CreateDirectory(generatedFilesDir); - return generatedFilesDir; - } - - public static bool IsCsWinRTComponent(this GeneratorExecutionContext context) - { - if (context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.CsWinRTComponent", out var isCsWinRTComponentStr)) - { - return bool.TryParse(isCsWinRTComponentStr, out var isCsWinRTComponent) && isCsWinRTComponent; - } - - return false; - } - - public static bool IsCsWinRTComponent(this AnalyzerConfigOptionsProvider provider) - { - if (provider.GlobalOptions.TryGetValue("build_property.CsWinRTComponent", out var isCsWinRTComponentStr)) - { - return bool.TryParse(isCsWinRTComponentStr, out var isCsWinRTComponent) && isCsWinRTComponent; - } - - return false; - } - - public static bool IsCsWinRTAotOptimizerEnabled(this AnalyzerConfigOptionsProvider provider) - { - if (provider.GlobalOptions.TryGetValue("build_property.CsWinRTAotOptimizerEnabled", out var isCsWinRTAotOptimizerEnabledStr)) - { - return bool.TryParse(isCsWinRTAotOptimizerEnabledStr, out var isCsWinRTAotOptimizerEnabled) && isCsWinRTAotOptimizerEnabled; - } - - return false; - } - - public static bool ShouldGenerateWinMDOnly(this GeneratorExecutionContext context) - { - if (context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.CsWinRTGenerateWinMDOnly", out var CsWinRTGenerateWinMDOnlyStr)) - { - return bool.TryParse(CsWinRTGenerateWinMDOnlyStr, out var CsWinRTGenerateWinMDOnly) && CsWinRTGenerateWinMDOnly; - } - - return false; +namespace Generator +{ + public static class Helper + { + public static Guid EncodeGuid(byte[] data) + { + if (BitConverter.IsLittleEndian) + { + // swap bytes of int a + byte t = data[0]; + data[0] = data[3]; + data[3] = t; + t = data[1]; + data[1] = data[2]; + data[2] = t; + // swap bytes of short b + t = data[4]; + data[4] = data[5]; + data[5] = t; + // swap bytes of short c and encode rfc time/version field + t = data[6]; + data[6] = data[7]; + data[7] = (byte)((t & 0x0f) | (5 << 4)); + // encode rfc clock/reserved field + data[8] = (byte)((data[8] & 0x3f) | 0x80); + } + return new Guid(data.Take(16).ToArray()); + } + } + + class AttributeDataComparer : IEqualityComparer + { + public bool Equals(AttributeData x, AttributeData y) + { + return string.CompareOrdinal(x.ToString(), y.ToString()) == 0; + } + + public int GetHashCode(AttributeData obj) + { + return obj.ToString().GetHashCode(); + } + } + + static class GeneratorExecutionContextHelper + { + public static string GetAssemblyName(this GeneratorExecutionContext context) + { + context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.AssemblyName", out var assemblyName); + return assemblyName; + } + + public static string GetAssemblyVersion(this GeneratorExecutionContext context) + { + context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.AssemblyVersion", out var assemblyVersion); + return assemblyVersion; + } + + public static string GetGeneratedFilesDir(this GeneratorExecutionContext context) + { + context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.CsWinRTGeneratedFilesDir", out var generatedFilesDir); + Directory.CreateDirectory(generatedFilesDir); + return generatedFilesDir; + } + + public static bool IsCsWinRTComponent(this GeneratorExecutionContext context) + { + if (context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.CsWinRTComponent", out var isCsWinRTComponentStr)) + { + return bool.TryParse(isCsWinRTComponentStr, out var isCsWinRTComponent) && isCsWinRTComponent; + } + + return false; + } + + public static bool IsCsWinRTComponent(this AnalyzerConfigOptionsProvider provider) + { + if (provider.GlobalOptions.TryGetValue("build_property.CsWinRTComponent", out var isCsWinRTComponentStr)) + { + return bool.TryParse(isCsWinRTComponentStr, out var isCsWinRTComponent) && isCsWinRTComponent; + } + + return false; + } + + public static bool IsCsWinRTAotOptimizerEnabled(this AnalyzerConfigOptionsProvider provider) + { + if (provider.GlobalOptions.TryGetValue("build_property.CsWinRTAotOptimizerEnabled", out var isCsWinRTAotOptimizerEnabledStr)) + { + return bool.TryParse(isCsWinRTAotOptimizerEnabledStr, out var isCsWinRTAotOptimizerEnabled) && isCsWinRTAotOptimizerEnabled; + } + + return false; + } + + public static bool ShouldGenerateWinMDOnly(this GeneratorExecutionContext context) + { + if (context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.CsWinRTGenerateWinMDOnly", out var CsWinRTGenerateWinMDOnlyStr)) + { + return bool.TryParse(CsWinRTGenerateWinMDOnlyStr, out var CsWinRTGenerateWinMDOnly) && CsWinRTGenerateWinMDOnly; + } + + return false; } /// @@ -119,51 +119,51 @@ public static bool ShouldGenerateWinMDOnly(this GeneratorExecutionContext contex /// /// The input value to use. /// Whether the "CsWinRTAotExportsEnabled" MSBuild property is defined. - public static bool ShouldGenerateWinRTNativeExports(this GeneratorExecutionContext context) - { - if (context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.CsWinRTAotExportsEnabled", out var isCsWinRTAotExportsEnabledStr)) - { - return bool.TryParse(isCsWinRTAotExportsEnabledStr, out var isCsWinRTAotExportsEnabled) && isCsWinRTAotExportsEnabled; - } - - return false; - } - - public static string GetCsWinRTExe(this GeneratorExecutionContext context) - { - context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.CsWinRTExe", out var cswinrtExe); - return cswinrtExe; - } - - public static bool GetKeepGeneratedSources(this GeneratorExecutionContext context) - { - context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.CsWinRTKeepGeneratedSources", out var keepGeneratedSourcesStr); - return keepGeneratedSourcesStr != null && bool.TryParse(keepGeneratedSourcesStr, out var keepGeneratedSources) && keepGeneratedSources; - } - - public static string GetCsWinRTWindowsMetadata(this GeneratorExecutionContext context) - { - context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.CsWinRTWindowsMetadata", out var cswinrtWindowsMetadata); - return cswinrtWindowsMetadata; - } - - public static string GetCsWinRTDependentMetadata(this GeneratorExecutionContext context) - { - context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.CsWinRTAuthoringInputs", out var winmds); - return winmds; - } - - public static string GetWinmdOutputFile(this GeneratorExecutionContext context) - { + public static bool ShouldGenerateWinRTNativeExports(this GeneratorExecutionContext context) + { + if (context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.CsWinRTAotExportsEnabled", out var isCsWinRTAotExportsEnabledStr)) + { + return bool.TryParse(isCsWinRTAotExportsEnabledStr, out var isCsWinRTAotExportsEnabled) && isCsWinRTAotExportsEnabled; + } + + return false; + } + + public static string GetCsWinRTExe(this GeneratorExecutionContext context) + { + context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.CsWinRTExe", out var cswinrtExe); + return cswinrtExe; + } + + public static bool GetKeepGeneratedSources(this GeneratorExecutionContext context) + { + context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.CsWinRTKeepGeneratedSources", out var keepGeneratedSourcesStr); + return keepGeneratedSourcesStr != null && bool.TryParse(keepGeneratedSourcesStr, out var keepGeneratedSources) && keepGeneratedSources; + } + + public static string GetCsWinRTWindowsMetadata(this GeneratorExecutionContext context) + { + context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.CsWinRTWindowsMetadata", out var cswinrtWindowsMetadata); + return cswinrtWindowsMetadata; + } + + public static string GetCsWinRTDependentMetadata(this GeneratorExecutionContext context) + { + context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.CsWinRTAuthoringInputs", out var winmds); + return winmds; + } + + public static string GetWinmdOutputFile(this GeneratorExecutionContext context) + { var fileName = context.GetAssemblyName(); if (context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.CsWinRTWinMDOutputFile", out var ret)) { fileName = ret!; - } - return Path.Combine(context.GetGeneratedFilesDir(), fileName + ".winmd"); - } - } - + } + return Path.Combine(context.GetGeneratedFilesDir(), fileName + ".winmd"); + } + } + static class GeneratorHelper { private static bool IsFundamentalType(ISymbol type) @@ -192,12 +192,12 @@ private static bool IsFundamentalType(ISymbol type) return type.ToDisplayString() == "System.Guid"; } - public static bool IsWinRTType(ISymbol type) + public static bool IsWinRTType(ISymbol type, TypeMapper mapper) { - return IsWinRTType(type, null); + return IsWinRTType(type, mapper, null); } - public static bool IsWinRTType(ISymbol type, Func isAuthoringWinRTType) + public static bool IsWinRTType(ISymbol type, TypeMapper mapper, Func isAuthoringWinRTType) { bool isProjectedType = type.GetAttributes(). Any(attribute => string.CompareOrdinal(attribute.AttributeClass.Name, "WindowsRuntimeTypeAttribute") == 0) || @@ -205,14 +205,14 @@ public static bool IsWinRTType(ISymbol type, Func isAuthoringWinR if (!isProjectedType & type.ContainingNamespace != null) { - isProjectedType = MappedCSharpTypes.ContainsKey(string.Join(".", type.ContainingNamespace.ToDisplayString(), type.MetadataName)); + isProjectedType = mapper.HasMappingForType(string.Join(".", type.ContainingNamespace.ToDisplayString(), type.MetadataName)); } // Ensure all generic parameters are WinRT types. if (isProjectedType && type is INamedTypeSymbol namedType && namedType.IsGenericType && !namedType.IsDefinition) { isProjectedType = namedType.TypeArguments.All(t => - IsWinRTType(t, isAuthoringWinRTType) || + IsWinRTType(t, mapper, isAuthoringWinRTType) || (isAuthoringWinRTType != null && isAuthoringWinRTType(t))); } @@ -295,7 +295,7 @@ private static string GetAbiTypeForFundamentalType(ISymbol type) return type.ToDisplayString(); } - public static bool IsBlittableValueType(ITypeSymbol type) + public static bool IsBlittableValueType(ITypeSymbol type, TypeMapper typeMapper) { if (!type.IsValueType) { @@ -325,9 +325,9 @@ public static bool IsBlittableValueType(ITypeSymbol type) } string customTypeMapKey = string.Join(".", type.ContainingNamespace.ToDisplayString(), type.MetadataName); - if (MappedCSharpTypes.ContainsKey(customTypeMapKey)) + if (typeMapper.HasMappingForType(customTypeMapKey)) { - return MappedCSharpTypes[customTypeMapKey].IsBlittable(); + return typeMapper.GetMappedType(customTypeMapKey).IsBlittable(); } if (type.TypeKind == TypeKind.Enum) @@ -339,7 +339,7 @@ public static bool IsBlittableValueType(ITypeSymbol type) { foreach (var typeMember in type.GetMembers()) { - if (typeMember is IFieldSymbol field && !IsBlittableValueType(field.Type)) + if (typeMember is IFieldSymbol field && !IsBlittableValueType(field.Type, typeMapper)) { return false; } @@ -348,7 +348,7 @@ public static bool IsBlittableValueType(ITypeSymbol type) return true; } - public static string GetAbiType(ITypeSymbol type) + public static string GetAbiType(ITypeSymbol type, TypeMapper mapper) { if (IsFundamentalType(type)) { @@ -368,9 +368,9 @@ public static string GetAbiType(ITypeSymbol type) if (type.IsValueType) { string customTypeMapKey = string.Join(".", type.ContainingNamespace.ToDisplayString(), type.MetadataName); - if (MappedCSharpTypes.ContainsKey(customTypeMapKey)) + if (mapper.HasMappingForType(customTypeMapKey)) { - string prefix = MappedCSharpTypes[customTypeMapKey].IsBlittable() ? "" : "ABI."; + string prefix = mapper.GetMappedType(customTypeMapKey).IsBlittable() ? "" : "ABI."; return prefix + typeStr; } @@ -385,7 +385,7 @@ public static string GetAbiType(ITypeSymbol type) // Handling authoring scenario where Impl type has the attributes and // if the current component is the one being authored, it may not be // generated yet to check given it is the same compilation. - else if (!IsBlittableValueType(type)) + else if (!IsBlittableValueType(type, mapper)) { return "ABI." + typeStr; } @@ -731,63 +731,5 @@ public bool IsBlittable() return isValueType && isBlittable; } } - - // Based on whether System.Type is used in an attribute declaration or elsewhere, we need to choose the correct custom mapping - // as attributes don't use the TypeName mapping. - internal static (string, string, string, bool, bool) GetSystemTypeCustomMapping(ISymbol containingSymbol) - { - bool isDefinedInAttribute = - containingSymbol != null && - string.CompareOrdinal((containingSymbol as INamedTypeSymbol).BaseType?.ToString(), "System.Attribute") == 0; - return isDefinedInAttribute ? - ("System", "Type", "mscorlib", true, false) : - ("Windows.UI.Xaml.Interop", "TypeName", "Windows.Foundation.UniversalApiContract", false, true); - } - - // This should be in sync with the reverse mapping from WinRT.Runtime/Projections.cs and cswinrt/helpers.h. - public static readonly Dictionary MappedCSharpTypes = new(StringComparer.Ordinal) - { - { "System.DateTimeOffset", new MappedType("Windows.Foundation", "DateTime", "Windows.Foundation.FoundationContract", true, false) }, - { "System.Exception", new MappedType("Windows.Foundation", "HResult", "Windows.Foundation.FoundationContract", true, false) }, - { "System.EventHandler`1", new MappedType("Windows.Foundation", "EventHandler`1", "Windows.Foundation.FoundationContract") }, - { "System.FlagsAttribute", new MappedType("System", "FlagsAttribute", "mscorlib" ) }, - { "System.IDisposable", new MappedType("Windows.Foundation", "IClosable", "Windows.Foundation.FoundationContract") }, - { "System.IServiceProvider", new MappedType("Microsoft.UI.Xaml", "IXamlServiceProvider", "Microsoft.UI") }, - { "System.Nullable`1", new MappedType("Windows.Foundation", "IReference`1", "Windows.Foundation.FoundationContract" ) }, - { "System.Object", new MappedType("System", "Object", "mscorlib" ) }, - { "System.TimeSpan", new MappedType("Windows.Foundation", "TimeSpan", "Windows.Foundation.FoundationContract", true, false) }, - { "System.Uri", new MappedType("Windows.Foundation", "Uri", "Windows.Foundation.FoundationContract") }, - { "System.ComponentModel.DataErrorsChangedEventArgs", new MappedType("Microsoft.UI.Xaml.Data", "DataErrorsChangedEventArgs", "Microsoft.UI") }, - { "System.ComponentModel.INotifyDataErrorInfo", new MappedType("Microsoft.UI.Xaml.Data", "INotifyDataErrorInfo", "Microsoft.UI") }, - { "System.ComponentModel.INotifyPropertyChanged", new MappedType("Microsoft.UI.Xaml.Data", "INotifyPropertyChanged", "Microsoft.UI") }, - { "System.ComponentModel.PropertyChangedEventArgs", new MappedType("Microsoft.UI.Xaml.Data", "PropertyChangedEventArgs", "Microsoft.UI") }, - { "System.ComponentModel.PropertyChangedEventHandler", new MappedType("Microsoft.UI.Xaml.Data", "PropertyChangedEventHandler", "Microsoft.UI") }, - { "System.Windows.Input.ICommand", new MappedType("Microsoft.UI.Xaml.Input", "ICommand", "Microsoft.UI") }, - { "System.Collections.IEnumerable", new MappedType("Microsoft.UI.Xaml.Interop", "IBindableIterable", "Microsoft.UI") }, - { "System.Collections.IList", new MappedType("Microsoft.UI.Xaml.Interop", "IBindableVector", "Microsoft.UI") }, - { "System.Collections.Specialized.INotifyCollectionChanged", new MappedType("Microsoft.UI.Xaml.Interop", "INotifyCollectionChanged", "Microsoft.UI") }, - { "System.Collections.Specialized.NotifyCollectionChangedAction", new MappedType("Microsoft.UI.Xaml.Interop", "NotifyCollectionChangedAction", "Microsoft.UI") }, - { "System.Collections.Specialized.NotifyCollectionChangedEventArgs", new MappedType("Microsoft.UI.Xaml.Interop", "NotifyCollectionChangedEventArgs", "Microsoft.UI") }, - { "System.Collections.Specialized.NotifyCollectionChangedEventHandler", new MappedType("Microsoft.UI.Xaml.Interop", "NotifyCollectionChangedEventHandler", "Microsoft.UI") }, - { "WinRT.EventRegistrationToken", new MappedType("Windows.Foundation", "EventRegistrationToken", "Windows.Foundation.FoundationContract", true, true) }, - { "System.AttributeTargets", new MappedType("Windows.Foundation.Metadata", "AttributeTargets", "Windows.Foundation.FoundationContract", true, true) }, - { "System.AttributeUsageAttribute", new MappedType("Windows.Foundation.Metadata", "AttributeUsageAttribute", "Windows.Foundation.FoundationContract") }, - { "System.Numerics.Matrix3x2", new MappedType("Windows.Foundation.Numerics", "Matrix3x2", "Windows.Foundation.FoundationContract", true, true) }, - { "System.Numerics.Matrix4x4", new MappedType("Windows.Foundation.Numerics", "Matrix4x4", "Windows.Foundation.FoundationContract", true, true) }, - { "System.Numerics.Plane", new MappedType("Windows.Foundation.Numerics", "Plane", "Windows.Foundation.FoundationContract", true, true) }, - { "System.Numerics.Quaternion", new MappedType("Windows.Foundation.Numerics", "Quaternion", "Windows.Foundation.FoundationContract", true, true) }, - { "System.Numerics.Vector2", new MappedType("Windows.Foundation.Numerics", "Vector2", "Windows.Foundation.FoundationContract", true, true) }, - { "System.Numerics.Vector3", new MappedType("Windows.Foundation.Numerics", "Vector3", "Windows.Foundation.FoundationContract", true, true) }, - { "System.Numerics.Vector4", new MappedType("Windows.Foundation.Numerics", "Vector4", "Windows.Foundation.FoundationContract", true, true) }, - { "System.Type", new MappedType(GetSystemTypeCustomMapping) }, - { "System.Collections.Generic.IEnumerable`1", new MappedType("Windows.Foundation.Collections", "IIterable`1", "Windows.Foundation.FoundationContract") }, - { "System.Collections.Generic.IEnumerator`1", new MappedType("Windows.Foundation.Collections", "IIterator`1", "Windows.Foundation.FoundationContract") }, - { "System.Collections.Generic.KeyValuePair`2", new MappedType("Windows.Foundation.Collections", "IKeyValuePair`2", "Windows.Foundation.FoundationContract") }, - { "System.Collections.Generic.IReadOnlyDictionary`2", new MappedType("Windows.Foundation.Collections", "IMapView`2", "Windows.Foundation.FoundationContract") }, - { "System.Collections.Generic.IDictionary`2", new MappedType("Windows.Foundation.Collections", "IMap`2", "Windows.Foundation.FoundationContract") }, - { "System.Collections.Generic.IReadOnlyList`1", new MappedType("Windows.Foundation.Collections", "IVectorView`1", "Windows.Foundation.FoundationContract") }, - { "System.Collections.Generic.IList`1", new MappedType("Windows.Foundation.Collections", "IVector`1", "Windows.Foundation.FoundationContract") }, - { "Windows.UI.Color", new MappedType("Windows.UI", "Color", "Windows.Foundation.UniversalApiContract", true, true) }, - }; - } -} + } +} diff --git a/src/Authoring/WinRT.SourceGenerator/TypeMapper.cs b/src/Authoring/WinRT.SourceGenerator/TypeMapper.cs new file mode 100644 index 000000000..e35ccc63e --- /dev/null +++ b/src/Authoring/WinRT.SourceGenerator/TypeMapper.cs @@ -0,0 +1,125 @@ +using Microsoft.CodeAnalysis; +using System; +using System.Collections.Generic; +using System.Text; +using static Generator.GeneratorHelper; + +namespace Generator +{ + internal sealed class TypeMapper + { + private readonly Dictionary typeMapping; + + // Based on whether System.Type is used in an attribute declaration or elsewhere, we need to choose the correct custom mapping + // as attributes don't use the TypeName mapping. + private static (string, string, string, bool, bool) GetSystemTypeCustomMapping(ISymbol containingSymbol) + { + bool isDefinedInAttribute = + containingSymbol != null && + string.CompareOrdinal((containingSymbol as INamedTypeSymbol).BaseType?.ToString(), "System.Attribute") == 0; + return isDefinedInAttribute ? + ("System", "Type", "mscorlib", true, false) : + ("Windows.UI.Xaml.Interop", "TypeName", "Windows.Foundation.UniversalApiContract", false, true); + } + + public TypeMapper(UiXamlMode xamlMode) + { + // This should be in sync with the reverse mapping from WinRT.Runtime/Projections.cs and cswinrt/helpers.h. + if (xamlMode == UiXamlMode.WindowsUiXaml) + { + typeMapping = new(StringComparer.Ordinal) + { + { "System.DateTimeOffset", new MappedType("Windows.Foundation", "DateTime", "Windows.Foundation.FoundationContract", true, false) }, + { "System.Exception", new MappedType("Windows.Foundation", "HResult", "Windows.Foundation.FoundationContract", true, false) }, + { "System.EventHandler`1", new MappedType("Windows.Foundation", "EventHandler`1", "Windows.Foundation.FoundationContract") }, + { "System.FlagsAttribute", new MappedType("System", "FlagsAttribute", "mscorlib" ) }, + { "System.IDisposable", new MappedType("Windows.Foundation", "IClosable", "Windows.Foundation.FoundationContract") }, + { "System.Nullable`1", new MappedType("Windows.Foundation", "IReference`1", "Windows.Foundation.FoundationContract" ) }, + { "System.Object", new MappedType("System", "Object", "mscorlib" ) }, + { "System.TimeSpan", new MappedType("Windows.Foundation", "TimeSpan", "Windows.Foundation.FoundationContract", true, false) }, + { "System.Uri", new MappedType("Windows.Foundation", "Uri", "Windows.Foundation.FoundationContract") }, + { "System.ComponentModel.INotifyPropertyChanged", new MappedType("Windows.UI.Xaml.Data", "INotifyPropertyChanged", "Windows.UI.Xaml") }, + { "System.ComponentModel.PropertyChangedEventArgs", new MappedType("Windows.UI.Xaml.Data", "PropertyChangedEventArgs", "Windows.UI.Xaml") }, + { "System.ComponentModel.PropertyChangedEventHandler", new MappedType("Windows.UI.Xaml.Data", "PropertyChangedEventHandler", "Windows.UI.Xaml") }, + { "System.Windows.Input.ICommand", new MappedType("Windows.UI.Xaml.Input", "ICommand", "Windows.UI.Xaml") }, + { "System.Collections.IEnumerable", new MappedType("Windows.UI.Xaml.Interop", "IBindableIterable", "Windows.UI.Xaml") }, + { "System.Collections.IList", new MappedType("Windows.UI.Xaml.Interop", "IBindableVector", "Windows.UI.Xaml") }, + { "System.Collections.Specialized.INotifyCollectionChanged", new MappedType("Windows.UI.Xaml.Interop", "INotifyCollectionChanged", "Windows.UI.Xaml") }, + { "System.Collections.Specialized.NotifyCollectionChangedAction", new MappedType("Windows.UI.Xaml.Interop", "NotifyCollectionChangedAction", "Windows.UI.Xaml") }, + { "System.Collections.Specialized.NotifyCollectionChangedEventArgs", new MappedType("Windows.UI.Xaml.Interop", "NotifyCollectionChangedEventArgs", "Windows.UI.Xaml") }, + { "System.Collections.Specialized.NotifyCollectionChangedEventHandler", new MappedType("Windows.UI.Xaml.Interop", "NotifyCollectionChangedEventHandler", "Windows.UI.Xaml") }, + { "WinRT.EventRegistrationToken", new MappedType("Windows.Foundation", "EventRegistrationToken", "Windows.Foundation.FoundationContract", true, true) }, + { "System.AttributeTargets", new MappedType("Windows.Foundation.Metadata", "AttributeTargets", "Windows.Foundation.FoundationContract", true, true) }, + { "System.AttributeUsageAttribute", new MappedType("Windows.Foundation.Metadata", "AttributeUsageAttribute", "Windows.Foundation.FoundationContract") }, + { "System.Numerics.Matrix3x2", new MappedType("Windows.Foundation.Numerics", "Matrix3x2", "Windows.Foundation.FoundationContract", true, true) }, + { "System.Numerics.Matrix4x4", new MappedType("Windows.Foundation.Numerics", "Matrix4x4", "Windows.Foundation.FoundationContract", true, true) }, + { "System.Numerics.Plane", new MappedType("Windows.Foundation.Numerics", "Plane", "Windows.Foundation.FoundationContract", true, true) }, + { "System.Numerics.Quaternion", new MappedType("Windows.Foundation.Numerics", "Quaternion", "Windows.Foundation.FoundationContract", true, true) }, + { "System.Numerics.Vector2", new MappedType("Windows.Foundation.Numerics", "Vector2", "Windows.Foundation.FoundationContract", true, true) }, + { "System.Numerics.Vector3", new MappedType("Windows.Foundation.Numerics", "Vector3", "Windows.Foundation.FoundationContract", true, true) }, + { "System.Numerics.Vector4", new MappedType("Windows.Foundation.Numerics", "Vector4", "Windows.Foundation.FoundationContract", true, true) }, + { "System.Type", new MappedType(GetSystemTypeCustomMapping) }, + { "System.Collections.Generic.IEnumerable`1", new MappedType("Windows.Foundation.Collections", "IIterable`1", "Windows.Foundation.FoundationContract") }, + { "System.Collections.Generic.IEnumerator`1", new MappedType("Windows.Foundation.Collections", "IIterator`1", "Windows.Foundation.FoundationContract") }, + { "System.Collections.Generic.KeyValuePair`2", new MappedType("Windows.Foundation.Collections", "IKeyValuePair`2", "Windows.Foundation.FoundationContract") }, + { "System.Collections.Generic.IReadOnlyDictionary`2", new MappedType("Windows.Foundation.Collections", "IMapView`2", "Windows.Foundation.FoundationContract") }, + { "System.Collections.Generic.IDictionary`2", new MappedType("Windows.Foundation.Collections", "IMap`2", "Windows.Foundation.FoundationContract") }, + { "System.Collections.Generic.IReadOnlyList`1", new MappedType("Windows.Foundation.Collections", "IVectorView`1", "Windows.Foundation.FoundationContract") }, + { "System.Collections.Generic.IList`1", new MappedType("Windows.Foundation.Collections", "IVector`1", "Windows.Foundation.FoundationContract") }, + { "Windows.UI.Color", new MappedType("Windows.UI", "Color", "Windows.Foundation.UniversalApiContract", true, true) }, + }; + } + else + { + typeMapping = new(StringComparer.Ordinal) + { + { "System.DateTimeOffset", new MappedType("Windows.Foundation", "DateTime", "Windows.Foundation.FoundationContract", true, false) }, + { "System.Exception", new MappedType("Windows.Foundation", "HResult", "Windows.Foundation.FoundationContract", true, false) }, + { "System.EventHandler`1", new MappedType("Windows.Foundation", "EventHandler`1", "Windows.Foundation.FoundationContract") }, + { "System.FlagsAttribute", new MappedType("System", "FlagsAttribute", "mscorlib" ) }, + { "System.IDisposable", new MappedType("Windows.Foundation", "IClosable", "Windows.Foundation.FoundationContract") }, + { "System.IServiceProvider", new MappedType("Microsoft.UI.Xaml", "IXamlServiceProvider", "Microsoft.UI") }, + { "System.Nullable`1", new MappedType("Windows.Foundation", "IReference`1", "Windows.Foundation.FoundationContract" ) }, + { "System.Object", new MappedType("System", "Object", "mscorlib" ) }, + { "System.TimeSpan", new MappedType("Windows.Foundation", "TimeSpan", "Windows.Foundation.FoundationContract", true, false) }, + { "System.Uri", new MappedType("Windows.Foundation", "Uri", "Windows.Foundation.FoundationContract") }, + { "System.ComponentModel.DataErrorsChangedEventArgs", new MappedType("Microsoft.UI.Xaml.Data", "DataErrorsChangedEventArgs", "Microsoft.UI") }, + { "System.ComponentModel.INotifyDataErrorInfo", new MappedType("Microsoft.UI.Xaml.Data", "INotifyDataErrorInfo", "Microsoft.UI") }, + { "System.ComponentModel.INotifyPropertyChanged", new MappedType("Microsoft.UI.Xaml.Data", "INotifyPropertyChanged", "Microsoft.UI") }, + { "System.ComponentModel.PropertyChangedEventArgs", new MappedType("Microsoft.UI.Xaml.Data", "PropertyChangedEventArgs", "Microsoft.UI") }, + { "System.ComponentModel.PropertyChangedEventHandler", new MappedType("Microsoft.UI.Xaml.Data", "PropertyChangedEventHandler", "Microsoft.UI") }, + { "System.Windows.Input.ICommand", new MappedType("Microsoft.UI.Xaml.Input", "ICommand", "Microsoft.UI") }, + { "System.Collections.IEnumerable", new MappedType("Microsoft.UI.Xaml.Interop", "IBindableIterable", "Microsoft.UI") }, + { "System.Collections.IList", new MappedType("Microsoft.UI.Xaml.Interop", "IBindableVector", "Microsoft.UI") }, + { "System.Collections.Specialized.INotifyCollectionChanged", new MappedType("Microsoft.UI.Xaml.Interop", "INotifyCollectionChanged", "Microsoft.UI") }, + { "System.Collections.Specialized.NotifyCollectionChangedAction", new MappedType("Microsoft.UI.Xaml.Interop", "NotifyCollectionChangedAction", "Microsoft.UI") }, + { "System.Collections.Specialized.NotifyCollectionChangedEventArgs", new MappedType("Microsoft.UI.Xaml.Interop", "NotifyCollectionChangedEventArgs", "Microsoft.UI") }, + { "System.Collections.Specialized.NotifyCollectionChangedEventHandler", new MappedType("Microsoft.UI.Xaml.Interop", "NotifyCollectionChangedEventHandler", "Microsoft.UI") }, + { "WinRT.EventRegistrationToken", new MappedType("Windows.Foundation", "EventRegistrationToken", "Windows.Foundation.FoundationContract", true, true) }, + { "System.AttributeTargets", new MappedType("Windows.Foundation.Metadata", "AttributeTargets", "Windows.Foundation.FoundationContract", true, true) }, + { "System.AttributeUsageAttribute", new MappedType("Windows.Foundation.Metadata", "AttributeUsageAttribute", "Windows.Foundation.FoundationContract") }, + { "System.Numerics.Matrix3x2", new MappedType("Windows.Foundation.Numerics", "Matrix3x2", "Windows.Foundation.FoundationContract", true, true) }, + { "System.Numerics.Matrix4x4", new MappedType("Windows.Foundation.Numerics", "Matrix4x4", "Windows.Foundation.FoundationContract", true, true) }, + { "System.Numerics.Plane", new MappedType("Windows.Foundation.Numerics", "Plane", "Windows.Foundation.FoundationContract", true, true) }, + { "System.Numerics.Quaternion", new MappedType("Windows.Foundation.Numerics", "Quaternion", "Windows.Foundation.FoundationContract", true, true) }, + { "System.Numerics.Vector2", new MappedType("Windows.Foundation.Numerics", "Vector2", "Windows.Foundation.FoundationContract", true, true) }, + { "System.Numerics.Vector3", new MappedType("Windows.Foundation.Numerics", "Vector3", "Windows.Foundation.FoundationContract", true, true) }, + { "System.Numerics.Vector4", new MappedType("Windows.Foundation.Numerics", "Vector4", "Windows.Foundation.FoundationContract", true, true) }, + { "System.Type", new MappedType(GetSystemTypeCustomMapping) }, + { "System.Collections.Generic.IEnumerable`1", new MappedType("Windows.Foundation.Collections", "IIterable`1", "Windows.Foundation.FoundationContract") }, + { "System.Collections.Generic.IEnumerator`1", new MappedType("Windows.Foundation.Collections", "IIterator`1", "Windows.Foundation.FoundationContract") }, + { "System.Collections.Generic.KeyValuePair`2", new MappedType("Windows.Foundation.Collections", "IKeyValuePair`2", "Windows.Foundation.FoundationContract") }, + { "System.Collections.Generic.IReadOnlyDictionary`2", new MappedType("Windows.Foundation.Collections", "IMapView`2", "Windows.Foundation.FoundationContract") }, + { "System.Collections.Generic.IDictionary`2", new MappedType("Windows.Foundation.Collections", "IMap`2", "Windows.Foundation.FoundationContract") }, + { "System.Collections.Generic.IReadOnlyList`1", new MappedType("Windows.Foundation.Collections", "IVectorView`1", "Windows.Foundation.FoundationContract") }, + { "System.Collections.Generic.IList`1", new MappedType("Windows.Foundation.Collections", "IVector`1", "Windows.Foundation.FoundationContract") }, + { "Windows.UI.Color", new MappedType("Windows.UI", "Color", "Windows.Foundation.UniversalApiContract", true, true) }, + }; + } + } + + public bool HasMappingForType(string typeName) => typeMapping.ContainsKey(typeName); + + public MappedType GetMappedType(string typeName) => typeMapping[typeName]; + } +} diff --git a/src/Authoring/WinRT.SourceGenerator/UiXamlMode.cs b/src/Authoring/WinRT.SourceGenerator/UiXamlMode.cs new file mode 100644 index 000000000..7432a1075 --- /dev/null +++ b/src/Authoring/WinRT.SourceGenerator/UiXamlMode.cs @@ -0,0 +1,26 @@ +using Microsoft.CodeAnalysis.Diagnostics; +using System; +using System.Collections.Generic; +using System.Text; + +namespace Generator +{ + internal enum UiXamlMode + { + MicrosoftUiXaml, + WindowsUiXaml, + } + + internal static class OptionsHelper + { + public static UiXamlMode GetUiXamlMode(this AnalyzerConfigOptions options) + { + if (options.TryGetValue("build_property.CsWinRTUiXamlMode", out var value) && Enum.TryParse(value, out UiXamlMode mode)) + { + return mode; + } + + return UiXamlMode.MicrosoftUiXaml; + } + } +} diff --git a/src/Authoring/WinRT.SourceGenerator/WinRTTypeWriter.cs b/src/Authoring/WinRT.SourceGenerator/WinRTTypeWriter.cs index 9e33c92c6..d2ef2cc11 100644 --- a/src/Authoring/WinRT.SourceGenerator/WinRTTypeWriter.cs +++ b/src/Authoring/WinRT.SourceGenerator/WinRTTypeWriter.cs @@ -265,7 +265,7 @@ class WinRTTypeWriter : CSharpSyntaxWalker private readonly Dictionary typeReferenceMapping; private readonly Dictionary assemblyReferenceMapping; private readonly MetadataBuilder metadataBuilder; - + private readonly TypeMapper mapper; private readonly Dictionary typeDefinitionMapping; private TypeDeclaration currentTypeDeclaration; @@ -275,12 +275,14 @@ public WinRTTypeWriter( string assembly, string version, MetadataBuilder metadataBuilder, - Logger logger) + Logger logger, + TypeMapper mapper) { this.assembly = assembly; this.version = version; this.metadataBuilder = metadataBuilder; Logger = logger; + this.mapper = mapper; typeReferenceMapping = new Dictionary(StringComparer.Ordinal); assemblyReferenceMapping = new Dictionary(StringComparer.Ordinal); typeDefinitionMapping = new Dictionary(StringComparer.Ordinal); @@ -435,9 +437,9 @@ private EntityHandle GetTypeReference(ISymbol symbol) var assembly = GetAssemblyForWinRTType(symbol); if (assembly == null) { - if (GeneratorHelper.MappedCSharpTypes.ContainsKey(fullType)) + if (mapper.HasMappingForType(fullType)) { - (@namespace, name, assembly, _, _) = GeneratorHelper.MappedCSharpTypes[fullType].GetMapping(currentTypeDeclaration.Node); + (@namespace, name, assembly, _, _) = mapper.GetMappedType(fullType).GetMapping(currentTypeDeclaration.Node); Logger.Log("custom mapping " + fullType + " to " + QualifiedName(@namespace, name) + " from " + assembly); } else @@ -520,9 +522,9 @@ private void EncodeSymbol(Symbol symbol, SignatureTypeEncoder typeEncoder) else { bool isValueType = symbol.Type.TypeKind == TypeKind.Enum || symbol.Type.TypeKind == TypeKind.Struct; - if (GeneratorHelper.MappedCSharpTypes.ContainsKey(QualifiedName(symbol.Type))) + if (mapper.HasMappingForType(QualifiedName(symbol.Type))) { - (_, _, _, _, isValueType) = GeneratorHelper.MappedCSharpTypes[QualifiedName(symbol.Type)].GetMapping(currentTypeDeclaration.Node); + (_, _, _, _, isValueType) = mapper.GetMappedType(QualifiedName(symbol.Type)).GetMapping(currentTypeDeclaration.Node); } typeEncoder.Type(GetTypeReference(symbol.Type), isValueType); } @@ -804,7 +806,7 @@ private void ProcessCustomMappedInterfaces(INamedTypeSymbol classSymbol) // Mark custom mapped interface members for removal later. // Note we want to also mark members from interfaces without mappings. foreach (var implementedInterface in GetInterfaces(classSymbol, true). - Where(symbol => GeneratorHelper.MappedCSharpTypes.ContainsKey(QualifiedName(symbol)) || + Where(symbol => mapper.HasMappingForType(QualifiedName(symbol)) || ImplementedInterfacesWithoutMapping.Contains(QualifiedName(symbol)))) { bool isPubliclyImplemented = false; @@ -825,7 +827,7 @@ private void ProcessCustomMappedInterfaces(INamedTypeSymbol classSymbol) } foreach (var implementedInterface in GetInterfaces(classSymbol) - .Where(symbol => GeneratorHelper.MappedCSharpTypes.ContainsKey(QualifiedName(symbol)))) + .Where(symbol => mapper.HasMappingForType(QualifiedName(symbol)))) { WriteCustomMappedTypeMembers(implementedInterface, true, isPublicImplementation[implementedInterface]); } @@ -853,9 +855,9 @@ INamedTypeSymbol GetTypeByMetadataName(string metadataName) private string GetMappedQualifiedTypeName(ITypeSymbol symbol) { string qualifiedName = QualifiedName(symbol); - if (GeneratorHelper.MappedCSharpTypes.ContainsKey(qualifiedName)) + if (mapper.HasMappingForType(qualifiedName)) { - var (@namespace, mappedTypeName, _, _, _) = GeneratorHelper.MappedCSharpTypes[qualifiedName].GetMapping(currentTypeDeclaration.Node); + var (@namespace, mappedTypeName, _, _, _) = mapper.GetMappedType(qualifiedName).GetMapping(currentTypeDeclaration.Node); qualifiedName = QualifiedName(@namespace, mappedTypeName); if (symbol is INamedTypeSymbol namedType && namedType.TypeArguments.Length > 0) { @@ -874,7 +876,7 @@ private string GetMappedQualifiedTypeName(ITypeSymbol symbol) private void WriteCustomMappedTypeMembers(INamedTypeSymbol symbol, bool isDefinition, bool isPublic = true) { - var (_, mappedTypeName, _, _, _) = GeneratorHelper.MappedCSharpTypes[QualifiedName(symbol)].GetMapping(currentTypeDeclaration.Node); + var (_, mappedTypeName, _, _, _) = mapper.GetMappedType(QualifiedName(symbol)).GetMapping(currentTypeDeclaration.Node); string qualifiedName = GetMappedQualifiedTypeName(symbol); Logger.Log("writing custom mapped type members for " + mappedTypeName + " public: " + isPublic + " qualified name: " + qualifiedName); @@ -1233,7 +1235,7 @@ void GatherPubliclyAccessibleInterfaces(ITypeSymbol symbol) GatherPubliclyAccessibleInterfaces(symbol); var baseType = symbol.BaseType; - while (baseType != null && !GeneratorHelper.IsWinRTType(baseType)) + while (baseType != null && !GeneratorHelper.IsWinRTType(baseType, mapper)) { GatherPubliclyAccessibleInterfaces(baseType); @@ -2438,9 +2440,9 @@ void AddType(INamedTypeSymbol type, bool treatAsProjectedType = false) { AddProjectedType(type); } - else if (GeneratorHelper.MappedCSharpTypes.ContainsKey(qualifiedName)) + else if (mapper.HasMappingForType(qualifiedName)) { - var (@namespace, name, assembly, isSystemType, _) = GeneratorHelper.MappedCSharpTypes[qualifiedName].GetMapping(); + var (@namespace, name, assembly, isSystemType, _) = mapper.GetMappedType(qualifiedName).GetMapping(); if (isSystemType) { var projectedType = Model.Compilation.GetTypeByMetadataName(QualifiedName(@namespace, name)); @@ -2532,7 +2534,7 @@ public void FinalizeGeneration() Logger.Log("finalizing interface " + implementedInterfaceQualifiedNameWithGenerics); var interfaceTypeDeclaration = typeDefinitionMapping[implementedInterfaceQualifiedNameWithGenerics]; - if (GeneratorHelper.MappedCSharpTypes.ContainsKey(QualifiedName(implementedInterface))) + if (mapper.HasMappingForType(QualifiedName(implementedInterface))) { Logger.Log("adding MethodImpls for custom mapped interface"); foreach (var interfaceMember in interfaceTypeDeclaration.MethodReferences) @@ -2663,11 +2665,11 @@ public void FinalizeGeneration() public void GenerateWinRTExposedClassAttributes(GeneratorExecutionContext context) { - bool IsWinRTType(ISymbol symbol) + bool IsWinRTType(ISymbol symbol, TypeMapper mapper) { if (!SymbolEqualityComparer.Default.Equals(symbol.ContainingAssembly, context.Compilation.Assembly)) { - return GeneratorHelper.IsWinRTType(symbol, IsWinRTType); + return GeneratorHelper.IsWinRTType(symbol, mapper, symbol => IsWinRTType(symbol, mapper)); } if (symbol is INamedTypeSymbol namedType) @@ -2701,8 +2703,8 @@ typeDeclaration.Node is INamedTypeSymbol symbol && symbol.TypeKind == TypeKind.Class && !symbol.IsStatic) { - vtableAttributesToAdd.Add(WinRTAotSourceGenerator.GetVtableAttributeToAdd(symbol, IsWinRTType, context.Compilation.Assembly, true, typeDeclaration.DefaultInterface)); - WinRTAotSourceGenerator.AddVtableAdapterTypeForKnownInterface(symbol, context.Compilation, IsWinRTType, vtableAttributesToAddOnLookupTable); + vtableAttributesToAdd.Add(WinRTAotSourceGenerator.GetVtableAttributeToAdd(symbol, IsWinRTType, mapper, context.Compilation.Assembly, true, typeDeclaration.DefaultInterface)); + WinRTAotSourceGenerator.AddVtableAdapterTypeForKnownInterface(symbol, context.Compilation, IsWinRTType, mapper, vtableAttributesToAddOnLookupTable); } } diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 5a1370dc5..caef79a59 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -30,6 +30,8 @@ netcoreapp3.1;net6.0;net8.0 netstandard2.0;net6.0;net8.0 netstandard2.0;net6.0;net8.0 + net6.0;net8.0 + net6.0;net8.0 net6.0-windows10.0.19041.0;net7.0-windows10.0.19041.0 net6.0-windows10.0.19041.0 net6.0;net8.0 diff --git a/src/Perf/IIDOptimizer/GuidPatcher.cs b/src/Perf/IIDOptimizer/GuidPatcher.cs index bd200dfd6..411b855fa 100644 --- a/src/Perf/IIDOptimizer/GuidPatcher.cs +++ b/src/Perf/IIDOptimizer/GuidPatcher.cs @@ -72,12 +72,14 @@ public GuidPatcher(AssemblyDefinition winRTRuntime, AssemblyDefinition targetAss guidGeneratorType = null; TypeDefinition? typeExtensionsType = null; + TypeDefinition? wuxMuxProjectedInterfaceAttributeType = null; // Use the type definition if we are patching WinRT.Runtime, otherwise lookup the types as references if (string.CompareOrdinal(assembly.Name.Name, "WinRT.Runtime") == 0) { - guidGeneratorType = winRTRuntimeAssembly.MainModule.Types.Where(typeDef => string.CompareOrdinal(typeDef.Name, "GuidGenerator") == 0).First(); - typeExtensionsType = winRTRuntimeAssembly.MainModule.Types.Where(typeDef => string.CompareOrdinal(typeDef.Name, "TypeExtensions") == 0).First(); + guidGeneratorType = winRTRuntimeAssembly.MainModule.Types.Where(typeDef => string.Equals(typeDef.Name, "GuidGenerator", StringComparison.Ordinal)).First(); + typeExtensionsType = winRTRuntimeAssembly.MainModule.Types.Where(typeDef => string.Equals(typeDef.Name, "TypeExtensions", StringComparison.Ordinal)).First(); + wuxMuxProjectedInterfaceAttributeType = winRTRuntimeAssembly.MainModule.Types.Where(typedef => string.Equals(typedef.Name, "WuxMuxProjectedInterfaceAttribute", StringComparison.Ordinal)).First(); } foreach (var asm in assembly.MainModule.AssemblyReferences) @@ -87,6 +89,7 @@ public GuidPatcher(AssemblyDefinition winRTRuntime, AssemblyDefinition targetAss guidGeneratorType = new TypeReference("WinRT", "GuidGenerator", assembly.MainModule, asm).Resolve(); typeExtensionsType = new TypeReference("WinRT", "TypeExtensions", assembly.MainModule, asm).Resolve(); + wuxMuxProjectedInterfaceAttributeType = new TypeReference("WinRT", "WuxMuxProjectedInterfaceAttribute", assembly.MainModule, asm).Resolve(); } else if (string.CompareOrdinal(asm.Name, "System.Runtime.InteropServices") == 0) { @@ -101,7 +104,7 @@ public GuidPatcher(AssemblyDefinition winRTRuntime, AssemblyDefinition targetAss getHelperTypeMethod = typeExtensionsType.Methods.First(m => String.CompareOrdinal(m.Name, "GetHelperType") == 0); } - signatureGenerator = new SignatureGenerator(assembly, guidAttributeType!, winRTRuntimeAssembly); + signatureGenerator = new SignatureGenerator(assembly, guidAttributeType!, wuxMuxProjectedInterfaceAttributeType!, winRTRuntimeAssembly); methodCache = new Dictionary(); } @@ -262,6 +265,11 @@ private void VisitSignature(SignaturePart rootSignaturePart, SignatureEmitter em emitter.PushCustomSignature(custom.Method); } break; + case GenericFallback fallback: + { + emitter.PushFallback(fallback.Type); + } + break; default: break; } diff --git a/src/Perf/IIDOptimizer/SignatureEmitter.cs b/src/Perf/IIDOptimizer/SignatureEmitter.cs index aa3d6a393..3483105d8 100644 --- a/src/Perf/IIDOptimizer/SignatureEmitter.cs +++ b/src/Perf/IIDOptimizer/SignatureEmitter.cs @@ -35,6 +35,8 @@ sealed record RuntimeGenericSignatureStep(GenericParameter OriginalTypeParameter sealed record RuntimeCustomSignatureStep(MethodReference method) : SignatureStep; + sealed record FallbackSignatureStep(TypeReference type) : SignatureStep; + public SignatureEmitter(TypeReference describedType, MethodDefinition guidDataGetterMethod) { this.describedType = describedType; @@ -76,6 +78,16 @@ public void PushCustomSignature(MethodReference customSignatureMethod) signatureSteps.Add(new RuntimeCustomSignatureStep(customSignatureMethod)); } + public void PushFallback(TypeReference type) + { + if (currentStringBuilder is not null) + { + signatureSteps.Add(new StringStep(currentStringBuilder.ToString())); + currentStringBuilder = null; + } + signatureSteps.Add(new FallbackSignatureStep(type)); + } + public void EmitGuidGetter( TypeDefinition guidDataBlockType, TypeDefinition implementationDetailsType, @@ -289,6 +301,25 @@ private void GenerateGuidFactoryFromComplexSignature(TypeDefinition implementati il.Emit(OpCodes.Stloc, fullSignatureLength); } break; + case FallbackSignatureStep(TypeReference type): + { + // byte[] bytes = Encoding.UTF8.GetBytes(GetSignature(typeof(type))) + il.Emit(OpCodes.Call, utf8EncodingGetter); + il.Emit(OpCodes.Ldtoken, type); + il.Emit(OpCodes.Call, getTypeFromHandleMethod); + il.Emit(OpCodes.Call, getSignatureMethod); + il.Emit(OpCodes.Callvirt, encodingGetBytes); + il.Emit(OpCodes.Dup); + // = new ReadOnlySpan(bytes); + il.Emit(OpCodes.Newobj, readOnlySpanOfByteArrayCtor); + il.Emit(OpCodes.Stloc, signatureParts[i]); + // signatureLength += bytes.Length + il.Emit(OpCodes.Ldlen); + il.Emit(OpCodes.Ldloc, fullSignatureLength); + il.Emit(OpCodes.Add_Ovf); + il.Emit(OpCodes.Stloc, fullSignatureLength); + } + break; default: il.Clear(); throw new InvalidOperationException(); diff --git a/src/Perf/IIDOptimizer/SignatureGenerator.cs b/src/Perf/IIDOptimizer/SignatureGenerator.cs index 7c6fd6282..67b2c2be3 100644 --- a/src/Perf/IIDOptimizer/SignatureGenerator.cs +++ b/src/Perf/IIDOptimizer/SignatureGenerator.cs @@ -37,6 +37,8 @@ sealed record NonGenericDelegateSignature(Guid DelegateIID) : SignaturePart; sealed record UninstantiatedGeneric(GenericParameter OriginalGenericParameter) : SignaturePart; + sealed record GenericFallback(TypeReference Type) : SignaturePart; + abstract record SignatureWithChildren(string GroupingName, string ThisEntitySignature, IEnumerable ChildrenSignatures) : SignaturePart; sealed record GenericSignature(Guid BaseGuid, IEnumerable GenericMemberSignatures) : @@ -55,12 +57,14 @@ sealed class SignatureGenerator { private readonly AssemblyDefinition assembly; private readonly TypeDefinition guidAttributeType; + private readonly TypeDefinition wuxMuxProjectedInterfaceAttributeType; private readonly AssemblyDefinition winRTRuntimeAssembly; - public SignatureGenerator(AssemblyDefinition assembly, TypeDefinition guidAttributeType, AssemblyDefinition runtimeAssembly) + public SignatureGenerator(AssemblyDefinition assembly, TypeDefinition guidAttributeType, TypeDefinition wuxMuxProjectedInterfaceAttributeType, AssemblyDefinition runtimeAssembly) { this.assembly = assembly; this.guidAttributeType = guidAttributeType; + this.wuxMuxProjectedInterfaceAttributeType = wuxMuxProjectedInterfaceAttributeType; this.winRTRuntimeAssembly = runtimeAssembly; } @@ -170,6 +174,13 @@ public SignaturePart GetSignatureParts(TypeReference type) return new RuntimeClassSignature(type, GetSignatureParts(iface)); } + // For types projected from WUX or MUX into .NET, we'll need to do a runtime lookup for the IID. + // TODO-WuxMux: We can instead take an option in the IID optimizer to hard-code the lookup for WUX or MUX when specified, which would be more efficient for scenarios where this is possible. + if (helperType?.Resolve().CustomAttributes.Any(attr => attr.AttributeType.Resolve() == wuxMuxProjectedInterfaceAttributeType) == true) + { + return new GenericFallback(type); + } + Guid? guidAttributeValue = type.ReadGuidFromAttribute(guidAttributeType, winRTRuntimeAssembly); if (guidAttributeValue == null) { diff --git a/src/Projections/Windows.UI.Xaml/Module.cs b/src/Projections/Windows.UI.Xaml/Module.cs new file mode 100644 index 000000000..636144eed --- /dev/null +++ b/src/Projections/Windows.UI.Xaml/Module.cs @@ -0,0 +1,3 @@ +#if NET +[assembly: global::System.Runtime.Versioning.SupportedOSPlatform("Windows")] +#endif diff --git a/src/Projections/Windows.UI.Xaml/Windows.UI.Xaml.csproj b/src/Projections/Windows.UI.Xaml/Windows.UI.Xaml.csproj new file mode 100644 index 000000000..d28f78380 --- /dev/null +++ b/src/Projections/Windows.UI.Xaml/Windows.UI.Xaml.csproj @@ -0,0 +1,28 @@ + + + + $(LibBuildTFMsNoNetStandard) + x64;x86 + Microsoft.Windows.UI.Xaml + true + + + + + + + + + + + + +-exclude Windows +-include Windows.UI.Xaml +-exclude Windows.UI.Xaml.Media.Animation.ConditionallyIndependentlyAnimatableAttribute +-exclude Windows.UI.Xaml.Media.Animation.KeyTime +-exclude Windows.UI.Xaml.Media.Animation.RepeatBehavior + + + + \ No newline at end of file diff --git a/src/Tests/AuthoringWuxConsumptionTest/AuthoringWuxConsumptionTest.exe.manifest b/src/Tests/AuthoringWuxConsumptionTest/AuthoringWuxConsumptionTest.exe.manifest new file mode 100644 index 000000000..3d69fa84a --- /dev/null +++ b/src/Tests/AuthoringWuxConsumptionTest/AuthoringWuxConsumptionTest.exe.manifest @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Tests/AuthoringWuxConsumptionTest/AuthoringWuxConsumptionTest.vcxproj b/src/Tests/AuthoringWuxConsumptionTest/AuthoringWuxConsumptionTest.vcxproj new file mode 100644 index 000000000..64c641b2f --- /dev/null +++ b/src/Tests/AuthoringWuxConsumptionTest/AuthoringWuxConsumptionTest.vcxproj @@ -0,0 +1,212 @@ + + + + + + + Debug + ARM64 + + + Debug + Win32 + + + Release + ARM64 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + {A04A0416-5E35-4DD0-8226-63D941B28467} + Win32Proj + AuthoringConsumptionTest + Application + v143 + v142 + Unicode + <_WinMDPlatform>$(Platform) + <_WinMDPlatform Condition="'$(Platform)' == 'Win32'">x86 + false + + + + + + + + + + + + + + Create + + + + + + + + true + true + true + true + + + + + {ffa9a78b-f53f-43ee-af87-24a80f4c330a} + TargetFramework=net6.0 + + + {0bb8f82d-874e-45aa-bca3-20ce0562164a} + TargetFramework=net6.0 + + + {7e33bcb7-19c5-4061-981d-ba695322708a} + + + {25244ced-966e-45f2-9711-1f51e951ff89} + TargetFramework=net6.0 + + + {d60cfcad-4a13-4047-91c8-9d7df4753493} + TargetFramework=net6.0 + + + + + ..\AuthoringWuxTest\bin\$(_WinMDPlatform)\$(Configuration)\net6.0\AuthoringWuxTest.winmd + true + + + + + + + + + + + + + + + Use + pch.h + Disabled + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + Level3 + + + true + Console + + + + + Use + pch.h + Disabled + X64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + Level3 + + + DebugFull + Console + + + + + Use + pch.h + Disabled + X64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + Level3 + + + DebugFull + Console + + + + + Use + pch.h + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + MultiThreadedDLL + Level3 + ProgramDatabase + + + true + Console + true + true + + + + + Use + pch.h + X64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + MultiThreadedDLL + Level3 + ProgramDatabase + + + true + Console + true + true + + + + + Use + pch.h + X64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + MultiThreadedDLL + Level3 + ProgramDatabase + + + true + Console + true + true + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + + + + + + \ No newline at end of file diff --git a/src/Tests/AuthoringWuxConsumptionTest/AuthoringWuxConsumptionTest.vcxproj.filters b/src/Tests/AuthoringWuxConsumptionTest/AuthoringWuxConsumptionTest.vcxproj.filters new file mode 100644 index 000000000..1332cff35 --- /dev/null +++ b/src/Tests/AuthoringWuxConsumptionTest/AuthoringWuxConsumptionTest.vcxproj.filters @@ -0,0 +1,39 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Header Files + + + + + Source Files + + + Source Files + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Tests/AuthoringWuxConsumptionTest/Directory.Build.targets b/src/Tests/AuthoringWuxConsumptionTest/Directory.Build.targets new file mode 100644 index 000000000..623267b30 --- /dev/null +++ b/src/Tests/AuthoringWuxConsumptionTest/Directory.Build.targets @@ -0,0 +1,16 @@ + + + + $(MSBuildProjectDirectory)/DoNotImport_MsAppxPackageTargets.targets + CopyTestAssets;$(PrepareForRunDependsOn) + + + + + + + + + diff --git a/src/Tests/AuthoringWuxConsumptionTest/DoNotImport_MsAppxPackageTargets.targets b/src/Tests/AuthoringWuxConsumptionTest/DoNotImport_MsAppxPackageTargets.targets new file mode 100644 index 000000000..bcb335b80 --- /dev/null +++ b/src/Tests/AuthoringWuxConsumptionTest/DoNotImport_MsAppxPackageTargets.targets @@ -0,0 +1,5 @@ + + + + + diff --git a/src/Tests/AuthoringWuxConsumptionTest/WinRT.Host.runtimeconfig.json b/src/Tests/AuthoringWuxConsumptionTest/WinRT.Host.runtimeconfig.json new file mode 100644 index 000000000..89437eff9 --- /dev/null +++ b/src/Tests/AuthoringWuxConsumptionTest/WinRT.Host.runtimeconfig.json @@ -0,0 +1,13 @@ +{ + "runtimeOptions": { + "tfm": "net6.0", + "rollForward": "LatestMinor", + "framework": { + "name": "Microsoft.NETCore.App", + "version": "6.0.0" + }, + "configProperties": { + "CsWinRT.UiXamlMode": "WindowsUiXaml" + } + } +} \ No newline at end of file diff --git a/src/Tests/AuthoringWuxConsumptionTest/packages.config b/src/Tests/AuthoringWuxConsumptionTest/packages.config new file mode 100644 index 000000000..98b40a750 --- /dev/null +++ b/src/Tests/AuthoringWuxConsumptionTest/packages.config @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/src/Tests/AuthoringWuxConsumptionTest/pch.cpp b/src/Tests/AuthoringWuxConsumptionTest/pch.cpp new file mode 100644 index 000000000..bcb5590be --- /dev/null +++ b/src/Tests/AuthoringWuxConsumptionTest/pch.cpp @@ -0,0 +1 @@ +#include "pch.h" diff --git a/src/Tests/AuthoringWuxConsumptionTest/pch.h b/src/Tests/AuthoringWuxConsumptionTest/pch.h new file mode 100644 index 000000000..db3c5d270 --- /dev/null +++ b/src/Tests/AuthoringWuxConsumptionTest/pch.h @@ -0,0 +1,26 @@ +#pragma once + +// Undefine GetCurrentTime macro to prevent +// conflict with Storyboard::GetCurrentTime +#undef GetCurrentTime + +#include +#include +#include + +#pragma push_macro("X86") +#pragma push_macro("X64") +#undef X86 +#undef X64 +#include "winrt/Windows.System.h" +#pragma pop_macro("X64") +#pragma pop_macro("X86") + +#include +#include +#include +#include + +#include + +#include "gtest/gtest.h" diff --git a/src/Tests/AuthoringWuxConsumptionTest/test.cpp b/src/Tests/AuthoringWuxConsumptionTest/test.cpp new file mode 100644 index 000000000..b182b935c --- /dev/null +++ b/src/Tests/AuthoringWuxConsumptionTest/test.cpp @@ -0,0 +1,75 @@ +#include "pch.h" + +using namespace winrt; +using namespace Windows::Foundation; +using namespace AuthoringWuxTest; + +TEST(AuthoringWuxTest, Collections) +{ + DisposableClass disposed; + disposed.Close(); + MultipleInterfaceMappingClass multipleInterfaces; + Windows::UI::Xaml::Interop::IBindableIterable bindable = multipleInterfaces; + Windows::Foundation::Collections::IVector vector = multipleInterfaces; + Windows::UI::Xaml::Interop::IBindableVector bindableVector = multipleInterfaces; + EXPECT_EQ(vector.Size(), 0); + EXPECT_EQ(bindableVector.Size(), 0); + vector.Append(DisposableClass()); + vector.Append(DisposableClass()); + vector.Append(disposed); + bindableVector.Append(DisposableClass()); + EXPECT_EQ(vector.Size(), 4); + EXPECT_EQ(bindableVector.Size(), 4); + + auto first = vector.First(); + EXPECT_TRUE(first.HasCurrent()); + EXPECT_FALSE(first.Current().IsDisposed()); + auto bindableFirst = bindable.First(); + EXPECT_TRUE(bindableFirst.HasCurrent()); + EXPECT_FALSE(bindableFirst.Current().as().IsDisposed()); + bindableFirst.Current().as().Close(); + EXPECT_TRUE(first.Current().IsDisposed()); + EXPECT_FALSE(vector.GetAt(1).IsDisposed()); + EXPECT_TRUE(vector.GetAt(2).IsDisposed()); + EXPECT_TRUE(bindableVector.First().Current().as().IsDisposed()); + EXPECT_FALSE(bindableVector.GetAt(3).as().IsDisposed()); + EXPECT_TRUE(bindableVector.GetAt(2).as().IsDisposed()); + for (auto obj : vector.GetView()) + { + obj.Close(); + } + + std::array view{}; + EXPECT_EQ(vector.GetMany(1, view), 2); + EXPECT_EQ(view.size(), 2); + for (auto& obj : view) + { + EXPECT_TRUE(obj.IsDisposed()); + } +} + +TEST(AuthoringWuxTest, PropertyChanged) +{ + CustomNotifyPropertyChanged customNotifyPropertyChanged; + Windows::UI::Xaml::Data::INotifyPropertyChanged propChanged = customNotifyPropertyChanged; + winrt::hstring propName = L"Number"; + bool eventTriggered = false; + auto token = propChanged.PropertyChanged(auto_revoke, [&eventTriggered, &propName](IInspectable sender, Windows::UI::Xaml::Data::PropertyChangedEventArgs args) + { + eventTriggered = (args.PropertyName() == propName); + }); + + customNotifyPropertyChanged.RaisePropertyChanged(propName); + + EXPECT_TRUE(eventTriggered); +} + +int main(int argc, char** argv) +{ + ::testing::InitGoogleTest(&argc, argv); + winrt::init_apartment(winrt::apartment_type::single_threaded); + auto manager = winrt::Windows::UI::Xaml::Hosting::WindowsXamlManager::InitializeForCurrentThread(); + int result = RUN_ALL_TESTS(); + manager.Close(); + return result; +} \ No newline at end of file diff --git a/src/Tests/AuthoringWuxTest/AuthoringWuxTest.csproj b/src/Tests/AuthoringWuxTest/AuthoringWuxTest.csproj new file mode 100644 index 000000000..a00cb2c58 --- /dev/null +++ b/src/Tests/AuthoringWuxTest/AuthoringWuxTest.csproj @@ -0,0 +1,22 @@ + + + + net6.0 + x64;x86 + true + true + WindowsUiXaml + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Tests/AuthoringWuxTest/Directory.Build.props b/src/Tests/AuthoringWuxTest/Directory.Build.props new file mode 100644 index 000000000..4cf186e3d --- /dev/null +++ b/src/Tests/AuthoringWuxTest/Directory.Build.props @@ -0,0 +1,9 @@ + + + + true + + + + + diff --git a/src/Tests/AuthoringWuxTest/Directory.Build.targets b/src/Tests/AuthoringWuxTest/Directory.Build.targets new file mode 100644 index 000000000..8dde12d1b --- /dev/null +++ b/src/Tests/AuthoringWuxTest/Directory.Build.targets @@ -0,0 +1,5 @@ + + + + + diff --git a/src/Tests/AuthoringWuxTest/Module.cs b/src/Tests/AuthoringWuxTest/Module.cs new file mode 100644 index 000000000..636144eed --- /dev/null +++ b/src/Tests/AuthoringWuxTest/Module.cs @@ -0,0 +1,3 @@ +#if NET +[assembly: global::System.Runtime.Versioning.SupportedOSPlatform("Windows")] +#endif diff --git a/src/Tests/AuthoringWuxTest/Program.cs b/src/Tests/AuthoringWuxTest/Program.cs new file mode 100644 index 000000000..004a3cb23 --- /dev/null +++ b/src/Tests/AuthoringWuxTest/Program.cs @@ -0,0 +1,171 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.ComponentModel; + +#pragma warning disable CA1416 + +namespace AuthoringWuxTest +{ + public sealed class DisposableClass : IDisposable + { + public bool IsDisposed { get; set; } + + public DisposableClass() + { + IsDisposed = false; + } + + public void Dispose() + { + IsDisposed = true; + } + } + public sealed class CustomNotifyPropertyChanged : INotifyPropertyChanged + { + public event PropertyChangedEventHandler PropertyChanged; + + public void RaisePropertyChanged(string propertyName) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + } + + public sealed class CustomNotifyCollectionChanged : INotifyCollectionChanged + { + public event NotifyCollectionChangedEventHandler CollectionChanged; + + public void RaiseCollectionChanged(NotifyCollectionChangedEventArgs args) + { + CollectionChanged?.Invoke(this, args); + } + } + + public sealed class CustomEnumerable : IEnumerable + { + private IEnumerable _enumerable; + + public CustomEnumerable(IEnumerable enumerable) + { + _enumerable = enumerable; + } + + public IEnumerator GetEnumerator() + { + return _enumerable.GetEnumerator(); + } + } + + public sealed class MultipleInterfaceMappingClass : IList, IList + { + private List _list = new List(); + + DisposableClass IList.this[int index] { get => _list[index]; set => _list[index] = value; } + object IList.this[int index] { get => _list[index]; set => ((IList)_list) [index] = value; } + + int ICollection.Count => _list.Count; + + int ICollection.Count => _list.Count; + + bool ICollection.IsReadOnly => true; + + bool IList.IsReadOnly => true; + + bool IList.IsFixedSize => false; + + bool ICollection.IsSynchronized => true; + + object ICollection.SyncRoot => ((ICollection) _list).SyncRoot; + + void ICollection.Add(DisposableClass item) + { + _list.Add(item); + } + + int IList.Add(object value) + { + return ((IList) _list).Add(value); + } + + void ICollection.Clear() + { + _list.Clear(); + } + + void IList.Clear() + { + _list.Clear(); + } + + bool ICollection.Contains(DisposableClass item) + { + return _list.Contains(item); + } + + bool IList.Contains(object value) + { + return ((IList) _list).Contains(value); + } + + void ICollection.CopyTo(DisposableClass[] array, int arrayIndex) + { + _list.CopyTo(array, arrayIndex); + } + + void ICollection.CopyTo(Array array, int index) + { + ((ICollection) _list).CopyTo(array, index); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return _list.GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return _list.GetEnumerator(); + } + + int IList.IndexOf(DisposableClass item) + { + return _list.IndexOf(item); + } + + int IList.IndexOf(object value) + { + return ((IList) _list).IndexOf(value); + } + + void IList.Insert(int index, DisposableClass item) + { + _list.Insert(index, item); + } + + void IList.Insert(int index, object value) + { + ((IList) _list).Insert(index, value); + } + + bool ICollection.Remove(DisposableClass item) + { + return _list.Remove(item); + } + + void IList.Remove(object value) + { + ((IList) _list).Remove(value); + } + + void IList.RemoveAt(int index) + { + _list.RemoveAt(index); + } + + void IList.RemoveAt(int index) + { + _list.RemoveAt(index); + } + } +} diff --git a/src/Tests/AuthoringWuxTest/Properties/launchSettings.json b/src/Tests/AuthoringWuxTest/Properties/launchSettings.json new file mode 100644 index 000000000..c05aeebf5 --- /dev/null +++ b/src/Tests/AuthoringWuxTest/Properties/launchSettings.json @@ -0,0 +1,8 @@ +{ + "profiles": { + "AuthoringSample": { + "commandName": "Project", + "nativeDebugging": true + } + } +} \ No newline at end of file diff --git a/src/WinRT.Runtime/GuidGenerator.cs b/src/WinRT.Runtime/GuidGenerator.cs index 8f028fa9e..0b8f71cb0 100644 --- a/src/WinRT.Runtime/GuidGenerator.cs +++ b/src/WinRT.Runtime/GuidGenerator.cs @@ -7,6 +7,7 @@ using System.Reflection; using System.Security.Cryptography; using System.Text; +using WinRT.Interop; namespace WinRT { @@ -19,16 +20,25 @@ static class GuidGenerator { public static Guid GetGUID(Type type) { - return type.GetGuidType().GUID; + type = type.GetGuidType(); + if (type.GetCustomAttribute() is {} wuxMuxAttribute) + { + return GetWuxMuxIID(wuxMuxAttribute); + } + return type.GUID; } - public static Guid GetIID( + public static Guid GetIID( #if NET [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] #endif Type type) { type = type.GetGuidType(); + if (type.GetCustomAttribute() is {} wuxMuxAttribute) + { + return GetWuxMuxIID(wuxMuxAttribute); + } if (!type.IsGenericType) { return type.GUID; @@ -36,21 +46,31 @@ public static Guid GetIID( return (Guid)type.GetField("PIID").GetValue(null); } - public static string GetSignature( + internal static Guid GetWuxMuxIID(WuxMuxProjectedTypeAttribute wuxMuxAttribute) + { + return Projections.UiXamlModeSetting switch + { + Projections.UiXamlMode.WindowsUiXaml => wuxMuxAttribute.WuxIID, + Projections.UiXamlMode.MicrosoftUiXaml => wuxMuxAttribute.MuxIID, + _ => throw new InvalidOperationException("Invalid UI XAML mode") + }; + } + + public static string GetSignature( #if NET [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] #endif Type type) - { + { if (type == typeof(object)) { return "cinterface(IInspectable)"; - } - + } + if (type == typeof(string)) { return "string"; - } + } var helperType = type.FindHelperType(); if (helperType != null) @@ -89,38 +109,38 @@ public static string GetSignature( if (!type.IsPrimitive) { var winrtTypeAttribute = type.GetCustomAttribute(); - if (winrtTypeAttribute != null && !string.IsNullOrEmpty(winrtTypeAttribute.GuidSignature)) - { - return winrtTypeAttribute.GuidSignature; + if (winrtTypeAttribute != null && !string.IsNullOrEmpty(winrtTypeAttribute.GuidSignature)) + { + return winrtTypeAttribute.GuidSignature; } - else if (winrtTypeAttribute == null && - (winrtTypeAttribute = type.GetAuthoringMetadataType()?.GetCustomAttribute()) != null && - !string.IsNullOrEmpty(winrtTypeAttribute.GuidSignature)) - { - return winrtTypeAttribute.GuidSignature; + else if (winrtTypeAttribute == null && + (winrtTypeAttribute = type.GetAuthoringMetadataType()?.GetCustomAttribute()) != null && + !string.IsNullOrEmpty(winrtTypeAttribute.GuidSignature)) + { + return winrtTypeAttribute.GuidSignature; } - else - { - var args = type.GetFields(BindingFlags.Instance | BindingFlags.Public).Select(fi => GetSignature(fi.FieldType)); - return "struct(" + type.FullName + ";" + String.Join(";", args) + ")"; + else + { + var args = type.GetFields(BindingFlags.Instance | BindingFlags.Public).Select(fi => GetSignature(fi.FieldType)); + return "struct(" + type.FullName + ";" + String.Join(";", args) + ")"; } } throw new InvalidOperationException("unsupported value type"); } } } - - // For authoring interfaces, we can use the metadata type or the helper type to get the guid. - // For built-in system interfaces that are custom type mapped, we use the helper type to get the guid. - // For others, either the type itself or the helper type has the same guid and can be used. + + // For authoring interfaces, we can use the metadata type or the helper type to get the guid. + // For built-in system interfaces that are custom type mapped, we use the helper type to get the guid. + // For others, either the type itself or the helper type has the same guid and can be used. type = type.IsInterface ? (helperType ?? type) : type; if (type.IsGenericType) { var args = type.GetGenericArguments().Select(t => GetSignature(t)); return "pinterface({" + GetGUID(type) + "};" + String.Join(";", args) + ")"; - } - + } + if (type.IsDelegate()) { return "delegate({" + GetGUID(type) + "})"; @@ -172,14 +192,14 @@ public static Guid CreateIID(Type type) { return new Guid(sig); } - else - { - return CreateIIDForGenericType(sig); + else + { + return CreateIIDForGenericType(sig); } } - internal static Guid CreateIIDForGenericType(string signature) - { + internal static Guid CreateIIDForGenericType(string signature) + { #if !NET var data = wrt_pinterface_namespace.ToByteArray().Concat(UTF8Encoding.UTF8.GetBytes(signature)).ToArray(); @@ -194,10 +214,10 @@ internal static Guid CreateIIDForGenericType(string signature) Span dataSpan = data; wrt_pinterface_namespace.TryWriteBytes(dataSpan); var numBytes = UTF8Encoding.UTF8.GetBytes(signature, dataSpan[16..]); - data = data[..(16 + numBytes)]; - - return encode_guid(SHA1.HashData(data)); -#endif + data = data[..(16 + numBytes)]; + + return encode_guid(SHA1.HashData(data)); +#endif } } } diff --git a/src/WinRT.Runtime/Interop/WuxMuxProjectedInterfaceAttribute.cs b/src/WinRT.Runtime/Interop/WuxMuxProjectedInterfaceAttribute.cs new file mode 100644 index 000000000..b30aa7dc4 --- /dev/null +++ b/src/WinRT.Runtime/Interop/WuxMuxProjectedInterfaceAttribute.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace WinRT.Interop +{ + /// + /// This type signals that the type it is applied to is projected into .NET from either a Windows.UI.Xaml type or a Microsoft.UI.Xaml type. + /// For this type, the GuidAttribute is not used and instead the GetGuidSignature method must be called to get the IID or generic IID signature part of the type. + /// + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] + internal sealed class WuxMuxProjectedTypeAttribute : Attribute + { + public Guid WuxIID { get; } + + public Guid MuxIID { get; } + + public WuxMuxProjectedTypeAttribute(string wuxIID, string muxIID) + { + WuxIID = Guid.Parse(wuxIID); + MuxIID = Guid.Parse(muxIID); + } + } +} diff --git a/src/WinRT.Runtime/MatchingRefApiCompatBaseline.txt b/src/WinRT.Runtime/MatchingRefApiCompatBaseline.txt index 212a3ac2d..8407ff19d 100644 --- a/src/WinRT.Runtime/MatchingRefApiCompatBaseline.txt +++ b/src/WinRT.Runtime/MatchingRefApiCompatBaseline.txt @@ -129,4 +129,9 @@ TypesMustExist : Type 'WinRT.StructTypeDetails' does not exist in the r MembersMustExist : Member 'public void WinRT.WindowsRuntimeTypeAttribute..ctor(System.String, System.String)' does not exist in the reference but it does exist in the implementation. MembersMustExist : Member 'public System.String WinRT.WindowsRuntimeTypeAttribute.GuidSignature.get()' does not exist in the reference but it does exist in the implementation. TypesMustExist : Type 'WinRT.WinRTExposedTypeAttribute' does not exist in the reference but it does exist in the implementation. -Total Issues: 130 +MembersMustExist : Member 'public System.Boolean WinRT.ComWrappersSupport.RegisterDelegateFactory(System.Type, System.Func)' does not exist in the reference but it does exist in the implementation. +MembersMustExist : Member 'public void WinRT.ComWrappersSupport.RegisterComInterfaceEntries(System.Type, System.Runtime.InteropServices.ComWrappers.ComInterfaceEntry[])' does not exist in the reference but it does exist in the implementation. +MembersMustExist : Member 'public System.ReadOnlySpan WinRT.MarshalString.FromAbiUnsafe(System.IntPtr)' does not exist in the reference but it does exist in the implementation. +CannotRemoveAttribute : Attribute 'WinRT.Interop.WuxMuxProjectedTypeAttribute' exists on 'ABI.System.Collections.Specialized.NotifyCollectionChangedEventHandler' in the implementation but not the reference. +CannotRemoveAttribute : Attribute 'WinRT.Interop.WuxMuxProjectedTypeAttribute' exists on 'ABI.System.ComponentModel.PropertyChangedEventHandler' in the implementation but not the reference. +Total Issues: 135 diff --git a/src/WinRT.Runtime/Projections.cs b/src/WinRT.Runtime/Projections.cs index 1f4d66d43..fab580b15 100644 --- a/src/WinRT.Runtime/Projections.cs +++ b/src/WinRT.Runtime/Projections.cs @@ -25,9 +25,33 @@ namespace WinRT #endif static class Projections { + internal enum UiXamlMode + { + MicrosoftUiXaml, + WindowsUiXaml + } + + private static UiXamlMode GetUIXamlModeSetting() + { + if (AppContext.GetData("CsWinRT.UiXamlMode") is string str && Enum.TryParse(str, out var mode)) + { +#if !NET5_0_OR_GREATER + if (mode == UiXamlMode.WindowsUiXaml) + { + throw new NotSupportedException("Windows.UI.Xaml is not supported before .NET 5. Please use built-in WinRT interop for Windows.UI.Xaml experiences"); + } +#endif + return mode; + } + return UiXamlMode.MicrosoftUiXaml; // We default to MUX for back-compat with existing projects. + } + + internal static UiXamlMode UiXamlModeSetting { get; } = GetUIXamlModeSetting(); + private static readonly ReaderWriterLockSlim rwlock = new ReaderWriterLockSlim(); private static readonly Dictionary CustomTypeToHelperTypeMappings = new Dictionary(); + private static readonly Dictionary CustomTypeToIIDMappings = new Dictionary(); private static readonly Dictionary CustomAbiTypeToTypeMappings = new Dictionary(); private static readonly Dictionary CustomAbiTypeNameToTypeMappings = new Dictionary(StringComparer.Ordinal); private static readonly Dictionary CustomTypeToAbiTypeNameMappings = new Dictionary(); @@ -36,7 +60,7 @@ static class Projections static Projections() { - // This should be in sync with cswinrt/helpers.h and the reverse mapping from WinRT.SourceGenerator/WinRTTypeWriter.cs. + // This should be in sync with cswinrt/helpers.h and the reverse mapping from WinRT.SourceGenerator/TypeMapper.cs. RegisterCustomAbiTypeMappingNoLock(typeof(bool), typeof(ABI.System.Boolean), "Boolean"); RegisterCustomAbiTypeMappingNoLock(typeof(char), typeof(ABI.System.Char), "Char"); RegisterCustomAbiTypeMappingNoLock(typeof(EventRegistrationToken), typeof(ABI.WinRT.EventRegistrationToken), "Windows.Foundation.EventRegistrationToken"); @@ -62,13 +86,41 @@ static Projections() RegisterCustomAbiTypeMappingNoLock(typeof(Exception), typeof(ABI.System.Exception), "Windows.Foundation.HResult"); RegisterCustomAbiTypeMappingNoLock(typeof(TimeSpan), typeof(ABI.System.TimeSpan), "Windows.Foundation.TimeSpan"); RegisterCustomAbiTypeMappingNoLock(typeof(Uri), typeof(ABI.System.Uri), "Windows.Foundation.Uri", isRuntimeClass: true); - RegisterCustomAbiTypeMappingNoLock(typeof(DataErrorsChangedEventArgs), typeof(ABI.System.ComponentModel.DataErrorsChangedEventArgs), "Microsoft.UI.Xaml.Data.DataErrorsChangedEventArgs", isRuntimeClass: true); - RegisterCustomAbiTypeMappingNoLock(typeof(PropertyChangedEventArgs), typeof(ABI.System.ComponentModel.PropertyChangedEventArgs), "Microsoft.UI.Xaml.Data.PropertyChangedEventArgs", isRuntimeClass: true); - RegisterCustomAbiTypeMappingNoLock(typeof(PropertyChangedEventHandler), typeof(ABI.System.ComponentModel.PropertyChangedEventHandler), "Microsoft.UI.Xaml.Data.PropertyChangedEventHandler"); - RegisterCustomAbiTypeMappingNoLock(typeof(INotifyDataErrorInfo), typeof(ABI.System.ComponentModel.INotifyDataErrorInfo), "Microsoft.UI.Xaml.Data.INotifyDataErrorInfo"); - RegisterCustomAbiTypeMappingNoLock(typeof(INotifyPropertyChanged), typeof(ABI.System.ComponentModel.INotifyPropertyChanged), "Microsoft.UI.Xaml.Data.INotifyPropertyChanged"); - RegisterCustomAbiTypeMappingNoLock(typeof(ICommand), typeof(ABI.System.Windows.Input.ICommand), "Microsoft.UI.Xaml.Interop.ICommand"); - RegisterCustomAbiTypeMappingNoLock(typeof(IServiceProvider), typeof(ABI.System.IServiceProvider), "Microsoft.UI.Xaml.IXamlServiceProvider"); + + if (UiXamlModeSetting == UiXamlMode.MicrosoftUiXaml) + { + RegisterCustomAbiTypeMappingNoLock(typeof(DataErrorsChangedEventArgs), typeof(ABI.System.ComponentModel.DataErrorsChangedEventArgs), "Microsoft.UI.Xaml.Data.DataErrorsChangedEventArgs", isRuntimeClass: true); + RegisterCustomAbiTypeMappingNoLock(typeof(PropertyChangedEventArgs), typeof(ABI.System.ComponentModel.PropertyChangedEventArgs), "Microsoft.UI.Xaml.Data.PropertyChangedEventArgs", isRuntimeClass: true); + RegisterCustomAbiTypeMappingNoLock(typeof(PropertyChangedEventHandler), typeof(ABI.System.ComponentModel.PropertyChangedEventHandler), "Microsoft.UI.Xaml.Data.PropertyChangedEventHandler"); + RegisterCustomAbiTypeMappingNoLock(typeof(INotifyDataErrorInfo), typeof(ABI.System.ComponentModel.INotifyDataErrorInfo), "Microsoft.UI.Xaml.Data.INotifyDataErrorInfo"); + RegisterCustomAbiTypeMappingNoLock(typeof(INotifyPropertyChanged), typeof(ABI.System.ComponentModel.INotifyPropertyChanged), "Microsoft.UI.Xaml.Data.INotifyPropertyChanged"); + RegisterCustomAbiTypeMappingNoLock(typeof(ICommand), typeof(ABI.System.Windows.Input.ICommand), "Microsoft.UI.Xaml.Interop.ICommand"); + RegisterCustomAbiTypeMappingNoLock(typeof(IServiceProvider), typeof(ABI.System.IServiceProvider), "Microsoft.UI.Xaml.IXamlServiceProvider"); + RegisterCustomAbiTypeMappingNoLock(typeof(IEnumerable), typeof(ABI.System.Collections.IEnumerable), "Microsoft.UI.Xaml.Interop.IBindableIterable"); + RegisterCustomAbiTypeMappingNoLock(typeof(IList), typeof(ABI.System.Collections.IList), "Microsoft.UI.Xaml.Interop.IBindableVector"); + RegisterCustomAbiTypeMappingNoLock(typeof(INotifyCollectionChanged), typeof(ABI.System.Collections.Specialized.INotifyCollectionChanged), "Microsoft.UI.Xaml.Interop.INotifyCollectionChanged"); + RegisterCustomAbiTypeMappingNoLock(typeof(NotifyCollectionChangedAction), typeof(ABI.System.Collections.Specialized.NotifyCollectionChangedAction), "Microsoft.UI.Xaml.Interop.NotifyCollectionChangedAction"); + RegisterCustomAbiTypeMappingNoLock(typeof(NotifyCollectionChangedEventArgs), typeof(ABI.System.Collections.Specialized.NotifyCollectionChangedEventArgs), "Microsoft.UI.Xaml.Interop.NotifyCollectionChangedEventArgs", isRuntimeClass: true); + RegisterCustomAbiTypeMappingNoLock(typeof(NotifyCollectionChangedEventHandler), typeof(ABI.System.Collections.Specialized.NotifyCollectionChangedEventHandler), "Microsoft.UI.Xaml.Interop.NotifyCollectionChangedEventHandler"); + CustomTypeToHelperTypeMappings.Add(typeof(Microsoft.UI.Xaml.Interop.IBindableVector), typeof(ABI.System.Collections.IList)); + } +#if NET5_0_OR_GREATER + else if (UiXamlModeSetting == UiXamlMode.WindowsUiXaml) + { + RegisterCustomAbiTypeMappingNoLock(typeof(PropertyChangedEventArgs), typeof(ABI.System.ComponentModel.PropertyChangedEventArgs), "Windows.UI.Xaml.Data.PropertyChangedEventArgs", isRuntimeClass: true); + RegisterCustomAbiTypeMappingNoLock(typeof(PropertyChangedEventHandler), typeof(ABI.System.ComponentModel.PropertyChangedEventHandler), "Windows.UI.Xaml.Data.PropertyChangedEventHandler"); + RegisterCustomAbiTypeMappingNoLock(typeof(INotifyPropertyChanged), typeof(ABI.System.ComponentModel.INotifyPropertyChanged), "Windows.UI.Xaml.Data.INotifyPropertyChanged"); + RegisterCustomAbiTypeMappingNoLock(typeof(ICommand), typeof(ABI.System.Windows.Input.ICommand), "Windows.UI.Xaml.Interop.ICommand"); + RegisterCustomAbiTypeMappingNoLock(typeof(IEnumerable), typeof(ABI.System.Collections.IEnumerable), "Windows.UI.Xaml.Interop.IBindableIterable"); + RegisterCustomAbiTypeMappingNoLock(typeof(IList), typeof(ABI.System.Collections.IList), "Windows.UI.Xaml.Interop.IBindableVector"); + RegisterCustomAbiTypeMappingNoLock(typeof(INotifyCollectionChanged), typeof(ABI.System.Collections.Specialized.INotifyCollectionChanged), "Windows.UI.Xaml.Interop.INotifyCollectionChanged"); + RegisterCustomAbiTypeMappingNoLock(typeof(NotifyCollectionChangedAction), typeof(ABI.System.Collections.Specialized.NotifyCollectionChangedAction), "Windows.UI.Xaml.Interop.NotifyCollectionChangedAction"); + RegisterCustomAbiTypeMappingNoLock(typeof(NotifyCollectionChangedEventArgs), typeof(ABI.System.Collections.Specialized.NotifyCollectionChangedEventArgs), "Windows.UI.Xaml.Interop.NotifyCollectionChangedEventArgs", isRuntimeClass: true); + RegisterCustomAbiTypeMappingNoLock(typeof(NotifyCollectionChangedEventHandler), typeof(ABI.System.Collections.Specialized.NotifyCollectionChangedEventHandler), "Windows.UI.Xaml.Interop.NotifyCollectionChangedEventHandler"); + CustomTypeToHelperTypeMappings.Add(typeof(Windows.UI.Xaml.Interop.IBindableVector), typeof(ABI.System.Collections.IList)); + } +#endif + RegisterCustomAbiTypeMappingNoLock(typeof(EventHandler<>), typeof(ABI.System.EventHandler<>), "Windows.Foundation.EventHandler`1"); RegisterCustomAbiTypeMappingNoLock(typeof(KeyValuePair<,>), typeof(ABI.System.Collections.Generic.KeyValuePair<,>), "Windows.Foundation.Collections.IKeyValuePair`2"); @@ -80,12 +132,6 @@ static Projections() RegisterCustomAbiTypeMappingNoLock(typeof(IReadOnlyDictionary<,>), typeof(ABI.System.Collections.Generic.IReadOnlyDictionary<,>), "Windows.Foundation.Collections.IMapView`2"); RegisterCustomAbiTypeMappingNoLock(typeof(IDisposable), typeof(ABI.System.IDisposable), "Windows.Foundation.IClosable"); - RegisterCustomAbiTypeMappingNoLock(typeof(IEnumerable), typeof(ABI.System.Collections.IEnumerable), "Microsoft.UI.Xaml.Interop.IBindableIterable"); - RegisterCustomAbiTypeMappingNoLock(typeof(IList), typeof(ABI.System.Collections.IList), "Microsoft.UI.Xaml.Interop.IBindableVector"); - RegisterCustomAbiTypeMappingNoLock(typeof(INotifyCollectionChanged), typeof(ABI.System.Collections.Specialized.INotifyCollectionChanged), "Microsoft.UI.Xaml.Interop.INotifyCollectionChanged"); - RegisterCustomAbiTypeMappingNoLock(typeof(NotifyCollectionChangedAction), typeof(ABI.System.Collections.Specialized.NotifyCollectionChangedAction), "Microsoft.UI.Xaml.Interop.NotifyCollectionChangedAction"); - RegisterCustomAbiTypeMappingNoLock(typeof(NotifyCollectionChangedEventArgs), typeof(ABI.System.Collections.Specialized.NotifyCollectionChangedEventArgs), "Microsoft.UI.Xaml.Interop.NotifyCollectionChangedEventArgs", isRuntimeClass: true); - RegisterCustomAbiTypeMappingNoLock(typeof(NotifyCollectionChangedEventHandler), typeof(ABI.System.Collections.Specialized.NotifyCollectionChangedEventHandler), "Microsoft.UI.Xaml.Interop.NotifyCollectionChangedEventHandler"); RegisterCustomAbiTypeMappingNoLock(typeof(Matrix3x2), typeof(ABI.System.Numerics.Matrix3x2), "Windows.Foundation.Numerics.Matrix3x2"); RegisterCustomAbiTypeMappingNoLock(typeof(Matrix4x4), typeof(ABI.System.Numerics.Matrix4x4), "Windows.Foundation.Numerics.Matrix4x4"); @@ -100,7 +146,6 @@ static Projections() CustomTypeToHelperTypeMappings.Add(typeof(IVector<>), typeof(ABI.System.Collections.Generic.IList<>)); CustomTypeToHelperTypeMappings.Add(typeof(IMapView<,>), typeof(ABI.System.Collections.Generic.IReadOnlyDictionary<,>)); CustomTypeToHelperTypeMappings.Add(typeof(IVectorView<>), typeof(ABI.System.Collections.Generic.IReadOnlyList<>)); - CustomTypeToHelperTypeMappings.Add(typeof(Microsoft.UI.Xaml.Interop.IBindableVector), typeof(ABI.System.Collections.IList)); #if NET CustomTypeToHelperTypeMappings.Add(typeof(ICollection<>), typeof(ABI.System.Collections.Generic.ICollection<>)); @@ -260,6 +305,11 @@ public static string FindCustomAbiTypeNameForType(Type type) } } + internal static Guid? FindCustomIIDForAbiType(Type type) + { + return CustomTypeToIIDMappings.TryGetValue(type, out Guid iid) ? iid : null; + } + private readonly static ConcurrentDictionary IsTypeWindowsRuntimeTypeCache = new(); public static bool IsTypeWindowsRuntimeType(Type type) { diff --git a/src/WinRT.Runtime/Projections/Bindable.net5.cs b/src/WinRT.Runtime/Projections/Bindable.net5.cs index 721c00255..f400c74d6 100644 --- a/src/WinRT.Runtime/Projections/Bindable.net5.cs +++ b/src/WinRT.Runtime/Projections/Bindable.net5.cs @@ -1,101 +1,162 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -using System; -using System.Collections; -using System.Collections.Generic; +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +using System; +using System.Collections; +using System.Collections.Generic; using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using WinRT; +using System.Runtime.InteropServices; +using WinRT; using WinRT.Interop; -#pragma warning disable 0169 // warning CS0169: The field '...' is never used -#pragma warning disable 0649 // warning CS0169: Field '...' is never assigned to - -namespace Microsoft.UI.Xaml.Interop -{ - [global::WinRT.WindowsRuntimeType] - [Guid("036D2C08-DF29-41AF-8AA2-D774BE62BA6F")] - [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Microsoft.UI.Xaml.Interop.IBindableIterable))] - internal interface IBindableIterable - { - IBindableIterator First(); - } - [global::WinRT.WindowsRuntimeType] - [Guid("6A1D6C07-076D-49F2-8314-F52C9C9A8331")] - [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Microsoft.UI.Xaml.Interop.IBindableIterator))] - internal interface IBindableIterator - { - bool MoveNext(); - // GetMany is not implemented by IBindableIterator, but it is here - // for compat purposes with WinUI where there are scenarios they do - // reinterpret_cast from IBindableIterator to IIterable. It is - // the last function in the vftable and shouldn't be called by anyone. - // If called, it will return NotImplementedException. - uint GetMany(ref object[] items); - object Current { get; } - bool HasCurrent { get; } - } - [global::WinRT.WindowsRuntimeType] - [Guid("393DE7DE-6FD0-4C0D-BB71-47244A113E93")] - internal interface IBindableVector : IEnumerable - { - object GetAt(uint index); - IBindableVectorView GetView(); - bool IndexOf(object value, out uint index); - void SetAt(uint index, object value); - void InsertAt(uint index, object value); - void RemoveAt(uint index); - void Append(object value); - void RemoveAtEnd(); - void Clear(); - uint Size { get; } - } - [global::WinRT.WindowsRuntimeType] - [Guid("346DD6E7-976E-4BC3-815D-ECE243BC0F33")] - [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Microsoft.UI.Xaml.Interop.IBindableVectorView))] - internal interface IBindableVectorView : IEnumerable - { - object GetAt(uint index); - bool IndexOf(object value, out uint index); - uint Size { get; } - } -} - -namespace ABI.Microsoft.UI.Xaml.Interop -{ - [DynamicInterfaceCastableImplementation] - [Guid("036D2C08-DF29-41AF-8AA2-D774BE62BA6F")] - internal unsafe interface IBindableIterable : global::Microsoft.UI.Xaml.Interop.IBindableIterable, ABI.System.Collections.IEnumerable - { - - } - - [DynamicInterfaceCastableImplementation] - [Guid("6A1D6C07-076D-49F2-8314-F52C9C9A8331")] - internal unsafe interface IBindableIterator : global::Microsoft.UI.Xaml.Interop.IBindableIterator +#pragma warning disable 0169 // warning CS0169: The field '...' is never used +#pragma warning disable 0649 // warning CS0169: Field '...' is never assigned to + +namespace ABI.System.Collections +{ + using WUX = global::Windows.UI.Xaml.Interop; + using MUX = global::Microsoft.UI.Xaml.Interop; + using global::System; + using global::System.Runtime.CompilerServices; + using global::System.Diagnostics.CodeAnalysis; + +#if EMBED + internal +#else + public +#endif + static class IEnumerableMethods + { + public static global::System.Guid IID { get; } = new Guid(new global::System.ReadOnlySpan(new byte[] { 0x08, 0x2C, 0x6D, 0x03, 0x29, 0xDF, 0xAF, 0x41, 0x8A, 0xA2, 0xD7, 0x74, 0xBE, 0x62, 0xBA, 0x6F })); + + public static IntPtr AbiToProjectionVftablePtr => IEnumerable.AbiToProjectionVftablePtr; + } + + [DynamicInterfaceCastableImplementation] + [Guid("036D2C08-DF29-41AF-8AA2-D774BE62BA6F")] + internal unsafe interface IEnumerable : global::System.Collections.IEnumerable, WUX.IBindableIterable, MUX.IBindableIterable { - public static readonly IntPtr AbiToProjectionVftablePtr; - static IBindableIterator() + public static string GetGuidSignature() => GuidGenerator.GetSignature(typeof(IEnumerable)); + + public sealed class AdaptiveFromAbiHelper : global::System.Collections.IEnumerable + { + private readonly Func _enumerator; + private readonly IWinRTObject _winRTObject; + + [DynamicDependency(DynamicallyAccessedMemberTypes.PublicMethods, typeof(IEnumerable<>))] + [SuppressMessage("Trimming", "IL2070:'this' argument does not satisfy 'DynamicallyAccessedMembersAttribute' in call to target method. The parameter of method does not have matching annotations.", Justification = "We explicitly preserve the type we're looking for with the DynamicDependency attribute.")] + [SuppressMessage("Trimming", "IL2075:'this' argument does not satisfy 'DynamicallyAccessedMembersAttribute' in call to target method. The return value of the source method does not have matching annotations.", Justification = "We can't annotate this case (GetMethod on a type returned from GetInterface), so we use DynamicDependency to keep alive the one type we care about's public methods.")] + public AdaptiveFromAbiHelper( + Type runtimeType, IWinRTObject winRTObject) + : this(winRTObject) + { + Type enumGenericType = (runtimeType.IsGenericType && runtimeType.GetGenericTypeDefinition() == typeof(IEnumerable<>)) ? + runtimeType : runtimeType.GetInterface("System.Collections.Generic.IEnumerable`1"); + if(enumGenericType != null) + { + var getEnumerator = enumGenericType.GetMethod("GetEnumerator"); + _enumerator = (IWinRTObject obj) => (IEnumerator)getEnumerator.Invoke(obj, null); + } + } + + public AdaptiveFromAbiHelper(IWinRTObject winRTObject) + { + _winRTObject = winRTObject; + if (winRTObject is WUX.IBindableIterable) + { + _enumerator = (IWinRTObject obj) => new Generic.FromAbiEnumerator(new NonGenericToGenericWuxIterator(((WUX.IBindableIterable)obj).First())); + } + else if (winRTObject is MUX.IBindableIterable) + { + _enumerator = (IWinRTObject obj) => new Generic.FromAbiEnumerator(new NonGenericToGenericMuxIterator(((MUX.IBindableIterable)obj).First())); + } + } + + public IEnumerator GetEnumerator() => _enumerator(_winRTObject); + + private sealed class NonGenericToGenericWuxIterator : global::Windows.Foundation.Collections.IIterator + { + private readonly WUX.IBindableIterator iterator; + + public NonGenericToGenericWuxIterator(WUX.IBindableIterator iterator) => this.iterator = iterator; + + public object _Current => iterator.Current; + public bool HasCurrent => iterator.HasCurrent; + public bool _MoveNext() { return iterator.MoveNext(); } + public uint GetMany(ref object[] items) => throw new NotSupportedException(); + } + + private sealed class NonGenericToGenericMuxIterator : global::Windows.Foundation.Collections.IIterator + { + private readonly MUX.IBindableIterator iterator; + + public NonGenericToGenericMuxIterator(MUX.IBindableIterator iterator) => this.iterator = iterator; + + public object _Current => iterator.Current; + public bool HasCurrent => iterator.HasCurrent; + public bool _MoveNext() { return iterator.MoveNext(); } + public uint GetMany(ref object[] items) => throw new NotSupportedException(); + } + } + + private sealed class ToWuxAbiHelper : WUX.IBindableIterable { - AbiToProjectionVftablePtr = ComWrappersSupport.AllocateVtableMemory(typeof(IBindableIterator), sizeof(IInspectable.Vftbl) + sizeof(IntPtr) * 4); - *(IInspectable.Vftbl*)AbiToProjectionVftablePtr = IInspectable.Vftbl.AbiToProjectionVftable; - ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[6] = &Do_Abi_get_Current_0; - ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[7] = &Do_Abi_get_HasCurrent_1; - ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[8] = &Do_Abi_MoveNext_2; - ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[9] = &Do_Abi_GetMany_3; + private readonly IEnumerable m_enumerable; + + internal ToWuxAbiHelper(IEnumerable enumerable) => m_enumerable = enumerable; + + WUX.IBindableIterator WUX.IBindableIterable.First() => MakeBindableIterator(m_enumerable.GetEnumerator()); + + internal static WUX.IBindableIterator MakeBindableIterator(IEnumerator enumerator) => + new Generic.IEnumerator.ToAbiHelper(new NonGenericToGenericEnumerator(enumerator)); + + private sealed class NonGenericToGenericEnumerator : IEnumerator + { + private readonly IEnumerator enumerator; + + public NonGenericToGenericEnumerator(IEnumerator enumerator) => this.enumerator = enumerator; + + public object Current => enumerator.Current; + public bool MoveNext() { return enumerator.MoveNext(); } + public void Reset() { enumerator.Reset(); } + public void Dispose() { } + } } - [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] - private static unsafe int Do_Abi_MoveNext_2(IntPtr thisPtr, byte* result) + private sealed class ToMuxAbiHelper(IEnumerable enumerable) : MUX.IBindableIterable + { + MUX.IBindableIterator MUX.IBindableIterable.First() => MakeBindableIterator(enumerable.GetEnumerator()); + + internal static MUX.IBindableIterator MakeBindableIterator(IEnumerator enumerator) => + new Generic.IEnumerator.ToAbiHelper(new NonGenericToGenericEnumerator(enumerator)); + + private sealed class NonGenericToGenericEnumerator(IEnumerator enumerator) : IEnumerator + { + public object Current => enumerator.Current; + public bool MoveNext() { return enumerator.MoveNext(); } + public void Reset() { enumerator.Reset(); } + public void Dispose() { } + } + } + + public static readonly IntPtr AbiToProjectionVftablePtr; + static IEnumerable() + { + AbiToProjectionVftablePtr = ComWrappersSupport.AllocateVtableMemory(typeof(IEnumerable), sizeof(IInspectable.Vftbl) + sizeof(IntPtr) * 1); + *(IInspectable.Vftbl*)AbiToProjectionVftablePtr = IInspectable.Vftbl.AbiToProjectionVftable; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[6] = Projections.UiXamlModeSetting is Projections.UiXamlMode.WindowsUiXaml ? &Do_Wux_Abi_First_0 : &Do_Mux_Abi_First_0; + } + + [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] + private static unsafe int Do_Wux_Abi_First_0(IntPtr thisPtr, IntPtr* result) { - bool __result = default; *result = default; try { - __result = global::WinRT.ComWrappersSupport.FindObject(thisPtr).MoveNext(); - *result = (byte)(__result ? 1 : 0); + var __this = global::WinRT.ComWrappersSupport.FindObject(thisPtr); + var iterator = ToWuxAbiHelper.MakeBindableIterator(__this.GetEnumerator()); + *result = MarshalInterface.FromManaged(iterator); } catch (Exception __exception__) { @@ -105,931 +166,620 @@ private static unsafe int Do_Abi_MoveNext_2(IntPtr thisPtr, byte* result) return 0; } - [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] - private static unsafe int Do_Abi_GetMany_3(IntPtr thisPtr, int __itemsSize, IntPtr items, uint* result) + [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] + private static unsafe int Do_Mux_Abi_First_0(IntPtr thisPtr, IntPtr* result) { *result = default; - try { - // Should never be called. - throw new NotImplementedException(); + var __this = global::WinRT.ComWrappersSupport.FindObject(thisPtr); + var iterator = ToMuxAbiHelper.MakeBindableIterator(__this.GetEnumerator()); + *result = MarshalInterface.FromManaged(iterator); } catch (Exception __exception__) { global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); } + return 0; } - [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] - private static unsafe int Do_Abi_get_Current_0(IntPtr thisPtr, IntPtr* value) + internal static ObjectReference ObjRefFromAbi(IntPtr thisPtr) { - object __value = default; - *value = default; + if (thisPtr == IntPtr.Zero) + { + return null; + } + return ObjectReference.FromAbi(thisPtr); + } + + private static AdaptiveFromAbiHelper _AbiHelper(IWinRTObject _this) + { + return (AdaptiveFromAbiHelper)_this.GetOrCreateTypeHelperData(typeof(global::System.Collections.IEnumerable).TypeHandle, + () => new AdaptiveFromAbiHelper(_this)); + } + + unsafe WUX.IBindableIterator WUX.IBindableIterable.First() + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IEnumerable).TypeHandle); + var ThisPtr = _obj.ThisPtr; + IntPtr __retval = default; try { - __value = global::WinRT.ComWrappersSupport.FindObject(thisPtr).Current; - *value = MarshalInspectable.FromManaged(__value); + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[6](ThisPtr, &__retval)); + return MarshalInterface.FromAbi(__retval); } - catch (Exception __exception__) + finally { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + MarshalInterface.DisposeAbi(__retval); } - return 0; } - [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] - private static unsafe int Do_Abi_get_HasCurrent_1(IntPtr thisPtr, byte* value) + unsafe MUX.IBindableIterator MUX.IBindableIterable.First() { - bool __value = default; - *value = default; + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IEnumerable).TypeHandle); + var ThisPtr = _obj.ThisPtr; + IntPtr __retval = default; try { - __value = global::WinRT.ComWrappersSupport.FindObject(thisPtr).HasCurrent; - *value = (byte)(__value ? 1 : 0); + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[6](ThisPtr, &__retval)); + return MarshalInterface.FromAbi(__retval); } - catch (Exception __exception__) + finally { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + MarshalInterface.DisposeAbi(__retval); } - return 0; - } - - internal static ObjectReference FromAbi(IntPtr thisPtr) => ObjectReference.FromAbi(thisPtr); - - unsafe bool global::Microsoft.UI.Xaml.Interop.IBindableIterator.MoveNext() - { - var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::Microsoft.UI.Xaml.Interop.IBindableIterator).TypeHandle); - var ThisPtr = _obj.ThisPtr; - byte __retval = default; - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[8](ThisPtr, &__retval)); - return __retval != 0; - } - - unsafe uint global::Microsoft.UI.Xaml.Interop.IBindableIterator.GetMany(ref object[] items) - { - // Should never be called. - throw new NotImplementedException(); - } - - unsafe object global::Microsoft.UI.Xaml.Interop.IBindableIterator.Current - { - get - { - var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::Microsoft.UI.Xaml.Interop.IBindableIterator).TypeHandle); - var ThisPtr = _obj.ThisPtr; - IntPtr __retval = default; - try - { - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[6](ThisPtr, &__retval)); - return MarshalInspectable.FromAbi(__retval); - } - finally - { - MarshalInspectable.DisposeAbi(__retval); - } - } - } - - unsafe bool global::Microsoft.UI.Xaml.Interop.IBindableIterator.HasCurrent - { - get - { - var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::Microsoft.UI.Xaml.Interop.IBindableIterator).TypeHandle); - var ThisPtr = _obj.ThisPtr; - byte __retval = default; - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[7](ThisPtr, &__retval)); - return __retval != 0; - } - } - - } - [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] - internal static class IBindableIterator_Delegates - { - public unsafe delegate int get_Current_0(IntPtr thisPtr, IntPtr* result); - public unsafe delegate int get_HasCurrent_1(IntPtr thisPtr, byte* result); - public unsafe delegate int MoveNext_2(IntPtr thisPtr, byte* result); - public unsafe delegate int GetMany_3(IntPtr thisPtr, int itemSize, IntPtr items, uint* result); - } - - [DynamicInterfaceCastableImplementation] - [Guid("346DD6E7-976E-4BC3-815D-ECE243BC0F33")] - internal unsafe interface IBindableVectorView : global::Microsoft.UI.Xaml.Interop.IBindableVectorView + } + + IEnumerator global::System.Collections.IEnumerable.GetEnumerator() + { + return _AbiHelper((IWinRTObject)this).GetEnumerator(); + } + } + + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] +#if EMBED + internal +#else + public +#endif + static class IEnumerable_Delegates { - public static readonly IntPtr AbiToProjectionVftablePtr; + public unsafe delegate int First_0(IntPtr thisPtr, IntPtr* result); + } - internal static readonly Guid IID = new(new ReadOnlySpan(new byte[] { 0xE7, 0xD6, 0x6D, 0x34, 0x6E, 0x97, 0xC3, 0x4B, 0x81, 0x5D, 0xEC, 0xE2, 0x43, 0xBC, 0x0F, 0x33 })); - - static IBindableVectorView() +#if EMBED + internal +#else + public +#endif + static class IListMethods + { + public static Guid IID { get; } = new Guid(new global::System.ReadOnlySpan(new byte[] { 0xDE, 0xE7, 0x3D, 0x39, 0xD0, 0x6F, 0x0D, 0x4C, 0xBB, 0x71, 0x47, 0x24, 0x4A, 0x11, 0x3E, 0x93 })); + + public static IntPtr AbiToProjectionVftablePtr => IList.AbiToProjectionVftablePtr; + } + + [DynamicInterfaceCastableImplementation] + [Guid("393DE7DE-6FD0-4C0D-BB71-47244A113E93")] + internal unsafe interface IList : global::System.Collections.IList, WUX.IBindableVector, MUX.IBindableVector + { + public static string GetGuidSignature() => GuidGenerator.GetSignature(typeof(IList)); + + public interface IBindableVectorAdapter { - AbiToProjectionVftablePtr = ComWrappersSupport.AllocateVtableMemory(typeof(IBindableVectorView), sizeof(IInspectable.Vftbl) + sizeof(IntPtr) * 3); - *(IInspectable.Vftbl*)AbiToProjectionVftablePtr = IInspectable.Vftbl.AbiToProjectionVftable; - ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[6] = &Do_Abi_GetAt_0; - ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[7] = &Do_Abi_get_Size_1; - ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[8] = &Do_Abi_IndexOf_2; + object GetAt(uint index); + IBindableVectorViewAdapter GetView(); + bool IndexOf(object value, out uint index); + void SetAt(uint index, object value); + void InsertAt(uint index, object value); + void RemoveAt(uint index); + void Append(object value); + void RemoveAtEnd(); + void Clear(); + uint Size { get; } } - [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] - private static unsafe int Do_Abi_GetAt_0(IntPtr thisPtr, uint index, IntPtr* result) + public interface IBindableVectorViewAdapter { - object __result = default; + object GetAt(uint index); + bool IndexOf(object value, out uint index); + uint Size { get; } + } - try - { - __result = global::WinRT.ComWrappersSupport.FindObject(thisPtr).GetAt(index); - *result = MarshalInspectable.FromManaged(__result); + private sealed class WuxBindableVectorAdapter(WUX.IBindableVector vector) : IBindableVectorAdapter + { + public object GetAt(uint index) => vector.GetAt(index); + public IBindableVectorViewAdapter GetView() => new WuxBindableVectorViewAdapter(vector.GetView()); + public bool IndexOf(object value, out uint index) => vector.IndexOf(value, out index); + public void SetAt(uint index, object value) => vector.SetAt(index, value); + public void InsertAt(uint index, object value) => vector.InsertAt(index, value); + public void RemoveAt(uint index) => vector.RemoveAt(index); + public void Append(object value) => vector.Append(value); + public void RemoveAtEnd() => vector.RemoveAtEnd(); + public void Clear() => vector.Clear(); + public uint Size => vector.Size; + private sealed class WuxBindableVectorViewAdapter(WUX.IBindableVectorView vectorView) : IBindableVectorViewAdapter + { + public object GetAt(uint index) => vectorView.GetAt(index); + public bool IndexOf(object value, out uint index) => vectorView.IndexOf(value, out index); + public uint Size => vectorView.Size; } - catch (Exception __exception__) + } + + private sealed class MuxBindableVectorAdapter(MUX.IBindableVector vector) : IBindableVectorAdapter + { + public object GetAt(uint index) => vector.GetAt(index); + public IBindableVectorViewAdapter GetView() => new WuxBindableVectorViewAdapter(vector.GetView()); + public bool IndexOf(object value, out uint index) => vector.IndexOf(value, out index); + public void SetAt(uint index, object value) => vector.SetAt(index, value); + public void InsertAt(uint index, object value) => vector.InsertAt(index, value); + public void RemoveAt(uint index) => vector.RemoveAt(index); + public void Append(object value) => vector.Append(value); + public void RemoveAtEnd() => vector.RemoveAtEnd(); + public void Clear() => vector.Clear(); + public uint Size => vector.Size; + + private sealed class WuxBindableVectorViewAdapter(MUX.IBindableVectorView vectorView) : IBindableVectorViewAdapter { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + public object GetAt(uint index) => vectorView.GetAt(index); + public bool IndexOf(object value, out uint index) => vectorView.IndexOf(value, out index); + public uint Size => vectorView.Size; } - return 0; } - [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] - private static unsafe int Do_Abi_IndexOf_2(IntPtr thisPtr, IntPtr value, uint* index, byte* returnValue) + public sealed class FromAbiHelper : global::System.Collections.IList { - bool __returnValue = default; + private readonly IBindableVectorAdapter _vector; - *index = default; - *returnValue = default; - uint __index = default; + public FromAbiHelper(IBindableVectorAdapter vector) + { + _vector = vector; + } - try + public bool IsSynchronized => false; + + public object SyncRoot { get => this; } + + public int Count { - __returnValue = global::WinRT.ComWrappersSupport.FindObject(thisPtr).IndexOf(MarshalInspectable.FromAbi(value), out __index); - *index = __index; - *returnValue = (byte)(__returnValue ? 1 : 0); + get + { + uint size = _vector.Size; + if (((uint)int.MaxValue) < size) + { + throw new InvalidOperationException(WinRTRuntimeErrorStrings.InvalidOperation_CollectionBackingListTooLarge); + } + return (int)size; + } } - catch (Exception __exception__) + + public void CopyTo(Array array, int arrayIndex) { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + if (array == null) + throw new ArgumentNullException(nameof(array)); + + // ICollection expects the destination array to be single-dimensional. + if (array.Rank != 1) + throw new ArgumentException(WinRTRuntimeErrorStrings.Arg_RankMultiDimNotSupported); + + int destLB = array.GetLowerBound(0); + int srcLen = Count; + int destLen = array.GetLength(0); + + if (arrayIndex < destLB) + throw new ArgumentOutOfRangeException(nameof(arrayIndex)); + + // Does the dimension in question have sufficient space to copy the expected number of entries? + // We perform this check before valid index check to ensure the exception message is in sync with + // the following snippet that uses regular framework code: + // + // ArrayList list = new ArrayList(); + // list.Add(1); + // Array items = Array.CreateInstance(typeof(object), new int[] { 1 }, new int[] { -1 }); + // list.CopyTo(items, 0); + + if (srcLen > (destLen - (arrayIndex - destLB))) + throw new ArgumentException(WinRTRuntimeErrorStrings.Argument_InsufficientSpaceToCopyCollection); + + if (arrayIndex - destLB > destLen) + throw new ArgumentException(WinRTRuntimeErrorStrings.Argument_IndexOutOfArrayBounds); + + // We need to verify the index as we; + for (uint i = 0; i < srcLen; i++) + { + array.SetValue(_vector.GetAt(i), i + arrayIndex); + } + } + + public object this[int index] + { + get => Indexer_Get(index); + set => Indexer_Set(index, value); + } + + internal object Indexer_Get(int index) + { + if (index < 0) + throw new ArgumentOutOfRangeException(nameof(index)); + + return GetAt(_vector, (uint)index); + } + + internal void Indexer_Set(int index, object value) + { + if (index < 0) + throw new ArgumentOutOfRangeException(nameof(index)); + + SetAt(_vector, (uint)index, value); + } + + public int Add(object value) + { + _vector.Append(value); + + uint size = _vector.Size; + if (((uint)int.MaxValue) < size) + { + throw new InvalidOperationException(WinRTRuntimeErrorStrings.InvalidOperation_CollectionBackingListTooLarge); + } + + return (int)(size - 1); + } + + public bool Contains(object item) + { + return _vector.IndexOf(item, out _); + } + + public void Clear() + { + _vector.Clear(); + } + + public bool IsFixedSize { get => false; } + + public bool IsReadOnly { get => false; } + + public int IndexOf(object item) + { + uint index; + bool exists = _vector.IndexOf(item, out index); + + if (!exists) + return -1; + + if (((uint)int.MaxValue) < index) + { + throw new InvalidOperationException(WinRTRuntimeErrorStrings.InvalidOperation_CollectionBackingListTooLarge); + } + + return (int)index; + } + + public void Insert(int index, object item) + { + if (index < 0) + throw new ArgumentOutOfRangeException(nameof(index)); + + InsertAtHelper(_vector, (uint)index, item); + } + + public void Remove(object item) + { + uint index; + bool exists = _vector.IndexOf(item, out index); + + if (exists) + { + if (((uint)int.MaxValue) < index) + { + throw new InvalidOperationException(WinRTRuntimeErrorStrings.InvalidOperation_CollectionBackingListTooLarge); + } + + RemoveAtHelper(_vector, index); + } + } + + public void RemoveAt(int index) + { + if (index < 0) + throw new ArgumentOutOfRangeException(nameof(index)); + + RemoveAtHelper(_vector, (uint)index); + } + + private static object GetAt(IBindableVectorAdapter _this, uint index) + { + try + { + return _this.GetAt(index); + + // We delegate bounds checking to the underlying collection and if it detected a fault, + // we translate it to the right exception: + } + catch (Exception ex) + { + if (ExceptionHelpers.E_BOUNDS == ex.HResult) + throw new ArgumentOutOfRangeException(nameof(index)); + throw; + } + } + + private static void SetAt(IBindableVectorAdapter _this, uint index, object value) + { + try + { + _this.SetAt(index, value); + + // We delegate bounds checking to the underlying collection and if it detected a fault, + // we translate it to the right exception: + } + catch (Exception ex) + { + if (ExceptionHelpers.E_BOUNDS == ex.HResult) + throw new ArgumentOutOfRangeException(nameof(index)); + throw; + } + } + + private static void InsertAtHelper(IBindableVectorAdapter _this, uint index, object item) + { + try + { + _this.InsertAt(index, item); + + // We delegate bounds checking to the underlying collection and if it detected a fault, + // we translate it to the right exception: + } + catch (Exception ex) + { + if (ExceptionHelpers.E_BOUNDS == ex.HResult) + throw new ArgumentOutOfRangeException(nameof(index)); + throw; + } + } + + private static void RemoveAtHelper(IBindableVectorAdapter _this, uint index) + { + try + { + _this.RemoveAt(index); + + // We delegate bounds checking to the underlying collection and if it detected a fault, + // we translate it to the right exception: + } + catch (Exception ex) + { + if (ExceptionHelpers.E_BOUNDS == ex.HResult) + throw new ArgumentOutOfRangeException(nameof(index)); + throw; + } + } + + public IEnumerator GetEnumerator() + { + return ((IEnumerable)(IWinRTObject)_vector).GetEnumerator(); } - return 0; } - [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] - private static unsafe int Do_Abi_get_Size_1(IntPtr thisPtr, uint* value) + public sealed class ToAbiHelper : WUX.IBindableVector, MUX.IBindableVector, IBindableVectorAdapter { - uint __value = default; + private global::System.Collections.IList _list; - *value = default; + public ToAbiHelper(global::System.Collections.IList list) => _list = list; - try + public object GetAt(uint index) { - __value = global::WinRT.ComWrappersSupport.FindObject(thisPtr).Size; - *value = __value; + EnsureIndexInt32(index, _list.Count); + + try + { + return _list[(int)index]; + } + catch (ArgumentOutOfRangeException ex) + { + throw ex.GetExceptionForHR(ExceptionHelpers.E_BOUNDS, WinRTRuntimeErrorStrings.ArgumentOutOfRange_Index); + } + } + + public uint Size { get => (uint)_list.Count; } + + IBindableVectorViewAdapter IBindableVectorAdapter.GetView() + { + return new ListToBindableVectorViewAdapter(_list); + } + + WUX.IBindableVectorView WUX.IBindableVector.GetView() + { + return new ListToBindableVectorViewAdapter(_list); + } + + MUX.IBindableVectorView MUX.IBindableVector.GetView() + { + return new ListToBindableVectorViewAdapter(_list); + } + + public bool IndexOf(object value, out uint index) + { + int ind = _list.IndexOf(value); + if (-1 == ind) + { + index = 0; + return false; + } + + index = (uint)ind; + return true; + } + + public void SetAt(uint index, object value) + { + EnsureIndexInt32(index, _list.Count); + + try + { + _list[(int)index] = value; + } + catch (ArgumentOutOfRangeException ex) + { + throw ex.GetExceptionForHR(ExceptionHelpers.E_BOUNDS, WinRTRuntimeErrorStrings.ArgumentOutOfRange_Index); + } + } + + public void InsertAt(uint index, object value) + { + // Inserting at an index one past the end of the list is equivalent to appending + // so we need to ensure that we're within (0, count + 1). + EnsureIndexInt32(index, _list.Count + 1); + + try + { + _list.Insert((int)index, value); + } + catch (ArgumentOutOfRangeException ex) + { + // Change error code to match what WinRT expects + ex.SetHResult(ExceptionHelpers.E_BOUNDS); + throw; + } + } + + public void RemoveAt(uint index) + { + EnsureIndexInt32(index, _list.Count); + + try + { + _list.RemoveAt((int)index); + } + catch (ArgumentOutOfRangeException ex) + { + // Change error code to match what WinRT expects + ex.SetHResult(ExceptionHelpers.E_BOUNDS); + throw; + } } - catch (Exception __exception__) + + public void Append(object value) { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + _list.Add(value); } - return 0; - } - - internal static ObjectReference FromAbi(IntPtr thisPtr) => ObjectReference.FromAbi(thisPtr); - - private static readonly global::System.Runtime.CompilerServices.ConditionalWeakTable _helperTable = new(); - - unsafe object global::Microsoft.UI.Xaml.Interop.IBindableVectorView.GetAt(uint index) - { - var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::Microsoft.UI.Xaml.Interop.IBindableIterator).TypeHandle); - var ThisPtr = _obj.ThisPtr; - IntPtr __retval = default; - try - { - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[6](ThisPtr, index, &__retval)); - return MarshalInspectable.FromAbi(__retval); - } - finally - { - MarshalInspectable.DisposeAbi(__retval); - } - } - - unsafe bool global::Microsoft.UI.Xaml.Interop.IBindableVectorView.IndexOf(object value, out uint index) - { - var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::Microsoft.UI.Xaml.Interop.IBindableIterator).TypeHandle); - var ThisPtr = _obj.ThisPtr; - ObjectReferenceValue __value = default; - uint __index = default; - byte __retval = default; - try - { - __value = MarshalInspectable.CreateMarshaler2(value); - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[8]( - ThisPtr, - MarshalInspectable.GetAbi(__value), - &__index, - &__retval)); - index = __index; - return __retval != 0; - } - finally - { - MarshalInspectable.DisposeMarshaler(__value); - } - } - - unsafe uint global::Microsoft.UI.Xaml.Interop.IBindableVectorView.Size - { - get - { - var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::Microsoft.UI.Xaml.Interop.IBindableIterator).TypeHandle); - var ThisPtr = _obj.ThisPtr; - uint __retval = default; - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[7](ThisPtr, &__retval)); - return __retval; - } - } - - IEnumerator IEnumerable.GetEnumerator() - { - return _helperTable.GetValue((IWinRTObject)this, - (enumerable) => new ABI.System.Collections.IEnumerable.FromAbiHelper((global::System.Collections.IEnumerable)(IWinRTObject)enumerable) - ).GetEnumerator(); - } - } - [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] - internal static class IBindableVectorView_Delegates - { - public unsafe delegate int GetAt_0(IntPtr thisPtr, uint index, IntPtr* result); - public unsafe delegate int get_Size_1(IntPtr thisPtr, uint* result); - public unsafe delegate int IndexOf_2(IntPtr thisPtr, IntPtr value, uint* index, byte* returnValue); - } -} - -namespace ABI.System.Collections -{ - using global::Microsoft.UI.Xaml.Interop; - using global::System; - using global::System.Runtime.CompilerServices; - -#if EMBED - internal -#else - public -#endif - static class IEnumerableMethods - { - public static global::System.Guid IID { get; } = new Guid(new global::System.ReadOnlySpan(new byte[] { 0x08, 0x2C, 0x6D, 0x03, 0x29, 0xDF, 0xAF, 0x41, 0x8A, 0xA2, 0xD7, 0x74, 0xBE, 0x62, 0xBA, 0x6F })); - public static IntPtr AbiToProjectionVftablePtr => IEnumerable.AbiToProjectionVftablePtr; - } - - [DynamicInterfaceCastableImplementation] - [Guid("036D2C08-DF29-41AF-8AA2-D774BE62BA6F")] - internal unsafe interface IEnumerable : global::System.Collections.IEnumerable, global::Microsoft.UI.Xaml.Interop.IBindableIterable - { - public static string GetGuidSignature() => GuidGenerator.GetSignature(typeof(IEnumerable)); - - public sealed class AdaptiveFromAbiHelper : FromAbiHelper, global::System.Collections.IEnumerable - { - private readonly Func _enumerator; - - public AdaptiveFromAbiHelper(Type runtimeType, IWinRTObject winRTObject) - :base(winRTObject) - { - Type enumGenericType = (runtimeType.IsGenericType && runtimeType.GetGenericTypeDefinition() == typeof(global::System.Collections.Generic.IEnumerable<>)) ? - runtimeType : runtimeType.GetInterface("System.Collections.Generic.IEnumerable`1"); - if(enumGenericType != null) - { - var getEnumerator = enumGenericType.GetMethod("GetEnumerator"); - _enumerator = (IWinRTObject obj) => (global::System.Collections.IEnumerator)getEnumerator.Invoke(obj, null); - } - } - - public override global::System.Collections.IEnumerator GetEnumerator() => _enumerator != null ? _enumerator(_winrtObject) : base.GetEnumerator(); - } - - public class FromAbiHelper : global::System.Collections.IEnumerable - { - private readonly global::System.Collections.IEnumerable _iterable; - protected readonly IWinRTObject _winrtObject; - - public FromAbiHelper(global::System.Collections.IEnumerable iterable) - { - _iterable = iterable; - } - - protected FromAbiHelper(IWinRTObject winrtObject) - { - _iterable = null; - _winrtObject = winrtObject; - } - - private IWinRTObject GetIterable() - { - return (IWinRTObject)_iterable ?? _winrtObject; - } - - public virtual global::System.Collections.IEnumerator GetEnumerator() => - new Generic.FromAbiEnumerator(new NonGenericToGenericIterator(((global::Microsoft.UI.Xaml.Interop.IBindableIterable) GetIterable()).First())); - - private sealed class NonGenericToGenericIterator : global::Windows.Foundation.Collections.IIterator - { - private readonly IBindableIterator iterator; - - public NonGenericToGenericIterator(IBindableIterator iterator) => this.iterator = iterator; - - public object _Current => iterator.Current; - public bool HasCurrent => iterator.HasCurrent; - public bool _MoveNext() { return iterator.MoveNext(); } - public uint GetMany(ref object[] items) => throw new NotSupportedException(); - } - } - - public sealed class ToAbiHelper : IBindableIterable - { - private readonly IEnumerable m_enumerable; - - internal ToAbiHelper(IEnumerable enumerable) => m_enumerable = enumerable; - - IBindableIterator IBindableIterable.First() => MakeBindableIterator(m_enumerable.GetEnumerator()); - - internal static IBindableIterator MakeBindableIterator(IEnumerator enumerator) => - new Generic.IEnumerator.ToAbiHelper(new NonGenericToGenericEnumerator(enumerator)); - - private sealed class NonGenericToGenericEnumerator : IEnumerator - { - private readonly IEnumerator enumerator; - - public NonGenericToGenericEnumerator(IEnumerator enumerator) => this.enumerator = enumerator; - - public object Current => enumerator.Current; - public bool MoveNext() { return enumerator.MoveNext(); } - public void Reset() { enumerator.Reset(); } - public void Dispose() { } - } - } + public void RemoveAtEnd() + { + if (_list.Count == 0) + { + Exception e = new InvalidOperationException(WinRTRuntimeErrorStrings.InvalidOperation_CannotRemoveLastFromEmptyCollection); + e.SetHResult(ExceptionHelpers.E_BOUNDS); + throw e; + } - public static readonly IntPtr AbiToProjectionVftablePtr; - static IEnumerable() - { - AbiToProjectionVftablePtr = ComWrappersSupport.AllocateVtableMemory(typeof(IEnumerable), sizeof(IInspectable.Vftbl) + sizeof(IntPtr) * 1); - *(IInspectable.Vftbl*)AbiToProjectionVftablePtr = IInspectable.Vftbl.AbiToProjectionVftable; - ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[6] = &Do_Abi_First_0; - } + uint size = (uint)_list.Count; + RemoveAt(size - 1); + } - [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] - private static unsafe int Do_Abi_First_0(IntPtr thisPtr, IntPtr* result) - { - *result = default; - try + public void Clear() { - var __this = global::WinRT.ComWrappersSupport.FindObject(thisPtr); - var iterator = ToAbiHelper.MakeBindableIterator(__this.GetEnumerator()); - *result = MarshalInterface.FromManaged(iterator); + _list.Clear(); } - catch (Exception __exception__) + + private static void EnsureIndexInt32(uint index, int listCapacity) { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + // We use '<=' and not '<' becasue int.MaxValue == index would imply + // that Size > int.MaxValue: + if (((uint)int.MaxValue) <= index || index >= (uint)listCapacity) + { + Exception e = new ArgumentOutOfRangeException(nameof(index), WinRTRuntimeErrorStrings.ArgumentOutOfRange_IndexLargerThanMaxValue); + e.SetHResult(ExceptionHelpers.E_BOUNDS); + throw e; + } } - return 0; - } - - internal static ObjectReference ObjRefFromAbi(IntPtr thisPtr) - { - if (thisPtr == IntPtr.Zero) - { - return null; - } - return ObjectReference.FromAbi(thisPtr); - } - - private static FromAbiHelper _AbiHelper(IWinRTObject _this) - { - return (FromAbiHelper)_this.GetOrCreateTypeHelperData(typeof(global::System.Collections.IEnumerable).TypeHandle, - () => new FromAbiHelper((global::System.Collections.IEnumerable)_this)); - } - - unsafe global::Microsoft.UI.Xaml.Interop.IBindableIterator global::Microsoft.UI.Xaml.Interop.IBindableIterable.First() - { - var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IEnumerable).TypeHandle); - var ThisPtr = _obj.ThisPtr; - IntPtr __retval = default; - try - { - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[6](ThisPtr, &__retval)); - return MarshalInterface.FromAbi(__retval); - } - finally - { - MarshalInterface.DisposeAbi(__retval); - } - } - - IEnumerator global::System.Collections.IEnumerable.GetEnumerator() - { - return _AbiHelper((IWinRTObject)this).GetEnumerator(); - } - } - - [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] -#if EMBED - internal -#else - public -#endif - static class IEnumerable_Delegates - { - public unsafe delegate int First_0(IntPtr thisPtr, IntPtr* result); - } - -#if EMBED - internal -#else - public -#endif - static class IListMethods - { - public static Guid IID { get; } = new Guid(new global::System.ReadOnlySpan(new byte[] { 0xDE, 0xE7, 0x3D, 0x39, 0xD0, 0x6F, 0x0D, 0x4C, 0xBB, 0x71, 0x47, 0x24, 0x4A, 0x11, 0x3E, 0x93 })); - - public static IntPtr AbiToProjectionVftablePtr => IList.AbiToProjectionVftablePtr; - } - [DynamicInterfaceCastableImplementation] - [Guid("393DE7DE-6FD0-4C0D-BB71-47244A113E93")] - internal unsafe interface IList : global::System.Collections.IList, global::Microsoft.UI.Xaml.Interop.IBindableVector - { - public static string GetGuidSignature() => GuidGenerator.GetSignature(typeof(IList)); - - public sealed class FromAbiHelper : global::System.Collections.IList - { - private readonly global::Microsoft.UI.Xaml.Interop.IBindableVector _vector; - - public FromAbiHelper(global::Microsoft.UI.Xaml.Interop.IBindableVector vector) - { - _vector = vector; - } - - public bool IsSynchronized => false; - - public object SyncRoot { get => this; } - - public int Count - { - get - { - uint size = _vector.Size; - if (((uint)int.MaxValue) < size) - { - throw new InvalidOperationException(WinRTRuntimeErrorStrings.InvalidOperation_CollectionBackingListTooLarge); - } - - return (int)size; - } - } - - public void CopyTo(Array array, int arrayIndex) - { - if (array == null) - throw new ArgumentNullException(nameof(array)); - - // ICollection expects the destination array to be single-dimensional. - if (array.Rank != 1) - throw new ArgumentException(WinRTRuntimeErrorStrings.Arg_RankMultiDimNotSupported); - - int destLB = array.GetLowerBound(0); - int srcLen = Count; - int destLen = array.GetLength(0); - - if (arrayIndex < destLB) - throw new ArgumentOutOfRangeException(nameof(arrayIndex)); - - // Does the dimension in question have sufficient space to copy the expected number of entries? - // We perform this check before valid index check to ensure the exception message is in sync with - // the following snippet that uses regular framework code: - // - // ArrayList list = new ArrayList(); - // list.Add(1); - // Array items = Array.CreateInstance(typeof(object), new int[] { 1 }, new int[] { -1 }); - // list.CopyTo(items, 0); - - if (srcLen > (destLen - (arrayIndex - destLB))) - throw new ArgumentException(WinRTRuntimeErrorStrings.Argument_InsufficientSpaceToCopyCollection); - - if (arrayIndex - destLB > destLen) - throw new ArgumentException(WinRTRuntimeErrorStrings.Argument_IndexOutOfArrayBounds); - - // We need to verify the index as we; - for (uint i = 0; i < srcLen; i++) - { - array.SetValue(_vector.GetAt(i), i + arrayIndex); - } - } - - public object this[int index] - { - get => Indexer_Get(index); - set => Indexer_Set(index, value); - } - - internal object Indexer_Get(int index) - { - if (index < 0) - throw new ArgumentOutOfRangeException(nameof(index)); - - return GetAt(_vector, (uint)index); - } - - internal void Indexer_Set(int index, object value) - { - if (index < 0) - throw new ArgumentOutOfRangeException(nameof(index)); - - SetAt(_vector, (uint)index, value); - } - - public int Add(object value) - { - _vector.Append(value); - - uint size = _vector.Size; - if (((uint)int.MaxValue) < size) - { - throw new InvalidOperationException(WinRTRuntimeErrorStrings.InvalidOperation_CollectionBackingListTooLarge); - } - - return (int)(size - 1); - } - - public bool Contains(object item) - { - return _vector.IndexOf(item, out _); - } - - public void Clear() - { - _vector.Clear(); - } - - public bool IsFixedSize { get => false; } - - public bool IsReadOnly { get => false; } - - public int IndexOf(object item) - { - uint index; - bool exists = _vector.IndexOf(item, out index); - - if (!exists) - return -1; - - if (((uint)int.MaxValue) < index) - { - throw new InvalidOperationException(WinRTRuntimeErrorStrings.InvalidOperation_CollectionBackingListTooLarge); - } - - return (int)index; - } - - public void Insert(int index, object item) - { - if (index < 0) - throw new ArgumentOutOfRangeException(nameof(index)); - - InsertAtHelper(_vector, (uint)index, item); - } - - public void Remove(object item) - { - uint index; - bool exists = _vector.IndexOf(item, out index); - - if (exists) - { - if (((uint)int.MaxValue) < index) - { - throw new InvalidOperationException(WinRTRuntimeErrorStrings.InvalidOperation_CollectionBackingListTooLarge); - } - - RemoveAtHelper(_vector, index); - } - } - - public void RemoveAt(int index) - { - if (index < 0) - throw new ArgumentOutOfRangeException(nameof(index)); - - RemoveAtHelper(_vector, (uint)index); - } - - private static object GetAt(global::Microsoft.UI.Xaml.Interop.IBindableVector _this, uint index) - { - try - { - return _this.GetAt(index); - - // We delegate bounds checking to the underlying collection and if it detected a fault, - // we translate it to the right exception: - } - catch (Exception ex) - { - if (ExceptionHelpers.E_BOUNDS == ex.HResult) - throw new ArgumentOutOfRangeException(nameof(index)); - throw; - } - } - - private static void SetAt(global::Microsoft.UI.Xaml.Interop.IBindableVector _this, uint index, object value) - { - try - { - _this.SetAt(index, value); - - // We delegate bounds checking to the underlying collection and if it detected a fault, - // we translate it to the right exception: - } - catch (Exception ex) - { - if (ExceptionHelpers.E_BOUNDS == ex.HResult) - throw new ArgumentOutOfRangeException(nameof(index)); - throw; - } - } - - private static void InsertAtHelper(global::Microsoft.UI.Xaml.Interop.IBindableVector _this, uint index, object item) - { - try - { - _this.InsertAt(index, item); - - // We delegate bounds checking to the underlying collection and if it detected a fault, - // we translate it to the right exception: - } - catch (Exception ex) - { - if (ExceptionHelpers.E_BOUNDS == ex.HResult) - throw new ArgumentOutOfRangeException(nameof(index)); - throw; - } - } - - private static void RemoveAtHelper(global::Microsoft.UI.Xaml.Interop.IBindableVector _this, uint index) - { - try - { - _this.RemoveAt(index); - - // We delegate bounds checking to the underlying collection and if it detected a fault, - // we translate it to the right exception: - } - catch (Exception ex) - { - if (ExceptionHelpers.E_BOUNDS == ex.HResult) - throw new ArgumentOutOfRangeException(nameof(index)); - throw; - } - } - - public IEnumerator GetEnumerator() - { - return ((IEnumerable)(IWinRTObject)_vector).GetEnumerator(); - } - } - - public sealed class ToAbiHelper : IBindableVector - { - private global::System.Collections.IList _list; - - public ToAbiHelper(global::System.Collections.IList list) => _list = list; - - public object GetAt(uint index) - { - EnsureIndexInt32(index, _list.Count); - - try - { - return _list[(int)index]; - } - catch (ArgumentOutOfRangeException ex) - { - throw ex.GetExceptionForHR(ExceptionHelpers.E_BOUNDS, WinRTRuntimeErrorStrings.ArgumentOutOfRange_Index); - } - } - - public uint Size { get => (uint)_list.Count; } - - IBindableVectorView IBindableVector.GetView() - { - return new ListToBindableVectorViewAdapter(_list); - } - - public bool IndexOf(object value, out uint index) - { - int ind = _list.IndexOf(value); - - if (-1 == ind) - { - index = 0; - return false; - } - - index = (uint)ind; - return true; - } - - public void SetAt(uint index, object value) - { - EnsureIndexInt32(index, _list.Count); - - try - { - _list[(int)index] = value; - } - catch (ArgumentOutOfRangeException ex) - { - throw ex.GetExceptionForHR(ExceptionHelpers.E_BOUNDS, WinRTRuntimeErrorStrings.ArgumentOutOfRange_Index); - } - } - - public void InsertAt(uint index, object value) - { - // Inserting at an index one past the end of the list is equivalent to appending - // so we need to ensure that we're within (0, count + 1). - EnsureIndexInt32(index, _list.Count + 1); - - try - { - _list.Insert((int)index, value); - } - catch (ArgumentOutOfRangeException ex) - { - // Change error code to match what WinRT expects - ex.SetHResult(ExceptionHelpers.E_BOUNDS); - throw; - } - } - - public void RemoveAt(uint index) - { - EnsureIndexInt32(index, _list.Count); - - try - { - _list.RemoveAt((int)index); - } - catch (ArgumentOutOfRangeException ex) - { - // Change error code to match what WinRT expects - ex.SetHResult(ExceptionHelpers.E_BOUNDS); - throw; - } - } - - public void Append(object value) - { - _list.Add(value); - } - - public void RemoveAtEnd() - { - if (_list.Count == 0) - { - Exception e = new InvalidOperationException(WinRTRuntimeErrorStrings.InvalidOperation_CannotRemoveLastFromEmptyCollection); - e.SetHResult(ExceptionHelpers.E_BOUNDS); - throw e; - } - - uint size = (uint)_list.Count; - RemoveAt(size - 1); - } - - public void Clear() - { - _list.Clear(); - } - - private static void EnsureIndexInt32(uint index, int listCapacity) - { - // We use '<=' and not '<' becasue int.MaxValue == index would imply - // that Size > int.MaxValue: - if (((uint)int.MaxValue) <= index || index >= (uint)listCapacity) - { - Exception e = new ArgumentOutOfRangeException(nameof(index), WinRTRuntimeErrorStrings.ArgumentOutOfRange_IndexLargerThanMaxValue); - e.SetHResult(ExceptionHelpers.E_BOUNDS); - throw e; - } - } - public IEnumerator GetEnumerator() => _list.GetEnumerator(); - internal sealed class ListToBindableVectorViewAdapterTypeDetails : IWinRTExposedTypeDetails + /// A Windows Runtime IBindableVectorView implementation that wraps around a managed IList exposing + /// it to Windows runtime interop. + internal sealed class ListToBindableVectorViewAdapter : WUX.IBindableVectorView, MUX.IBindableVectorView, IBindableVectorViewAdapter { - public ComWrappers.ComInterfaceEntry[] GetExposedInterfaces() + private readonly global::System.Collections.IList list; + + internal ListToBindableVectorViewAdapter(global::System.Collections.IList list) + { + if (list == null) + throw new ArgumentNullException(nameof(list)); + this.list = list; + } + + private static void EnsureIndexInt32(uint index, int listCapacity) { - return new ComWrappers.ComInterfaceEntry[] + // We use '<=' and not '<' becasue int.MaxValue == index would imply + // that Size > int.MaxValue: + if (((uint)int.MaxValue) <= index || index >= (uint)listCapacity) { - new ComWrappers.ComInterfaceEntry - { - IID = ABI.Microsoft.UI.Xaml.Interop.IBindableVectorView.IID, - Vtable = ABI.Microsoft.UI.Xaml.Interop.IBindableVectorView.AbiToProjectionVftablePtr - }, - new ComWrappers.ComInterfaceEntry - { - IID = ABI.System.Collections.IEnumerableMethods.IID, - Vtable = ABI.System.Collections.IEnumerableMethods.AbiToProjectionVftablePtr - } - }; + Exception e = new ArgumentOutOfRangeException(nameof(index), WinRTRuntimeErrorStrings.ArgumentOutOfRange_IndexLargerThanMaxValue); + e.SetHResult(ExceptionHelpers.E_BOUNDS); + throw e; + } } - } - /// A Windows Runtime IBindableVectorView implementation that wraps around a managed IList exposing - /// it to Windows runtime interop. - [global::WinRT.WinRTExposedType(typeof(ListToBindableVectorViewAdapterTypeDetails))] - internal sealed class ListToBindableVectorViewAdapter : IBindableVectorView - { - private readonly global::System.Collections.IList list; - - internal ListToBindableVectorViewAdapter(global::System.Collections.IList list) - { - if (list == null) - throw new ArgumentNullException(nameof(list)); - this.list = list; - } - - private static void EnsureIndexInt32(uint index, int listCapacity) - { - // We use '<=' and not '<' becasue int.MaxValue == index would imply - // that Size > int.MaxValue: - if (((uint)int.MaxValue) <= index || index >= (uint)listCapacity) - { - Exception e = new ArgumentOutOfRangeException(nameof(index), WinRTRuntimeErrorStrings.ArgumentOutOfRange_IndexLargerThanMaxValue); - e.SetHResult(ExceptionHelpers.E_BOUNDS); - throw e; - } - } - - public IBindableIterator First() => - IEnumerable.ToAbiHelper.MakeBindableIterator(list.GetEnumerator()); - - public object GetAt(uint index) - { - EnsureIndexInt32(index, list.Count); - - try - { - return list[(int)index]; - } - catch (ArgumentOutOfRangeException ex) - { - throw ex.GetExceptionForHR(ExceptionHelpers.E_BOUNDS, WinRTRuntimeErrorStrings.ArgumentOutOfRange_Index); - } - } - - public uint Size => (uint)list.Count; - - public bool IndexOf(object value, out uint index) - { - int ind = list.IndexOf(value); - - if (-1 == ind) - { - index = 0; - return false; - } - - index = (uint)ind; - return true; - } - - public IEnumerator GetEnumerator() => list.GetEnumerator(); - } + public object GetAt(uint index) + { + EnsureIndexInt32(index, list.Count); + + try + { + return list[(int)index]; + } + catch (ArgumentOutOfRangeException ex) + { + throw ex.GetExceptionForHR(ExceptionHelpers.E_BOUNDS, WinRTRuntimeErrorStrings.ArgumentOutOfRange_Index); + } + } + + public uint Size => (uint)list.Count; + + public bool IndexOf(object value, out uint index) + { + int ind = list.IndexOf(value); + + if (-1 == ind) + { + index = 0; + return false; + } + + index = (uint)ind; + return true; + } + + public IEnumerator GetEnumerator() => list.GetEnumerator(); + } } - public static readonly IntPtr AbiToProjectionVftablePtr; + public static readonly IntPtr AbiToProjectionVftablePtr; static IList() { - AbiToProjectionVftablePtr = ComWrappersSupport.AllocateVtableMemory(typeof(IList), sizeof(IInspectable.Vftbl) + sizeof(IntPtr) * 10); - *(IInspectable.Vftbl*)AbiToProjectionVftablePtr = IInspectable.Vftbl.AbiToProjectionVftable; + AbiToProjectionVftablePtr = ComWrappersSupport.AllocateVtableMemory(typeof(IList), sizeof(IInspectable.Vftbl) + sizeof(IntPtr) * 10); + *(IInspectable.Vftbl*)AbiToProjectionVftablePtr = IInspectable.Vftbl.AbiToProjectionVftable; ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[6] = &Do_Abi_GetAt_0; - ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[7] = &Do_Abi_get_Size_1; - ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[8] = &Do_Abi_GetView_2; - ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[9] = &Do_Abi_IndexOf_3; - ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[10] = &Do_Abi_SetAt_4; - ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[11] = &Do_Abi_InsertAt_5; - ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[12] = &Do_Abi_RemoveAt_6; - ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[13] = &Do_Abi_Append_7; - ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[14] = &Do_Abi_RemoveAtEnd_8; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[7] = &Do_Abi_get_Size_1; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[8] = Projections.UiXamlModeSetting is Projections.UiXamlMode.WindowsUiXaml ? &Do_Wux_Abi_GetView_2 : &Do_Mux_Abi_GetView_2; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[9] = &Do_Abi_IndexOf_3; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[10] = &Do_Abi_SetAt_4; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[11] = &Do_Abi_InsertAt_5; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[12] = &Do_Abi_RemoveAt_6; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[13] = &Do_Abi_Append_7; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[14] = &Do_Abi_RemoveAtEnd_8; ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[15] = &Do_Abi_Clear_9; } private static readonly ConditionalWeakTable _adapterTable = new(); - private static IBindableVector FindAdapter(IntPtr thisPtr) + private static IBindableVectorAdapter FindAdapter(IntPtr thisPtr) { var __this = global::WinRT.ComWrappersSupport.FindObject(thisPtr); return _adapterTable.GetValue(__this, (list) => new ToAbiHelper(list)); @@ -1055,14 +805,32 @@ private static unsafe int Do_Abi_GetAt_0(IntPtr thisPtr, uint index, IntPtr* res } [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] - private static unsafe int Do_Abi_GetView_2(IntPtr thisPtr, IntPtr* result) + private static unsafe int Do_Wux_Abi_GetView_2(IntPtr thisPtr, IntPtr* result) + { + IBindableVectorViewAdapter __result = default; + *result = default; + try + { + __result = FindAdapter(thisPtr).GetView(); + *result = MarshalInterface.FromManaged((WUX.IBindableVectorView)__result); + } + catch (Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + + [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] + private static unsafe int Do_Mux_Abi_GetView_2(IntPtr thisPtr, IntPtr* result) { - global::Microsoft.UI.Xaml.Interop.IBindableVectorView __result = default; + IBindableVectorViewAdapter __result = default; *result = default; try { __result = FindAdapter(thisPtr).GetView(); - *result = MarshalInterface.FromManaged(__result); + *result = MarshalInterface.FromManaged((MUX.IBindableVectorView)__result); } catch (Exception __exception__) { @@ -1201,202 +969,344 @@ private static unsafe int Do_Abi_get_Size_1(IntPtr thisPtr, uint* value) return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); } return 0; - } - - internal static ObjectReference ObjRefFromAbi(IntPtr thisPtr) - { - if (thisPtr == IntPtr.Zero) - { - return null; - } - return ObjectReference.FromAbi(thisPtr); - } - - internal static FromAbiHelper _VectorToList(IWinRTObject _this) - { - return (FromAbiHelper)_this.GetOrCreateTypeHelperData(typeof(global::System.Collections.IList).TypeHandle, - () => new FromAbiHelper((global::Microsoft.UI.Xaml.Interop.IBindableVector)_this)); - } - - unsafe object global::Microsoft.UI.Xaml.Interop.IBindableVector.GetAt(uint index) - { - var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); - var ThisPtr = _obj.ThisPtr; - IntPtr __retval = default; - try - { - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[6](ThisPtr, index, &__retval)); - return MarshalInspectable.FromAbi(__retval); - } - finally - { - MarshalInspectable.DisposeAbi(__retval); - } - } - - unsafe global::Microsoft.UI.Xaml.Interop.IBindableVectorView global::Microsoft.UI.Xaml.Interop.IBindableVector.GetView() - { - var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); - var ThisPtr = _obj.ThisPtr; - IntPtr __retval = default; - try - { - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[8](ThisPtr, &__retval)); - return MarshalInterface.FromAbi(__retval); - } - finally - { - MarshalInterface.DisposeAbi(__retval); - } - } - - unsafe bool global::Microsoft.UI.Xaml.Interop.IBindableVector.IndexOf(object value, out uint index) - { - var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); - var ThisPtr = _obj.ThisPtr; - ObjectReferenceValue __value = default; - uint __index = default; - byte __retval = default; - try - { + } + + internal static ObjectReference ObjRefFromAbi(IntPtr thisPtr) + { + if (thisPtr == IntPtr.Zero) + { + return null; + } + return ObjectReference.FromAbi(thisPtr); + } + + internal static FromAbiHelper _VectorToList(IWinRTObject _this) + { + IBindableVectorAdapter adapter = null; + if (Projections.UiXamlModeSetting is Projections.UiXamlMode.WindowsUiXaml) + { + adapter = new WuxBindableVectorAdapter((WUX.IBindableVector)_this); + } + else + { + adapter = new MuxBindableVectorAdapter((MUX.IBindableVector)_this); + } + return (FromAbiHelper)_this.GetOrCreateTypeHelperData(typeof(global::System.Collections.IList).TypeHandle, + () => new FromAbiHelper(adapter)); + } + + unsafe object WUX.IBindableVector.GetAt(uint index) + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); + var ThisPtr = _obj.ThisPtr; + IntPtr __retval = default; + try + { + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[6](ThisPtr, index, &__retval)); + return MarshalInspectable.FromAbi(__retval); + } + finally + { + MarshalInspectable.DisposeAbi(__retval); + } + } + + unsafe WUX.IBindableVectorView WUX.IBindableVector.GetView() + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); + var ThisPtr = _obj.ThisPtr; + IntPtr __retval = default; + try + { + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[8](ThisPtr, &__retval)); + return MarshalInterface.FromAbi(__retval); + } + finally + { + MarshalInterface.DisposeAbi(__retval); + } + } + + unsafe bool WUX.IBindableVector.IndexOf(object value, out uint index) + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); + var ThisPtr = _obj.ThisPtr; + ObjectReferenceValue __value = default; + uint __index = default; + byte __retval = default; + try + { + __value = MarshalInspectable.CreateMarshaler2(value); + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[9](ThisPtr, MarshalInspectable.GetAbi(__value), &__index, &__retval)); + index = __index; + return __retval != 0; + } + finally + { + MarshalInspectable.DisposeMarshaler(__value); + } + } + + unsafe void WUX.IBindableVector.SetAt(uint index, object value) + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); + var ThisPtr = _obj.ThisPtr; + ObjectReferenceValue __value = default; + try + { + __value = MarshalInspectable.CreateMarshaler2(value); + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[10](ThisPtr, index, MarshalInspectable.GetAbi(__value))); + } + finally + { + MarshalInspectable.DisposeMarshaler(__value); + } + } + + unsafe void WUX.IBindableVector.InsertAt(uint index, object value) + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); + var ThisPtr = _obj.ThisPtr; + ObjectReferenceValue __value = default; + try + { + __value = MarshalInspectable.CreateMarshaler2(value); + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[11](ThisPtr, index, MarshalInspectable.GetAbi(__value))); + } + finally + { + MarshalInspectable.DisposeMarshaler(__value); + } + } + + unsafe void WUX.IBindableVector.RemoveAt(uint index) + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); + var ThisPtr = _obj.ThisPtr; + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[12](ThisPtr, index)); + } + + unsafe void WUX.IBindableVector.Append(object value) + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); + var ThisPtr = _obj.ThisPtr; + ObjectReferenceValue __value = default; + try + { + __value = MarshalInspectable.CreateMarshaler2(value); + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[13](ThisPtr, MarshalInspectable.GetAbi(__value))); + } + finally + { + MarshalInspectable.DisposeMarshaler(__value); + } + } + + unsafe void WUX.IBindableVector.RemoveAtEnd() + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); + var ThisPtr = _obj.ThisPtr; + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[14](ThisPtr)); + } + + unsafe void WUX.IBindableVector.Clear() + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); + var ThisPtr = _obj.ThisPtr; + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[15](ThisPtr)); + } + + unsafe uint WUX.IBindableVector.Size + { + get + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); + var ThisPtr = _obj.ThisPtr; + uint __retval = default; + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[7](ThisPtr, &__retval)); + return __retval; + } + } + + unsafe object MUX.IBindableVector.GetAt(uint index) + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); + var ThisPtr = _obj.ThisPtr; + IntPtr __retval = default; + try + { + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[6](ThisPtr, index, &__retval)); + return MarshalInspectable.FromAbi(__retval); + } + finally + { + MarshalInspectable.DisposeAbi(__retval); + } + } + + unsafe MUX.IBindableVectorView MUX.IBindableVector.GetView() + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); + var ThisPtr = _obj.ThisPtr; + IntPtr __retval = default; + try + { + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[8](ThisPtr, &__retval)); + return MarshalInterface.FromAbi(__retval); + } + finally + { + MarshalInterface.DisposeAbi(__retval); + } + } + + unsafe bool MUX.IBindableVector.IndexOf(object value, out uint index) + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); + var ThisPtr = _obj.ThisPtr; + ObjectReferenceValue __value = default; + uint __index = default; + byte __retval = default; + try + { __value = MarshalInspectable.CreateMarshaler2(value); - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[9](ThisPtr, MarshalInspectable.GetAbi(__value), &__index, &__retval)); - index = __index; - return __retval != 0; - } - finally - { - MarshalInspectable.DisposeMarshaler(__value); - } - } - - unsafe void global::Microsoft.UI.Xaml.Interop.IBindableVector.SetAt(uint index, object value) - { - var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); - var ThisPtr = _obj.ThisPtr; - ObjectReferenceValue __value = default; - try - { + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[9](ThisPtr, MarshalInspectable.GetAbi(__value), &__index, &__retval)); + index = __index; + return __retval != 0; + } + finally + { + MarshalInspectable.DisposeMarshaler(__value); + } + } + + unsafe void MUX.IBindableVector.SetAt(uint index, object value) + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); + var ThisPtr = _obj.ThisPtr; + ObjectReferenceValue __value = default; + try + { __value = MarshalInspectable.CreateMarshaler2(value); - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[10](ThisPtr, index, MarshalInspectable.GetAbi(__value))); - } - finally - { - MarshalInspectable.DisposeMarshaler(__value); - } - } - - unsafe void global::Microsoft.UI.Xaml.Interop.IBindableVector.InsertAt(uint index, object value) - { - var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); - var ThisPtr = _obj.ThisPtr; - ObjectReferenceValue __value = default; - try - { + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[10](ThisPtr, index, MarshalInspectable.GetAbi(__value))); + } + finally + { + MarshalInspectable.DisposeMarshaler(__value); + } + } + + unsafe void MUX.IBindableVector.InsertAt(uint index, object value) + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); + var ThisPtr = _obj.ThisPtr; + ObjectReferenceValue __value = default; + try + { __value = MarshalInspectable.CreateMarshaler2(value); - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[11](ThisPtr, index, MarshalInspectable.GetAbi(__value))); - } - finally - { - MarshalInspectable.DisposeMarshaler(__value); - } - } - - unsafe void global::Microsoft.UI.Xaml.Interop.IBindableVector.RemoveAt(uint index) - { - var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[11](ThisPtr, index, MarshalInspectable.GetAbi(__value))); + } + finally + { + MarshalInspectable.DisposeMarshaler(__value); + } + } + + unsafe void MUX.IBindableVector.RemoveAt(uint index) + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); + var ThisPtr = _obj.ThisPtr; + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[12](ThisPtr, index)); + } + + unsafe void MUX.IBindableVector.Append(object value) + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); var ThisPtr = _obj.ThisPtr; - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[12](ThisPtr, index)); - } - - unsafe void global::Microsoft.UI.Xaml.Interop.IBindableVector.Append(object value) - { - var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); - var ThisPtr = _obj.ThisPtr; - ObjectReferenceValue __value = default; - try - { + ObjectReferenceValue __value = default; + try + { __value = MarshalInspectable.CreateMarshaler2(value); - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[13](ThisPtr, MarshalInspectable.GetAbi(__value))); - } - finally - { - MarshalInspectable.DisposeMarshaler(__value); - } - } - - unsafe void global::Microsoft.UI.Xaml.Interop.IBindableVector.RemoveAtEnd() - { - var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[13](ThisPtr, MarshalInspectable.GetAbi(__value))); + } + finally + { + MarshalInspectable.DisposeMarshaler(__value); + } + } + + unsafe void MUX.IBindableVector.RemoveAtEnd() + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); var ThisPtr = _obj.ThisPtr; - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[14](ThisPtr)); - } - - unsafe void global::Microsoft.UI.Xaml.Interop.IBindableVector.Clear() - { - var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[14](ThisPtr)); + } + + unsafe void MUX.IBindableVector.Clear() + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); var ThisPtr = _obj.ThisPtr; - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[15](ThisPtr)); - } - - unsafe uint global::Microsoft.UI.Xaml.Interop.IBindableVector.Size - { - get - { - var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); - var ThisPtr = _obj.ThisPtr; + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[15](ThisPtr)); + } + + unsafe uint MUX.IBindableVector.Size + { + get + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); + var ThisPtr = _obj.ThisPtr; uint __retval = default; - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[7](ThisPtr, &__retval)); - return __retval; - } - } - - object global::System.Collections.IList.this[int index] - { - get => _VectorToList((IWinRTObject)this)[index]; - - set => _VectorToList((IWinRTObject)this)[index] = value; - } - - bool global::System.Collections.IList.IsFixedSize => _VectorToList((IWinRTObject)this).IsFixedSize; - - bool global::System.Collections.IList.IsReadOnly => _VectorToList((IWinRTObject)this).IsReadOnly; - - int global::System.Collections.ICollection.Count => _VectorToList((IWinRTObject)this).Count; - - bool global::System.Collections.ICollection.IsSynchronized => _VectorToList((IWinRTObject)this).IsSynchronized; - - object global::System.Collections.ICollection.SyncRoot => _VectorToList((IWinRTObject)this).SyncRoot; - - int global::System.Collections.IList.Add(object value) => _VectorToList((IWinRTObject)this).Add(value); - - void global::System.Collections.IList.Clear() => _VectorToList((IWinRTObject)this).Clear(); - - bool global::System.Collections.IList.Contains(object value) => _VectorToList((IWinRTObject)this).Contains(value); - - int global::System.Collections.IList.IndexOf(object value) => _VectorToList((IWinRTObject)this).IndexOf(value); - - void global::System.Collections.IList.Insert(int index, object value) => _VectorToList((IWinRTObject)this).Insert(index, value); - - void global::System.Collections.IList.Remove(object value) => _VectorToList((IWinRTObject)this).Remove(value); - - void global::System.Collections.IList.RemoveAt(int index) => _VectorToList((IWinRTObject)this).RemoveAt(index); - - void global::System.Collections.ICollection.CopyTo(Array array, int index) => _VectorToList((IWinRTObject)this).CopyTo(array, index); - - IEnumerator global::System.Collections.IEnumerable.GetEnumerator() => _VectorToList((IWinRTObject)this).GetEnumerator(); - } - internal static class IList_Delegates - { - public unsafe delegate int GetAt_0(IntPtr thisPtr, uint index, IntPtr* result); - public unsafe delegate int get_Size_1(IntPtr thisPtr, uint* result); - public unsafe delegate int GetView_2(IntPtr thisPtr, IntPtr* result); - public unsafe delegate int IndexOf_3(IntPtr thisPtr, IntPtr value, uint* index, byte* returnValue); - public unsafe delegate int SetAt_4(IntPtr thisPtr, uint index, IntPtr value); - public unsafe delegate int InsertAt_5(IntPtr thisPtr, uint index, IntPtr value); - public unsafe delegate int RemoveAt_6(IntPtr thisPtr, uint index); - public unsafe delegate int Append_7(IntPtr thisPtr, IntPtr value); - public unsafe delegate int RemoveAtEnd_8(IntPtr thisPtr); - public unsafe delegate int Clear_9(IntPtr thisPtr); - } -} + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[7](ThisPtr, &__retval)); + return __retval; + } + } + + object global::System.Collections.IList.this[int index] + { + get => _VectorToList((IWinRTObject)this)[index]; + + set => _VectorToList((IWinRTObject)this)[index] = value; + } + + bool global::System.Collections.IList.IsFixedSize => _VectorToList((IWinRTObject)this).IsFixedSize; + + bool global::System.Collections.IList.IsReadOnly => _VectorToList((IWinRTObject)this).IsReadOnly; + + int global::System.Collections.ICollection.Count => _VectorToList((IWinRTObject)this).Count; + + bool global::System.Collections.ICollection.IsSynchronized => _VectorToList((IWinRTObject)this).IsSynchronized; + + object global::System.Collections.ICollection.SyncRoot => _VectorToList((IWinRTObject)this).SyncRoot; + + int global::System.Collections.IList.Add(object value) => _VectorToList((IWinRTObject)this).Add(value); + + void global::System.Collections.IList.Clear() => _VectorToList((IWinRTObject)this).Clear(); + + bool global::System.Collections.IList.Contains(object value) => _VectorToList((IWinRTObject)this).Contains(value); + + int global::System.Collections.IList.IndexOf(object value) => _VectorToList((IWinRTObject)this).IndexOf(value); + + void global::System.Collections.IList.Insert(int index, object value) => _VectorToList((IWinRTObject)this).Insert(index, value); + + void global::System.Collections.IList.Remove(object value) => _VectorToList((IWinRTObject)this).Remove(value); + + void global::System.Collections.IList.RemoveAt(int index) => _VectorToList((IWinRTObject)this).RemoveAt(index); + + void global::System.Collections.ICollection.CopyTo(Array array, int index) => _VectorToList((IWinRTObject)this).CopyTo(array, index); + + IEnumerator global::System.Collections.IEnumerable.GetEnumerator() => _VectorToList((IWinRTObject)this).GetEnumerator(); + } + internal static class IList_Delegates + { + public unsafe delegate int GetAt_0(IntPtr thisPtr, uint index, IntPtr* result); + public unsafe delegate int get_Size_1(IntPtr thisPtr, uint* result); + public unsafe delegate int GetView_2(IntPtr thisPtr, IntPtr* result); + public unsafe delegate int IndexOf_3(IntPtr thisPtr, IntPtr value, uint* index, byte* returnValue); + public unsafe delegate int SetAt_4(IntPtr thisPtr, uint index, IntPtr value); + public unsafe delegate int InsertAt_5(IntPtr thisPtr, uint index, IntPtr value); + public unsafe delegate int RemoveAt_6(IntPtr thisPtr, uint index); + public unsafe delegate int Append_7(IntPtr thisPtr, IntPtr value); + public unsafe delegate int RemoveAtEnd_8(IntPtr thisPtr); + public unsafe delegate int Clear_9(IntPtr thisPtr); + } +} diff --git a/src/WinRT.Runtime/Projections/ICommand.net5.cs b/src/WinRT.Runtime/Projections/ICommand.net5.cs index 8f6ca008a..1f4c89b8c 100644 --- a/src/WinRT.Runtime/Projections/ICommand.net5.cs +++ b/src/WinRT.Runtime/Projections/ICommand.net5.cs @@ -20,6 +20,7 @@ static class ICommandMethods public static IntPtr AbiToProjectionVftablePtr => ICommand.Vftbl.AbiToProjectionVftablePtr; } + // ICommand has the same IID for both Windows.UI.Xaml.Input.ICommand and Microsoft.UI.Xaml.Input.ICommand, so we can use one interface definition for both without marking it as a WUX/MUX type. [EditorBrowsable(EditorBrowsableState.Never)] [Guid("E5AF3542-CA67-4081-995B-709DD13792DF")] [DynamicInterfaceCastableImplementation] diff --git a/src/WinRT.Runtime/Projections/ICustomPropertyProvider.net5.cs b/src/WinRT.Runtime/Projections/ICustomPropertyProvider.net5.cs index ca33a3457..0684e4cf5 100644 --- a/src/WinRT.Runtime/Projections/ICustomPropertyProvider.net5.cs +++ b/src/WinRT.Runtime/Projections/ICustomPropertyProvider.net5.cs @@ -6,6 +6,8 @@ using System.Runtime.InteropServices; using WinRT; +// These types have the same GUIDs in both Microsoft.UI.Xaml and Windows.UI.Xaml, +// so we don't need to duplicate them for the internal usage here as they can be transparently used by both WUX and MUX. namespace Microsoft.UI.Xaml.Data { [global::WinRT.WindowsRuntimeType] diff --git a/src/WinRT.Runtime/Projections/IEnumerable.net5.cs b/src/WinRT.Runtime/Projections/IEnumerable.net5.cs index e27a07dc4..334efee24 100644 --- a/src/WinRT.Runtime/Projections/IEnumerable.net5.cs +++ b/src/WinRT.Runtime/Projections/IEnumerable.net5.cs @@ -938,7 +938,7 @@ public static void DisposeAbi(IntPtr abi) => // In IEnumerator<> scenarios, we use this as a helper for the implementation and don't actually use it to // create a CCW. [global::WinRT.WinRTExposedType(typeof(IBindableIteratorTypeDetails))] - public sealed class ToAbiHelper : global::Windows.Foundation.Collections.IIterator, global::Microsoft.UI.Xaml.Interop.IBindableIterator + public sealed class ToAbiHelper : global::Windows.Foundation.Collections.IIterator, global::Microsoft.UI.Xaml.Interop.IBindableIterator, global::Windows.UI.Xaml.Interop.IBindableIterator { private readonly global::System.Collections.Generic.IEnumerator m_enumerator; private bool m_firstItem = true; @@ -1033,6 +1033,11 @@ public uint GetMany(ref T[] items) // Should not be called. throw new NotImplementedException(); } + uint global::Windows.UI.Xaml.Interop.IBindableIterator.GetMany(ref object[] items) + { + // Should not be called. + throw new NotImplementedException(); + } } public static readonly IntPtr AbiToProjectionVftablePtr; diff --git a/src/WinRT.Runtime/Projections/INotifyCollectionChanged.net5.cs b/src/WinRT.Runtime/Projections/INotifyCollectionChanged.net5.cs index 7c0d94350..161d7cf8e 100644 --- a/src/WinRT.Runtime/Projections/INotifyCollectionChanged.net5.cs +++ b/src/WinRT.Runtime/Projections/INotifyCollectionChanged.net5.cs @@ -1,20 +1,22 @@ -// Copyright (c) Microsoft Corporation. +// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. using System; using System.ComponentModel; +using System.Reflection; using System.Runtime.InteropServices; using WinRT; +using WinRT.Interop; namespace ABI.System.Collections.Specialized -{ +{ #if EMBED - internal + internal #else public #endif - static class INotifyCollectionChangedMethods - { + static class INotifyCollectionChangedMethods + { private volatile static global::System.Runtime.CompilerServices.ConditionalWeakTable _CollectionChanged; private static global::System.Runtime.CompilerServices.ConditionalWeakTable MakeCollectionChangedTable() { @@ -23,7 +25,7 @@ static class INotifyCollectionChangedMethods } private static global::System.Runtime.CompilerServices.ConditionalWeakTable CollectionChanged => _CollectionChanged ?? MakeCollectionChangedTable(); - + public static unsafe (Action, Action) Get_CollectionChanged(IObjectReference obj, object thisObj) { var eventSource = _CollectionChanged.GetValue(thisObj, (key) => @@ -35,19 +37,20 @@ public static unsafe (Action**)ThisPtr)[7]); }); return eventSource.EventActions; - } - - public static global::System.Guid IID { get; } = new Guid(new global::System.ReadOnlySpan(new byte[] { 0xE1, 0x55, 0x01, 0x53, 0xA5, 0x28, 0x93, 0x56, 0x87, 0xCE, 0x30, 0x72, 0x4D, 0x95, 0xA0, 0x6D })); - - public static IntPtr AbiToProjectionVftablePtr => INotifyCollectionChanged.Vftbl.AbiToProjectionVftablePtr; + } + + public static global::System.Guid IID { get; } = GuidGenerator.GetWuxMuxIID(typeof(INotifyCollectionChanged).GetCustomAttribute()); + public static IntPtr AbiToProjectionVftablePtr => INotifyCollectionChanged.Vftbl.AbiToProjectionVftablePtr; } [DynamicInterfaceCastableImplementation] [EditorBrowsable(EditorBrowsableState.Never)] - [Guid("530155E1-28A5-5693-87CE-30724D95A06D")] + [Guid("530155E1-28A5-5693-87CE-30724D95A06D")] + [WuxMuxProjectedType(wuxIID: "CF75D69C-F2F4-486B-B302-BB4C09BAEBFA", muxIID: "530155E1-28A5-5693-87CE-30724D95A06D")] internal unsafe interface INotifyCollectionChanged : global::System.Collections.Specialized.INotifyCollectionChanged { [Guid("530155E1-28A5-5693-87CE-30724D95A06D")] + [WuxMuxProjectedType(wuxIID: "CF75D69C-F2F4-486B-B302-BB4C09BAEBFA", muxIID: "530155E1-28A5-5693-87CE-30724D95A06D")] public struct Vftbl { internal IInspectable.Vftbl IInspectableVftbl; @@ -76,15 +79,15 @@ static unsafe Vftbl() } private volatile static global::System.Runtime.CompilerServices.ConditionalWeakTable> _collectionChanged_TokenTables; - - private static global::System.Runtime.CompilerServices.ConditionalWeakTable> MakeConditionalWeakTable() - { - global::System.Threading.Interlocked.CompareExchange(ref _collectionChanged_TokenTables, new(), null); - return _collectionChanged_TokenTables; + + private static global::System.Runtime.CompilerServices.ConditionalWeakTable> MakeConditionalWeakTable() + { + global::System.Threading.Interlocked.CompareExchange(ref _collectionChanged_TokenTables, new(), null); + return _collectionChanged_TokenTables; } - private static global::System.Runtime.CompilerServices.ConditionalWeakTable> _CollectionChanged_TokenTables => _collectionChanged_TokenTables ?? MakeConditionalWeakTable(); - + private static global::System.Runtime.CompilerServices.ConditionalWeakTable> _CollectionChanged_TokenTables => _collectionChanged_TokenTables ?? MakeConditionalWeakTable(); + [UnmanagedCallersOnly] private static unsafe int Do_Abi_add_CollectionChanged_0(IntPtr thisPtr, IntPtr handler, global::WinRT.EventRegistrationToken* token) { @@ -134,5 +137,5 @@ private static (Action _CollectionChanged((IWinRTObject)this).Item1(value); remove => _CollectionChanged((IWinRTObject)this).Item2(value); } - } + } } diff --git a/src/WinRT.Runtime/Projections/INotifyPropertyChanged.net5.cs b/src/WinRT.Runtime/Projections/INotifyPropertyChanged.net5.cs index 576c284f8..558e8e46c 100644 --- a/src/WinRT.Runtime/Projections/INotifyPropertyChanged.net5.cs +++ b/src/WinRT.Runtime/Projections/INotifyPropertyChanged.net5.cs @@ -2,31 +2,36 @@ // Licensed under the MIT License. using System; +using System.Reflection; using System.Runtime.InteropServices; using WinRT; +using WinRT.Interop; namespace ABI.System.ComponentModel -{ +{ #if EMBED internal #else public #endif static class INotifyPropertyChangedMethods - { - public static global::System.Guid IID { get; } = new Guid(new global::System.ReadOnlySpan(new byte[] { 0x01, 0x76, 0xB1, 0x90, 0x65, 0xB0, 0x6E, 0x58, 0x83, 0xD9, 0x9A, 0xDC, 0x3A, 0x69, 0x52, 0x84 })); + { + public static global::System.Guid IID { get; } = GuidGenerator.GetWuxMuxIID(typeof(INotifyPropertyChanged).GetCustomAttribute()); public static IntPtr AbiToProjectionVftablePtr => INotifyPropertyChanged.Vftbl.AbiToProjectionVftablePtr; } [DynamicInterfaceCastableImplementation] [Guid("90B17601-B065-586E-83D9-9ADC3A695284")] + [WuxMuxProjectedType(wuxIID: "CF75D69C-F2F4-486B-B302-BB4C09BAEBFA", muxIID: "90B17601-B065-586E-83D9-9ADC3A695284")] internal unsafe interface INotifyPropertyChanged : global::System.ComponentModel.INotifyPropertyChanged { [Guid("90B17601-B065-586E-83D9-9ADC3A695284")] [StructLayout(LayoutKind.Sequential)] + [WuxMuxProjectedType(wuxIID: "CF75D69C-F2F4-486B-B302-BB4C09BAEBFA", muxIID: "90B17601-B065-586E-83D9-9ADC3A695284")] public struct Vftbl { + internal IInspectable.Vftbl IInspectableVftbl; private delegate* unmanaged _add_PropertyChanged_0; @@ -67,6 +72,7 @@ private static unsafe int Do_Abi_add_PropertyChanged_0(IntPtr thisPtr, IntPtr ha *token = default; try { + global::System.Diagnostics.Debugger.Launch(); var __this = global::WinRT.ComWrappersSupport.FindObject(thisPtr); var __handler = global::ABI.System.ComponentModel.PropertyChangedEventHandler.FromAbi(handler); *token = _PropertyChanged_TokenTables.GetOrCreateValue(__this).AddEventHandler(__handler); diff --git a/src/WinRT.Runtime/Projections/Microsoft.UI.Xaml.Bindable.net5.cs b/src/WinRT.Runtime/Projections/Microsoft.UI.Xaml.Bindable.net5.cs new file mode 100644 index 000000000..95397bad6 --- /dev/null +++ b/src/WinRT.Runtime/Projections/Microsoft.UI.Xaml.Bindable.net5.cs @@ -0,0 +1,367 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using WinRT; +using WinRT.Interop; + + +#pragma warning disable 0169 // warning CS0169: The field '...' is never used +#pragma warning disable 0649 // warning CS0169: Field '...' is never assigned to + +namespace Microsoft.UI.Xaml.Interop +{ + [global::WinRT.WindowsRuntimeType] + [Guid("036D2C08-DF29-41AF-8AA2-D774BE62BA6F")] + [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Microsoft.UI.Xaml.Interop.IBindableIterable))] + internal interface IBindableIterable + { + IBindableIterator First(); + } + [global::WinRT.WindowsRuntimeType] + [Guid("6A1D6C07-076D-49F2-8314-F52C9C9A8331")] + [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Microsoft.UI.Xaml.Interop.IBindableIterator))] + internal interface IBindableIterator + { + bool MoveNext(); + // GetMany is not implemented by IBindableIterator, but it is here + // for compat purposes with WinUI where there are scenarios they do + // reinterpret_cast from IBindableIterator to IIterable. It is + // the last function in the vftable and shouldn't be called by anyone. + // If called, it will return NotImplementedException. + uint GetMany(ref object[] items); + object Current { get; } + bool HasCurrent { get; } + } + [global::WinRT.WindowsRuntimeType] + [Guid("393DE7DE-6FD0-4C0D-BB71-47244A113E93")] + internal interface IBindableVector : IEnumerable + { + object GetAt(uint index); + IBindableVectorView GetView(); + bool IndexOf(object value, out uint index); + void SetAt(uint index, object value); + void InsertAt(uint index, object value); + void RemoveAt(uint index); + void Append(object value); + void RemoveAtEnd(); + void Clear(); + uint Size { get; } + } + [global::WinRT.WindowsRuntimeType] + [Guid("346DD6E7-976E-4BC3-815D-ECE243BC0F33")] + [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Microsoft.UI.Xaml.Interop.IBindableVectorView))] + internal interface IBindableVectorView : IEnumerable + { + object GetAt(uint index); + bool IndexOf(object value, out uint index); + uint Size { get; } + } +} + +namespace ABI.Microsoft.UI.Xaml.Interop +{ + [DynamicInterfaceCastableImplementation] + [Guid("036D2C08-DF29-41AF-8AA2-D774BE62BA6F")] + internal unsafe interface IBindableIterable : global::Microsoft.UI.Xaml.Interop.IBindableIterable, ABI.System.Collections.IEnumerable + { + + } + + [DynamicInterfaceCastableImplementation] + [Guid("6A1D6C07-076D-49F2-8314-F52C9C9A8331")] + internal unsafe interface IBindableIterator : global::Microsoft.UI.Xaml.Interop.IBindableIterator + { + public static readonly IntPtr AbiToProjectionVftablePtr; + static IBindableIterator() + { + AbiToProjectionVftablePtr = ComWrappersSupport.AllocateVtableMemory(typeof(IBindableIterator), sizeof(IInspectable.Vftbl) + sizeof(IntPtr) * 4); + *(IInspectable.Vftbl*)AbiToProjectionVftablePtr = IInspectable.Vftbl.AbiToProjectionVftable; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[6] = &Do_Abi_get_Current_0; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[7] = &Do_Abi_get_HasCurrent_1; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[8] = &Do_Abi_MoveNext_2; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[9] = &Do_Abi_GetMany_3; + } + + [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] + private static unsafe int Do_Abi_MoveNext_2(IntPtr thisPtr, byte* result) + { + bool __result = default; + *result = default; + try + { + __result = global::WinRT.ComWrappersSupport.FindObject(thisPtr).MoveNext(); + *result = (byte)(__result ? 1 : 0); + } + catch (Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + + [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] + private static unsafe int Do_Abi_GetMany_3(IntPtr thisPtr, int __itemsSize, IntPtr items, uint* result) + { + *result = default; + + try + { + // Should never be called. + throw new NotImplementedException(); + } + catch (Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + } + + [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] + private static unsafe int Do_Abi_get_Current_0(IntPtr thisPtr, IntPtr* value) + { + object __value = default; + *value = default; + try + { + __value = global::WinRT.ComWrappersSupport.FindObject(thisPtr).Current; + *value = MarshalInspectable.FromManaged(__value); + } + catch (Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + + [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] + private static unsafe int Do_Abi_get_HasCurrent_1(IntPtr thisPtr, byte* value) + { + bool __value = default; + *value = default; + try + { + __value = global::WinRT.ComWrappersSupport.FindObject(thisPtr).HasCurrent; + *value = (byte)(__value ? 1 : 0); + } + catch (Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + + internal static ObjectReference FromAbi(IntPtr thisPtr) => ObjectReference.FromAbi(thisPtr); + + unsafe bool global::Microsoft.UI.Xaml.Interop.IBindableIterator.MoveNext() + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::Microsoft.UI.Xaml.Interop.IBindableIterator).TypeHandle); + var ThisPtr = _obj.ThisPtr; + byte __retval = default; + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[8](ThisPtr, &__retval)); + return __retval != 0; + } + + unsafe uint global::Microsoft.UI.Xaml.Interop.IBindableIterator.GetMany(ref object[] items) + { + // Should never be called. + throw new NotImplementedException(); + } + + unsafe object global::Microsoft.UI.Xaml.Interop.IBindableIterator.Current + { + get + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::Microsoft.UI.Xaml.Interop.IBindableIterator).TypeHandle); + var ThisPtr = _obj.ThisPtr; + IntPtr __retval = default; + try + { + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[6](ThisPtr, &__retval)); + return MarshalInspectable.FromAbi(__retval); + } + finally + { + MarshalInspectable.DisposeAbi(__retval); + } + } + } + + unsafe bool global::Microsoft.UI.Xaml.Interop.IBindableIterator.HasCurrent + { + get + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::Microsoft.UI.Xaml.Interop.IBindableIterator).TypeHandle); + var ThisPtr = _obj.ThisPtr; + byte __retval = default; + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[7](ThisPtr, &__retval)); + return __retval != 0; + } + } + + } + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + internal static class IBindableIterator_Delegates + { + public unsafe delegate int get_Current_0(IntPtr thisPtr, IntPtr* result); + public unsafe delegate int get_HasCurrent_1(IntPtr thisPtr, byte* result); + public unsafe delegate int MoveNext_2(IntPtr thisPtr, byte* result); + public unsafe delegate int GetMany_3(IntPtr thisPtr, int itemSize, IntPtr items, uint* result); + } + + [DynamicInterfaceCastableImplementation] + [Guid("346DD6E7-976E-4BC3-815D-ECE243BC0F33")] + internal unsafe interface IBindableVectorView : global::Microsoft.UI.Xaml.Interop.IBindableVectorView + { + public static readonly IntPtr AbiToProjectionVftablePtr; + static IBindableVectorView() + { + AbiToProjectionVftablePtr = ComWrappersSupport.AllocateVtableMemory(typeof(IBindableVectorView), sizeof(IInspectable.Vftbl) + sizeof(IntPtr) * 3); + *(IInspectable.Vftbl*)AbiToProjectionVftablePtr = IInspectable.Vftbl.AbiToProjectionVftable; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[6] = &Do_Abi_GetAt_0; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[7] = &Do_Abi_get_Size_1; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[8] = &Do_Abi_IndexOf_2; + } + + [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] + private static unsafe int Do_Abi_GetAt_0(IntPtr thisPtr, uint index, IntPtr* result) + { + object __result = default; + + try + { + __result = global::WinRT.ComWrappersSupport.FindObject(thisPtr).GetAt(index); + *result = MarshalInspectable.FromManaged(__result); + + } + catch (Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + + [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] + private static unsafe int Do_Abi_IndexOf_2(IntPtr thisPtr, IntPtr value, uint* index, byte* returnValue) + { + bool __returnValue = default; + + *index = default; + *returnValue = default; + uint __index = default; + + try + { + __returnValue = global::WinRT.ComWrappersSupport.FindObject(thisPtr).IndexOf(MarshalInspectable.FromAbi(value), out __index); + *index = __index; + *returnValue = (byte)(__returnValue ? 1 : 0); + + } + catch (Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + + [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] + private static unsafe int Do_Abi_get_Size_1(IntPtr thisPtr, uint* value) + { + uint __value = default; + + *value = default; + + try + { + __value = global::WinRT.ComWrappersSupport.FindObject(thisPtr).Size; + *value = __value; + + } + catch (Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + + internal static ObjectReference FromAbi(IntPtr thisPtr) => ObjectReference.FromAbi(thisPtr); + + private static readonly global::System.Runtime.CompilerServices.ConditionalWeakTable _helperTable = new(); + + unsafe object global::Microsoft.UI.Xaml.Interop.IBindableVectorView.GetAt(uint index) + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::Microsoft.UI.Xaml.Interop.IBindableIterator).TypeHandle); + var ThisPtr = _obj.ThisPtr; + IntPtr __retval = default; + try + { + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[6](ThisPtr, index, &__retval)); + return MarshalInspectable.FromAbi(__retval); + } + finally + { + MarshalInspectable.DisposeAbi(__retval); + } + } + + unsafe bool global::Microsoft.UI.Xaml.Interop.IBindableVectorView.IndexOf(object value, out uint index) + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::Microsoft.UI.Xaml.Interop.IBindableIterator).TypeHandle); + var ThisPtr = _obj.ThisPtr; + ObjectReferenceValue __value = default; + uint __index = default; + byte __retval = default; + try + { + __value = MarshalInspectable.CreateMarshaler2(value); + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[8]( + ThisPtr, + MarshalInspectable.GetAbi(__value), + &__index, + &__retval)); + index = __index; + return __retval != 0; + } + finally + { + MarshalInspectable.DisposeMarshaler(__value); + } + } + + unsafe uint global::Microsoft.UI.Xaml.Interop.IBindableVectorView.Size + { + get + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::Microsoft.UI.Xaml.Interop.IBindableIterator).TypeHandle); + var ThisPtr = _obj.ThisPtr; + uint __retval = default; + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[7](ThisPtr, &__retval)); + return __retval; + } + } + + IEnumerator IEnumerable.GetEnumerator() + { + return _helperTable.GetValue((IWinRTObject)this, + (enumerable) => new ABI.System.Collections.IEnumerable.AdaptiveFromAbiHelper(enumerable) + ).GetEnumerator(); + } + } + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + internal static class IBindableVectorView_Delegates + { + public unsafe delegate int GetAt_0(IntPtr thisPtr, uint index, IntPtr* result); + public unsafe delegate int get_Size_1(IntPtr thisPtr, uint* result); + public unsafe delegate int IndexOf_2(IntPtr thisPtr, IntPtr value, uint* index, byte* returnValue); + } +} diff --git a/src/WinRT.Runtime/Projections/Bindable.netstandard2.0.cs b/src/WinRT.Runtime/Projections/Microsoft.UI.Xaml.Bindable.netstandard2.0.cs similarity index 100% rename from src/WinRT.Runtime/Projections/Bindable.netstandard2.0.cs rename to src/WinRT.Runtime/Projections/Microsoft.UI.Xaml.Bindable.netstandard2.0.cs diff --git a/src/WinRT.Runtime/Projections/NotifyCollectionChangedAction.cs b/src/WinRT.Runtime/Projections/NotifyCollectionChangedAction.cs index b6ccf1bc7..62d5af9f4 100644 --- a/src/WinRT.Runtime/Projections/NotifyCollectionChangedAction.cs +++ b/src/WinRT.Runtime/Projections/NotifyCollectionChangedAction.cs @@ -1,10 +1,15 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. +using WinRT; + namespace ABI.System.Collections.Specialized { static class NotifyCollectionChangedAction { - public static string GetGuidSignature() => "enum(Microsoft.UI.Xaml.Interop.NotifyCollectionChangedAction;i4)"; + public static string GetGuidSignature() => + Projections.UiXamlModeSetting == Projections.UiXamlMode.WindowsUiXaml + ? "enum(Windows.UI.Xaml.Interop.NotifyCollectionChangedAction;i4)" + : "enum(Microsoft.UI.Xaml.Interop.NotifyCollectionChangedAction;i4)"; } } diff --git a/src/WinRT.Runtime/Projections/NotifyCollectionChangedEventArgs.cs b/src/WinRT.Runtime/Projections/NotifyCollectionChangedEventArgs.cs index 2cc04a771..75bb92ca3 100644 --- a/src/WinRT.Runtime/Projections/NotifyCollectionChangedEventArgs.cs +++ b/src/WinRT.Runtime/Projections/NotifyCollectionChangedEventArgs.cs @@ -1,279 +1,368 @@ // Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -using ABI.Microsoft.UI.Xaml.Interop; -using System; -using System.ComponentModel; -using System.Runtime.InteropServices; -using WinRT; -using WinRT.Interop; - -namespace ABI.Microsoft.UI.Xaml.Interop -{ - [global::WinRT.ObjectReferenceWrapper(nameof(_obj))] - [Guid("DA049FF2-D2E0-5FE8-8C7B-F87F26060B6F")] - internal sealed unsafe class INotifyCollectionChangedEventArgs - { - [Guid("DA049FF2-D2E0-5FE8-8C7B-F87F26060B6F")] - [StructLayout(LayoutKind.Sequential)] - public struct Vftbl - { - internal IInspectable.Vftbl IInspectableVftbl; - private void* _get_Action_0; - public delegate* unmanaged[Stdcall] get_Action_0 => (delegate* unmanaged[Stdcall])_get_Action_0; - private void* _get_NewItems_1; - public delegate* unmanaged[Stdcall] get_NewItems_1 => (delegate* unmanaged[Stdcall])_get_NewItems_1; - private void* _get_OldItems_2; - public delegate* unmanaged[Stdcall] get_OldItems_2 => (delegate* unmanaged[Stdcall])_get_OldItems_2; - private void* _get_NewStartingIndex_3; - public delegate* unmanaged[Stdcall] get_NewStartingIndex_3 => (delegate* unmanaged[Stdcall])_get_NewStartingIndex_3; - private void* _get_OldStartingIndex_4; - public delegate* unmanaged[Stdcall] get_OldStartingIndex_4 => (delegate* unmanaged[Stdcall])_get_OldStartingIndex_4; - } - internal static ObjectReference FromAbi(IntPtr thisPtr) => ObjectReference.FromAbi(thisPtr); - - public static implicit operator INotifyCollectionChangedEventArgs(IObjectReference obj) => (obj != null) ? new INotifyCollectionChangedEventArgs(obj) : null; - private readonly ObjectReference _obj; - public IObjectReference ObjRef { get => _obj; } - public IntPtr ThisPtr => _obj.ThisPtr; - public ObjectReference AsInterface() => _obj.As(); - public A As() => _obj.AsType(); - public INotifyCollectionChangedEventArgs(IObjectReference obj) : this(obj.As()) { } - internal INotifyCollectionChangedEventArgs(ObjectReference obj) - { - _obj = obj; - } - - public unsafe global::System.Collections.Specialized.NotifyCollectionChangedAction Action - { - get - { - global::System.Collections.Specialized.NotifyCollectionChangedAction __retval = default; - global::WinRT.ExceptionHelpers.ThrowExceptionForHR(_obj.Vftbl.get_Action_0(ThisPtr, &__retval)); - return __retval; - } - } - - public unsafe global::System.Collections.IList NewItems - { - get - { - IntPtr __retval = default; - try - { - global::WinRT.ExceptionHelpers.ThrowExceptionForHR(_obj.Vftbl.get_NewItems_1(ThisPtr, &__retval)); - return MarshalInterface.FromAbi(__retval); - } - finally - { - MarshalInterface.DisposeAbi(__retval); - } - } - } - - public unsafe int NewStartingIndex - { - get - { - int __retval = default; - global::WinRT.ExceptionHelpers.ThrowExceptionForHR(_obj.Vftbl.get_NewStartingIndex_3(ThisPtr, &__retval)); - return __retval; - } - } - - public unsafe global::System.Collections.IList OldItems - { - get - { - IntPtr __retval = default; - try - { - global::WinRT.ExceptionHelpers.ThrowExceptionForHR(_obj.Vftbl.get_OldItems_2(ThisPtr, &__retval)); - return MarshalInterface.FromAbi(__retval); - } - finally - { - MarshalInterface.DisposeAbi(__retval); - } - } - } - - public unsafe int OldStartingIndex - { - get - { - int __retval = default; - global::WinRT.ExceptionHelpers.ThrowExceptionForHR(_obj.Vftbl.get_OldStartingIndex_4(ThisPtr, &__retval)); - return __retval; - } - } - } - - [global::WinRT.ObjectReferenceWrapper(nameof(_obj))] - [Guid("5108EBA4-4892-5A20-8374-A96815E0FD27")] - internal sealed unsafe class WinRTNotifyCollectionChangedEventArgsRuntimeClassFactory - { - [Guid("5108EBA4-4892-5A20-8374-A96815E0FD27")] - [StructLayout(LayoutKind.Sequential)] - public struct Vftbl - { - internal IInspectable.Vftbl IInspectableVftbl; - private void* _CreateInstanceWithAllParameters_0; - public delegate* unmanaged[Stdcall] CreateInstanceWithAllParameters_0 => (delegate* unmanaged[Stdcall])_CreateInstanceWithAllParameters_0; - } - public static ObjectReference FromAbi(IntPtr thisPtr) => ObjectReference.FromAbi(thisPtr); - - public static implicit operator WinRTNotifyCollectionChangedEventArgsRuntimeClassFactory(IObjectReference obj) => (obj != null) ? new WinRTNotifyCollectionChangedEventArgsRuntimeClassFactory(obj) : null; - public static implicit operator WinRTNotifyCollectionChangedEventArgsRuntimeClassFactory(ObjectReference obj) => (obj != null) ? new WinRTNotifyCollectionChangedEventArgsRuntimeClassFactory(obj) : null; - private readonly ObjectReference _obj; - public IntPtr ThisPtr => _obj.ThisPtr; - public ObjectReference AsInterface() => _obj.As(); - public A As() => _obj.AsType(); - public WinRTNotifyCollectionChangedEventArgsRuntimeClassFactory(IObjectReference obj) : this(obj.As()) { } - public WinRTNotifyCollectionChangedEventArgsRuntimeClassFactory(ObjectReference obj) - { - _obj = obj; - } - - public unsafe IObjectReference CreateInstanceWithAllParameters(global::System.Collections.Specialized.NotifyCollectionChangedAction action, global::System.Collections.IList newItems, global::System.Collections.IList oldItems, int newIndex, int oldIndex, object baseInterface, out IObjectReference innerInterface) - { - ObjectReferenceValue __newItems = default; - ObjectReferenceValue __oldItems = default; - ObjectReferenceValue __baseInterface = default; - IntPtr __innerInterface = default; - IntPtr __retval = default; - try - { - __newItems = MarshalInterface.CreateMarshaler2(newItems); - __oldItems = MarshalInterface.CreateMarshaler2(oldItems); - __baseInterface = MarshalInspectable.CreateMarshaler2(baseInterface); - global::WinRT.ExceptionHelpers.ThrowExceptionForHR(_obj.Vftbl.CreateInstanceWithAllParameters_0(ThisPtr, action, MarshalInterface.GetAbi(__newItems), MarshalInterface.GetAbi(__oldItems), newIndex, oldIndex, MarshalInspectable.GetAbi(__baseInterface), &__innerInterface, &__retval)); - innerInterface = ObjectReference.FromAbi(__innerInterface); - return ObjectReference.FromAbi(__retval); - } - finally - { - MarshalInterface.DisposeMarshaler(__newItems); - MarshalInterface.DisposeMarshaler(__oldItems); - MarshalInspectable.DisposeMarshaler(__baseInterface); - MarshalInspectable.DisposeAbi(__innerInterface); - MarshalInspectable.DisposeAbi(__retval); - } +// Licensed under the MIT License. + +using ABI.Microsoft.UI.Xaml.Interop; +using System; +using System.ComponentModel; +using System.Runtime.InteropServices; +using WinRT; +using WinRT.Interop; + +namespace ABI.Microsoft.UI.Xaml.Interop +{ + [global::WinRT.ObjectReferenceWrapper(nameof(_obj))] + [Guid("DA049FF2-D2E0-5FE8-8C7B-F87F26060B6F")] + [WuxMuxProjectedType(wuxIID: "4CF68D33-E3F2-4964-B85E-945B4F7E2F21", muxIID: "DA049FF2-D2E0-5FE8-8C7B-F87F26060B6F")] + internal sealed unsafe class INotifyCollectionChangedEventArgs + { + [Guid("DA049FF2-D2E0-5FE8-8C7B-F87F26060B6F")] + [StructLayout(LayoutKind.Sequential)] + [WuxMuxProjectedType(wuxIID: "4CF68D33-E3F2-4964-B85E-945B4F7E2F21", muxIID: "DA049FF2-D2E0-5FE8-8C7B-F87F26060B6F")] + public struct Vftbl + { + internal IInspectable.Vftbl IInspectableVftbl; + private void* _get_Action_0; + public delegate* unmanaged[Stdcall] get_Action_0 => (delegate* unmanaged[Stdcall])_get_Action_0; + private void* _get_NewItems_1; + public delegate* unmanaged[Stdcall] get_NewItems_1 => (delegate* unmanaged[Stdcall])_get_NewItems_1; + private void* _get_OldItems_2; + public delegate* unmanaged[Stdcall] get_OldItems_2 => (delegate* unmanaged[Stdcall])_get_OldItems_2; + private void* _get_NewStartingIndex_3; + public delegate* unmanaged[Stdcall] get_NewStartingIndex_3 => (delegate* unmanaged[Stdcall])_get_NewStartingIndex_3; + private void* _get_OldStartingIndex_4; + public delegate* unmanaged[Stdcall] get_OldStartingIndex_4 => (delegate* unmanaged[Stdcall])_get_OldStartingIndex_4; + } + internal static ObjectReference FromAbi(IntPtr thisPtr) => ObjectReference.FromAbi(thisPtr); + + public static implicit operator INotifyCollectionChangedEventArgs(IObjectReference obj) => (obj != null) ? new INotifyCollectionChangedEventArgs(obj) : null; + private readonly ObjectReference _obj; + public IObjectReference ObjRef { get => _obj; } + public IntPtr ThisPtr => _obj.ThisPtr; + public ObjectReference AsInterface() => _obj.As(); + public A As() => _obj.AsType(); + public INotifyCollectionChangedEventArgs(IObjectReference obj) : this(obj.As()) { } + internal INotifyCollectionChangedEventArgs(ObjectReference obj) + { + _obj = obj; + } + + public unsafe global::System.Collections.Specialized.NotifyCollectionChangedAction Action + { + get + { + global::System.Collections.Specialized.NotifyCollectionChangedAction __retval = default; + global::WinRT.ExceptionHelpers.ThrowExceptionForHR(_obj.Vftbl.get_Action_0(ThisPtr, &__retval)); + return __retval; + } + } + + public unsafe global::System.Collections.IList NewItems + { + get + { + IntPtr __retval = default; + try + { + global::WinRT.ExceptionHelpers.ThrowExceptionForHR(_obj.Vftbl.get_NewItems_1(ThisPtr, &__retval)); + return MarshalInterface.FromAbi(__retval); + } + finally + { + MarshalInterface.DisposeAbi(__retval); + } + } + } + + public unsafe int NewStartingIndex + { + get + { + int __retval = default; + global::WinRT.ExceptionHelpers.ThrowExceptionForHR(_obj.Vftbl.get_NewStartingIndex_3(ThisPtr, &__retval)); + return __retval; + } + } + + public unsafe global::System.Collections.IList OldItems + { + get + { + IntPtr __retval = default; + try + { + global::WinRT.ExceptionHelpers.ThrowExceptionForHR(_obj.Vftbl.get_OldItems_2(ThisPtr, &__retval)); + return MarshalInterface.FromAbi(__retval); + } + finally + { + MarshalInterface.DisposeAbi(__retval); + } + } + } + + public unsafe int OldStartingIndex + { + get + { + int __retval = default; + global::WinRT.ExceptionHelpers.ThrowExceptionForHR(_obj.Vftbl.get_OldStartingIndex_4(ThisPtr, &__retval)); + return __retval; + } + } + } + + internal interface IWinRTNotifyCollectionChangedEventArgsRuntimeClassFactory + { + IObjectReference CreateInstanceWithAllParameters(global::System.Collections.Specialized.NotifyCollectionChangedAction action, global::System.Collections.IList newItems, global::System.Collections.IList oldItems, int newIndex, int oldIndex, object baseInterface, out IObjectReference innerInterface); + ObjectReferenceValue CreateInstanceWithAllParameters(global::System.Collections.Specialized.NotifyCollectionChangedAction action, global::System.Collections.IList newItems, global::System.Collections.IList oldItems, int newIndex, int oldIndex); + } + + [global::WinRT.ObjectReferenceWrapper(nameof(_obj))] + [Guid("5108EBA4-4892-5A20-8374-A96815E0FD27")] + internal sealed unsafe class MUXNotifyCollectionChangedEventArgsRuntimeClassFactory : IWinRTNotifyCollectionChangedEventArgsRuntimeClassFactory + { + [Guid("5108EBA4-4892-5A20-8374-A96815E0FD27")] + [StructLayout(LayoutKind.Sequential)] + public struct Vftbl + { + internal IInspectable.Vftbl IInspectableVftbl; + private void* _CreateInstanceWithAllParameters_0; + public delegate* unmanaged[Stdcall] CreateInstanceWithAllParameters_0 => (delegate* unmanaged[Stdcall])_CreateInstanceWithAllParameters_0; + } + public static ObjectReference FromAbi(IntPtr thisPtr) => ObjectReference.FromAbi(thisPtr); + + public static implicit operator MUXNotifyCollectionChangedEventArgsRuntimeClassFactory(IObjectReference obj) => (obj != null) ? new MUXNotifyCollectionChangedEventArgsRuntimeClassFactory(obj) : null; + public static implicit operator MUXNotifyCollectionChangedEventArgsRuntimeClassFactory(ObjectReference obj) => (obj != null) ? new MUXNotifyCollectionChangedEventArgsRuntimeClassFactory(obj) : null; + private readonly ObjectReference _obj; + public IntPtr ThisPtr => _obj.ThisPtr; + public ObjectReference AsInterface() => _obj.As(); + public A As() => _obj.AsType(); + public MUXNotifyCollectionChangedEventArgsRuntimeClassFactory(IObjectReference obj) : this(obj.As()) { } + public MUXNotifyCollectionChangedEventArgsRuntimeClassFactory(ObjectReference obj) + { + _obj = obj; + } + + public unsafe IObjectReference CreateInstanceWithAllParameters(global::System.Collections.Specialized.NotifyCollectionChangedAction action, global::System.Collections.IList newItems, global::System.Collections.IList oldItems, int newIndex, int oldIndex, object baseInterface, out IObjectReference innerInterface) + { + ObjectReferenceValue __newItems = default; + ObjectReferenceValue __oldItems = default; + ObjectReferenceValue __baseInterface = default; + IntPtr __innerInterface = default; + IntPtr __retval = default; + try + { + __newItems = MarshalInterface.CreateMarshaler2(newItems); + __oldItems = MarshalInterface.CreateMarshaler2(oldItems); + __baseInterface = MarshalInspectable.CreateMarshaler2(baseInterface); + global::WinRT.ExceptionHelpers.ThrowExceptionForHR(_obj.Vftbl.CreateInstanceWithAllParameters_0(ThisPtr, action, MarshalInterface.GetAbi(__newItems), MarshalInterface.GetAbi(__oldItems), newIndex, oldIndex, MarshalInspectable.GetAbi(__baseInterface), &__innerInterface, &__retval)); + innerInterface = ObjectReference.FromAbi(__innerInterface); + return ObjectReference.FromAbi(__retval); + } + finally + { + MarshalInterface.DisposeMarshaler(__newItems); + MarshalInterface.DisposeMarshaler(__oldItems); + MarshalInspectable.DisposeMarshaler(__baseInterface); + MarshalInspectable.DisposeAbi(__innerInterface); + MarshalInspectable.DisposeAbi(__retval); + } + } + + public unsafe ObjectReferenceValue CreateInstanceWithAllParameters(global::System.Collections.Specialized.NotifyCollectionChangedAction action, global::System.Collections.IList newItems, global::System.Collections.IList oldItems, int newIndex, int oldIndex) + { + ObjectReferenceValue __newItems = default; + ObjectReferenceValue __oldItems = default; + IntPtr __innerInterface = default; + IntPtr __retval = default; + try + { + __newItems = MarshalInterface.CreateMarshaler2(newItems); + __oldItems = MarshalInterface.CreateMarshaler2(oldItems); + global::WinRT.ExceptionHelpers.ThrowExceptionForHR(_obj.Vftbl.CreateInstanceWithAllParameters_0(ThisPtr, action, MarshalInterface.GetAbi(__newItems), MarshalInterface.GetAbi(__oldItems), newIndex, oldIndex, IntPtr.Zero, &__innerInterface, &__retval)); + return new ObjectReferenceValue(__retval); + } + finally + { + __newItems.Dispose(); + __oldItems.Dispose(); + MarshalInspectable.DisposeAbi(__innerInterface); + } } + } - public unsafe ObjectReferenceValue CreateInstanceWithAllParameters(global::System.Collections.Specialized.NotifyCollectionChangedAction action, global::System.Collections.IList newItems, global::System.Collections.IList oldItems, int newIndex, int oldIndex) - { - ObjectReferenceValue __newItems = default; - ObjectReferenceValue __oldItems = default; - IntPtr __innerInterface = default; - IntPtr __retval = default; - try - { - __newItems = MarshalInterface.CreateMarshaler2(newItems); - __oldItems = MarshalInterface.CreateMarshaler2(oldItems); - global::WinRT.ExceptionHelpers.ThrowExceptionForHR(_obj.Vftbl.CreateInstanceWithAllParameters_0(ThisPtr, action, MarshalInterface.GetAbi(__newItems), MarshalInterface.GetAbi(__oldItems), newIndex, oldIndex, IntPtr.Zero, &__innerInterface, &__retval)); - return new ObjectReferenceValue(__retval); - } - finally - { - __newItems.Dispose(); - __oldItems.Dispose(); - MarshalInspectable.DisposeAbi(__innerInterface); - } - } - } -} - -namespace ABI.System.Collections.Specialized -{ - [EditorBrowsable(EditorBrowsableState.Never)] - [StructLayout(LayoutKind.Sequential)] -#if EMBED - internal -#else - public -#endif - struct NotifyCollectionChangedEventArgs + [global::WinRT.ObjectReferenceWrapper(nameof(_obj))] + [Guid("B30C3E3A-DF8D-44A5-9A38-7AC0D08CE63D")] + internal sealed unsafe class WUXNotifyCollectionChangedEventArgsRuntimeClassFactory : IWinRTNotifyCollectionChangedEventArgsRuntimeClassFactory { - private static WinRTNotifyCollectionChangedEventArgsRuntimeClassFactory Instance = ActivationFactory.Get("Microsoft.UI.Xaml.Interop.NotifyCollectionChangedEventArgs"); - - public static IObjectReference CreateMarshaler(global::System.Collections.Specialized.NotifyCollectionChangedEventArgs value) - { - if (value is null) - { - return null; - } - - return Instance.CreateInstanceWithAllParameters(value.Action, value.NewItems, value.OldItems, value.NewStartingIndex, value.OldStartingIndex, null, out _); + [Guid("B30C3E3A-DF8D-44A5-9A38-7AC0D08CE63D")] + [StructLayout(LayoutKind.Sequential)] + public struct Vftbl + { + internal IInspectable.Vftbl IInspectableVftbl; + private void* _CreateInstanceWithAllParameters_0; + public delegate* unmanaged[Stdcall] CreateInstanceWithAllParameters_0 => (delegate* unmanaged[Stdcall])_CreateInstanceWithAllParameters_0; } + public static ObjectReference FromAbi(IntPtr thisPtr) => ObjectReference.FromAbi(thisPtr); - public static ObjectReferenceValue CreateMarshaler2(global::System.Collections.Specialized.NotifyCollectionChangedEventArgs value) - { - if (value is null) - { - return new ObjectReferenceValue(); - } - - return Instance.CreateInstanceWithAllParameters(value.Action, value.NewItems, value.OldItems, value.NewStartingIndex, value.OldStartingIndex); - } - - public static IntPtr GetAbi(IObjectReference m) => m?.ThisPtr ?? IntPtr.Zero; - - public static global::System.Collections.Specialized.NotifyCollectionChangedEventArgs FromAbi(IntPtr ptr) - { - if (ptr == IntPtr.Zero) - { - return null; - } - - INotifyCollectionChangedEventArgs args = INotifyCollectionChangedEventArgs.FromAbi(ptr); - return CreateNotifyCollectionChangedEventArgs(args.Action, args.NewItems, args.OldItems, args.NewStartingIndex, args.OldStartingIndex); - } - - private static global::System.Collections.Specialized.NotifyCollectionChangedEventArgs CreateNotifyCollectionChangedEventArgs( - global::System.Collections.Specialized.NotifyCollectionChangedAction action, - global::System.Collections.IList newItems, - global::System.Collections.IList oldItems, - int newStartingIndex, - int oldStartingIndex) => - action switch - { - global::System.Collections.Specialized.NotifyCollectionChangedAction.Add => new global::System.Collections.Specialized.NotifyCollectionChangedEventArgs(action, newItems, newStartingIndex), - global::System.Collections.Specialized.NotifyCollectionChangedAction.Remove => new global::System.Collections.Specialized.NotifyCollectionChangedEventArgs(action, oldItems, oldStartingIndex), - global::System.Collections.Specialized.NotifyCollectionChangedAction.Replace => new global::System.Collections.Specialized.NotifyCollectionChangedEventArgs(action, newItems, oldItems, newStartingIndex), - global::System.Collections.Specialized.NotifyCollectionChangedAction.Move => new global::System.Collections.Specialized.NotifyCollectionChangedEventArgs(action, newItems, newStartingIndex, oldStartingIndex), - global::System.Collections.Specialized.NotifyCollectionChangedAction.Reset => new global::System.Collections.Specialized.NotifyCollectionChangedEventArgs(global::System.Collections.Specialized.NotifyCollectionChangedAction.Reset), - _ => throw new ArgumentException(), - }; - - public static unsafe void CopyManaged(global::System.Collections.Specialized.NotifyCollectionChangedEventArgs o, IntPtr dest) - { - *(IntPtr*)dest.ToPointer() = CreateMarshaler2(o).Detach(); - } - - public static IntPtr FromManaged(global::System.Collections.Specialized.NotifyCollectionChangedEventArgs value) - { - if (value is null) - { - return IntPtr.Zero; - } - return CreateMarshaler2(value).Detach(); - } - - public static void DisposeMarshaler(IObjectReference m) { m?.Dispose(); } + public static implicit operator WUXNotifyCollectionChangedEventArgsRuntimeClassFactory(IObjectReference obj) => (obj != null) ? new WUXNotifyCollectionChangedEventArgsRuntimeClassFactory(obj) : null; + public static implicit operator WUXNotifyCollectionChangedEventArgsRuntimeClassFactory(ObjectReference obj) => (obj != null) ? new WUXNotifyCollectionChangedEventArgsRuntimeClassFactory(obj) : null; + private readonly ObjectReference _obj; + public IntPtr ThisPtr => _obj.ThisPtr; + public ObjectReference AsInterface() => _obj.As(); + public A As() => _obj.AsType(); + public WUXNotifyCollectionChangedEventArgsRuntimeClassFactory(IObjectReference obj) : this(obj.As()) { } + public WUXNotifyCollectionChangedEventArgsRuntimeClassFactory(ObjectReference obj) + { + _obj = obj; + } + + public unsafe IObjectReference CreateInstanceWithAllParameters(global::System.Collections.Specialized.NotifyCollectionChangedAction action, global::System.Collections.IList newItems, global::System.Collections.IList oldItems, int newIndex, int oldIndex, object baseInterface, out IObjectReference innerInterface) + { + ObjectReferenceValue __newItems = default; + ObjectReferenceValue __oldItems = default; + ObjectReferenceValue __baseInterface = default; + IntPtr __innerInterface = default; + IntPtr __retval = default; + try + { + __newItems = MarshalInterface.CreateMarshaler2(newItems); + __oldItems = MarshalInterface.CreateMarshaler2(oldItems); + __baseInterface = MarshalInspectable.CreateMarshaler2(baseInterface); + global::WinRT.ExceptionHelpers.ThrowExceptionForHR(_obj.Vftbl.CreateInstanceWithAllParameters_0(ThisPtr, action, MarshalInterface.GetAbi(__newItems), MarshalInterface.GetAbi(__oldItems), newIndex, oldIndex, MarshalInspectable.GetAbi(__baseInterface), &__innerInterface, &__retval)); + innerInterface = ObjectReference.FromAbi(__innerInterface); + return ObjectReference.FromAbi(__retval); + } + finally + { + MarshalInterface.DisposeMarshaler(__newItems); + MarshalInterface.DisposeMarshaler(__oldItems); + MarshalInspectable.DisposeMarshaler(__baseInterface); + MarshalInspectable.DisposeAbi(__innerInterface); + MarshalInspectable.DisposeAbi(__retval); + } + } + + public unsafe ObjectReferenceValue CreateInstanceWithAllParameters(global::System.Collections.Specialized.NotifyCollectionChangedAction action, global::System.Collections.IList newItems, global::System.Collections.IList oldItems, int newIndex, int oldIndex) + { + ObjectReferenceValue __newItems = default; + ObjectReferenceValue __oldItems = default; + IntPtr __innerInterface = default; + IntPtr __retval = default; + try + { + __newItems = MarshalInterface.CreateMarshaler2(newItems); + __oldItems = MarshalInterface.CreateMarshaler2(oldItems); + global::WinRT.ExceptionHelpers.ThrowExceptionForHR(_obj.Vftbl.CreateInstanceWithAllParameters_0(ThisPtr, action, MarshalInterface.GetAbi(__newItems), MarshalInterface.GetAbi(__oldItems), newIndex, oldIndex, IntPtr.Zero, &__innerInterface, &__retval)); + return new ObjectReferenceValue(__retval); + } + finally + { + __newItems.Dispose(); + __oldItems.Dispose(); + MarshalInspectable.DisposeAbi(__innerInterface); + } + } + } +} + +namespace ABI.System.Collections.Specialized +{ + [EditorBrowsable(EditorBrowsableState.Never)] + [StructLayout(LayoutKind.Sequential)] +#if EMBED + internal +#else + public +#endif + struct NotifyCollectionChangedEventArgs + { + private static IWinRTNotifyCollectionChangedEventArgsRuntimeClassFactory Instance = + Projections.UiXamlModeSetting == Projections.UiXamlMode.WindowsUiXaml + ? new WUXNotifyCollectionChangedEventArgsRuntimeClassFactory(ActivationFactory.Get("Windows.UI.Xaml.Interop.NotifyCollectionChangedEventArgs")) + : new MUXNotifyCollectionChangedEventArgsRuntimeClassFactory(ActivationFactory.Get("Microsoft.UI.Xaml.Interop.NotifyCollectionChangedEventArgs")); + + public static IObjectReference CreateMarshaler(global::System.Collections.Specialized.NotifyCollectionChangedEventArgs value) + { + if (value is null) + { + return null; + } + + return Instance.CreateInstanceWithAllParameters(value.Action, value.NewItems, value.OldItems, value.NewStartingIndex, value.OldStartingIndex, null, out _); + } + + public static ObjectReferenceValue CreateMarshaler2(global::System.Collections.Specialized.NotifyCollectionChangedEventArgs value) + { + if (value is null) + { + return new ObjectReferenceValue(); + } + + return Instance.CreateInstanceWithAllParameters(value.Action, value.NewItems, value.OldItems, value.NewStartingIndex, value.OldStartingIndex); + } + + public static IntPtr GetAbi(IObjectReference m) => m?.ThisPtr ?? IntPtr.Zero; + + public static global::System.Collections.Specialized.NotifyCollectionChangedEventArgs FromAbi(IntPtr ptr) + { + if (ptr == IntPtr.Zero) + { + return null; + } + + INotifyCollectionChangedEventArgs args = INotifyCollectionChangedEventArgs.FromAbi(ptr); + return CreateNotifyCollectionChangedEventArgs(args.Action, args.NewItems, args.OldItems, args.NewStartingIndex, args.OldStartingIndex); + } + + private static global::System.Collections.Specialized.NotifyCollectionChangedEventArgs CreateNotifyCollectionChangedEventArgs( + global::System.Collections.Specialized.NotifyCollectionChangedAction action, + global::System.Collections.IList newItems, + global::System.Collections.IList oldItems, + int newStartingIndex, + int oldStartingIndex) => + action switch + { + global::System.Collections.Specialized.NotifyCollectionChangedAction.Add => new global::System.Collections.Specialized.NotifyCollectionChangedEventArgs(action, newItems, newStartingIndex), + global::System.Collections.Specialized.NotifyCollectionChangedAction.Remove => new global::System.Collections.Specialized.NotifyCollectionChangedEventArgs(action, oldItems, oldStartingIndex), + global::System.Collections.Specialized.NotifyCollectionChangedAction.Replace => new global::System.Collections.Specialized.NotifyCollectionChangedEventArgs(action, newItems, oldItems, newStartingIndex), + global::System.Collections.Specialized.NotifyCollectionChangedAction.Move => new global::System.Collections.Specialized.NotifyCollectionChangedEventArgs(action, newItems, newStartingIndex, oldStartingIndex), + global::System.Collections.Specialized.NotifyCollectionChangedAction.Reset => new global::System.Collections.Specialized.NotifyCollectionChangedEventArgs(global::System.Collections.Specialized.NotifyCollectionChangedAction.Reset), + _ => throw new ArgumentException(), + }; + + public static unsafe void CopyManaged(global::System.Collections.Specialized.NotifyCollectionChangedEventArgs o, IntPtr dest) + { + *(IntPtr*)dest.ToPointer() = CreateMarshaler2(o).Detach(); + } + + public static IntPtr FromManaged(global::System.Collections.Specialized.NotifyCollectionChangedEventArgs value) + { + if (value is null) + { + return IntPtr.Zero; + } + return CreateMarshaler2(value).Detach(); + } + + public static void DisposeMarshaler(IObjectReference m) { m?.Dispose(); } public static void DisposeAbi(IntPtr abi) { MarshalInspectable.DisposeAbi(abi); } - public static unsafe MarshalInterfaceHelper.MarshalerArray CreateMarshalerArray(global::System.Collections.Specialized.NotifyCollectionChangedEventArgs[] array) => MarshalInterfaceHelper.CreateMarshalerArray2(array, CreateMarshaler2); - public static (int length, IntPtr data) GetAbiArray(object box) => MarshalInterfaceHelper.GetAbiArray(box); - public static unsafe global::System.Collections.Specialized.NotifyCollectionChangedEventArgs[] FromAbiArray(object box) => MarshalInterfaceHelper.FromAbiArray(box, FromAbi); - public static void CopyAbiArray(global::System.Collections.Specialized.NotifyCollectionChangedEventArgs[] array, object box) => MarshalInterfaceHelper.CopyAbiArray(array, box, FromAbi); - public static (int length, IntPtr data) FromManagedArray(global::System.Collections.Specialized.NotifyCollectionChangedEventArgs[] array) => MarshalInterfaceHelper.FromManagedArray(array, FromManaged); - public static void DisposeMarshalerArray(MarshalInterfaceHelper.MarshalerArray array) => MarshalInterfaceHelper.DisposeMarshalerArray(array); - public static unsafe void DisposeAbiArray(object box) => MarshalInspectable.DisposeAbiArray(box); - - public static string GetGuidSignature() - { - return "rc(Microsoft.UI.Xaml.Interop.NotifyCollectionChangedEventArgs;{4cf68d33-e3f2-4964-b85e-945b4f7e2f21})"; - } - } -} + public static unsafe MarshalInterfaceHelper.MarshalerArray CreateMarshalerArray(global::System.Collections.Specialized.NotifyCollectionChangedEventArgs[] array) => MarshalInterfaceHelper.CreateMarshalerArray2(array, CreateMarshaler2); + public static (int length, IntPtr data) GetAbiArray(object box) => MarshalInterfaceHelper.GetAbiArray(box); + public static unsafe global::System.Collections.Specialized.NotifyCollectionChangedEventArgs[] FromAbiArray(object box) => MarshalInterfaceHelper.FromAbiArray(box, FromAbi); + public static void CopyAbiArray(global::System.Collections.Specialized.NotifyCollectionChangedEventArgs[] array, object box) => MarshalInterfaceHelper.CopyAbiArray(array, box, FromAbi); + public static (int length, IntPtr data) FromManagedArray(global::System.Collections.Specialized.NotifyCollectionChangedEventArgs[] array) => MarshalInterfaceHelper.FromManagedArray(array, FromManaged); + public static void DisposeMarshalerArray(MarshalInterfaceHelper.MarshalerArray array) => MarshalInterfaceHelper.DisposeMarshalerArray(array); + public static unsafe void DisposeAbiArray(object box) => MarshalInspectable.DisposeAbiArray(box); + + public static string GetGuidSignature() + { + if (Projections.UiXamlModeSetting == Projections.UiXamlMode.WindowsUiXaml) + { + return "rc(Windows.UI.Xaml.Interop.NotifyCollectionChangedEventArgs;{4cf68d33-e3f2-4964-b85e-945b4f7e2f21})"; + } + return "rc(Microsoft.UI.Xaml.Interop.NotifyCollectionChangedEventArgs;{4cf68d33-e3f2-4964-b85e-945b4f7e2f21})"; + } + } +} diff --git a/src/WinRT.Runtime/Projections/NotifyCollectionChangedEventHandler.cs b/src/WinRT.Runtime/Projections/NotifyCollectionChangedEventHandler.cs index 1d39d310d..9305dc542 100644 --- a/src/WinRT.Runtime/Projections/NotifyCollectionChangedEventHandler.cs +++ b/src/WinRT.Runtime/Projections/NotifyCollectionChangedEventHandler.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. +// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. using System; @@ -13,6 +13,7 @@ namespace ABI.System.Collections.Specialized [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] [Guid("8B0909DC-2005-5D93-BF8A-725F017BAA8D")] + [WuxMuxProjectedType(wuxIID: "CA10B37C-F382-4591-8557-5E24965279B0", muxIID: "8B0909DC-2005-5D93-BF8A-725F017BAA8D")] #if EMBED internal #else @@ -41,28 +42,32 @@ static unsafe NotifyCollectionChangedEventHandler() var nativeVftbl = ComWrappersSupport.AllocateVtableMemory(typeof(NotifyCollectionChangedEventHandler), Marshal.SizeOf()); Marshal.StructureToPtr(AbiToProjectionVftable, nativeVftbl, false); AbiToProjectionVftablePtr = nativeVftbl; + + IID = Projections.UiXamlModeSetting == Projections.UiXamlMode.WindowsUiXaml + ? Guid.Parse("CA10B37C-F382-4591-8557-5E24965279B0") + : Guid.Parse("8B0909DC-2005-5D93-BF8A-725F017BAA8D"); } public static global::System.Delegate AbiInvokeDelegate { get; } - private static readonly Guid IID = new(0x8B0909DC, 0x2005, 0x5D93, 0xBF, 0x8A, 0x72, 0x5F, 0x01, 0x7B, 0xAA, 0x8D); + private static readonly Guid IID; public static unsafe IObjectReference CreateMarshaler(global::System.Collections.Specialized.NotifyCollectionChangedEventHandler managedDelegate) => - managedDelegate is null ? null : MarshalDelegate.CreateMarshaler(managedDelegate, IID); - + managedDelegate is null ? null : MarshalDelegate.CreateMarshaler(managedDelegate, IID); + public static unsafe ObjectReferenceValue CreateMarshaler2(global::System.Collections.Specialized.NotifyCollectionChangedEventHandler managedDelegate) => MarshalDelegate.CreateMarshaler2(managedDelegate, IID); public static IntPtr GetAbi(IObjectReference value) => MarshalInterfaceHelper.GetAbi(value); public static unsafe global::System.Collections.Specialized.NotifyCollectionChangedEventHandler FromAbi(IntPtr nativeDelegate) - { + { return MarshalDelegate.FromAbi(nativeDelegate); } - public static global::System.Collections.Specialized.NotifyCollectionChangedEventHandler CreateRcw(IntPtr ptr) - { - return new global::System.Collections.Specialized.NotifyCollectionChangedEventHandler(new NativeDelegateWrapper(ComWrappersSupport.GetObjectReferenceForInterface(ptr, IID)).Invoke); + public static global::System.Collections.Specialized.NotifyCollectionChangedEventHandler CreateRcw(IntPtr ptr) + { + return new global::System.Collections.Specialized.NotifyCollectionChangedEventHandler(new NativeDelegateWrapper(ComWrappersSupport.GetObjectReferenceForInterface(ptr, IID)).Invoke); } [global::WinRT.ObjectReferenceWrapper(nameof(_nativeDelegate))] @@ -129,8 +134,8 @@ public static IntPtr FromManaged(global::System.Collections.Specialized.NotifyCo public static void DisposeMarshaler(IObjectReference value) => MarshalInterfaceHelper.DisposeMarshaler(value); - public static void DisposeAbi(IntPtr abi) => MarshalInterfaceHelper.DisposeAbi(abi); - + public static void DisposeAbi(IntPtr abi) => MarshalInterfaceHelper.DisposeAbi(abi); + public static unsafe MarshalInterfaceHelper.MarshalerArray CreateMarshalerArray(global::System.Collections.Specialized.NotifyCollectionChangedEventHandler[] array) => MarshalInterfaceHelper.CreateMarshalerArray2(array, CreateMarshaler2); public static (int length, IntPtr data) GetAbiArray(object box) => MarshalInterfaceHelper.GetAbiArray(box); public static unsafe global::System.Collections.Specialized.NotifyCollectionChangedEventHandler[] FromAbiArray(object box) => MarshalInterfaceHelper.FromAbiArray(box, FromAbi); @@ -145,7 +150,7 @@ public static IntPtr FromManaged(global::System.Collections.Specialized.NotifyCo private static unsafe int Do_Abi_Invoke(IntPtr thisPtr, IntPtr sender, IntPtr e) { try - { + { #if NET var invoke = ComWrappersSupport.FindObject(thisPtr); invoke.Invoke(MarshalInspectable.FromAbi(sender), global::ABI.System.Collections.Specialized.NotifyCollectionChangedEventArgs.FromAbi(e)); @@ -167,9 +172,9 @@ private static unsafe int Do_Abi_Invoke(IntPtr thisPtr, IntPtr sender, IntPtr e) internal sealed unsafe class NotifyCollectionChangedEventSource : EventSource { - internal NotifyCollectionChangedEventSource(IObjectReference obj, + internal NotifyCollectionChangedEventSource(IObjectReference obj, #if NET - delegate* unmanaged[Stdcall] addHandler, + delegate* unmanaged[Stdcall] addHandler, #else delegate* unmanaged[Stdcall] addHandler, #endif diff --git a/src/WinRT.Runtime/Projections/PropertyChangedEventArgs.cs b/src/WinRT.Runtime/Projections/PropertyChangedEventArgs.cs index 4529aff6c..c81fb9afb 100644 --- a/src/WinRT.Runtime/Projections/PropertyChangedEventArgs.cs +++ b/src/WinRT.Runtime/Projections/PropertyChangedEventArgs.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. +// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. using System; @@ -18,10 +18,15 @@ internal unsafe struct IPropertyChangedEventArgsVftbl public delegate* unmanaged[Stdcall] get_PropertyName_0 => (delegate* unmanaged[Stdcall])_get_PropertyName_0; } + internal interface IWinRTPropertyChangedEventArgsRuntimeClassFactory + { + IObjectReference CreateInstance(string name, object baseInterface, out IObjectReference innerInterface); + ObjectReferenceValue CreateInstance(string name); + } [global::WinRT.ObjectReferenceWrapper(nameof(_obj))] [Guid("7C0C27A8-0B41-5070-B160-FC9AE960A36C")] - internal sealed unsafe class WinRTPropertyChangedEventArgsRuntimeClassFactory + internal sealed unsafe class MUXPropertyChangedEventArgsRuntimeClassFactory : IWinRTPropertyChangedEventArgsRuntimeClassFactory { [Guid("7C0C27A8-0B41-5070-B160-FC9AE960A36C")] [StructLayout(LayoutKind.Sequential)] @@ -33,14 +38,14 @@ public struct Vftbl } public static ObjectReference FromAbi(IntPtr thisPtr) => ObjectReference.FromAbi(thisPtr); - public static implicit operator WinRTPropertyChangedEventArgsRuntimeClassFactory(IObjectReference obj) => (obj != null) ? new WinRTPropertyChangedEventArgsRuntimeClassFactory(obj) : null; - public static implicit operator WinRTPropertyChangedEventArgsRuntimeClassFactory(ObjectReference obj) => (obj != null) ? new WinRTPropertyChangedEventArgsRuntimeClassFactory(obj) : null; + public static implicit operator MUXPropertyChangedEventArgsRuntimeClassFactory(IObjectReference obj) => (obj != null) ? new MUXPropertyChangedEventArgsRuntimeClassFactory(obj) : null; + public static implicit operator MUXPropertyChangedEventArgsRuntimeClassFactory(ObjectReference obj) => (obj != null) ? new MUXPropertyChangedEventArgsRuntimeClassFactory(obj) : null; private readonly ObjectReference _obj; public IntPtr ThisPtr => _obj.ThisPtr; public ObjectReference AsInterface() => _obj.As(); public A As() => _obj.AsType(); - public WinRTPropertyChangedEventArgsRuntimeClassFactory(IObjectReference obj) : this(obj.As()) { } - public WinRTPropertyChangedEventArgsRuntimeClassFactory(ObjectReference obj) + public MUXPropertyChangedEventArgsRuntimeClassFactory(IObjectReference obj) : this(obj.As()) { } + public MUXPropertyChangedEventArgsRuntimeClassFactory(ObjectReference obj) { _obj = obj; } @@ -54,11 +59,11 @@ public unsafe IObjectReference CreateInstance(string name, object baseInterface, { MarshalString.Pinnable __name = new(name); fixed (void* ___name = __name) - { + { __baseInterface = MarshalInspectable.CreateMarshaler(baseInterface); global::WinRT.ExceptionHelpers.ThrowExceptionForHR(_obj.Vftbl.CreateInstance_0(ThisPtr, MarshalString.GetAbi(ref __name), MarshalInspectable.GetAbi(__baseInterface), &__innerInterface, &__retval)); innerInterface = ObjectReference.FromAbi(__innerInterface); - return ObjectReference.Attach(ref __retval); + return ObjectReference.Attach(ref __retval); } } finally @@ -67,8 +72,8 @@ public unsafe IObjectReference CreateInstance(string name, object baseInterface, MarshalInspectable.DisposeAbi(__innerInterface); MarshalInspectable.DisposeAbi(__retval); } - } - + } + public unsafe ObjectReferenceValue CreateInstance(string name) { IntPtr __innerInterface = default; @@ -77,7 +82,7 @@ public unsafe ObjectReferenceValue CreateInstance(string name) { MarshalString.Pinnable __name = new(name); fixed (void* ___name = __name) - { + { global::WinRT.ExceptionHelpers.ThrowExceptionForHR(_obj.Vftbl.CreateInstance_0(ThisPtr, MarshalString.GetAbi(ref __name), IntPtr.Zero, &__innerInterface, &__retval)); return new ObjectReferenceValue(__retval); } @@ -87,7 +92,78 @@ public unsafe ObjectReferenceValue CreateInstance(string name) MarshalInspectable.DisposeAbi(__innerInterface); } } + } + + + + [global::WinRT.ObjectReferenceWrapper(nameof(_obj))] + [Guid("6DCC9C03-E0C7-4EEE-8EA9-37E3406EEB1C")] + internal sealed unsafe class WUXPropertyChangedEventArgsRuntimeClassFactory : IWinRTPropertyChangedEventArgsRuntimeClassFactory + { + [Guid("6DCC9C03-E0C7-4EEE-8EA9-37E3406EEB1C")] + [StructLayout(LayoutKind.Sequential)] + public struct Vftbl + { + internal IInspectable.Vftbl IInspectableVftbl; + private void* _CreateInstance_0; + public delegate* unmanaged[Stdcall] CreateInstance_0 => (delegate* unmanaged[Stdcall])_CreateInstance_0; + } + public static ObjectReference FromAbi(IntPtr thisPtr) => ObjectReference.FromAbi(thisPtr); + + public static implicit operator WUXPropertyChangedEventArgsRuntimeClassFactory(IObjectReference obj) => (obj != null) ? new WUXPropertyChangedEventArgsRuntimeClassFactory(obj) : null; + public static implicit operator WUXPropertyChangedEventArgsRuntimeClassFactory(ObjectReference obj) => (obj != null) ? new WUXPropertyChangedEventArgsRuntimeClassFactory(obj) : null; + private readonly ObjectReference _obj; + public IntPtr ThisPtr => _obj.ThisPtr; + public ObjectReference AsInterface() => _obj.As(); + public A As() => _obj.AsType(); + public WUXPropertyChangedEventArgsRuntimeClassFactory(IObjectReference obj) : this(obj.As()) { } + public WUXPropertyChangedEventArgsRuntimeClassFactory(ObjectReference obj) + { + _obj = obj; + } + public unsafe IObjectReference CreateInstance(string name, object baseInterface, out IObjectReference innerInterface) + { + IObjectReference __baseInterface = default; + IntPtr __innerInterface = default; + IntPtr __retval = default; + try + { + MarshalString.Pinnable __name = new(name); + fixed (void* ___name = __name) + { + __baseInterface = MarshalInspectable.CreateMarshaler(baseInterface); + global::WinRT.ExceptionHelpers.ThrowExceptionForHR(_obj.Vftbl.CreateInstance_0(ThisPtr, MarshalString.GetAbi(ref __name), MarshalInspectable.GetAbi(__baseInterface), &__innerInterface, &__retval)); + innerInterface = ObjectReference.FromAbi(__innerInterface); + return ObjectReference.Attach(ref __retval); + } + } + finally + { + MarshalInspectable.DisposeMarshaler(__baseInterface); + MarshalInspectable.DisposeAbi(__innerInterface); + MarshalInspectable.DisposeAbi(__retval); + } + } + + public unsafe ObjectReferenceValue CreateInstance(string name) + { + IntPtr __innerInterface = default; + IntPtr __retval = default; + try + { + MarshalString.Pinnable __name = new(name); + fixed (void* ___name = __name) + { + global::WinRT.ExceptionHelpers.ThrowExceptionForHR(_obj.Vftbl.CreateInstance_0(ThisPtr, MarshalString.GetAbi(ref __name), IntPtr.Zero, &__innerInterface, &__retval)); + return new ObjectReferenceValue(__retval); + } + } + finally + { + MarshalInspectable.DisposeAbi(__innerInterface); + } + } } } @@ -102,7 +178,10 @@ namespace ABI.System.ComponentModel #endif unsafe struct PropertyChangedEventArgs { - private static ABI.Microsoft.UI.Xaml.Data.WinRTPropertyChangedEventArgsRuntimeClassFactory Instance = ActivationFactory.Get("Microsoft.UI.Xaml.Data.PropertyChangedEventArgs"); + private static ABI.Microsoft.UI.Xaml.Data.IWinRTPropertyChangedEventArgsRuntimeClassFactory Instance = + Projections.UiXamlModeSetting == Projections.UiXamlMode.WindowsUiXaml + ? new ABI.Microsoft.UI.Xaml.Data.WUXPropertyChangedEventArgsRuntimeClassFactory(ActivationFactory.Get("Windows.UI.Xaml.Data.PropertyChangedEventArgs")) + : new ABI.Microsoft.UI.Xaml.Data.MUXPropertyChangedEventArgsRuntimeClassFactory(ActivationFactory.Get("Microsoft.UI.Xaml.Data.PropertyChangedEventArgs")); public static IObjectReference CreateMarshaler(global::System.ComponentModel.PropertyChangedEventArgs value) { @@ -112,8 +191,8 @@ public static IObjectReference CreateMarshaler(global::System.ComponentModel.Pro } return Instance.CreateInstance(value.PropertyName, null, out _); - } - + } + public static ObjectReferenceValue CreateMarshaler2(global::System.ComponentModel.PropertyChangedEventArgs value) { if (value is null) @@ -136,6 +215,8 @@ public static ObjectReferenceValue CreateMarshaler2(global::System.ComponentMode IntPtr propertyName = IntPtr.Zero; try { + // We can use the Microsoft.UI.Xaml.Data.IPropertyChangedEventArgsVftbl here in both WUX and MUX because the vtables are laid out the same and we know + // that we have either a MUX or WUX IPropertyChangedEventArgs pointer in ptr. ExceptionHelpers.ThrowExceptionForHR((**(ABI.Microsoft.UI.Xaml.Data.IPropertyChangedEventArgsVftbl**)ptr).get_PropertyName_0(ptr, &propertyName)); return new global::System.ComponentModel.PropertyChangedEventArgs(MarshalString.FromAbi(propertyName)); } @@ -160,8 +241,8 @@ public static IntPtr FromManaged(global::System.ComponentModel.PropertyChangedEv } public static void DisposeMarshaler(IObjectReference m) { m?.Dispose(); } - public static void DisposeAbi(IntPtr abi) { MarshalInspectable.DisposeAbi(abi); } - + public static void DisposeAbi(IntPtr abi) { MarshalInspectable.DisposeAbi(abi); } + public static unsafe MarshalInterfaceHelper.MarshalerArray CreateMarshalerArray(global::System.ComponentModel.PropertyChangedEventArgs[] array) => MarshalInterfaceHelper.CreateMarshalerArray2(array, CreateMarshaler2); public static (int length, IntPtr data) GetAbiArray(object box) => MarshalInterfaceHelper.GetAbiArray(box); public static unsafe global::System.ComponentModel.PropertyChangedEventArgs[] FromAbiArray(object box) => MarshalInterfaceHelper.FromAbiArray(box, FromAbi); @@ -172,6 +253,11 @@ public static IntPtr FromManaged(global::System.ComponentModel.PropertyChangedEv public static string GetGuidSignature() { + if (Projections.UiXamlModeSetting == Projections.UiXamlMode.WindowsUiXaml) + { + return "rc(Windows.UI.Xaml.Data.NotifyPropertyChangedEventArgs;{4f33a9a0-5cf4-47a4-b16f-d7faaf17457e})"; + } + return "rc(Microsoft.UI.Xaml.Data.NotifyPropertyChangedEventArgs;{4f33a9a0-5cf4-47a4-b16f-d7faaf17457e})"; } } diff --git a/src/WinRT.Runtime/Projections/PropertyChangedEventHandler.cs b/src/WinRT.Runtime/Projections/PropertyChangedEventHandler.cs index 28334aadd..3fc9f29ce 100644 --- a/src/WinRT.Runtime/Projections/PropertyChangedEventHandler.cs +++ b/src/WinRT.Runtime/Projections/PropertyChangedEventHandler.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. +// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. using System; @@ -12,6 +12,7 @@ namespace ABI.System.ComponentModel { [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] [Guid("E3DE52F6-1E32-5DA6-BB2D-B5B6096C962D")] + [WuxMuxProjectedType(wuxIID: "50F19C16-0A22-4D8E-A089-1EA9951657D2", muxIID: "E3DE52F6-1E32-5DA6-BB2D-B5B6096C962D")] #if EMBED internal #else @@ -40,28 +41,31 @@ static unsafe PropertyChangedEventHandler() var nativeVftbl = ComWrappersSupport.AllocateVtableMemory(typeof(PropertyChangedEventHandler), Marshal.SizeOf()); Marshal.StructureToPtr(AbiToProjectionVftable, nativeVftbl, false); AbiToProjectionVftablePtr = nativeVftbl; + IID = Projections.UiXamlModeSetting == Projections.UiXamlMode.WindowsUiXaml + ? Guid.Parse("50F19C16-0A22-4D8E-A089-1EA9951657D2") + : Guid.Parse("E3DE52F6-1E32-5DA6-BB2D-B5B6096C962D"); } - public static global::System.Delegate AbiInvokeDelegate { get; } - - private static readonly Guid IID = new(0xE3DE52F6, 0x1E32, 0x5DA6, 0xBB, 0x2D, 0xB5, 0xB6, 0x09, 0x6C, 0x96, 0x2D); + public static global::System.Delegate AbiInvokeDelegate { get; } + + private static readonly Guid IID; public static unsafe IObjectReference CreateMarshaler(global::System.ComponentModel.PropertyChangedEventHandler managedDelegate) => - managedDelegate is null ? null : MarshalDelegate.CreateMarshaler(managedDelegate, IID); - + managedDelegate is null ? null : MarshalDelegate.CreateMarshaler(managedDelegate, IID); + public static unsafe ObjectReferenceValue CreateMarshaler2(global::System.ComponentModel.PropertyChangedEventHandler managedDelegate) => MarshalDelegate.CreateMarshaler2(managedDelegate, IID); public static IntPtr GetAbi(IObjectReference value) => MarshalInterfaceHelper.GetAbi(value); public static unsafe global::System.ComponentModel.PropertyChangedEventHandler FromAbi(IntPtr nativeDelegate) - { + { return MarshalDelegate.FromAbi(nativeDelegate); - } - - public static global::System.ComponentModel.PropertyChangedEventHandler CreateRcw(IntPtr ptr) - { - return new global::System.ComponentModel.PropertyChangedEventHandler(new NativeDelegateWrapper(ComWrappersSupport.GetObjectReferenceForInterface(ptr, IID)).Invoke); + } + + public static global::System.ComponentModel.PropertyChangedEventHandler CreateRcw(IntPtr ptr) + { + return new global::System.ComponentModel.PropertyChangedEventHandler(new NativeDelegateWrapper(ComWrappersSupport.GetObjectReferenceForInterface(ptr, IID)).Invoke); } [global::WinRT.ObjectReferenceWrapper(nameof(_nativeDelegate))] @@ -127,8 +131,8 @@ public static IntPtr FromManaged(global::System.ComponentModel.PropertyChangedEv public static void DisposeMarshaler(IObjectReference value) => MarshalInterfaceHelper.DisposeMarshaler(value); - public static void DisposeAbi(IntPtr abi) => MarshalInterfaceHelper.DisposeAbi(abi); - + public static void DisposeAbi(IntPtr abi) => MarshalInterfaceHelper.DisposeAbi(abi); + public static unsafe MarshalInterfaceHelper.MarshalerArray CreateMarshalerArray(global::System.ComponentModel.PropertyChangedEventHandler[] array) => MarshalInterfaceHelper.CreateMarshalerArray2(array, CreateMarshaler2); public static (int length, IntPtr data) GetAbiArray(object box) => MarshalInterfaceHelper.GetAbiArray(box); public static unsafe global::System.ComponentModel.PropertyChangedEventHandler[] FromAbiArray(object box) => MarshalInterfaceHelper.FromAbiArray(box, FromAbi); @@ -143,7 +147,7 @@ public static IntPtr FromManaged(global::System.ComponentModel.PropertyChangedEv private static unsafe int Do_Abi_Invoke(IntPtr thisPtr, IntPtr sender, IntPtr e) { try - { + { #if NET var invoke = ComWrappersSupport.FindObject(thisPtr); invoke.Invoke(MarshalInspectable.FromAbi(sender), global::ABI.System.ComponentModel.PropertyChangedEventArgs.FromAbi(e)); @@ -167,7 +171,7 @@ internal sealed unsafe class PropertyChangedEventSource : EventSource addHandler, + delegate* unmanaged[Stdcall] addHandler, #else delegate* unmanaged[Stdcall] addHandler, #endif diff --git a/src/WinRT.Runtime/Projections/Windows.UI.Xaml.Bindable.net5.cs b/src/WinRT.Runtime/Projections/Windows.UI.Xaml.Bindable.net5.cs new file mode 100644 index 000000000..7f54e9b25 --- /dev/null +++ b/src/WinRT.Runtime/Projections/Windows.UI.Xaml.Bindable.net5.cs @@ -0,0 +1,367 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using WinRT; +using WinRT.Interop; + + +#pragma warning disable 0169 // warning CS0169: The field '...' is never used +#pragma warning disable 0649 // warning CS0169: Field '...' is never assigned to + +namespace Windows.UI.Xaml.Interop +{ + [global::WinRT.WindowsRuntimeType] + [Guid("036D2C08-DF29-41AF-8AA2-D774BE62BA6F")] + [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Windows.UI.Xaml.Interop.IBindableIterable))] + internal interface IBindableIterable + { + IBindableIterator First(); + } + [global::WinRT.WindowsRuntimeType] + [Guid("6A1D6C07-076D-49F2-8314-F52C9C9A8331")] + [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Windows.UI.Xaml.Interop.IBindableIterator))] + internal interface IBindableIterator + { + bool MoveNext(); + // GetMany is not implemented by IBindableIterator, but it is here + // for compat purposes with WinUI where there are scenarios they do + // reinterpret_cast from IBindableIterator to IIterable. It is + // the last function in the vftable and shouldn't be called by anyone. + // If called, it will return NotImplementedException. + uint GetMany(ref object[] items); + object Current { get; } + bool HasCurrent { get; } + } + [global::WinRT.WindowsRuntimeType] + [Guid("393DE7DE-6FD0-4C0D-BB71-47244A113E93")] + internal interface IBindableVector : IEnumerable + { + object GetAt(uint index); + IBindableVectorView GetView(); + bool IndexOf(object value, out uint index); + void SetAt(uint index, object value); + void InsertAt(uint index, object value); + void RemoveAt(uint index); + void Append(object value); + void RemoveAtEnd(); + void Clear(); + uint Size { get; } + } + [global::WinRT.WindowsRuntimeType] + [Guid("346DD6E7-976E-4BC3-815D-ECE243BC0F33")] + [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Windows.UI.Xaml.Interop.IBindableVectorView))] + internal interface IBindableVectorView : IEnumerable + { + object GetAt(uint index); + bool IndexOf(object value, out uint index); + uint Size { get; } + } +} + +namespace ABI.Windows.UI.Xaml.Interop +{ + [DynamicInterfaceCastableImplementation] + [Guid("036D2C08-DF29-41AF-8AA2-D774BE62BA6F")] + internal unsafe interface IBindableIterable : global::Windows.UI.Xaml.Interop.IBindableIterable, ABI.System.Collections.IEnumerable + { + + } + + [DynamicInterfaceCastableImplementation] + [Guid("6A1D6C07-076D-49F2-8314-F52C9C9A8331")] + internal unsafe interface IBindableIterator : global::Windows.UI.Xaml.Interop.IBindableIterator + { + public static readonly IntPtr AbiToProjectionVftablePtr; + static IBindableIterator() + { + AbiToProjectionVftablePtr = ComWrappersSupport.AllocateVtableMemory(typeof(IBindableIterator), sizeof(IInspectable.Vftbl) + sizeof(IntPtr) * 4); + *(IInspectable.Vftbl*)AbiToProjectionVftablePtr = IInspectable.Vftbl.AbiToProjectionVftable; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[6] = &Do_Abi_get_Current_0; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[7] = &Do_Abi_get_HasCurrent_1; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[8] = &Do_Abi_MoveNext_2; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[9] = &Do_Abi_GetMany_3; + } + + [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] + private static unsafe int Do_Abi_MoveNext_2(IntPtr thisPtr, byte* result) + { + bool __result = default; + *result = default; + try + { + __result = global::WinRT.ComWrappersSupport.FindObject(thisPtr).MoveNext(); + *result = (byte)(__result ? 1 : 0); + } + catch (Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + + [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] + private static unsafe int Do_Abi_GetMany_3(IntPtr thisPtr, int __itemsSize, IntPtr items, uint* result) + { + *result = default; + + try + { + // Should never be called. + throw new NotImplementedException(); + } + catch (Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + } + + [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] + private static unsafe int Do_Abi_get_Current_0(IntPtr thisPtr, IntPtr* value) + { + object __value = default; + *value = default; + try + { + __value = global::WinRT.ComWrappersSupport.FindObject(thisPtr).Current; + *value = MarshalInspectable.FromManaged(__value); + } + catch (Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + + [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] + private static unsafe int Do_Abi_get_HasCurrent_1(IntPtr thisPtr, byte* value) + { + bool __value = default; + *value = default; + try + { + __value = global::WinRT.ComWrappersSupport.FindObject(thisPtr).HasCurrent; + *value = (byte)(__value ? 1 : 0); + } + catch (Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + + internal static ObjectReference FromAbi(IntPtr thisPtr) => ObjectReference.FromAbi(thisPtr); + + unsafe bool global::Windows.UI.Xaml.Interop.IBindableIterator.MoveNext() + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::Windows.UI.Xaml.Interop.IBindableIterator).TypeHandle); + var ThisPtr = _obj.ThisPtr; + byte __retval = default; + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[8](ThisPtr, &__retval)); + return __retval != 0; + } + + unsafe uint global::Windows.UI.Xaml.Interop.IBindableIterator.GetMany(ref object[] items) + { + // Should never be called. + throw new NotImplementedException(); + } + + unsafe object global::Windows.UI.Xaml.Interop.IBindableIterator.Current + { + get + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::Windows.UI.Xaml.Interop.IBindableIterator).TypeHandle); + var ThisPtr = _obj.ThisPtr; + IntPtr __retval = default; + try + { + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[6](ThisPtr, &__retval)); + return MarshalInspectable.FromAbi(__retval); + } + finally + { + MarshalInspectable.DisposeAbi(__retval); + } + } + } + + unsafe bool global::Windows.UI.Xaml.Interop.IBindableIterator.HasCurrent + { + get + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::Windows.UI.Xaml.Interop.IBindableIterator).TypeHandle); + var ThisPtr = _obj.ThisPtr; + byte __retval = default; + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[7](ThisPtr, &__retval)); + return __retval != 0; + } + } + + } + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + internal static class IBindableIterator_Delegates + { + public unsafe delegate int get_Current_0(IntPtr thisPtr, IntPtr* result); + public unsafe delegate int get_HasCurrent_1(IntPtr thisPtr, byte* result); + public unsafe delegate int MoveNext_2(IntPtr thisPtr, byte* result); + public unsafe delegate int GetMany_3(IntPtr thisPtr, int itemSize, IntPtr items, uint* result); + } + + [DynamicInterfaceCastableImplementation] + [Guid("346DD6E7-976E-4BC3-815D-ECE243BC0F33")] + internal unsafe interface IBindableVectorView : global::Windows.UI.Xaml.Interop.IBindableVectorView + { + public static readonly IntPtr AbiToProjectionVftablePtr; + static IBindableVectorView() + { + AbiToProjectionVftablePtr = ComWrappersSupport.AllocateVtableMemory(typeof(IBindableVectorView), sizeof(IInspectable.Vftbl) + sizeof(IntPtr) * 3); + *(IInspectable.Vftbl*)AbiToProjectionVftablePtr = IInspectable.Vftbl.AbiToProjectionVftable; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[6] = &Do_Abi_GetAt_0; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[7] = &Do_Abi_get_Size_1; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[8] = &Do_Abi_IndexOf_2; + } + + [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] + private static unsafe int Do_Abi_GetAt_0(IntPtr thisPtr, uint index, IntPtr* result) + { + object __result = default; + + try + { + __result = global::WinRT.ComWrappersSupport.FindObject(thisPtr).GetAt(index); + *result = MarshalInspectable.FromManaged(__result); + + } + catch (Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + + [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] + private static unsafe int Do_Abi_IndexOf_2(IntPtr thisPtr, IntPtr value, uint* index, byte* returnValue) + { + bool __returnValue = default; + + *index = default; + *returnValue = default; + uint __index = default; + + try + { + __returnValue = global::WinRT.ComWrappersSupport.FindObject(thisPtr).IndexOf(MarshalInspectable.FromAbi(value), out __index); + *index = __index; + *returnValue = (byte)(__returnValue ? 1 : 0); + + } + catch (Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + + [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] + private static unsafe int Do_Abi_get_Size_1(IntPtr thisPtr, uint* value) + { + uint __value = default; + + *value = default; + + try + { + __value = global::WinRT.ComWrappersSupport.FindObject(thisPtr).Size; + *value = __value; + + } + catch (Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + + internal static ObjectReference FromAbi(IntPtr thisPtr) => ObjectReference.FromAbi(thisPtr); + + private static readonly global::System.Runtime.CompilerServices.ConditionalWeakTable _helperTable = new(); + + unsafe object global::Windows.UI.Xaml.Interop.IBindableVectorView.GetAt(uint index) + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::Windows.UI.Xaml.Interop.IBindableIterator).TypeHandle); + var ThisPtr = _obj.ThisPtr; + IntPtr __retval = default; + try + { + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[6](ThisPtr, index, &__retval)); + return MarshalInspectable.FromAbi(__retval); + } + finally + { + MarshalInspectable.DisposeAbi(__retval); + } + } + + unsafe bool global::Windows.UI.Xaml.Interop.IBindableVectorView.IndexOf(object value, out uint index) + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::Windows.UI.Xaml.Interop.IBindableIterator).TypeHandle); + var ThisPtr = _obj.ThisPtr; + ObjectReferenceValue __value = default; + uint __index = default; + byte __retval = default; + try + { + __value = MarshalInspectable.CreateMarshaler2(value); + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[8]( + ThisPtr, + MarshalInspectable.GetAbi(__value), + &__index, + &__retval)); + index = __index; + return __retval != 0; + } + finally + { + MarshalInspectable.DisposeMarshaler(__value); + } + } + + unsafe uint global::Windows.UI.Xaml.Interop.IBindableVectorView.Size + { + get + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::Windows.UI.Xaml.Interop.IBindableIterator).TypeHandle); + var ThisPtr = _obj.ThisPtr; + uint __retval = default; + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[7](ThisPtr, &__retval)); + return __retval; + } + } + + IEnumerator IEnumerable.GetEnumerator() + { + return _helperTable.GetValue((IWinRTObject)this, + (enumerable) => new ABI.System.Collections.IEnumerable.AdaptiveFromAbiHelper(enumerable) + ).GetEnumerator(); + } + } + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + internal static class IBindableVectorView_Delegates + { + public unsafe delegate int GetAt_0(IntPtr thisPtr, uint index, IntPtr* result); + public unsafe delegate int get_Size_1(IntPtr thisPtr, uint* result); + public unsafe delegate int IndexOf_2(IntPtr thisPtr, IntPtr value, uint* index, byte* returnValue); + } +} diff --git a/src/cswinrt.sln b/src/cswinrt.sln index bdc0d86a0..e6bb53157 100644 --- a/src/cswinrt.sln +++ b/src/cswinrt.sln @@ -160,6 +160,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WinAppSDK", "Projections\Wi EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestLibrary", "Tests\FunctionalTests\TestLibrary\TestLibrary.csproj", "{335D51AC-1DCF-4487-A2BD-34CE2F17B3C4}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Windows.UI.Xaml", "Projections\Windows.UI.Xaml\Windows.UI.Xaml.csproj", "{E85F3614-79B6-4652-BDB0-64AF68874CE0}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AuthoringWuxTest", "Tests\AuthoringWuxTest\AuthoringWuxTest.csproj", "{D60CFCAD-4A13-4047-91C8-9D7DF4753493}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AuthoringWuxConsumptionTest", "Tests\AuthoringWuxConsumptionTest\AuthoringWuxConsumptionTest.vcxproj", "{A04A0416-5E35-4DD0-8226-63D941B28467}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|ARM = Debug|ARM @@ -732,6 +738,54 @@ Global {335D51AC-1DCF-4487-A2BD-34CE2F17B3C4}.Release|x64.Build.0 = Release|x64 {335D51AC-1DCF-4487-A2BD-34CE2F17B3C4}.Release|x86.ActiveCfg = Release|x86 {335D51AC-1DCF-4487-A2BD-34CE2F17B3C4}.Release|x86.Build.0 = Release|x86 + {E85F3614-79B6-4652-BDB0-64AF68874CE0}.Debug|ARM.ActiveCfg = Debug|x86 + {E85F3614-79B6-4652-BDB0-64AF68874CE0}.Debug|ARM.Build.0 = Debug|x86 + {E85F3614-79B6-4652-BDB0-64AF68874CE0}.Debug|ARM64.ActiveCfg = Debug|x86 + {E85F3614-79B6-4652-BDB0-64AF68874CE0}.Debug|ARM64.Build.0 = Debug|x86 + {E85F3614-79B6-4652-BDB0-64AF68874CE0}.Debug|x64.ActiveCfg = Debug|x64 + {E85F3614-79B6-4652-BDB0-64AF68874CE0}.Debug|x64.Build.0 = Debug|x64 + {E85F3614-79B6-4652-BDB0-64AF68874CE0}.Debug|x86.ActiveCfg = Debug|x86 + {E85F3614-79B6-4652-BDB0-64AF68874CE0}.Debug|x86.Build.0 = Debug|x86 + {E85F3614-79B6-4652-BDB0-64AF68874CE0}.Release|ARM.ActiveCfg = Release|x86 + {E85F3614-79B6-4652-BDB0-64AF68874CE0}.Release|ARM.Build.0 = Release|x86 + {E85F3614-79B6-4652-BDB0-64AF68874CE0}.Release|ARM64.ActiveCfg = Release|x86 + {E85F3614-79B6-4652-BDB0-64AF68874CE0}.Release|ARM64.Build.0 = Release|x86 + {E85F3614-79B6-4652-BDB0-64AF68874CE0}.Release|x64.ActiveCfg = Release|x64 + {E85F3614-79B6-4652-BDB0-64AF68874CE0}.Release|x64.Build.0 = Release|x64 + {E85F3614-79B6-4652-BDB0-64AF68874CE0}.Release|x86.ActiveCfg = Release|x86 + {E85F3614-79B6-4652-BDB0-64AF68874CE0}.Release|x86.Build.0 = Release|x86 + {D60CFCAD-4A13-4047-91C8-9D7DF4753493}.Debug|ARM.ActiveCfg = Debug|x86 + {D60CFCAD-4A13-4047-91C8-9D7DF4753493}.Debug|ARM.Build.0 = Debug|x86 + {D60CFCAD-4A13-4047-91C8-9D7DF4753493}.Debug|ARM64.ActiveCfg = Debug|x86 + {D60CFCAD-4A13-4047-91C8-9D7DF4753493}.Debug|ARM64.Build.0 = Debug|x86 + {D60CFCAD-4A13-4047-91C8-9D7DF4753493}.Debug|x64.ActiveCfg = Debug|x64 + {D60CFCAD-4A13-4047-91C8-9D7DF4753493}.Debug|x64.Build.0 = Debug|x64 + {D60CFCAD-4A13-4047-91C8-9D7DF4753493}.Debug|x86.ActiveCfg = Debug|x86 + {D60CFCAD-4A13-4047-91C8-9D7DF4753493}.Debug|x86.Build.0 = Debug|x86 + {D60CFCAD-4A13-4047-91C8-9D7DF4753493}.Release|ARM.ActiveCfg = Release|x86 + {D60CFCAD-4A13-4047-91C8-9D7DF4753493}.Release|ARM.Build.0 = Release|x86 + {D60CFCAD-4A13-4047-91C8-9D7DF4753493}.Release|ARM64.ActiveCfg = Release|x86 + {D60CFCAD-4A13-4047-91C8-9D7DF4753493}.Release|ARM64.Build.0 = Release|x86 + {D60CFCAD-4A13-4047-91C8-9D7DF4753493}.Release|x64.ActiveCfg = Release|x64 + {D60CFCAD-4A13-4047-91C8-9D7DF4753493}.Release|x64.Build.0 = Release|x64 + {D60CFCAD-4A13-4047-91C8-9D7DF4753493}.Release|x86.ActiveCfg = Release|x86 + {D60CFCAD-4A13-4047-91C8-9D7DF4753493}.Release|x86.Build.0 = Release|x86 + {A04A0416-5E35-4DD0-8226-63D941B28467}.Debug|ARM.ActiveCfg = Debug|Win32 + {A04A0416-5E35-4DD0-8226-63D941B28467}.Debug|ARM.Build.0 = Debug|Win32 + {A04A0416-5E35-4DD0-8226-63D941B28467}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {A04A0416-5E35-4DD0-8226-63D941B28467}.Debug|ARM64.Build.0 = Debug|ARM64 + {A04A0416-5E35-4DD0-8226-63D941B28467}.Debug|x64.ActiveCfg = Debug|x64 + {A04A0416-5E35-4DD0-8226-63D941B28467}.Debug|x64.Build.0 = Debug|x64 + {A04A0416-5E35-4DD0-8226-63D941B28467}.Debug|x86.ActiveCfg = Debug|Win32 + {A04A0416-5E35-4DD0-8226-63D941B28467}.Debug|x86.Build.0 = Debug|Win32 + {A04A0416-5E35-4DD0-8226-63D941B28467}.Release|ARM.ActiveCfg = Release|Win32 + {A04A0416-5E35-4DD0-8226-63D941B28467}.Release|ARM.Build.0 = Release|Win32 + {A04A0416-5E35-4DD0-8226-63D941B28467}.Release|ARM64.ActiveCfg = Release|ARM64 + {A04A0416-5E35-4DD0-8226-63D941B28467}.Release|ARM64.Build.0 = Release|ARM64 + {A04A0416-5E35-4DD0-8226-63D941B28467}.Release|x64.ActiveCfg = Release|x64 + {A04A0416-5E35-4DD0-8226-63D941B28467}.Release|x64.Build.0 = Release|x64 + {A04A0416-5E35-4DD0-8226-63D941B28467}.Release|x86.ActiveCfg = Release|Win32 + {A04A0416-5E35-4DD0-8226-63D941B28467}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -777,6 +831,9 @@ Global {C44DB047-5DF0-4732-98F4-A181D3AD8A7F} = {5ECC38F0-16FD-47E1-B8DC-8C474008AD55} {7B803846-91AE-4B98-AC93-D3FCFB2DE5AA} = {6D41796B-9904-40B8-BBCB-40B2D1BAE44B} {335D51AC-1DCF-4487-A2BD-34CE2F17B3C4} = {5ECC38F0-16FD-47E1-B8DC-8C474008AD55} + {E85F3614-79B6-4652-BDB0-64AF68874CE0} = {6D41796B-9904-40B8-BBCB-40B2D1BAE44B} + {D60CFCAD-4A13-4047-91C8-9D7DF4753493} = {CFB651EC-DAA4-4A11-ABCD-C77F90602EB5} + {A04A0416-5E35-4DD0-8226-63D941B28467} = {CFB651EC-DAA4-4A11-ABCD-C77F90602EB5} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {5AE8C9D7-2613-4E1A-A4F2-579BAC28D0A2} diff --git a/src/cswinrt/code_writers.h b/src/cswinrt/code_writers.h index 43bf8381b..db36d19ca 100644 --- a/src/cswinrt/code_writers.h +++ b/src/cswinrt/code_writers.h @@ -1440,7 +1440,7 @@ private % Make_%() if (event.Name() == "CanExecuteChanged" && event_type == "global::System.EventHandler") { auto parent_type = w.write_temp("%", bind(event.Parent(), typedef_name_type::NonProjected, true)); - if (parent_type == "Microsoft.UI.Xaml.Input.ICommand") + if (parent_type == "Microsoft.UI.Xaml.Input.ICommand" || parent_type == "Windows.UI.Xaml.Input.ICommand") { event_type = "global::System.EventHandler"; } diff --git a/src/cswinrt/cswinrt.vcxproj b/src/cswinrt/cswinrt.vcxproj index 674c12582..6980f4ebe 100644 --- a/src/cswinrt/cswinrt.vcxproj +++ b/src/cswinrt/cswinrt.vcxproj @@ -109,6 +109,12 @@ + + + + + + diff --git a/src/cswinrt/cswinrt.vcxproj.filters b/src/cswinrt/cswinrt.vcxproj.filters index 57e31721d..b06989e5d 100644 --- a/src/cswinrt/cswinrt.vcxproj.filters +++ b/src/cswinrt/cswinrt.vcxproj.filters @@ -51,6 +51,21 @@ {369a6d8a-43e6-48af-82c1-bb2e555909a4} + + {22aeef74-f4df-40f4-a18f-8053ac54f966} + + + {bb545b29-ba72-4949-b044-790f57ba17a5} + + + {8451fa83-9750-4aec-ae8c-a4149c4b98a6} + + + {98453be9-888b-4032-b5cd-4034b17197c9} + + + {03980bb6-f657-4c07-a456-5b4774de5773} + @@ -174,6 +189,24 @@ strings + + strings\additions\Windows.UI.Xaml.Controls.Primitives + + + strings\additions\Windows.UI.Xaml.Media.Animation + + + strings\additions\Windows.UI.Xaml.Media.Media3D + + + strings\additions\Windows.UI.Xaml.Media + + + strings\additions\Windows.UI.Xaml + + + strings\additions\Windows.UI.Xaml + diff --git a/src/cswinrt/helpers.h b/src/cswinrt/helpers.h index fcc3f7cc3..93b1ce916 100644 --- a/src/cswinrt/helpers.h +++ b/src/cswinrt/helpers.h @@ -670,7 +670,8 @@ namespace cswinrt } mapped_types[] = { // Make sure to keep this table consistent with the registrations in WinRT.Runtime/Projections.cs - // and the reverse mapping in WinRT.SourceGenerator/WinRTTypeWriter.cs. + // and the reverse mapping in WinRT.SourceGenerator/TypeMapper.cs. + // This table can include both the MUX and WUX types as only one will be selected at runtime. // NOTE: Must keep namespaces sorted (outer) and abi type names sorted (inner) { "Microsoft.UI.Xaml", { @@ -816,13 +817,92 @@ namespace cswinrt { "IColorHelperStatics2" }, } }, - // Temporary, until WinUI provides TypeName + { "Windows.UI.Xaml", + { + { "CornerRadius", "Windows.UI.Xaml", "CornerRadius" }, + { "CornerRadiusHelper" }, + { "Duration", "Windows.UI.Xaml", "Duration" }, + { "DurationHelper" }, + { "DurationType", "Windows.UI.Xaml", "DurationType" }, + { "GridLength", "Windows.UI.Xaml", "GridLength" }, + { "GridLengthHelper" }, + { "GridUnitType", "Windows.UI.Xaml", "GridUnitType" }, + { "ICornerRadiusHelper" }, + { "ICornerRadiusHelperStatics" }, + { "IDurationHelper" }, + { "IDurationHelperStatics" }, + { "IGridLengthHelper" }, + { "IGridLengthHelperStatics" }, + { "IThicknessHelper" }, + { "IThicknessHelperStatics" }, + { "Thickness", "Windows.UI.Xaml", "Thickness" }, + { "ThicknessHelper" }, + { "IXamlServiceProvider", "System", "IServiceProvider" }, + } + }, + { "Windows.UI.Xaml.Controls.Primitives", + { + { "GeneratorPosition", "Windows.UI.Xaml.Controls.Primitives", "GeneratorPosition" }, + { "GeneratorPositionHelper" }, + { "IGeneratorPositionHelper" }, + { "IGeneratorPositionHelperStatics" }, + } + }, + { "Windows.UI.Xaml.Data", + { + { "DataErrorsChangedEventArgs", "System.ComponentModel", "DataErrorsChangedEventArgs" }, + { "INotifyDataErrorInfo", "System.ComponentModel", "INotifyDataErrorInfo", true, true }, + { "INotifyPropertyChanged", "System.ComponentModel", "INotifyPropertyChanged" }, + { "PropertyChangedEventArgs", "System.ComponentModel", "PropertyChangedEventArgs" }, + { "PropertyChangedEventHandler", "System.ComponentModel", "PropertyChangedEventHandler" }, + } + }, + { "Windows.UI.Xaml.Input", + { + { "ICommand", "System.Windows.Input", "ICommand", true } + } + }, { "Windows.UI.Xaml.Interop", { + { "IBindableIterable", "System.Collections", "IEnumerable", true, true }, + { "IBindableVector", "System.Collections", "IList", true, true }, + { "INotifyCollectionChanged", "System.Collections.Specialized", "INotifyCollectionChanged", true }, + { "NotifyCollectionChangedAction", "System.Collections.Specialized", "NotifyCollectionChangedAction" }, + { "NotifyCollectionChangedEventArgs", "System.Collections.Specialized", "NotifyCollectionChangedEventArgs", true }, + { "NotifyCollectionChangedEventHandler", "System.Collections.Specialized", "NotifyCollectionChangedEventHandler", true }, { "TypeKind", "Windows.UI.Xaml.Interop", "TypeKind", true }, { "TypeName", "System", "Type", true } } }, + { "Windows.UI.Xaml.Media", + { + { "IMatrixHelper" }, + { "IMatrixHelperStatics" }, + { "Matrix", "Windows.UI.Xaml.Media", "Matrix" }, + { "MatrixHelper" }, + } + }, + { "Windows.UI.Xaml.Media.Animation", + { + { "IKeyTimeHelper" }, + { "IKeyTimeHelperStatics" }, + { "IRepeatBehaviorHelper" }, + { "IRepeatBehaviorHelperStatics" }, + { "KeyTime", "Windows.UI.Xaml.Media.Animation", "KeyTime" }, + { "KeyTimeHelper" }, + { "RepeatBehavior", "Windows.UI.Xaml.Media.Animation", "RepeatBehavior" }, + { "RepeatBehaviorHelper" }, + { "RepeatBehaviorType", "Windows.UI.Xaml.Media.Animation", "RepeatBehaviorType" } + } + }, + { "Windows.UI.Xaml.Media.Media3D", + { + { "IMatrix3DHelper" }, + { "IMatrix3DHelperStatics" }, + { "Matrix3D", "Windows.UI.Xaml.Media.Media3D", "Matrix3D" }, + { "Matrix3DHelper" }, + } + }, }; auto nsItr = std::lower_bound(std::begin(mapped_types), std::end(mapped_types), typeNamespace, [](auto&& v, std::string_view ns) diff --git a/src/cswinrt/strings/additions/Windows.UI.Xaml.Controls/Windows.UI.Xaml.Controls.Primitives.cs b/src/cswinrt/strings/additions/Windows.UI.Xaml.Controls/Windows.UI.Xaml.Controls.Primitives.cs new file mode 100644 index 000000000..ec28e9295 --- /dev/null +++ b/src/cswinrt/strings/additions/Windows.UI.Xaml.Controls/Windows.UI.Xaml.Controls.Primitives.cs @@ -0,0 +1,73 @@ + +namespace Windows.UI.Xaml.Controls.Primitives +{ + using global::Windows.Foundation; + + [global::WinRT.WindowsRuntimeType("Windows.UI.Xaml")] + [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Windows.UI.Xaml.Controls.Primitives.GeneratorPosition))] + [StructLayout(LayoutKind.Sequential)] +#if EMBED + internal +#else + public +#endif + struct GeneratorPosition + { + private int _index; + private int _offset; + + public int Index { get { return _index; } set { _index = value; } } + public int Offset { get { return _offset; } set { _offset = value; } } + + public GeneratorPosition(int index, int offset) + { + _index = index; + _offset = offset; + } + + public override int GetHashCode() + { + return _index.GetHashCode() + _offset.GetHashCode(); + } + + public override string ToString() + { + return string.Concat("GeneratorPosition (", _index.ToString(global::System.Globalization.CultureInfo.InvariantCulture), ",", _offset.ToString(global::System.Globalization.CultureInfo.InvariantCulture), ")"); + } + + public override bool Equals(object o) + { + if (o is GeneratorPosition) + { + GeneratorPosition that = (GeneratorPosition)o; + return _index == that._index && + _offset == that._offset; + } + return false; + } + + public static bool operator ==(GeneratorPosition gp1, GeneratorPosition gp2) + { + return gp1._index == gp2._index && + gp1._offset == gp2._offset; + } + + public static bool operator !=(GeneratorPosition gp1, GeneratorPosition gp2) + { + return !(gp1 == gp2); + } + } +} + +namespace ABI.Windows.UI.Xaml.Controls.Primitives +{ +#if EMBED + internal +#else + public +#endif + static class GeneratorPosition + { + public static string GetGuidSignature() => $"struct(Windows.UI.Xaml.Controls.Primitives.GeneratorPosition;i4;i4)"; + } +} diff --git a/src/cswinrt/strings/additions/Windows.UI.Xaml.Media.Animation/Windows.UI.Xaml.Media.Animation.cs b/src/cswinrt/strings/additions/Windows.UI.Xaml.Media.Animation/Windows.UI.Xaml.Media.Animation.cs new file mode 100644 index 000000000..259898959 --- /dev/null +++ b/src/cswinrt/strings/additions/Windows.UI.Xaml.Media.Animation/Windows.UI.Xaml.Media.Animation.cs @@ -0,0 +1,326 @@ + +namespace Windows.UI.Xaml.Media.Animation +{ + using global::Windows.Foundation; + + [global::WinRT.WindowsRuntimeType("Windows.UI.Xaml")] + [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Windows.UI.Xaml.Media.Animation.KeyTime))] + [StructLayout(LayoutKind.Sequential)] +#if EMBED + internal +#else + public +#endif + struct KeyTime + { + private TimeSpan _timeSpan; + + public static KeyTime FromTimeSpan(TimeSpan timeSpan) + { + if (timeSpan < TimeSpan.Zero) + { + throw new ArgumentOutOfRangeException(nameof(timeSpan)); + } + + KeyTime keyTime = default; + + keyTime._timeSpan = timeSpan; + + return keyTime; + } + + public static bool Equals(KeyTime keyTime1, KeyTime keyTime2) + { + return (keyTime1._timeSpan == keyTime2._timeSpan); + } + + public static bool operator ==(KeyTime keyTime1, KeyTime keyTime2) + { + return KeyTime.Equals(keyTime1, keyTime2); + } + + public static bool operator !=(KeyTime keyTime1, KeyTime keyTime2) + { + return !KeyTime.Equals(keyTime1, keyTime2); + } + + public bool Equals(KeyTime value) + { + return KeyTime.Equals(this, value); + } + + public override bool Equals(object value) + { + return value is KeyTime && this == (KeyTime)value; + } + + public override int GetHashCode() + { + return _timeSpan.GetHashCode(); + } + + public override string ToString() + { + return _timeSpan.ToString(); + } + + public static implicit operator KeyTime(TimeSpan timeSpan) + { + return KeyTime.FromTimeSpan(timeSpan); + } + + public TimeSpan TimeSpan + { + get + { + return _timeSpan; + } + } + } + + [global::WinRT.WindowsRuntimeType("Windows.UI.Xaml")] +#if EMBED + internal +#else + public +#endif + enum RepeatBehaviorType + { + Count, + Duration, + Forever + } + + [global::WinRT.WindowsRuntimeType("Windows.UI.Xaml")] + [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Windows.UI.Xaml.Media.Animation.RepeatBehavior))] + [StructLayout(LayoutKind.Sequential)] +#if EMBED + internal +#else + public +#endif + struct RepeatBehavior : IFormattable + { + private double _Count; + private TimeSpan _Duration; + private RepeatBehaviorType _Type; + + internal static bool IsFinite(double value) + { + return !(double.IsNaN(value) || double.IsInfinity(value)); + } + + public RepeatBehavior(double count) + { + if (!IsFinite(count) || count < 0.0) + { + throw new ArgumentOutOfRangeException(nameof(count)); + } + + _Duration = new TimeSpan(0); + _Count = count; + _Type = RepeatBehaviorType.Count; + } + + public RepeatBehavior(TimeSpan duration) + { + if (duration < new TimeSpan(0)) + { + throw new ArgumentOutOfRangeException(nameof(duration)); + } + + _Duration = duration; + _Count = 0.0; + _Type = RepeatBehaviorType.Duration; + } + + public static RepeatBehavior Forever + { + get + { + RepeatBehavior forever = default; + forever.Type = RepeatBehaviorType.Forever; + + return forever; + } + } + + public bool HasCount + { + get + { + return Type == RepeatBehaviorType.Count; + } + } + + public bool HasDuration + { + get + { + return Type == RepeatBehaviorType.Duration; + } + } + + public double Count + { + get { return _Count; } + set { _Count = value; } + } + + public TimeSpan Duration + { + get { return _Duration; } + set { _Duration = value; } + } + + public RepeatBehaviorType Type + { + get { return _Type; } + set { _Type = value; } + } + + public override string ToString() + { + return InternalToString(null, null); + } + + public string ToString(IFormatProvider formatProvider) + { + return InternalToString(null, formatProvider); + } + + string IFormattable.ToString(string format, IFormatProvider formatProvider) + { + return InternalToString(format, formatProvider); + } + + internal string InternalToString(string format, IFormatProvider formatProvider) + { + switch (_Type) + { + case RepeatBehaviorType.Forever: + + return "Forever"; + + case RepeatBehaviorType.Count: + + global::System.Text.StringBuilder sb = new global::System.Text.StringBuilder(); + + sb.AppendFormat( + formatProvider, + "{0:" + format + "}x", + _Count); + + return sb.ToString(); + + case RepeatBehaviorType.Duration: + + return _Duration.ToString(); + + default: + return string.Empty; + } + } + + public override bool Equals(object value) + { + if (value is RepeatBehavior) + { + return this.Equals((RepeatBehavior)value); + } + else + { + return false; + } + } + + public bool Equals(RepeatBehavior repeatBehavior) + { + if (_Type == repeatBehavior._Type) + { + return _Type switch + { + RepeatBehaviorType.Forever => true, + RepeatBehaviorType.Count => _Count == repeatBehavior._Count, + RepeatBehaviorType.Duration => _Duration == repeatBehavior._Duration, + _ => false, + }; + } + else + { + return false; + } + } + + public static bool Equals(RepeatBehavior repeatBehavior1, RepeatBehavior repeatBehavior2) + { + return repeatBehavior1.Equals(repeatBehavior2); + } + + public override int GetHashCode() + { + return _Type switch + { + RepeatBehaviorType.Count => _Count.GetHashCode(), + RepeatBehaviorType.Duration => _Duration.GetHashCode(), + + // We try to choose an unlikely hash code value for Forever. + // All Forevers need to return the same hash code value. + RepeatBehaviorType.Forever => int.MaxValue - 42, + + _ => base.GetHashCode(), + }; + } + + public static bool operator ==(RepeatBehavior repeatBehavior1, RepeatBehavior repeatBehavior2) + { + return repeatBehavior1.Equals(repeatBehavior2); + } + + public static bool operator !=(RepeatBehavior repeatBehavior1, RepeatBehavior repeatBehavior2) + { + return !repeatBehavior1.Equals(repeatBehavior2); + } + } +} + +namespace ABI.Windows.UI.Xaml.Media.Animation +{ +#if EMBED + internal +#else + public +#endif + static class KeyTime + { + public static string GetGuidSignature() + { + string timeSpanSignature = global::WinRT.GuidGenerator.GetSignature(typeof(global::System.TimeSpan)); + return $"struct(Windows.UI.Xaml.Media.Animation.KeyTime;{timeSpanSignature})"; + } + } + +#if EMBED + internal +#else + public +#endif + static class RepeatBehavior + { + public static string GetGuidSignature() + { + string timeSpanSignature = global::WinRT.GuidGenerator.GetSignature(typeof(global::System.TimeSpan)); + return $"struct(Windows.UI.Xaml.Media.Animation.RepeatBehavior;f8;{timeSpanSignature};{RepeatBehaviorType.GetGuidSignature()})"; + } + } + +#if EMBED + internal +#else + public +#endif + static class RepeatBehaviorType + { + public static string GetGuidSignature() => "enum(Windows.UI.Xaml.Media.Animation.RepeatBehaviorType;i4)"; + } +} diff --git a/src/cswinrt/strings/additions/Windows.UI.Xaml.Media.Media3D/Windows.UI.Xaml.Media.Media3D.cs b/src/cswinrt/strings/additions/Windows.UI.Xaml.Media.Media3D/Windows.UI.Xaml.Media.Media3D.cs new file mode 100644 index 000000000..98dfb069e --- /dev/null +++ b/src/cswinrt/strings/additions/Windows.UI.Xaml.Media.Media3D/Windows.UI.Xaml.Media.Media3D.cs @@ -0,0 +1,711 @@ + +namespace Windows.UI.Xaml.Media.Media3D +{ + using global::Windows.Foundation; + + [global::WinRT.WindowsRuntimeType("Windows.UI.Xaml")] + [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Windows.UI.Xaml.Media.Media3D.Matrix3D))] + [StructLayout(LayoutKind.Sequential)] +#if EMBED + internal +#else + public +#endif + struct Matrix3D : IFormattable + { + // Assuming this matrix has fourth column of 0,0,0,1 and isn't identity this function: + // Returns false if HasInverse is false, otherwise inverts the matrix. + private bool NormalizedAffineInvert() + { + double z20 = _m12 * _m23 - _m22 * _m13; + double z10 = _m32 * _m13 - _m12 * _m33; + double z00 = _m22 * _m33 - _m32 * _m23; + double det = _m31 * z20 + _m21 * z10 + _m11 * z00; + + if (IsZero(det)) + { + return false; + } + + // Compute 3x3 non-zero cofactors for the 2nd column + double z21 = _m21 * _m13 - _m11 * _m23; + double z11 = _m11 * _m33 - _m31 * _m13; + double z01 = _m31 * _m23 - _m21 * _m33; + + // Compute all six 2x2 determinants of 1st two columns + double y01 = _m11 * _m22 - _m21 * _m12; + double y02 = _m11 * _m32 - _m31 * _m12; + double y03 = _m11 * _offsetY - _offsetX * _m12; + double y12 = _m21 * _m32 - _m31 * _m22; + double y13 = _m21 * _offsetY - _offsetX * _m22; + double y23 = _m31 * _offsetY - _offsetX * _m32; + + // Compute all non-zero and non-one 3x3 cofactors for 2nd + // two columns + double z23 = _m23 * y03 - _offsetZ * y01 - _m13 * y13; + double z13 = _m13 * y23 - _m33 * y03 + _offsetZ * y02; + double z03 = _m33 * y13 - _offsetZ * y12 - _m23 * y23; + double z22 = y01; + double z12 = -y02; + double z02 = y12; + + double rcp = 1.0 / det; + + // Multiply all 3x3 cofactors by reciprocal & transpose + _m11 = (z00 * rcp); + _m12 = (z10 * rcp); + _m13 = (z20 * rcp); + + _m21 = (z01 * rcp); + _m22 = (z11 * rcp); + _m23 = (z21 * rcp); + + _m31 = (z02 * rcp); + _m32 = (z12 * rcp); + _m33 = (z22 * rcp); + + _offsetX = (z03 * rcp); + _offsetY = (z13 * rcp); + _offsetZ = (z23 * rcp); + + return true; + } + + // RETURNS true if has inverse & invert was done. Otherwise returns false & leaves matrix unchanged. + private bool InvertCore() + { + if (IsAffine) + { + return NormalizedAffineInvert(); + } + + // compute all six 2x2 determinants of 2nd two columns + double y01 = _m13 * _m24 - _m23 * _m14; + double y02 = _m13 * _m34 - _m33 * _m14; + double y03 = _m13 * _m44 - _offsetZ * _m14; + double y12 = _m23 * _m34 - _m33 * _m24; + double y13 = _m23 * _m44 - _offsetZ * _m24; + double y23 = _m33 * _m44 - _offsetZ * _m34; + + // Compute 3x3 cofactors for 1st the column + double z30 = _m22 * y02 - _m32 * y01 - _m12 * y12; + double z20 = _m12 * y13 - _m22 * y03 + _offsetY * y01; + double z10 = _m32 * y03 - _offsetY * y02 - _m12 * y23; + double z00 = _m22 * y23 - _m32 * y13 + _offsetY * y12; + + // Compute 4x4 determinant + double det = _offsetX * z30 + _m31 * z20 + _m21 * z10 + _m11 * z00; + + if (IsZero(det)) + { + return false; + } + + // Compute 3x3 cofactors for the 2nd column + double z31 = _m11 * y12 - _m21 * y02 + _m31 * y01; + double z21 = _m21 * y03 - _offsetX * y01 - _m11 * y13; + double z11 = _m11 * y23 - _m31 * y03 + _offsetX * y02; + double z01 = _m31 * y13 - _offsetX * y12 - _m21 * y23; + + // Compute all six 2x2 determinants of 1st two columns + y01 = _m11 * _m22 - _m21 * _m12; + y02 = _m11 * _m32 - _m31 * _m12; + y03 = _m11 * _offsetY - _offsetX * _m12; + y12 = _m21 * _m32 - _m31 * _m22; + y13 = _m21 * _offsetY - _offsetX * _m22; + y23 = _m31 * _offsetY - _offsetX * _m32; + + // Compute all 3x3 cofactors for 2nd two columns + double z33 = _m13 * y12 - _m23 * y02 + _m33 * y01; + double z23 = _m23 * y03 - _offsetZ * y01 - _m13 * y13; + double z13 = _m13 * y23 - _m33 * y03 + _offsetZ * y02; + double z03 = _m33 * y13 - _offsetZ * y12 - _m23 * y23; + double z32 = _m24 * y02 - _m34 * y01 - _m14 * y12; + double z22 = _m14 * y13 - _m24 * y03 + _m44 * y01; + double z12 = _m34 * y03 - _m44 * y02 - _m14 * y23; + double z02 = _m24 * y23 - _m34 * y13 + _m44 * y12; + + double rcp = 1.0 / det; + + // Multiply all 3x3 cofactors by reciprocal & transpose + _m11 = (z00 * rcp); + _m12 = (z10 * rcp); + _m13 = (z20 * rcp); + _m14 = (z30 * rcp); + + _m21 = (z01 * rcp); + _m22 = (z11 * rcp); + _m23 = (z21 * rcp); + _m24 = (z31 * rcp); + + _m31 = (z02 * rcp); + _m32 = (z12 * rcp); + _m33 = (z22 * rcp); + _m34 = (z32 * rcp); + + _offsetX = (z03 * rcp); + _offsetY = (z13 * rcp); + _offsetZ = (z23 * rcp); + _m44 = (z33 * rcp); + + return true; + } + + public Matrix3D(double m11, double m12, double m13, double m14, + double m21, double m22, double m23, double m24, + double m31, double m32, double m33, double m34, + double offsetX, double offsetY, double offsetZ, double m44) + { + _m11 = m11; + _m12 = m12; + _m13 = m13; + _m14 = m14; + _m21 = m21; + _m22 = m22; + _m23 = m23; + _m24 = m24; + _m31 = m31; + _m32 = m32; + _m33 = m33; + _m34 = m34; + _offsetX = offsetX; + _offsetY = offsetY; + _offsetZ = offsetZ; + _m44 = m44; + } + + // the transform is identity by default + // Actually fill in the fields - some (internal) code uses the fields directly for perf. + private static Matrix3D s_identity = CreateIdentity(); + + public double M11 + { + get + { + return _m11; + } + set + { + _m11 = value; + } + } + + public double M12 + { + get + { + return _m12; + } + set + { + _m12 = value; + } + } + + public double M13 + { + get + { + return _m13; + } + set + { + _m13 = value; + } + } + + public double M14 + { + get + { + return _m14; + } + set + { + _m14 = value; + } + } + + public double M21 + { + get + { + return _m21; + } + set + { + _m21 = value; + } + } + + public double M22 + { + get + { + return _m22; + } + set + { + _m22 = value; + } + } + + public double M23 + { + get + { + return _m23; + } + set + { + _m23 = value; + } + } + + public double M24 + { + get + { + return _m24; + } + set + { + _m24 = value; + } + } + + public double M31 + { + get + { + return _m31; + } + set + { + _m31 = value; + } + } + + public double M32 + { + get + { + return _m32; + } + set + { + _m32 = value; + } + } + + public double M33 + { + get + { + return _m33; + } + set + { + _m33 = value; + } + } + + public double M34 + { + get + { + return _m34; + } + set + { + _m34 = value; + } + } + + public double OffsetX + { + get + { + return _offsetX; + } + set + { + _offsetX = value; + } + } + + public double OffsetY + { + get + { + return _offsetY; + } + set + { + _offsetY = value; + } + } + + public double OffsetZ + { + get + { + return _offsetZ; + } + set + { + _offsetZ = value; + } + } + + public double M44 + { + get + { + return _m44; + } + set + { + _m44 = value; + } + } + + public static Matrix3D Identity + { + get + { + return s_identity; + } + } + + public bool IsIdentity + { + get + { + return (_m11 == 1 && _m12 == 0 && _m13 == 0 && _m14 == 0 && + _m21 == 0 && _m22 == 1 && _m23 == 0 && _m24 == 0 && + _m31 == 0 && _m32 == 0 && _m33 == 1 && _m34 == 0 && + _offsetX == 0 && _offsetY == 0 && _offsetZ == 0 && _m44 == 1); + } + } + + public override string ToString() + { + // Delegate to the internal method which implements all ToString calls. + return ConvertToString(null /* format string */, null /* format provider */); + } + + public string ToString(IFormatProvider provider) + { + // Delegate to the internal method which implements all ToString calls. + return ConvertToString(null /* format string */, provider); + } + + string IFormattable.ToString(string format, IFormatProvider provider) + { + // Delegate to the internal method which implements all ToString calls. + return ConvertToString(format, provider); + } + + private string ConvertToString(string format, IFormatProvider provider) + { + if (IsIdentity) + { + return "Identity"; + } + + // Helper to get the numeric list separator for a given culture. + char separator = TokenizerHelper.GetNumericListSeparator(provider); + return string.Format(provider, + "{1:" + format + "}{0}{2:" + format + "}{0}{3:" + format + "}{0}{4:" + format + "}{0}{5:" + format + + "}{0}{6:" + format + "}{0}{7:" + format + "}{0}{8:" + format + "}{0}{9:" + format + "}{0}{10:" + format + + "}{0}{11:" + format + "}{0}{12:" + format + "}{0}{13:" + format + "}{0}{14:" + format + "}{0}{15:" + format + "}{0}{16:" + format + "}", + separator, + _m11, _m12, _m13, _m14, + _m21, _m22, _m23, _m24, + _m31, _m32, _m33, _m34, + _offsetX, _offsetY, _offsetZ, _m44); + } + + public override int GetHashCode() + { + // Perform field-by-field XOR of HashCodes + return M11.GetHashCode() ^ + M12.GetHashCode() ^ + M13.GetHashCode() ^ + M14.GetHashCode() ^ + M21.GetHashCode() ^ + M22.GetHashCode() ^ + M23.GetHashCode() ^ + M24.GetHashCode() ^ + M31.GetHashCode() ^ + M32.GetHashCode() ^ + M33.GetHashCode() ^ + M34.GetHashCode() ^ + OffsetX.GetHashCode() ^ + OffsetY.GetHashCode() ^ + OffsetZ.GetHashCode() ^ + M44.GetHashCode(); + } + + public override bool Equals(object o) + { + return o is Matrix3D && Matrix3D.Equals(this, (Matrix3D)o); + } + + public bool Equals(Matrix3D value) + { + return Matrix3D.Equals(this, value); + } + + public static bool operator ==(Matrix3D matrix1, Matrix3D matrix2) + { + return matrix1.M11 == matrix2.M11 && + matrix1.M12 == matrix2.M12 && + matrix1.M13 == matrix2.M13 && + matrix1.M14 == matrix2.M14 && + matrix1.M21 == matrix2.M21 && + matrix1.M22 == matrix2.M22 && + matrix1.M23 == matrix2.M23 && + matrix1.M24 == matrix2.M24 && + matrix1.M31 == matrix2.M31 && + matrix1.M32 == matrix2.M32 && + matrix1.M33 == matrix2.M33 && + matrix1.M34 == matrix2.M34 && + matrix1.OffsetX == matrix2.OffsetX && + matrix1.OffsetY == matrix2.OffsetY && + matrix1.OffsetZ == matrix2.OffsetZ && + matrix1.M44 == matrix2.M44; + } + + public static bool operator !=(Matrix3D matrix1, Matrix3D matrix2) + { + return !(matrix1 == matrix2); + } + + public static Matrix3D operator *(Matrix3D matrix1, Matrix3D matrix2) + { + Matrix3D matrix3D = default; + + matrix3D.M11 = matrix1.M11 * matrix2.M11 + + matrix1.M12 * matrix2.M21 + + matrix1.M13 * matrix2.M31 + + matrix1.M14 * matrix2.OffsetX; + matrix3D.M12 = matrix1.M11 * matrix2.M12 + + matrix1.M12 * matrix2.M22 + + matrix1.M13 * matrix2.M32 + + matrix1.M14 * matrix2.OffsetY; + matrix3D.M13 = matrix1.M11 * matrix2.M13 + + matrix1.M12 * matrix2.M23 + + matrix1.M13 * matrix2.M33 + + matrix1.M14 * matrix2.OffsetZ; + matrix3D.M14 = matrix1.M11 * matrix2.M14 + + matrix1.M12 * matrix2.M24 + + matrix1.M13 * matrix2.M34 + + matrix1.M14 * matrix2.M44; + matrix3D.M21 = matrix1.M21 * matrix2.M11 + + matrix1.M22 * matrix2.M21 + + matrix1.M23 * matrix2.M31 + + matrix1.M24 * matrix2.OffsetX; + matrix3D.M22 = matrix1.M21 * matrix2.M12 + + matrix1.M22 * matrix2.M22 + + matrix1.M23 * matrix2.M32 + + matrix1.M24 * matrix2.OffsetY; + matrix3D.M23 = matrix1.M21 * matrix2.M13 + + matrix1.M22 * matrix2.M23 + + matrix1.M23 * matrix2.M33 + + matrix1.M24 * matrix2.OffsetZ; + matrix3D.M24 = matrix1.M21 * matrix2.M14 + + matrix1.M22 * matrix2.M24 + + matrix1.M23 * matrix2.M34 + + matrix1.M24 * matrix2.M44; + matrix3D.M31 = matrix1.M31 * matrix2.M11 + + matrix1.M32 * matrix2.M21 + + matrix1.M33 * matrix2.M31 + + matrix1.M34 * matrix2.OffsetX; + matrix3D.M32 = matrix1.M31 * matrix2.M12 + + matrix1.M32 * matrix2.M22 + + matrix1.M33 * matrix2.M32 + + matrix1.M34 * matrix2.OffsetY; + matrix3D.M33 = matrix1.M31 * matrix2.M13 + + matrix1.M32 * matrix2.M23 + + matrix1.M33 * matrix2.M33 + + matrix1.M34 * matrix2.OffsetZ; + matrix3D.M34 = matrix1.M31 * matrix2.M14 + + matrix1.M32 * matrix2.M24 + + matrix1.M33 * matrix2.M34 + + matrix1.M34 * matrix2.M44; + matrix3D.OffsetX = matrix1.OffsetX * matrix2.M11 + + matrix1.OffsetY * matrix2.M21 + + matrix1.OffsetZ * matrix2.M31 + + matrix1.M44 * matrix2.OffsetX; + matrix3D.OffsetY = matrix1.OffsetX * matrix2.M12 + + matrix1.OffsetY * matrix2.M22 + + matrix1.OffsetZ * matrix2.M32 + + matrix1.M44 * matrix2.OffsetY; + matrix3D.OffsetZ = matrix1.OffsetX * matrix2.M13 + + matrix1.OffsetY * matrix2.M23 + + matrix1.OffsetZ * matrix2.M33 + + matrix1.M44 * matrix2.OffsetZ; + matrix3D.M44 = matrix1.OffsetX * matrix2.M14 + + matrix1.OffsetY * matrix2.M24 + + matrix1.OffsetZ * matrix2.M34 + + matrix1.M44 * matrix2.M44; + + // matrix3D._type is not set. + + return matrix3D; + } + + public bool HasInverse + { + get + { + return !IsZero(Determinant); + } + } + + public void Invert() + { + if (!InvertCore()) + { + throw new InvalidOperationException(); + } + } + + private static Matrix3D CreateIdentity() + { + Matrix3D matrix3D = default; + matrix3D.SetMatrix(1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1); + return matrix3D; + } + + private void SetMatrix(double m11, double m12, double m13, double m14, + double m21, double m22, double m23, double m24, + double m31, double m32, double m33, double m34, + double offsetX, double offsetY, double offsetZ, double m44) + { + _m11 = m11; + _m12 = m12; + _m13 = m13; + _m14 = m14; + _m21 = m21; + _m22 = m22; + _m23 = m23; + _m24 = m24; + _m31 = m31; + _m32 = m32; + _m33 = m33; + _m34 = m34; + _offsetX = offsetX; + _offsetY = offsetY; + _offsetZ = offsetZ; + _m44 = m44; + } + + private static bool Equals(Matrix3D matrix1, Matrix3D matrix2) + { + return matrix1.M11.Equals(matrix2.M11) && + matrix1.M12.Equals(matrix2.M12) && + matrix1.M13.Equals(matrix2.M13) && + matrix1.M14.Equals(matrix2.M14) && + matrix1.M21.Equals(matrix2.M21) && + matrix1.M22.Equals(matrix2.M22) && + matrix1.M23.Equals(matrix2.M23) && + matrix1.M24.Equals(matrix2.M24) && + matrix1.M31.Equals(matrix2.M31) && + matrix1.M32.Equals(matrix2.M32) && + matrix1.M33.Equals(matrix2.M33) && + matrix1.M34.Equals(matrix2.M34) && + matrix1.OffsetX.Equals(matrix2.OffsetX) && + matrix1.OffsetY.Equals(matrix2.OffsetY) && + matrix1.OffsetZ.Equals(matrix2.OffsetZ) && + matrix1.M44.Equals(matrix2.M44); + } + + private double GetNormalizedAffineDeterminant() + { + double z20 = _m12 * _m23 - _m22 * _m13; + double z10 = _m32 * _m13 - _m12 * _m33; + double z00 = _m22 * _m33 - _m32 * _m23; + + return _m31 * z20 + _m21 * z10 + _m11 * z00; + } + + private bool IsAffine + { + get + { + return (_m14 == 0.0 && _m24 == 0.0 && _m34 == 0.0 && _m44 == 1.0); + } + } + + private double Determinant + { + get + { + if (IsAffine) + { + return GetNormalizedAffineDeterminant(); + } + + // compute all six 2x2 determinants of 2nd two columns + double y01 = _m13 * _m24 - _m23 * _m14; + double y02 = _m13 * _m34 - _m33 * _m14; + double y03 = _m13 * _m44 - _offsetZ * _m14; + double y12 = _m23 * _m34 - _m33 * _m24; + double y13 = _m23 * _m44 - _offsetZ * _m24; + double y23 = _m33 * _m44 - _offsetZ * _m34; + + // Compute 3x3 cofactors for 1st the column + double z30 = _m22 * y02 - _m32 * y01 - _m12 * y12; + double z20 = _m12 * y13 - _m22 * y03 + _offsetY * y01; + double z10 = _m32 * y03 - _offsetY * y02 - _m12 * y23; + double z00 = _m22 * y23 - _m32 * y13 + _offsetY * y12; + + return _offsetX * z30 + _m31 * z20 + _m21 * z10 + _m11 * z00; + } + } + + private static bool IsZero(double value) + { + return Math.Abs(value) < 10.0 * DBL_EPSILON_RELATIVE_1; + } + + private const double DBL_EPSILON_RELATIVE_1 = 1.1102230246251567e-016; /* smallest such that 1.0+DBL_EPSILON != 1.0 */ + + private double _m11; + private double _m12; + private double _m13; + private double _m14; + private double _m21; + private double _m22; + private double _m23; + private double _m24; + private double _m31; + private double _m32; + private double _m33; + private double _m34; + private double _offsetX; + private double _offsetY; + private double _offsetZ; + private double _m44; + } +} + +namespace ABI.Windows.UI.Xaml.Media.Media3D +{ +#if EMBED + internal +#else + public +#endif + static class Matrix3D + { + public static string GetGuidSignature() => + $"struct(Windows.UI.Xaml.Media.Media3D.Matrix3D;f8;f8;f8;f8;f8;f8;f8;f8;f8;f8;f8;f8;f8;f8;f8;f8)"; + } +} diff --git a/src/cswinrt/strings/additions/Windows.UI.Xaml.Media/Windows.UI.Xaml.Media.cs b/src/cswinrt/strings/additions/Windows.UI.Xaml.Media/Windows.UI.Xaml.Media.cs new file mode 100644 index 000000000..b156e5104 --- /dev/null +++ b/src/cswinrt/strings/additions/Windows.UI.Xaml.Media/Windows.UI.Xaml.Media.cs @@ -0,0 +1,263 @@ + +namespace Windows.UI.Xaml.Media +{ + using global::Windows.Foundation; + + [global::WinRT.WindowsRuntimeType("Windows.UI.Xaml")] + [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Windows.UI.Xaml.Media.Matrix))] + [StructLayout(LayoutKind.Sequential)] +#if EMBED + internal +#else + public +#endif + struct Matrix : IFormattable + { + public Matrix(double m11, double m12, + double m21, double m22, + double offsetX, double offsetY) + { + _m11 = m11; + _m12 = m12; + _m21 = m21; + _m22 = m22; + _offsetX = offsetX; + _offsetY = offsetY; + } + + // the transform is identity by default + private static Matrix s_identity = CreateIdentity(); + + public double M11 + { + get + { + return _m11; + } + set + { + _m11 = value; + } + } + + public double M12 + { + get + { + return _m12; + } + set + { + _m12 = value; + } + } + + public double M21 + { + get + { + return _m21; + } + set + { + _m21 = value; + } + } + + public double M22 + { + get + { + return _m22; + } + set + { + _m22 = value; + } + } + + public double OffsetX + { + get + { + return _offsetX; + } + set + { + _offsetX = value; + } + } + + public double OffsetY + { + get + { + return _offsetY; + } + set + { + _offsetY = value; + } + } + + public static Matrix Identity + { + get + { + return s_identity; + } + } + + public bool IsIdentity + { + get + { + return (_m11 == 1 && _m12 == 0 && _m21 == 0 && _m22 == 1 && _offsetX == 0 && _offsetY == 0); + } + } + + public override string ToString() + { + // Delegate to the internal method which implements all ToString calls. + return ConvertToString(null /* format string */, null /* format provider */); + } + + public string ToString(IFormatProvider provider) + { + // Delegate to the internal method which implements all ToString calls. + return ConvertToString(null /* format string */, provider); + } + + string IFormattable.ToString(string format, IFormatProvider provider) + { + // Delegate to the internal method which implements all ToString calls. + return ConvertToString(format, provider); + } + + private string ConvertToString(string format, IFormatProvider provider) + { + if (IsIdentity) + { + return "Identity"; + } + + // Helper to get the numeric list separator for a given culture. + char separator = TokenizerHelper.GetNumericListSeparator(provider); + return string.Format(provider, + "{1:" + format + "}{0}{2:" + format + "}{0}{3:" + format + "}{0}{4:" + format + "}{0}{5:" + format + "}{0}{6:" + format + "}", + separator, + _m11, + _m12, + _m21, + _m22, + _offsetX, + _offsetY); + } + + public Point Transform(Point point) + { + float x = (float)point.X; + float y = (float)point.Y; + this.MultiplyPoint(ref x, ref y); + Point point2 = new Point(x, y); + return point2; + } + + public override int GetHashCode() + { + // Perform field-by-field XOR of HashCodes + return M11.GetHashCode() ^ + M12.GetHashCode() ^ + M21.GetHashCode() ^ + M22.GetHashCode() ^ + OffsetX.GetHashCode() ^ + OffsetY.GetHashCode(); + } + + public override bool Equals(object o) + { + return o is Matrix && Matrix.Equals(this, (Matrix)o); + } + + public bool Equals(Matrix value) + { + return Matrix.Equals(this, value); + } + + public static bool operator ==(Matrix matrix1, Matrix matrix2) + { + return matrix1.M11 == matrix2.M11 && + matrix1.M12 == matrix2.M12 && + matrix1.M21 == matrix2.M21 && + matrix1.M22 == matrix2.M22 && + matrix1.OffsetX == matrix2.OffsetX && + matrix1.OffsetY == matrix2.OffsetY; + } + + public static bool operator !=(Matrix matrix1, Matrix matrix2) + { + return !(matrix1 == matrix2); + } + + private static Matrix CreateIdentity() + { + Matrix matrix = default; + matrix.SetMatrix(1, 0, + 0, 1, + 0, 0); + return matrix; + } + + private void SetMatrix(double m11, double m12, + double m21, double m22, + double offsetX, double offsetY) + { + _m11 = m11; + _m12 = m12; + _m21 = m21; + _m22 = m22; + _offsetX = offsetX; + _offsetY = offsetY; + } + + private void MultiplyPoint(ref float x, ref float y) + { + double num = (y * _m21) + _offsetX; + double num2 = (x * _m12) + _offsetY; + x *= (float)_m11; + x += (float)num; + y *= (float)_m22; + y += (float)num2; + } + + private static bool Equals(Matrix matrix1, Matrix matrix2) + { + return matrix1.M11.Equals(matrix2.M11) && + matrix1.M12.Equals(matrix2.M12) && + matrix1.M21.Equals(matrix2.M21) && + matrix1.M22.Equals(matrix2.M22) && + matrix1.OffsetX.Equals(matrix2.OffsetX) && + matrix1.OffsetY.Equals(matrix2.OffsetY); + } + + private double _m11; + private double _m12; + private double _m21; + private double _m22; + private double _offsetX; + private double _offsetY; + } +} + +namespace ABI.Windows.UI.Xaml.Media +{ +#if EMBED + internal +#else + public +#endif + static class Matrix + { + public static string GetGuidSignature() => $"struct(Windows.UI.Xaml.Media.Matrix;f8;f8;f8;f8;f8;f8)"; + } +} diff --git a/src/cswinrt/strings/additions/Windows.UI.Xaml/Windows.UI.Xaml.SR.cs b/src/cswinrt/strings/additions/Windows.UI.Xaml/Windows.UI.Xaml.SR.cs new file mode 100644 index 000000000..cbb4596bb --- /dev/null +++ b/src/cswinrt/strings/additions/Windows.UI.Xaml/Windows.UI.Xaml.SR.cs @@ -0,0 +1,17 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace Windows.UI.Xaml +{ + static class SR + { + public static string DirectUI_CornerRadius_InvalidMember = "Invalid value for {0} property on CornerRadius."; + public static string DirectUI_InvalidArgument = "Invalid argument."; + public static string ElementNotAvailable_Default = "The element is not available."; + public static string ElementNotEnabled_Default = "The element is not enabled."; + public static string XamlParse_Default = "XAML parsing failed."; + public static string LayoutCycle_Default = "A cycle occurred while laying out the GUI."; + public static string PlatformNotSupported_WindowsRuntime = "Windows Runtime (WinRT) is not supported on this platform."; + } +} diff --git a/src/cswinrt/strings/additions/Windows.UI.Xaml/Windows.UI.Xaml.cs b/src/cswinrt/strings/additions/Windows.UI.Xaml/Windows.UI.Xaml.cs new file mode 100644 index 000000000..341d016d6 --- /dev/null +++ b/src/cswinrt/strings/additions/Windows.UI.Xaml/Windows.UI.Xaml.cs @@ -0,0 +1,774 @@ + +namespace Windows.UI.Xaml +{ + using global::Windows.Foundation; + + [global::WinRT.WindowsRuntimeType("Windows.UI.Xaml")] + [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Windows.UI.Xaml.CornerRadius))] + [StructLayout(LayoutKind.Sequential)] +#if EMBED + internal +#else + public +#endif + struct CornerRadius + { + private double _TopLeft; + private double _TopRight; + private double _BottomRight; + private double _BottomLeft; + + public CornerRadius(double uniformRadius) + { + Validate(uniformRadius, uniformRadius, uniformRadius, uniformRadius); + _TopLeft = _TopRight = _BottomRight = _BottomLeft = uniformRadius; + } + + public CornerRadius(double topLeft, double topRight, double bottomRight, double bottomLeft) + { + Validate(topLeft, topRight, bottomRight, bottomLeft); + + _TopLeft = topLeft; + _TopRight = topRight; + _BottomRight = bottomRight; + _BottomLeft = bottomLeft; + } + + private static void Validate(double topLeft, double topRight, double bottomRight, double bottomLeft) + { + if (topLeft < 0.0 || double.IsNaN(topLeft)) + throw new ArgumentException(string.Format(SR.DirectUI_CornerRadius_InvalidMember, "TopLeft")); + + if (topRight < 0.0 || double.IsNaN(topRight)) + throw new ArgumentException(string.Format(SR.DirectUI_CornerRadius_InvalidMember, "TopRight")); + + if (bottomRight < 0.0 || double.IsNaN(bottomRight)) + throw new ArgumentException(string.Format(SR.DirectUI_CornerRadius_InvalidMember, "BottomRight")); + + if (bottomLeft < 0.0 || double.IsNaN(bottomLeft)) + throw new ArgumentException(string.Format(SR.DirectUI_CornerRadius_InvalidMember, "BottomLeft")); + } + + public override string ToString() + { + return ToString(global::System.Globalization.CultureInfo.InvariantCulture); + } + + internal string ToString(global::System.Globalization.CultureInfo cultureInfo) + { + char listSeparator = TokenizerHelper.GetNumericListSeparator(cultureInfo); + + // Initial capacity [64] is an estimate based on a sum of: + // 48 = 4x double (twelve digits is generous for the range of values likely) + // 8 = 4x Unit Type string (approx two characters) + // 4 = 4x separator characters + global::System.Text.StringBuilder sb = new global::System.Text.StringBuilder(64); + + sb.Append(InternalToString(_TopLeft, cultureInfo)); + sb.Append(listSeparator); + sb.Append(InternalToString(_TopRight, cultureInfo)); + sb.Append(listSeparator); + sb.Append(InternalToString(_BottomRight, cultureInfo)); + sb.Append(listSeparator); + sb.Append(InternalToString(_BottomLeft, cultureInfo)); + return sb.ToString(); + } + + internal string InternalToString(double l, global::System.Globalization.CultureInfo cultureInfo) + { + if (double.IsNaN(l)) return "Auto"; + return Convert.ToString(l, cultureInfo); + } + + public override bool Equals(object obj) + { + if (obj is CornerRadius) + { + CornerRadius otherObj = (CornerRadius)obj; + return (this == otherObj); + } + return (false); + } + + public bool Equals(CornerRadius cornerRadius) + { + return (this == cornerRadius); + } + + public override int GetHashCode() + { + return _TopLeft.GetHashCode() ^ _TopRight.GetHashCode() ^ _BottomLeft.GetHashCode() ^ _BottomRight.GetHashCode(); + } + + public static bool operator ==(CornerRadius cr1, CornerRadius cr2) + { + return cr1._TopLeft == cr2._TopLeft && cr1._TopRight == cr2._TopRight && cr1._BottomRight == cr2._BottomRight && cr1._BottomLeft == cr2._BottomLeft; + } + + public static bool operator !=(CornerRadius cr1, CornerRadius cr2) + { + return (!(cr1 == cr2)); + } + + public double TopLeft + { + get { return _TopLeft; } + set + { + Validate(value, 0, 0, 0); + _TopLeft = value; + } + } + + public double TopRight + { + get { return _TopRight; } + set + { + Validate(0, value, 0, 0); + _TopRight = value; + } + } + + public double BottomRight + { + get { return _BottomRight; } + set + { + Validate(0, 0, value, 0); + _BottomRight = value; + } + } + + public double BottomLeft + { + get { return _BottomLeft; } + set + { + Validate(0, 0, 0, value); + _BottomLeft = value; + } + } + } + + [global::WinRT.WindowsRuntimeType("Windows.UI.Xaml")] +#if EMBED + internal +#else + public +#endif + enum GridUnitType + { + Auto = 0, + Pixel, + Star, + } + + [global::WinRT.WindowsRuntimeType("Windows.UI.Xaml")] + [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Windows.UI.Xaml.GridLength))] + [StructLayout(LayoutKind.Sequential)] +#if EMBED + internal +#else + public +#endif + struct GridLength + { + private readonly double _unitValue; + private readonly GridUnitType _unitType; + + private const double Default = 1.0; + private static readonly GridLength s_auto = new GridLength(Default, GridUnitType.Auto); + + public GridLength(double pixels) + : this(pixels, GridUnitType.Pixel) + { + } + + internal static bool IsFinite(double value) + { + return !(double.IsNaN(value) || double.IsInfinity(value)); + } + + public GridLength(double value, GridUnitType type) + { + if (!IsFinite(value) || value < 0.0) + { + throw new ArgumentException(SR.DirectUI_InvalidArgument, nameof(value)); + } + if (type != GridUnitType.Auto && type != GridUnitType.Pixel && type != GridUnitType.Star) + { + throw new ArgumentException(SR.DirectUI_InvalidArgument, nameof(type)); + } + + _unitValue = (type == GridUnitType.Auto) ? Default : value; + _unitType = type; + } + + + public double Value { get { return ((_unitType == GridUnitType.Auto) ? s_auto._unitValue : _unitValue); } } + public GridUnitType GridUnitType { get { return (_unitType); } } + + + public bool IsAbsolute { get { return (_unitType == GridUnitType.Pixel); } } + public bool IsAuto { get { return (_unitType == GridUnitType.Auto); } } + public bool IsStar { get { return (_unitType == GridUnitType.Star); } } + + public static GridLength Auto + { + get { return (s_auto); } + } + + + public static bool operator ==(GridLength gl1, GridLength gl2) + { + return (gl1.GridUnitType == gl2.GridUnitType + && gl1.Value == gl2.Value); + } + + public static bool operator !=(GridLength gl1, GridLength gl2) + { + return (gl1.GridUnitType != gl2.GridUnitType + || gl1.Value != gl2.Value); + } + + public override bool Equals(object oCompare) + { + if (oCompare is GridLength) + { + GridLength l = (GridLength)oCompare; + return (this == l); + } + else + return false; + } + + public bool Equals(GridLength gridLength) + { + return (this == gridLength); + } + + public override int GetHashCode() + { + return ((int)_unitValue + (int)_unitType); + } + + public override string ToString() + { + return this.ToString(global::System.Globalization.CultureInfo.InvariantCulture); + } + + internal string ToString(global::System.Globalization.CultureInfo cultureInfo) + { + char listSeparator = TokenizerHelper.GetNumericListSeparator(cultureInfo); + + // Initial capacity [64] is an estimate based on a sum of: + // 12 = 1x double (twelve digits is generous for the range of values likely) + // 8 = 4x Unit Type string (approx two characters) + // 2 = 2x separator characters + + if (_unitType == GridUnitType.Auto) + { + return "Auto"; + } + else if (_unitType == GridUnitType.Pixel) + { + return Convert.ToString(_unitValue, cultureInfo); + } + else + { + return Convert.ToString(_unitValue, cultureInfo) + "*"; + } + } + } + + [global::WinRT.WindowsRuntimeType("Windows.UI.Xaml")] + [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Windows.UI.Xaml.Thickness))] + [StructLayout(LayoutKind.Sequential)] +#if EMBED + internal +#else + public +#endif + struct Thickness + { + private double _Left; + private double _Top; + private double _Right; + private double _Bottom; + + public Thickness(double uniformLength) + { + _Left = _Top = _Right = _Bottom = uniformLength; + } + + public Thickness(double left, double top, double right, double bottom) + { + _Left = left; + _Top = top; + _Right = right; + _Bottom = bottom; + } + + public double Left + { + get { return _Left; } + set { _Left = value; } + } + + public double Top + { + get { return _Top; } + set { _Top = value; } + } + + public double Right + { + get { return _Right; } + set { _Right = value; } + } + + public double Bottom + { + get { return _Bottom; } + set { _Bottom = value; } + } + + public override string ToString() + { + return ToString(global::System.Globalization.CultureInfo.InvariantCulture); + } + + internal string ToString(global::System.Globalization.CultureInfo cultureInfo) + { + char listSeparator = TokenizerHelper.GetNumericListSeparator(cultureInfo); + + // Initial capacity [64] is an estimate based on a sum of: + // 48 = 4x double (twelve digits is generous for the range of values likely) + // 8 = 4x Unit Type string (approx two characters) + // 4 = 4x separator characters + global::System.Text.StringBuilder sb = new global::System.Text.StringBuilder(64); + + sb.Append(InternalToString(_Left, cultureInfo)); + sb.Append(listSeparator); + sb.Append(InternalToString(_Top, cultureInfo)); + sb.Append(listSeparator); + sb.Append(InternalToString(_Right, cultureInfo)); + sb.Append(listSeparator); + sb.Append(InternalToString(_Bottom, cultureInfo)); + return sb.ToString(); + } + + internal string InternalToString(double l, global::System.Globalization.CultureInfo cultureInfo) + { + if (double.IsNaN(l)) return "Auto"; + return Convert.ToString(l, cultureInfo); + } + + public override bool Equals(object obj) + { + if (obj is Thickness) + { + Thickness otherObj = (Thickness)obj; + return (this == otherObj); + } + return (false); + } + + public bool Equals(Thickness thickness) + { + return (this == thickness); + } + + public override int GetHashCode() + { + return _Left.GetHashCode() ^ _Top.GetHashCode() ^ _Right.GetHashCode() ^ _Bottom.GetHashCode(); + } + + public static bool operator ==(Thickness t1, Thickness t2) + { + return t1._Left == t2._Left && t1._Top == t2._Top && t1._Right == t2._Right && t1._Bottom == t2._Bottom; + } + + public static bool operator !=(Thickness t1, Thickness t2) + { + return (!(t1 == t2)); + } + } + + [global::WinRT.WindowsRuntimeType("Windows.UI.Xaml")] +#if EMBED + internal +#else + public +#endif + enum DurationType + { + Automatic, + TimeSpan, + Forever + } + + [global::WinRT.WindowsRuntimeType("Windows.UI.Xaml")] + [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Windows.UI.Xaml.Duration))] + [StructLayout(LayoutKind.Sequential)] +#if EMBED + internal +#else + public +#endif + struct Duration + { + private readonly TimeSpan _timeSpan; + private DurationType _durationType; + + public Duration(TimeSpan timeSpan) + { + _durationType = DurationType.TimeSpan; + _timeSpan = timeSpan; + } + + public static implicit operator Duration(TimeSpan timeSpan) + { + return new Duration(timeSpan); + } + + public static Duration operator +(Duration t1, Duration t2) + { + if (t1.HasTimeSpan && t2.HasTimeSpan) + { + return new Duration(t1._timeSpan + t2._timeSpan); + } + else if (t1._durationType != DurationType.Automatic && t2._durationType != DurationType.Automatic) + { + return Duration.Forever; + } + else + { + // Automatic + anything is Automatic + return Duration.Automatic; + } + } + + public static Duration operator -(Duration t1, Duration t2) + { + if (t1.HasTimeSpan && t2.HasTimeSpan) + { + return new Duration(t1._timeSpan - t2._timeSpan); + } + else if (t1._durationType == DurationType.Forever && t2.HasTimeSpan) + { + return Duration.Forever; + } + else + { + return Duration.Automatic; + } + } + + public static bool operator ==(Duration t1, Duration t2) + { + return t1.Equals(t2); + } + + public static bool operator !=(Duration t1, Duration t2) + { + return !(t1.Equals(t2)); + } + + public static bool operator >(Duration t1, Duration t2) + { + if (t1.HasTimeSpan && t2.HasTimeSpan) + { + return t1._timeSpan > t2._timeSpan; + } + else if (t1.HasTimeSpan && t2._durationType == DurationType.Forever) + { + return false; + } + else if (t1._durationType == DurationType.Forever && t2.HasTimeSpan) + { + return true; + } + else + { + return false; + } + } + + public static bool operator >=(Duration t1, Duration t2) + { + if (t1._durationType == DurationType.Automatic && t2._durationType == DurationType.Automatic) + { + return true; + } + else if (t1._durationType == DurationType.Automatic || t2._durationType == DurationType.Automatic) + { + return false; + } + else + { + return !(t1 < t2); + } + } + + public static bool operator <(Duration t1, Duration t2) + { + if (t1.HasTimeSpan && t2.HasTimeSpan) + { + return t1._timeSpan < t2._timeSpan; + } + else if (t1.HasTimeSpan && t2._durationType == DurationType.Forever) + { + return true; + } + else if (t1._durationType == DurationType.Forever && t2.HasTimeSpan) + { + return false; + } + else + { + return false; + } + } + + public static bool operator <=(Duration t1, Duration t2) + { + if (t1._durationType == DurationType.Automatic && t2._durationType == DurationType.Automatic) + { + return true; + } + else if (t1._durationType == DurationType.Automatic || t2._durationType == DurationType.Automatic) + { + return false; + } + else + { + return !(t1 > t2); + } + } + + public static int Compare(Duration t1, Duration t2) + { + if (t1._durationType == DurationType.Automatic) + { + if (t2._durationType == DurationType.Automatic) + { + return 0; + } + else + { + return -1; + } + } + else if (t2._durationType == DurationType.Automatic) + { + return 1; + } + else + { + if (t1 < t2) + { + return -1; + } + else if (t1 > t2) + { + return 1; + } + else + { + return 0; + } + } + } + + public static Duration operator +(Duration duration) + { + return duration; + } + + public bool HasTimeSpan + { + get + { + return _durationType == DurationType.TimeSpan; + } + } + + public static Duration Automatic + { + get + { + Duration duration = default; + duration._durationType = DurationType.Automatic; + + return duration; + } + } + + public static Duration Forever + { + get + { + Duration duration = default; + duration._durationType = DurationType.Forever; + + return duration; + } + } + + public TimeSpan TimeSpan + { + get + { + if (HasTimeSpan) + { + return _timeSpan; + } + else + { + throw new InvalidOperationException(); + } + } + } + + public Duration Add(Duration duration) + { + return this + duration; + } + + public override bool Equals(object value) + { + return value is Duration && Equals((Duration)value); + } + + public bool Equals(Duration duration) + { + if (HasTimeSpan) + { + if (duration.HasTimeSpan) + { + return _timeSpan == duration._timeSpan; + } + else + { + return false; + } + } + else + { + return _durationType == duration._durationType; + } + } + + public static bool Equals(Duration t1, Duration t2) + { + return t1.Equals(t2); + } + + public override int GetHashCode() + { + if (HasTimeSpan) + { + return _timeSpan.GetHashCode(); + } + else + { + return _durationType.GetHashCode() + 17; + } + } + + public Duration Subtract(Duration duration) + { + return this - duration; + } + + public override string ToString() + { + if (HasTimeSpan) + { + return _timeSpan.ToString(); // "00"; //TypeDescriptor.GetConverter(_timeSpan).ConvertToString(_timeSpan); + } + else if (_durationType == DurationType.Forever) + { + return "Forever"; + } + else // IsAutomatic + { + return "Automatic"; + } + } + } +} + +namespace ABI.Windows.UI.Xaml +{ +#if EMBED + internal +#else + public +#endif + static class CornerRadius + { + public static string GetGuidSignature() => $"struct(Windows.UI.Xaml.CornerRadius;f8;f8;f8;f8)"; + } + +#if EMBED + internal +#else + public +#endif + static class Duration + { + public static string GetGuidSignature() + { + string timeSpanSignature = global::WinRT.GuidGenerator.GetSignature(typeof(global::System.TimeSpan)); + string durationTypeSignature = global::WinRT.GuidGenerator.GetSignature(typeof(global::Windows.UI.Xaml.DurationType)); + return $"struct(Windows.UI.Xaml.Duration;{timeSpanSignature};{durationTypeSignature})"; + } + } + +#if EMBED + internal +#else + public +#endif + static class DurationType + { + public static string GetGuidSignature() => "enum(Windows.UI.Xaml.DurationType;i4)"; + } + +#if EMBED + internal +#else + public +#endif + static class GridLength + { + public static string GetGuidSignature() + { + string unitTypeSignature = global::WinRT.GuidGenerator.GetSignature(typeof(global::Windows.UI.Xaml.GridUnitType)); + return $"struct(Windows.UI.Xaml.GridLength;f8;{unitTypeSignature})"; + } + } + +#if EMBED + internal +#else + public +#endif + static class GridUnitType + { + public static string GetGuidSignature() => "enum(Windows.UI.Xaml.GridUnitType;i4)"; + } + +#if EMBED + internal +#else + public +#endif + static class Thickness + { + public static string GetGuidSignature() => $"struct(Windows.UI.Xaml.Thickness;f8;f8;f8;f8)"; + } +} From 1c5d082f0671d81c0755c107877c5e3ff5207cb9 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Thu, 18 Jan 2024 15:01:14 -0800 Subject: [PATCH 11/46] PR feedback --- .../Configuration/FeatureSwitches.cs | 40 +++++++++++++++++++ .../Configuration/ILLink.Substitutions.xml | 4 ++ src/WinRT.Runtime/GuidGenerator.cs | 2 +- src/WinRT.Runtime/Projections.cs | 17 +------- .../Projections/Bindable.net5.cs | 6 +-- .../INotifyCollectionChanged.net5.cs | 13 ++++-- .../INotifyPropertyChanged.net5.cs | 10 ++++- .../NotifyCollectionChangedAction.cs | 2 +- .../NotifyCollectionChangedEventArgs.cs | 4 +- .../NotifyCollectionChangedEventHandler.cs | 2 +- .../Projections/PropertyChangedEventArgs.cs | 4 +- .../PropertyChangedEventHandler.cs | 2 +- 12 files changed, 75 insertions(+), 31 deletions(-) diff --git a/src/WinRT.Runtime/Configuration/FeatureSwitches.cs b/src/WinRT.Runtime/Configuration/FeatureSwitches.cs index cedcaec85..d32b98d09 100644 --- a/src/WinRT.Runtime/Configuration/FeatureSwitches.cs +++ b/src/WinRT.Runtime/Configuration/FeatureSwitches.cs @@ -77,4 +77,44 @@ private static bool GetConfigurationValue(string propertyName, ref int cachedRes return isEnabled; } + + private static Projections.WuxMuxMode _wuxMuxMode = Projections.WuxMuxMode.Unknown; + + internal static Projections.WuxMuxMode WuxMuxMode => GetWuMuxMode("CsWinRT.WuxMuxMode", ref _wuxMuxMode); + + /// + /// Gets a configuration value for a specified property. + /// + /// The property name to retrieve the value for. + /// The cached result for the target configuration value. + /// The value of the specified configuration setting. + private static Projections.WuxMuxMode GetWuxMuxMode(string propertyName, ref Projections.WuxMuxMode cachedResult) + { + // This method doesn't need to worry about concurrent accesses to the cached result, + // as even if the configuration value is retrieved twice, that'll always be the same. + if (cachedResult != Projections.WuxMuxMode.Unknown) + { + return cachedResult; + } + + // Get the configuration switch value, or its default. + // All feature switches have a default set in the .targets file. + if (AppContext.GetData(propertyName) is string str && Enum.TryParse(str, out var mode)) + { + cachedResult = mode; + } + else + { + cachedResult = Projections.WuxMuxMode.MicrosoftUiXaml; + } + +#if !NET5_0_OR_GREATER + if (mode == UiXamlMode.WindowsUiXaml) + { + throw new NotSupportedException("Windows.UI.Xaml is not supported before .NET 5. Please use built-in WinRT interop for Windows.UI.Xaml experiences"); + } +#endif + + return cachedResult; + } } \ No newline at end of file diff --git a/src/WinRT.Runtime/Configuration/ILLink.Substitutions.xml b/src/WinRT.Runtime/Configuration/ILLink.Substitutions.xml index 4e91edb80..9b56cd877 100644 --- a/src/WinRT.Runtime/Configuration/ILLink.Substitutions.xml +++ b/src/WinRT.Runtime/Configuration/ILLink.Substitutions.xml @@ -5,6 +5,10 @@ + + + + \ No newline at end of file diff --git a/src/WinRT.Runtime/GuidGenerator.cs b/src/WinRT.Runtime/GuidGenerator.cs index 0b8f71cb0..cef072a33 100644 --- a/src/WinRT.Runtime/GuidGenerator.cs +++ b/src/WinRT.Runtime/GuidGenerator.cs @@ -48,7 +48,7 @@ public static Guid GetIID( internal static Guid GetWuxMuxIID(WuxMuxProjectedTypeAttribute wuxMuxAttribute) { - return Projections.UiXamlModeSetting switch + return FeatureSwitches.WuxMuxMode switch { Projections.UiXamlMode.WindowsUiXaml => wuxMuxAttribute.WuxIID, Projections.UiXamlMode.MicrosoftUiXaml => wuxMuxAttribute.MuxIID, diff --git a/src/WinRT.Runtime/Projections.cs b/src/WinRT.Runtime/Projections.cs index fab580b15..b806ad23d 100644 --- a/src/WinRT.Runtime/Projections.cs +++ b/src/WinRT.Runtime/Projections.cs @@ -27,26 +27,11 @@ static class Projections { internal enum UiXamlMode { + Unknown, MicrosoftUiXaml, WindowsUiXaml } - private static UiXamlMode GetUIXamlModeSetting() - { - if (AppContext.GetData("CsWinRT.UiXamlMode") is string str && Enum.TryParse(str, out var mode)) - { -#if !NET5_0_OR_GREATER - if (mode == UiXamlMode.WindowsUiXaml) - { - throw new NotSupportedException("Windows.UI.Xaml is not supported before .NET 5. Please use built-in WinRT interop for Windows.UI.Xaml experiences"); - } -#endif - return mode; - } - return UiXamlMode.MicrosoftUiXaml; // We default to MUX for back-compat with existing projects. - } - - internal static UiXamlMode UiXamlModeSetting { get; } = GetUIXamlModeSetting(); private static readonly ReaderWriterLockSlim rwlock = new ReaderWriterLockSlim(); diff --git a/src/WinRT.Runtime/Projections/Bindable.net5.cs b/src/WinRT.Runtime/Projections/Bindable.net5.cs index f400c74d6..c499a23a0 100644 --- a/src/WinRT.Runtime/Projections/Bindable.net5.cs +++ b/src/WinRT.Runtime/Projections/Bindable.net5.cs @@ -145,7 +145,7 @@ static IEnumerable() { AbiToProjectionVftablePtr = ComWrappersSupport.AllocateVtableMemory(typeof(IEnumerable), sizeof(IInspectable.Vftbl) + sizeof(IntPtr) * 1); *(IInspectable.Vftbl*)AbiToProjectionVftablePtr = IInspectable.Vftbl.AbiToProjectionVftable; - ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[6] = Projections.UiXamlModeSetting is Projections.UiXamlMode.WindowsUiXaml ? &Do_Wux_Abi_First_0 : &Do_Mux_Abi_First_0; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[6] = FeatureSwitches.WuxMuxMode is Projections.UiXamlMode.WindowsUiXaml ? &Do_Wux_Abi_First_0 : &Do_Mux_Abi_First_0; } [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] @@ -767,7 +767,7 @@ static IList() *(IInspectable.Vftbl*)AbiToProjectionVftablePtr = IInspectable.Vftbl.AbiToProjectionVftable; ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[6] = &Do_Abi_GetAt_0; ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[7] = &Do_Abi_get_Size_1; - ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[8] = Projections.UiXamlModeSetting is Projections.UiXamlMode.WindowsUiXaml ? &Do_Wux_Abi_GetView_2 : &Do_Mux_Abi_GetView_2; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[8] = FeatureSwitches.WuxMuxMode is Projections.UiXamlMode.WindowsUiXaml ? &Do_Wux_Abi_GetView_2 : &Do_Mux_Abi_GetView_2; ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[9] = &Do_Abi_IndexOf_3; ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[10] = &Do_Abi_SetAt_4; ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[11] = &Do_Abi_InsertAt_5; @@ -983,7 +983,7 @@ internal static ObjectReference ObjRefFromAbi(IntPtr thisPtr) internal static FromAbiHelper _VectorToList(IWinRTObject _this) { IBindableVectorAdapter adapter = null; - if (Projections.UiXamlModeSetting is Projections.UiXamlMode.WindowsUiXaml) + if (FeatureSwitches.WuxMuxMode is Projections.UiXamlMode.WindowsUiXaml) { adapter = new WuxBindableVectorAdapter((WUX.IBindableVector)_this); } diff --git a/src/WinRT.Runtime/Projections/INotifyCollectionChanged.net5.cs b/src/WinRT.Runtime/Projections/INotifyCollectionChanged.net5.cs index 161d7cf8e..10eecc5bf 100644 --- a/src/WinRT.Runtime/Projections/INotifyCollectionChanged.net5.cs +++ b/src/WinRT.Runtime/Projections/INotifyCollectionChanged.net5.cs @@ -38,19 +38,26 @@ public static unsafe (Action()); + private static ReadOnlySpan GetIID() + => FeatureSwitches.WuxMuxMode switch + { + Projections.UiXamlMode.WindowsUiXaml => new(new byte[] { 0xd5, 0x67, 0xb1, 0x28, 0x31, 0x1a, 0x5b, 0x46, 0x9b, 0x25, 0xd5, 0xc3, 0xae, 0x68, 0x6c, 0x40 }), + Projections.UiXamlMode.MicrosoftUiXaml => new(new byte[] { 0xe1, 0x55, 0x1, 0x53, 0xa5, 0x28, 0x93, 0x56, 0x87, 0xce, 0x30, 0x72, 0x4d, 0x95, 0xa0, 0x6d }), + _ => throw new InvalidOperationException("Invalid UI XAML mode") + }; public static IntPtr AbiToProjectionVftablePtr => INotifyCollectionChanged.Vftbl.AbiToProjectionVftablePtr; } [DynamicInterfaceCastableImplementation] [EditorBrowsable(EditorBrowsableState.Never)] [Guid("530155E1-28A5-5693-87CE-30724D95A06D")] - [WuxMuxProjectedType(wuxIID: "CF75D69C-F2F4-486B-B302-BB4C09BAEBFA", muxIID: "530155E1-28A5-5693-87CE-30724D95A06D")] + [WuxMuxProjectedType(wuxIID: "28b167d5-1a31-465b-9b25-d5c3ae686c40", muxIID: "530155E1-28A5-5693-87CE-30724D95A06D")] internal unsafe interface INotifyCollectionChanged : global::System.Collections.Specialized.INotifyCollectionChanged { [Guid("530155E1-28A5-5693-87CE-30724D95A06D")] - [WuxMuxProjectedType(wuxIID: "CF75D69C-F2F4-486B-B302-BB4C09BAEBFA", muxIID: "530155E1-28A5-5693-87CE-30724D95A06D")] + [WuxMuxProjectedType(wuxIID: "28b167d5-1a31-465b-9b25-d5c3ae686c40", muxIID: "530155E1-28A5-5693-87CE-30724D95A06D")] public struct Vftbl { internal IInspectable.Vftbl IInspectableVftbl; diff --git a/src/WinRT.Runtime/Projections/INotifyPropertyChanged.net5.cs b/src/WinRT.Runtime/Projections/INotifyPropertyChanged.net5.cs index 558e8e46c..f928c2ec1 100644 --- a/src/WinRT.Runtime/Projections/INotifyPropertyChanged.net5.cs +++ b/src/WinRT.Runtime/Projections/INotifyPropertyChanged.net5.cs @@ -16,7 +16,15 @@ namespace ABI.System.ComponentModel #endif static class INotifyPropertyChangedMethods { - public static global::System.Guid IID { get; } = GuidGenerator.GetWuxMuxIID(typeof(INotifyPropertyChanged).GetCustomAttribute()); + public static global::System.Guid IID { get; } = new(GetIID()); + + private static ReadOnlySpan GetIID() + => FeatureSwitches.WuxMuxMode switch + { + Projections.UiXamlMode.WindowsUiXaml => new(new byte[] { 0x9c, 0xd6, 0x75, 0xcf, 0xf4, 0xf2, 0x6b, 0x48, 0xb3, 0x2, 0xbb, 0x4c, 0x9, 0xba, 0xeb, 0xfa }), + Projections.UiXamlMode.MicrosoftUiXaml => new(new byte[] { 0x1, 0x76, 0xb1, 0x90, 0x65, 0xb0, 0x6e, 0x58, 0x83, 0xd9, 0x9a, 0xdc, 0x3a, 0x69, 0x52, 0x84 }), + _ => throw new InvalidOperationException("Invalid UI XAML mode") + }; public static IntPtr AbiToProjectionVftablePtr => INotifyPropertyChanged.Vftbl.AbiToProjectionVftablePtr; } diff --git a/src/WinRT.Runtime/Projections/NotifyCollectionChangedAction.cs b/src/WinRT.Runtime/Projections/NotifyCollectionChangedAction.cs index 62d5af9f4..7a3d5d757 100644 --- a/src/WinRT.Runtime/Projections/NotifyCollectionChangedAction.cs +++ b/src/WinRT.Runtime/Projections/NotifyCollectionChangedAction.cs @@ -8,7 +8,7 @@ namespace ABI.System.Collections.Specialized static class NotifyCollectionChangedAction { public static string GetGuidSignature() => - Projections.UiXamlModeSetting == Projections.UiXamlMode.WindowsUiXaml + FeatureSwitches.WuxMuxMode == Projections.UiXamlMode.WindowsUiXaml ? "enum(Windows.UI.Xaml.Interop.NotifyCollectionChangedAction;i4)" : "enum(Microsoft.UI.Xaml.Interop.NotifyCollectionChangedAction;i4)"; } diff --git a/src/WinRT.Runtime/Projections/NotifyCollectionChangedEventArgs.cs b/src/WinRT.Runtime/Projections/NotifyCollectionChangedEventArgs.cs index 75bb92ca3..53368c1c5 100644 --- a/src/WinRT.Runtime/Projections/NotifyCollectionChangedEventArgs.cs +++ b/src/WinRT.Runtime/Projections/NotifyCollectionChangedEventArgs.cs @@ -278,7 +278,7 @@ namespace ABI.System.Collections.Specialized struct NotifyCollectionChangedEventArgs { private static IWinRTNotifyCollectionChangedEventArgsRuntimeClassFactory Instance = - Projections.UiXamlModeSetting == Projections.UiXamlMode.WindowsUiXaml + FeatureSwitches.WuxMuxMode == Projections.UiXamlMode.WindowsUiXaml ? new WUXNotifyCollectionChangedEventArgsRuntimeClassFactory(ActivationFactory.Get("Windows.UI.Xaml.Interop.NotifyCollectionChangedEventArgs")) : new MUXNotifyCollectionChangedEventArgsRuntimeClassFactory(ActivationFactory.Get("Microsoft.UI.Xaml.Interop.NotifyCollectionChangedEventArgs")); @@ -358,7 +358,7 @@ public static IntPtr FromManaged(global::System.Collections.Specialized.NotifyCo public static string GetGuidSignature() { - if (Projections.UiXamlModeSetting == Projections.UiXamlMode.WindowsUiXaml) + if (FeatureSwitches.WuxMuxMode == Projections.UiXamlMode.WindowsUiXaml) { return "rc(Windows.UI.Xaml.Interop.NotifyCollectionChangedEventArgs;{4cf68d33-e3f2-4964-b85e-945b4f7e2f21})"; } diff --git a/src/WinRT.Runtime/Projections/NotifyCollectionChangedEventHandler.cs b/src/WinRT.Runtime/Projections/NotifyCollectionChangedEventHandler.cs index 9305dc542..4f053315a 100644 --- a/src/WinRT.Runtime/Projections/NotifyCollectionChangedEventHandler.cs +++ b/src/WinRT.Runtime/Projections/NotifyCollectionChangedEventHandler.cs @@ -43,7 +43,7 @@ static unsafe NotifyCollectionChangedEventHandler() Marshal.StructureToPtr(AbiToProjectionVftable, nativeVftbl, false); AbiToProjectionVftablePtr = nativeVftbl; - IID = Projections.UiXamlModeSetting == Projections.UiXamlMode.WindowsUiXaml + IID = FeatureSwitches.WuxMuxMode == Projections.UiXamlMode.WindowsUiXaml ? Guid.Parse("CA10B37C-F382-4591-8557-5E24965279B0") : Guid.Parse("8B0909DC-2005-5D93-BF8A-725F017BAA8D"); } diff --git a/src/WinRT.Runtime/Projections/PropertyChangedEventArgs.cs b/src/WinRT.Runtime/Projections/PropertyChangedEventArgs.cs index c81fb9afb..dd30c7459 100644 --- a/src/WinRT.Runtime/Projections/PropertyChangedEventArgs.cs +++ b/src/WinRT.Runtime/Projections/PropertyChangedEventArgs.cs @@ -179,7 +179,7 @@ namespace ABI.System.ComponentModel unsafe struct PropertyChangedEventArgs { private static ABI.Microsoft.UI.Xaml.Data.IWinRTPropertyChangedEventArgsRuntimeClassFactory Instance = - Projections.UiXamlModeSetting == Projections.UiXamlMode.WindowsUiXaml + FeatureSwitches.WuxMuxMode == Projections.UiXamlMode.WindowsUiXaml ? new ABI.Microsoft.UI.Xaml.Data.WUXPropertyChangedEventArgsRuntimeClassFactory(ActivationFactory.Get("Windows.UI.Xaml.Data.PropertyChangedEventArgs")) : new ABI.Microsoft.UI.Xaml.Data.MUXPropertyChangedEventArgsRuntimeClassFactory(ActivationFactory.Get("Microsoft.UI.Xaml.Data.PropertyChangedEventArgs")); @@ -253,7 +253,7 @@ public static IntPtr FromManaged(global::System.ComponentModel.PropertyChangedEv public static string GetGuidSignature() { - if (Projections.UiXamlModeSetting == Projections.UiXamlMode.WindowsUiXaml) + if (FeatureSwitches.WuxMuxMode == Projections.UiXamlMode.WindowsUiXaml) { return "rc(Windows.UI.Xaml.Data.NotifyPropertyChangedEventArgs;{4f33a9a0-5cf4-47a4-b16f-d7faaf17457e})"; } diff --git a/src/WinRT.Runtime/Projections/PropertyChangedEventHandler.cs b/src/WinRT.Runtime/Projections/PropertyChangedEventHandler.cs index 3fc9f29ce..c77c589e2 100644 --- a/src/WinRT.Runtime/Projections/PropertyChangedEventHandler.cs +++ b/src/WinRT.Runtime/Projections/PropertyChangedEventHandler.cs @@ -41,7 +41,7 @@ static unsafe PropertyChangedEventHandler() var nativeVftbl = ComWrappersSupport.AllocateVtableMemory(typeof(PropertyChangedEventHandler), Marshal.SizeOf()); Marshal.StructureToPtr(AbiToProjectionVftable, nativeVftbl, false); AbiToProjectionVftablePtr = nativeVftbl; - IID = Projections.UiXamlModeSetting == Projections.UiXamlMode.WindowsUiXaml + IID = FeatureSwitches.WuxMuxMode == Projections.UiXamlMode.WindowsUiXaml ? Guid.Parse("50F19C16-0A22-4D8E-A089-1EA9951657D2") : Guid.Parse("E3DE52F6-1E32-5DA6-BB2D-B5B6096C962D"); } From f09f81db389d80c163ad0496928822484f718918 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Fri, 19 Jan 2024 11:12:17 -0800 Subject: [PATCH 12/46] Use boolean feature flag for the WinRT.Runtime side of the support --- nuget/Microsoft.Windows.CsWinRT.targets | 8 +++- .../WinRT.Host.runtimeconfig.json | 2 +- .../Configuration/FeatureSwitches.cs | 41 ++++--------------- .../Configuration/ILLink.Substitutions.xml | 6 +-- src/WinRT.Runtime/GuidGenerator.cs | 9 ++-- src/WinRT.Runtime/Projections.cs | 11 +---- .../Projections/Bindable.net5.cs | 6 +-- .../INotifyCollectionChanged.net5.cs | 9 ++-- .../INotifyPropertyChanged.net5.cs | 9 ++-- .../NotifyCollectionChangedAction.cs | 2 +- .../NotifyCollectionChangedEventArgs.cs | 4 +- .../NotifyCollectionChangedEventHandler.cs | 2 +- .../Projections/PropertyChangedEventArgs.cs | 4 +- .../PropertyChangedEventHandler.cs | 2 +- 14 files changed, 38 insertions(+), 77 deletions(-) diff --git a/nuget/Microsoft.Windows.CsWinRT.targets b/nuget/Microsoft.Windows.CsWinRT.targets index 03c1d284a..b956c039b 100644 --- a/nuget/Microsoft.Windows.CsWinRT.targets +++ b/nuget/Microsoft.Windows.CsWinRT.targets @@ -231,8 +231,12 @@ $(CsWinRTInternalProjection) - - $(CsWinRTUiXamlMode) + + true + true + + + false true diff --git a/src/Tests/AuthoringWuxConsumptionTest/WinRT.Host.runtimeconfig.json b/src/Tests/AuthoringWuxConsumptionTest/WinRT.Host.runtimeconfig.json index 89437eff9..c625b0c81 100644 --- a/src/Tests/AuthoringWuxConsumptionTest/WinRT.Host.runtimeconfig.json +++ b/src/Tests/AuthoringWuxConsumptionTest/WinRT.Host.runtimeconfig.json @@ -7,7 +7,7 @@ "version": "6.0.0" }, "configProperties": { - "CsWinRT.UiXamlMode": "WindowsUiXaml" + "CSWINRT_USE_WINDOWS_UI_XAML_PROJECTIONS": "true" } } } \ No newline at end of file diff --git a/src/WinRT.Runtime/Configuration/FeatureSwitches.cs b/src/WinRT.Runtime/Configuration/FeatureSwitches.cs index d32b98d09..21e33b0f1 100644 --- a/src/WinRT.Runtime/Configuration/FeatureSwitches.cs +++ b/src/WinRT.Runtime/Configuration/FeatureSwitches.cs @@ -78,43 +78,16 @@ private static bool GetConfigurationValue(string propertyName, ref int cachedRes return isEnabled; } - private static Projections.WuxMuxMode _wuxMuxMode = Projections.WuxMuxMode.Unknown; - - internal static Projections.WuxMuxMode WuxMuxMode => GetWuMuxMode("CsWinRT.WuxMuxMode", ref _wuxMuxMode); - /// - /// Gets a configuration value for a specified property. + /// The configuration property name for . /// - /// The property name to retrieve the value for. - /// The cached result for the target configuration value. - /// The value of the specified configuration setting. - private static Projections.WuxMuxMode GetWuxMuxMode(string propertyName, ref Projections.WuxMuxMode cachedResult) - { - // This method doesn't need to worry about concurrent accesses to the cached result, - // as even if the configuration value is retrieved twice, that'll always be the same. - if (cachedResult != Projections.WuxMuxMode.Unknown) - { - return cachedResult; - } - - // Get the configuration switch value, or its default. - // All feature switches have a default set in the .targets file. - if (AppContext.GetData(propertyName) is string str && Enum.TryParse(str, out var mode)) - { - cachedResult = mode; - } - else - { - cachedResult = Projections.WuxMuxMode.MicrosoftUiXaml; - } + private const string IsWuxModePropertyName = "CSWINRT_USE_WINDOWS_UI_XAML_PROJECTIONS"; -#if !NET5_0_OR_GREATER - if (mode == UiXamlMode.WindowsUiXaml) - { - throw new NotSupportedException("Windows.UI.Xaml is not supported before .NET 5. Please use built-in WinRT interop for Windows.UI.Xaml experiences"); - } -#endif + private static int _isWuxMode; - return cachedResult; + public static bool IsWuxMode + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => GetConfigurationValue("CSWINRT_ENABLE_WUX_MODE", ref _isWuxMode); } } \ No newline at end of file diff --git a/src/WinRT.Runtime/Configuration/ILLink.Substitutions.xml b/src/WinRT.Runtime/Configuration/ILLink.Substitutions.xml index 9b56cd877..9dc9a2b54 100644 --- a/src/WinRT.Runtime/Configuration/ILLink.Substitutions.xml +++ b/src/WinRT.Runtime/Configuration/ILLink.Substitutions.xml @@ -6,9 +6,9 @@ - - - + + + \ No newline at end of file diff --git a/src/WinRT.Runtime/GuidGenerator.cs b/src/WinRT.Runtime/GuidGenerator.cs index cef072a33..38f9cf678 100644 --- a/src/WinRT.Runtime/GuidGenerator.cs +++ b/src/WinRT.Runtime/GuidGenerator.cs @@ -48,12 +48,9 @@ public static Guid GetIID( internal static Guid GetWuxMuxIID(WuxMuxProjectedTypeAttribute wuxMuxAttribute) { - return FeatureSwitches.WuxMuxMode switch - { - Projections.UiXamlMode.WindowsUiXaml => wuxMuxAttribute.WuxIID, - Projections.UiXamlMode.MicrosoftUiXaml => wuxMuxAttribute.MuxIID, - _ => throw new InvalidOperationException("Invalid UI XAML mode") - }; + return FeatureSwitches.IsWuxMode + ? wuxMuxAttribute.WuxIID + : wuxMuxAttribute.MuxIID; } public static string GetSignature( diff --git a/src/WinRT.Runtime/Projections.cs b/src/WinRT.Runtime/Projections.cs index 07705c31e..ec4f0b1a5 100644 --- a/src/WinRT.Runtime/Projections.cs +++ b/src/WinRT.Runtime/Projections.cs @@ -25,13 +25,6 @@ namespace WinRT #endif static class Projections { - internal enum UiXamlMode - { - Unknown, - MicrosoftUiXaml, - WindowsUiXaml - } - private static readonly ReaderWriterLockSlim rwlock = new ReaderWriterLockSlim(); @@ -72,7 +65,7 @@ static Projections() RegisterCustomAbiTypeMappingNoLock(typeof(TimeSpan), typeof(ABI.System.TimeSpan), "Windows.Foundation.TimeSpan"); RegisterCustomAbiTypeMappingNoLock(typeof(Uri), typeof(ABI.System.Uri), "Windows.Foundation.Uri", isRuntimeClass: true); - if (UiXamlModeSetting == UiXamlMode.MicrosoftUiXaml) + if (!FeatureSwitches.IsWuxMode) { RegisterCustomAbiTypeMappingNoLock(typeof(DataErrorsChangedEventArgs), typeof(ABI.System.ComponentModel.DataErrorsChangedEventArgs), "Microsoft.UI.Xaml.Data.DataErrorsChangedEventArgs", isRuntimeClass: true); RegisterCustomAbiTypeMappingNoLock(typeof(PropertyChangedEventArgs), typeof(ABI.System.ComponentModel.PropertyChangedEventArgs), "Microsoft.UI.Xaml.Data.PropertyChangedEventArgs", isRuntimeClass: true); @@ -90,7 +83,7 @@ static Projections() CustomTypeToHelperTypeMappings.Add(typeof(Microsoft.UI.Xaml.Interop.IBindableVector), typeof(ABI.System.Collections.IList)); } #if NET5_0_OR_GREATER - else if (UiXamlModeSetting == UiXamlMode.WindowsUiXaml) + else { RegisterCustomAbiTypeMappingNoLock(typeof(PropertyChangedEventArgs), typeof(ABI.System.ComponentModel.PropertyChangedEventArgs), "Windows.UI.Xaml.Data.PropertyChangedEventArgs", isRuntimeClass: true); RegisterCustomAbiTypeMappingNoLock(typeof(PropertyChangedEventHandler), typeof(ABI.System.ComponentModel.PropertyChangedEventHandler), "Windows.UI.Xaml.Data.PropertyChangedEventHandler"); diff --git a/src/WinRT.Runtime/Projections/Bindable.net5.cs b/src/WinRT.Runtime/Projections/Bindable.net5.cs index c499a23a0..47fb56870 100644 --- a/src/WinRT.Runtime/Projections/Bindable.net5.cs +++ b/src/WinRT.Runtime/Projections/Bindable.net5.cs @@ -145,7 +145,7 @@ static IEnumerable() { AbiToProjectionVftablePtr = ComWrappersSupport.AllocateVtableMemory(typeof(IEnumerable), sizeof(IInspectable.Vftbl) + sizeof(IntPtr) * 1); *(IInspectable.Vftbl*)AbiToProjectionVftablePtr = IInspectable.Vftbl.AbiToProjectionVftable; - ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[6] = FeatureSwitches.WuxMuxMode is Projections.UiXamlMode.WindowsUiXaml ? &Do_Wux_Abi_First_0 : &Do_Mux_Abi_First_0; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[6] = FeatureSwitches.IsWuxMode ? &Do_Wux_Abi_First_0 : &Do_Mux_Abi_First_0; } [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] @@ -767,7 +767,7 @@ static IList() *(IInspectable.Vftbl*)AbiToProjectionVftablePtr = IInspectable.Vftbl.AbiToProjectionVftable; ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[6] = &Do_Abi_GetAt_0; ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[7] = &Do_Abi_get_Size_1; - ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[8] = FeatureSwitches.WuxMuxMode is Projections.UiXamlMode.WindowsUiXaml ? &Do_Wux_Abi_GetView_2 : &Do_Mux_Abi_GetView_2; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[8] = FeatureSwitches.IsWuxMode ? &Do_Wux_Abi_GetView_2 : &Do_Mux_Abi_GetView_2; ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[9] = &Do_Abi_IndexOf_3; ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[10] = &Do_Abi_SetAt_4; ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[11] = &Do_Abi_InsertAt_5; @@ -983,7 +983,7 @@ internal static ObjectReference ObjRefFromAbi(IntPtr thisPtr) internal static FromAbiHelper _VectorToList(IWinRTObject _this) { IBindableVectorAdapter adapter = null; - if (FeatureSwitches.WuxMuxMode is Projections.UiXamlMode.WindowsUiXaml) + if (FeatureSwitches.IsWuxMode) { adapter = new WuxBindableVectorAdapter((WUX.IBindableVector)_this); } diff --git a/src/WinRT.Runtime/Projections/INotifyCollectionChanged.net5.cs b/src/WinRT.Runtime/Projections/INotifyCollectionChanged.net5.cs index 10eecc5bf..f1153236b 100644 --- a/src/WinRT.Runtime/Projections/INotifyCollectionChanged.net5.cs +++ b/src/WinRT.Runtime/Projections/INotifyCollectionChanged.net5.cs @@ -41,12 +41,9 @@ public static unsafe (Action GetIID() - => FeatureSwitches.WuxMuxMode switch - { - Projections.UiXamlMode.WindowsUiXaml => new(new byte[] { 0xd5, 0x67, 0xb1, 0x28, 0x31, 0x1a, 0x5b, 0x46, 0x9b, 0x25, 0xd5, 0xc3, 0xae, 0x68, 0x6c, 0x40 }), - Projections.UiXamlMode.MicrosoftUiXaml => new(new byte[] { 0xe1, 0x55, 0x1, 0x53, 0xa5, 0x28, 0x93, 0x56, 0x87, 0xce, 0x30, 0x72, 0x4d, 0x95, 0xa0, 0x6d }), - _ => throw new InvalidOperationException("Invalid UI XAML mode") - }; + => FeatureSwitches.IsWuxMode + ? new(new byte[] { 0xd5, 0x67, 0xb1, 0x28, 0x31, 0x1a, 0x5b, 0x46, 0x9b, 0x25, 0xd5, 0xc3, 0xae, 0x68, 0x6c, 0x40 }), + : new(new byte[] { 0xe1, 0x55, 0x1, 0x53, 0xa5, 0x28, 0x93, 0x56, 0x87, 0xce, 0x30, 0x72, 0x4d, 0x95, 0xa0, 0x6d }); public static IntPtr AbiToProjectionVftablePtr => INotifyCollectionChanged.Vftbl.AbiToProjectionVftablePtr; } diff --git a/src/WinRT.Runtime/Projections/INotifyPropertyChanged.net5.cs b/src/WinRT.Runtime/Projections/INotifyPropertyChanged.net5.cs index f928c2ec1..2cde26bb3 100644 --- a/src/WinRT.Runtime/Projections/INotifyPropertyChanged.net5.cs +++ b/src/WinRT.Runtime/Projections/INotifyPropertyChanged.net5.cs @@ -19,12 +19,9 @@ static class INotifyPropertyChangedMethods public static global::System.Guid IID { get; } = new(GetIID()); private static ReadOnlySpan GetIID() - => FeatureSwitches.WuxMuxMode switch - { - Projections.UiXamlMode.WindowsUiXaml => new(new byte[] { 0x9c, 0xd6, 0x75, 0xcf, 0xf4, 0xf2, 0x6b, 0x48, 0xb3, 0x2, 0xbb, 0x4c, 0x9, 0xba, 0xeb, 0xfa }), - Projections.UiXamlMode.MicrosoftUiXaml => new(new byte[] { 0x1, 0x76, 0xb1, 0x90, 0x65, 0xb0, 0x6e, 0x58, 0x83, 0xd9, 0x9a, 0xdc, 0x3a, 0x69, 0x52, 0x84 }), - _ => throw new InvalidOperationException("Invalid UI XAML mode") - }; + => FeatureSwitches.IsWuxMode + ? new(new byte[] { 0x9c, 0xd6, 0x75, 0xcf, 0xf4, 0xf2, 0x6b, 0x48, 0xb3, 0x2, 0xbb, 0x4c, 0x9, 0xba, 0xeb, 0xfa }) + : new(new byte[] { 0x1, 0x76, 0xb1, 0x90, 0x65, 0xb0, 0x6e, 0x58, 0x83, 0xd9, 0x9a, 0xdc, 0x3a, 0x69, 0x52, 0x84 }); public static IntPtr AbiToProjectionVftablePtr => INotifyPropertyChanged.Vftbl.AbiToProjectionVftablePtr; } diff --git a/src/WinRT.Runtime/Projections/NotifyCollectionChangedAction.cs b/src/WinRT.Runtime/Projections/NotifyCollectionChangedAction.cs index 7a3d5d757..7d234390b 100644 --- a/src/WinRT.Runtime/Projections/NotifyCollectionChangedAction.cs +++ b/src/WinRT.Runtime/Projections/NotifyCollectionChangedAction.cs @@ -8,7 +8,7 @@ namespace ABI.System.Collections.Specialized static class NotifyCollectionChangedAction { public static string GetGuidSignature() => - FeatureSwitches.WuxMuxMode == Projections.UiXamlMode.WindowsUiXaml + FeatureSwitches.IsWuxMode ? "enum(Windows.UI.Xaml.Interop.NotifyCollectionChangedAction;i4)" : "enum(Microsoft.UI.Xaml.Interop.NotifyCollectionChangedAction;i4)"; } diff --git a/src/WinRT.Runtime/Projections/NotifyCollectionChangedEventArgs.cs b/src/WinRT.Runtime/Projections/NotifyCollectionChangedEventArgs.cs index 53368c1c5..f71fe0a22 100644 --- a/src/WinRT.Runtime/Projections/NotifyCollectionChangedEventArgs.cs +++ b/src/WinRT.Runtime/Projections/NotifyCollectionChangedEventArgs.cs @@ -278,7 +278,7 @@ namespace ABI.System.Collections.Specialized struct NotifyCollectionChangedEventArgs { private static IWinRTNotifyCollectionChangedEventArgsRuntimeClassFactory Instance = - FeatureSwitches.WuxMuxMode == Projections.UiXamlMode.WindowsUiXaml + FeatureSwitches.IsWuxMode ? new WUXNotifyCollectionChangedEventArgsRuntimeClassFactory(ActivationFactory.Get("Windows.UI.Xaml.Interop.NotifyCollectionChangedEventArgs")) : new MUXNotifyCollectionChangedEventArgsRuntimeClassFactory(ActivationFactory.Get("Microsoft.UI.Xaml.Interop.NotifyCollectionChangedEventArgs")); @@ -358,7 +358,7 @@ public static IntPtr FromManaged(global::System.Collections.Specialized.NotifyCo public static string GetGuidSignature() { - if (FeatureSwitches.WuxMuxMode == Projections.UiXamlMode.WindowsUiXaml) + if (FeatureSwitches.IsWuxMode) { return "rc(Windows.UI.Xaml.Interop.NotifyCollectionChangedEventArgs;{4cf68d33-e3f2-4964-b85e-945b4f7e2f21})"; } diff --git a/src/WinRT.Runtime/Projections/NotifyCollectionChangedEventHandler.cs b/src/WinRT.Runtime/Projections/NotifyCollectionChangedEventHandler.cs index 4f053315a..8e33b074d 100644 --- a/src/WinRT.Runtime/Projections/NotifyCollectionChangedEventHandler.cs +++ b/src/WinRT.Runtime/Projections/NotifyCollectionChangedEventHandler.cs @@ -43,7 +43,7 @@ static unsafe NotifyCollectionChangedEventHandler() Marshal.StructureToPtr(AbiToProjectionVftable, nativeVftbl, false); AbiToProjectionVftablePtr = nativeVftbl; - IID = FeatureSwitches.WuxMuxMode == Projections.UiXamlMode.WindowsUiXaml + IID = FeatureSwitches.IsWuxMode ? Guid.Parse("CA10B37C-F382-4591-8557-5E24965279B0") : Guid.Parse("8B0909DC-2005-5D93-BF8A-725F017BAA8D"); } diff --git a/src/WinRT.Runtime/Projections/PropertyChangedEventArgs.cs b/src/WinRT.Runtime/Projections/PropertyChangedEventArgs.cs index dd30c7459..06f57ac6b 100644 --- a/src/WinRT.Runtime/Projections/PropertyChangedEventArgs.cs +++ b/src/WinRT.Runtime/Projections/PropertyChangedEventArgs.cs @@ -179,7 +179,7 @@ namespace ABI.System.ComponentModel unsafe struct PropertyChangedEventArgs { private static ABI.Microsoft.UI.Xaml.Data.IWinRTPropertyChangedEventArgsRuntimeClassFactory Instance = - FeatureSwitches.WuxMuxMode == Projections.UiXamlMode.WindowsUiXaml + FeatureSwitches.IsWuxMode ? new ABI.Microsoft.UI.Xaml.Data.WUXPropertyChangedEventArgsRuntimeClassFactory(ActivationFactory.Get("Windows.UI.Xaml.Data.PropertyChangedEventArgs")) : new ABI.Microsoft.UI.Xaml.Data.MUXPropertyChangedEventArgsRuntimeClassFactory(ActivationFactory.Get("Microsoft.UI.Xaml.Data.PropertyChangedEventArgs")); @@ -253,7 +253,7 @@ public static IntPtr FromManaged(global::System.ComponentModel.PropertyChangedEv public static string GetGuidSignature() { - if (FeatureSwitches.WuxMuxMode == Projections.UiXamlMode.WindowsUiXaml) + if (FeatureSwitches.IsWuxMode) { return "rc(Windows.UI.Xaml.Data.NotifyPropertyChangedEventArgs;{4f33a9a0-5cf4-47a4-b16f-d7faaf17457e})"; } diff --git a/src/WinRT.Runtime/Projections/PropertyChangedEventHandler.cs b/src/WinRT.Runtime/Projections/PropertyChangedEventHandler.cs index c77c589e2..e8c7f16e6 100644 --- a/src/WinRT.Runtime/Projections/PropertyChangedEventHandler.cs +++ b/src/WinRT.Runtime/Projections/PropertyChangedEventHandler.cs @@ -41,7 +41,7 @@ static unsafe PropertyChangedEventHandler() var nativeVftbl = ComWrappersSupport.AllocateVtableMemory(typeof(PropertyChangedEventHandler), Marshal.SizeOf()); Marshal.StructureToPtr(AbiToProjectionVftable, nativeVftbl, false); AbiToProjectionVftablePtr = nativeVftbl; - IID = FeatureSwitches.WuxMuxMode == Projections.UiXamlMode.WindowsUiXaml + IID = FeatureSwitches.IsWuxMode ? Guid.Parse("50F19C16-0A22-4D8E-A089-1EA9951657D2") : Guid.Parse("E3DE52F6-1E32-5DA6-BB2D-B5B6096C962D"); } From 1a7d5a3d8030b5ea79c1da9a51a5bd7f0208fab3 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Fri, 19 Jan 2024 14:03:45 -0800 Subject: [PATCH 13/46] Rename MSBuild property and expected values. --- nuget/Microsoft.Windows.CsWinRT.Authoring.targets | 2 +- nuget/Microsoft.Windows.CsWinRT.targets | 4 ++-- src/Authoring/WinRT.SourceGenerator/TypeMapper.cs | 2 +- src/Authoring/WinRT.SourceGenerator/UiXamlMode.cs | 8 ++++---- src/Tests/AuthoringWuxTest/AuthoringWuxTest.csproj | 2 +- .../Projections/INotifyCollectionChanged.net5.cs | 2 +- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/nuget/Microsoft.Windows.CsWinRT.Authoring.targets b/nuget/Microsoft.Windows.CsWinRT.Authoring.targets index bb3ae3f19..7117831f8 100644 --- a/nuget/Microsoft.Windows.CsWinRT.Authoring.targets +++ b/nuget/Microsoft.Windows.CsWinRT.Authoring.targets @@ -31,7 +31,7 @@ Copyright (C) Microsoft Corporation. All rights reserved. - + diff --git a/nuget/Microsoft.Windows.CsWinRT.targets b/nuget/Microsoft.Windows.CsWinRT.targets index b956c039b..e9d751dd4 100644 --- a/nuget/Microsoft.Windows.CsWinRT.targets +++ b/nuget/Microsoft.Windows.CsWinRT.targets @@ -231,11 +231,11 @@ $(CsWinRTInternalProjection) - + true true - + false true diff --git a/src/Authoring/WinRT.SourceGenerator/TypeMapper.cs b/src/Authoring/WinRT.SourceGenerator/TypeMapper.cs index e35ccc63e..722509cc9 100644 --- a/src/Authoring/WinRT.SourceGenerator/TypeMapper.cs +++ b/src/Authoring/WinRT.SourceGenerator/TypeMapper.cs @@ -25,7 +25,7 @@ private static (string, string, string, bool, bool) GetSystemTypeCustomMapping(I public TypeMapper(UiXamlMode xamlMode) { // This should be in sync with the reverse mapping from WinRT.Runtime/Projections.cs and cswinrt/helpers.h. - if (xamlMode == UiXamlMode.WindowsUiXaml) + if (xamlMode == UiXamlMode.WindowsUIXaml) { typeMapping = new(StringComparer.Ordinal) { diff --git a/src/Authoring/WinRT.SourceGenerator/UiXamlMode.cs b/src/Authoring/WinRT.SourceGenerator/UiXamlMode.cs index 7432a1075..dd04f5573 100644 --- a/src/Authoring/WinRT.SourceGenerator/UiXamlMode.cs +++ b/src/Authoring/WinRT.SourceGenerator/UiXamlMode.cs @@ -7,20 +7,20 @@ namespace Generator { internal enum UiXamlMode { - MicrosoftUiXaml, - WindowsUiXaml, + MicrosoftUIXaml, + WindowsUIXaml, } internal static class OptionsHelper { public static UiXamlMode GetUiXamlMode(this AnalyzerConfigOptions options) { - if (options.TryGetValue("build_property.CsWinRTUiXamlMode", out var value) && Enum.TryParse(value, out UiXamlMode mode)) + if (options.TryGetValue("build_property.CsWinRTUIXamlProjections", out var value) && Enum.TryParse(value, out UiXamlMode mode)) { return mode; } - return UiXamlMode.MicrosoftUiXaml; + return UiXamlMode.MicrosoftUIXaml; } } } diff --git a/src/Tests/AuthoringWuxTest/AuthoringWuxTest.csproj b/src/Tests/AuthoringWuxTest/AuthoringWuxTest.csproj index a00cb2c58..fbd8d334e 100644 --- a/src/Tests/AuthoringWuxTest/AuthoringWuxTest.csproj +++ b/src/Tests/AuthoringWuxTest/AuthoringWuxTest.csproj @@ -5,7 +5,7 @@ x64;x86 true true - WindowsUiXaml + WindowsUIXaml diff --git a/src/WinRT.Runtime/Projections/INotifyCollectionChanged.net5.cs b/src/WinRT.Runtime/Projections/INotifyCollectionChanged.net5.cs index f1153236b..becd96930 100644 --- a/src/WinRT.Runtime/Projections/INotifyCollectionChanged.net5.cs +++ b/src/WinRT.Runtime/Projections/INotifyCollectionChanged.net5.cs @@ -42,7 +42,7 @@ public static unsafe (Action GetIID() => FeatureSwitches.IsWuxMode - ? new(new byte[] { 0xd5, 0x67, 0xb1, 0x28, 0x31, 0x1a, 0x5b, 0x46, 0x9b, 0x25, 0xd5, 0xc3, 0xae, 0x68, 0x6c, 0x40 }), + ? new(new byte[] { 0xd5, 0x67, 0xb1, 0x28, 0x31, 0x1a, 0x5b, 0x46, 0x9b, 0x25, 0xd5, 0xc3, 0xae, 0x68, 0x6c, 0x40 }) : new(new byte[] { 0xe1, 0x55, 0x1, 0x53, 0xa5, 0x28, 0x93, 0x56, 0x87, 0xce, 0x30, 0x72, 0x4d, 0x95, 0xa0, 0x6d }); public static IntPtr AbiToProjectionVftablePtr => INotifyCollectionChanged.Vftbl.AbiToProjectionVftablePtr; } From b1344aa06dc6f12a9298ec498d5afa41d5b2d3d0 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Fri, 19 Jan 2024 14:04:27 -0800 Subject: [PATCH 14/46] Consolidate item groups --- nuget/Microsoft.Windows.CsWinRT.targets | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/nuget/Microsoft.Windows.CsWinRT.targets b/nuget/Microsoft.Windows.CsWinRT.targets index e9d751dd4..7cc46e72f 100644 --- a/nuget/Microsoft.Windows.CsWinRT.targets +++ b/nuget/Microsoft.Windows.CsWinRT.targets @@ -230,17 +230,6 @@ $(CsWinRTInternalProjection) - - - true - true - - - false - true - - - @@ -260,6 +249,15 @@ $(CsWinRTInternalProjection) + + + true + true + + + false + true + From afe0e220ab1ec65757368ffb1f6579e974e8f188 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Fri, 19 Jan 2024 14:09:41 -0800 Subject: [PATCH 15/46] Rename UiXamlMode to UIXamlProjectionsMode to better match the MSBuild property --- .../WinRT.SourceGenerator/AotOptimizer.cs | 2 +- .../WinRT.SourceGenerator/DiagnosticUtils.cs | 348 +++++++++--------- .../WinRT.SourceGenerator/Generator.cs | 2 +- .../WinRT.SourceGenerator/TypeMapper.cs | 4 +- ...UiXamlMode.cs => UIXamlProjectionsMode.cs} | 8 +- 5 files changed, 182 insertions(+), 182 deletions(-) rename src/Authoring/WinRT.SourceGenerator/{UiXamlMode.cs => UIXamlProjectionsMode.cs} (55%) diff --git a/src/Authoring/WinRT.SourceGenerator/AotOptimizer.cs b/src/Authoring/WinRT.SourceGenerator/AotOptimizer.cs index f6996659d..42e7c4795 100644 --- a/src/Authoring/WinRT.SourceGenerator/AotOptimizer.cs +++ b/src/Authoring/WinRT.SourceGenerator/AotOptimizer.cs @@ -20,7 +20,7 @@ public void Initialize(IncrementalGeneratorInitializationContext context) { var properties = context.AnalyzerConfigOptionsProvider.Select(static (provider, _) => (provider.IsCsWinRTAotOptimizerEnabled(), provider.IsCsWinRTComponent())); - var typeMapper = context.AnalyzerConfigOptionsProvider.Select((options, ct) => options.GlobalOptions.GetUiXamlMode()).Select((mode, ct) => new TypeMapper(mode)); + var typeMapper = context.AnalyzerConfigOptionsProvider.Select((options, ct) => options.GlobalOptions.GetUIXamlProjectionsMode()).Select((mode, ct) => new TypeMapper(mode)); var possibleVtableAttributesToAdd = context.SyntaxProvider.CreateSyntaxProvider( static (n, _) => NeedVtableAttribute(n), diff --git a/src/Authoring/WinRT.SourceGenerator/DiagnosticUtils.cs b/src/Authoring/WinRT.SourceGenerator/DiagnosticUtils.cs index 528bd1598..809bb9bde 100644 --- a/src/Authoring/WinRT.SourceGenerator/DiagnosticUtils.cs +++ b/src/Authoring/WinRT.SourceGenerator/DiagnosticUtils.cs @@ -7,16 +7,16 @@ using System; using WinRT.SourceGenerator; -namespace Generator +namespace Generator { public partial class WinRTComponentScanner { - public WinRTComponentScanner(GeneratorExecutionContext context, string assemblyName) - { + public WinRTComponentScanner(GeneratorExecutionContext context, string assemblyName) + { _assemblyName = assemblyName; _context = context; _flag = false; - _typeMapper = new TypeMapper(context.AnalyzerConfigOptions.GlobalOptions.GetUiXamlMode()); + _typeMapper = new TypeMapper(context.AnalyzerConfigOptions.GlobalOptions.GetUIXamlProjectionsMode()); } private readonly string _assemblyName; @@ -33,59 +33,59 @@ public void FindDiagnostics() { WinRTSyntaxReceiver syntaxReceiver = (WinRTSyntaxReceiver)_context.SyntaxReceiver; - if (!syntaxReceiver.Declarations.Any()) - { + if (!syntaxReceiver.Declarations.Any()) + { Report(WinRTRules.NoPublicTypesRule, null); return; } - CheckNamespaces(); - CheckDeclarations(); - } - - private void CheckNamespaces() - { + CheckNamespaces(); + CheckDeclarations(); + } + + private void CheckNamespaces() + { WinRTSyntaxReceiver syntaxReceiver = (WinRTSyntaxReceiver)_context.SyntaxReceiver; - - // Used to check for conflicitng namespace names - HashSet namespaceNames = new(); - - foreach (var @namespace in syntaxReceiver.Namespaces) - { - var model = _context.Compilation.GetSemanticModel(@namespace.SyntaxTree); - var namespaceSymbol = model.GetDeclaredSymbol(@namespace); - - string namespaceString = namespaceSymbol.ToString(); - - bool newNamespaceDeclaration = true; - // Because modules could have a namespace defined in different places (i.e. defines a partial class) - // we can't rely on `Contains` so we manually check that namespace names cannot differ by case only - foreach (var usedNamespaceName in namespaceNames) - { - if (String.Equals(namespaceString, usedNamespaceName, StringComparison.OrdinalIgnoreCase) && - !String.Equals(namespaceString, usedNamespaceName, StringComparison.Ordinal)) - { - newNamespaceDeclaration = false; - Report(WinRTRules.NamespacesDifferByCase, namespaceSymbol.Locations.First(), namespaceString); - } - } - - if (newNamespaceDeclaration) - { - namespaceNames.Add(namespaceString); - } - - if (IsInvalidNamespace(namespaceSymbol, _assemblyName)) - { - Report(WinRTRules.DisjointNamespaceRule, namespaceSymbol.Locations.First(), _assemblyName, namespaceString); - } + + // Used to check for conflicitng namespace names + HashSet namespaceNames = new(); + + foreach (var @namespace in syntaxReceiver.Namespaces) + { + var model = _context.Compilation.GetSemanticModel(@namespace.SyntaxTree); + var namespaceSymbol = model.GetDeclaredSymbol(@namespace); + + string namespaceString = namespaceSymbol.ToString(); + + bool newNamespaceDeclaration = true; + // Because modules could have a namespace defined in different places (i.e. defines a partial class) + // we can't rely on `Contains` so we manually check that namespace names cannot differ by case only + foreach (var usedNamespaceName in namespaceNames) + { + if (String.Equals(namespaceString, usedNamespaceName, StringComparison.OrdinalIgnoreCase) && + !String.Equals(namespaceString, usedNamespaceName, StringComparison.Ordinal)) + { + newNamespaceDeclaration = false; + Report(WinRTRules.NamespacesDifferByCase, namespaceSymbol.Locations.First(), namespaceString); + } + } + + if (newNamespaceDeclaration) + { + namespaceNames.Add(namespaceString); + } + + if (IsInvalidNamespace(namespaceSymbol, _assemblyName)) + { + Report(WinRTRules.DisjointNamespaceRule, namespaceSymbol.Locations.First(), _assemblyName, namespaceString); + } } } - private void CheckDeclarations() - { - WinRTSyntaxReceiver syntaxReceiver = (WinRTSyntaxReceiver)_context.SyntaxReceiver; - + private void CheckDeclarations() + { + WinRTSyntaxReceiver syntaxReceiver = (WinRTSyntaxReceiver)_context.SyntaxReceiver; + foreach (var declaration in syntaxReceiver.Declarations) { var model = _context.Compilation.GetSemanticModel(declaration.SyntaxTree); @@ -93,12 +93,12 @@ private void CheckDeclarations() // Check symbol information for whether it is public to properly detect partial types // which can leave out modifier. Also ignore nested types not effectively public - if (symbol.DeclaredAccessibility != Accessibility.Public || - (symbol is ITypeSymbol typeSymbol && !typeSymbol.IsPubliclyAccessible())) - { - continue; - } - + if (symbol.DeclaredAccessibility != Accessibility.Public || + (symbol is ITypeSymbol typeSymbol && !typeSymbol.IsPubliclyAccessible())) + { + continue; + } + if (declaration is ClassDeclarationSyntax @class) { var classId = @class.Identifier; @@ -107,7 +107,7 @@ private void CheckDeclarations() var props = @class.DescendantNodes().OfType().Where(IsPublic); // filter out methods and properties that will be replaced with our custom type mappings - IgnoreCustomTypeMappings(classSymbol, _typeMapper, ref publicMethods, ref props); + IgnoreCustomTypeMappings(classSymbol, _typeMapper, ref publicMethods, ref props); if (!classSymbol.IsSealed && !classSymbol.IsStatic) { @@ -118,103 +118,103 @@ private void CheckDeclarations() HasMultipleConstructorsOfSameArity(@class); if (classSymbol.IsGenericType) - { + { Report(WinRTRules.GenericTypeRule, @class.GetLocation(), classId); } // check for things in nonWindowsRuntimeInterfaces - ImplementsInvalidInterface(classSymbol, @class); - - CheckProperties(props, classId); - - // check types -- todo: check for !valid types - CheckMethods(publicMethods, classId); - + ImplementsInvalidInterface(classSymbol, @class); + + CheckProperties(props, classId); + + // check types -- todo: check for !valid types + CheckMethods(publicMethods, classId); + CheckInterfaces(model, @class); } else if (declaration is InterfaceDeclarationSyntax @interface) { var interfaceSym = model.GetDeclaredSymbol(@interface); var methods = @interface.DescendantNodes().OfType(); - var props = @interface.DescendantNodes().OfType().Where(IsPublic); - - // filter out methods and properties that will be replaced with our custom type mappings - IgnoreCustomTypeMappings(interfaceSym, _typeMapper, ref methods, ref props); - + var props = @interface.DescendantNodes().OfType().Where(IsPublic); + + // filter out methods and properties that will be replaced with our custom type mappings + IgnoreCustomTypeMappings(interfaceSym, _typeMapper, ref methods, ref props); + if (interfaceSym.IsGenericType) { Report(WinRTRules.GenericTypeRule, @interface.GetLocation(), @interface.Identifier); } - ImplementsInvalidInterface(interfaceSym, @interface); - - CheckProperties(props, @interface.Identifier); - + ImplementsInvalidInterface(interfaceSym, @interface); + + CheckProperties(props, @interface.Identifier); + CheckMethods(methods, @interface.Identifier); - } - else if (declaration is StructDeclarationSyntax @struct) - { - CheckStructFields(@struct); - } + } + else if (declaration is StructDeclarationSyntax @struct) + { + CheckStructFields(@struct); + } } - } - - private void CheckInterfaces(SemanticModel model, ClassDeclarationSyntax @class) - { - var classId = @class.Identifier; + } + + private void CheckInterfaces(SemanticModel model, ClassDeclarationSyntax @class) + { + var classId = @class.Identifier; var classSymbol = model.GetDeclaredSymbol(@class); - - var iWinRTObject = model.Compilation.GetTypeByMetadataName("WinRT.IWinRTObject"); - // validate that the class correctly implements all its interfaces - var methods = classSymbol.GetMembers().OfType().ToList(); - foreach (var iface in classSymbol.AllInterfaces) - { - if (SymbolEqualityComparer.Default.Equals(iface, iWinRTObject)) - { - continue; - } - foreach (var member in iface.GetMembers().OfType()) - { - var impl = classSymbol.FindImplementationForInterfaceMember(member); - if (impl == null) - { - var explicitIfaceImpl = methods.Where(m => IsMethodImpl(m, member)); - if (!explicitIfaceImpl.Any()) - { - Report(WinRTRules.UnimplementedInterface, @class.GetLocation(), classId.Text, iface.ToDisplayString(), member.ToDisplayString()); - } - } - } - } - } - - private bool IsMethodImpl(IMethodSymbol m, IMethodSymbol interfaceMethod) - { - if (m.Name != interfaceMethod.Name) - { - return false; - } - if (!m.Parameters.SequenceEqual(interfaceMethod.Parameters)) - { - return false; - } - - // the return type can be covariant with the interface method's return type (i.e. a sub-type) - if (SymEq(m.ReturnType, interfaceMethod.ReturnType) && !m.ReturnType.AllInterfaces.Contains(interfaceMethod.ReturnType)) - { - return false; - } - return true; - } - - private void IgnoreCustomTypeMappings(INamedTypeSymbol typeSymbol, - TypeMapper typeMapper, - ref IEnumerable methods, + + var iWinRTObject = model.Compilation.GetTypeByMetadataName("WinRT.IWinRTObject"); + // validate that the class correctly implements all its interfaces + var methods = classSymbol.GetMembers().OfType().ToList(); + foreach (var iface in classSymbol.AllInterfaces) + { + if (SymbolEqualityComparer.Default.Equals(iface, iWinRTObject)) + { + continue; + } + foreach (var member in iface.GetMembers().OfType()) + { + var impl = classSymbol.FindImplementationForInterfaceMember(member); + if (impl == null) + { + var explicitIfaceImpl = methods.Where(m => IsMethodImpl(m, member)); + if (!explicitIfaceImpl.Any()) + { + Report(WinRTRules.UnimplementedInterface, @class.GetLocation(), classId.Text, iface.ToDisplayString(), member.ToDisplayString()); + } + } + } + } + } + + private bool IsMethodImpl(IMethodSymbol m, IMethodSymbol interfaceMethod) + { + if (m.Name != interfaceMethod.Name) + { + return false; + } + if (!m.Parameters.SequenceEqual(interfaceMethod.Parameters)) + { + return false; + } + + // the return type can be covariant with the interface method's return type (i.e. a sub-type) + if (SymEq(m.ReturnType, interfaceMethod.ReturnType) && !m.ReturnType.AllInterfaces.Contains(interfaceMethod.ReturnType)) + { + return false; + } + return true; + } + + private void IgnoreCustomTypeMappings(INamedTypeSymbol typeSymbol, + TypeMapper typeMapper, + ref IEnumerable methods, ref IEnumerable properties) { - string QualifiedName(INamedTypeSymbol sym) - { - return sym.OriginalDefinition.ContainingNamespace + "." + sym.OriginalDefinition.MetadataName; + string QualifiedName(INamedTypeSymbol sym) + { + return sym.OriginalDefinition.ContainingNamespace + "." + sym.OriginalDefinition.MetadataName; } HashSet classMethods = new(); @@ -224,7 +224,7 @@ string QualifiedName(INamedTypeSymbol sym) WinRTTypeWriter.ImplementedInterfacesWithoutMapping.Contains(QualifiedName(symbol)))) { foreach (var interfaceMember in @interface.GetMembers()) - { + { classMethods.Add(typeSymbol.FindImplementationForInterfaceMember(interfaceMember)); } } @@ -279,9 +279,9 @@ private void HasConflictingParameterName(MethodDeclarationSyntax method) bool IsInvalidParameterName(ParameterSyntax stx) { return stx.Identifier.Value.Equals(GeneratedReturnValueName); } var hasInvalidParams = method.ParameterList.Parameters.Any(IsInvalidParameterName); - if (hasInvalidParams) - { - Report(WinRTRules.ParameterNamedValueRule, method.GetLocation(), method.Identifier); + if (hasInvalidParams) + { + Report(WinRTRules.ParameterNamedValueRule, method.GetLocation(), method.Identifier); } } @@ -310,7 +310,7 @@ private void CheckMethods(IEnumerable methodDeclaration foreach (var arg in methodSym.Parameters) { ReportIfInvalidType(arg.Type, method.GetLocation(), method.Identifier, typeId); - } + } } /* Finishes up the work started by `CheckOverloadAttributes` */ foreach (var thing in overloadsWithoutAttributeMap) @@ -329,9 +329,9 @@ private void CheckProperties(IEnumerable props, Synta var propSym = GetModel(prop.SyntaxTree).GetDeclaredSymbol(prop); var loc = prop.GetLocation(); - if (propSym.GetMethod == null || !propSym.GetMethod.DeclaredAccessibility.Equals(Accessibility.Public)) - { - Report(WinRTRules.PrivateGetterRule, loc, prop.Identifier); + if (propSym.GetMethod == null || !propSym.GetMethod.DeclaredAccessibility.Equals(Accessibility.Public)) + { + Report(WinRTRules.PrivateGetterRule, loc, prop.Identifier); } ReportIfInvalidType(propSym.Type, loc, prop.Identifier, typeId); @@ -348,12 +348,12 @@ private void CheckStructFields(StructDeclarationSyntax @struct) { // delegates not allowed if (@struct.DescendantNodes().OfType().Any()) - { + { Report(WinRTRules.StructHasInvalidFieldRule, @struct.GetLocation(), @struct.Identifier, SimplifySyntaxTypeString(typeof(DelegateDeclarationSyntax).Name)); } // methods not allowed if (@struct.DescendantNodes().OfType().Any()) - { + { Report(WinRTRules.StructHasInvalidFieldRule, @struct.GetLocation(), @struct.Identifier, SimplifySyntaxTypeString(typeof(MethodDeclarationSyntax).Name)); } @@ -361,16 +361,16 @@ private void CheckStructFields(StructDeclarationSyntax @struct) // constructors not allowed if (structSym.Constructors.Length > 1) - { + { Report(WinRTRules.StructHasInvalidFieldRule, @struct.GetLocation(), @struct.Identifier, SimplifySyntaxTypeString(typeof(ConstructorDeclarationSyntax).Name)); } var fields = @struct.DescendantNodes().OfType(); - foreach (var field in fields) + foreach (var field in fields) { // all fields must be public if (!IsPublic(field)) - { + { Report(WinRTRules.StructHasPrivateFieldRule, field.GetLocation(), @struct.Identifier); } @@ -384,14 +384,14 @@ private void CheckStructFields(StructDeclarationSyntax @struct) { IFieldSymbol varFieldSym = (IFieldSymbol)GetModel(variable.SyntaxTree).GetDeclaredSymbol(variable); - if (ValidStructFieldTypes.Contains(varFieldSym.Type.SpecialType) || + if (ValidStructFieldTypes.Contains(varFieldSym.Type.SpecialType) || varFieldSym.Type.TypeKind == TypeKind.Struct || varFieldSym.Type.TypeKind == TypeKind.Enum) { break; } else - { + { Report(WinRTRules.StructHasInvalidFieldRule, variable.GetLocation(), @struct.Identifier, varFieldSym.Name); } } @@ -409,23 +409,23 @@ private void CheckStructFields(StructDeclarationSyntax @struct) /// the authored namespace to checkthe name of the component/winmd /// True iff namespace is disjoint from the assembly name private bool IsInvalidNamespace(INamespaceSymbol @namespace, string assemblyName) - { - if (string.CompareOrdinal(@namespace.ToString(), assemblyName) == 0) - { - return false; - } - + { + if (string.CompareOrdinal(@namespace.ToString(), assemblyName) == 0) + { + return false; + } + var topLevel = @namespace; while (!topLevel.ContainingNamespace.IsGlobalNamespace) - { - if (string.CompareOrdinal(topLevel.ToString(), assemblyName) == 0) - { - return false; + { + if (string.CompareOrdinal(topLevel.ToString(), assemblyName) == 0) + { + return false; } topLevel = topLevel.ContainingNamespace; - } - - return string.CompareOrdinal(topLevel.ToString(), assemblyName) != 0; + } + + return string.CompareOrdinal(topLevel.ToString(), assemblyName) != 0; } ///Array types can only be one dimensional and not System.Array, @@ -433,22 +433,22 @@ private bool IsInvalidNamespace(INamespaceSymbol @namespace, string assemblyName ///The type to checkwhere the type is ///The method or property with this type in its signature /// the type this member (method/prop) lives in - private void ReportIfInvalidType(ITypeSymbol typeSymbol, Location loc, SyntaxToken memberId, SyntaxToken typeId) + private void ReportIfInvalidType(ITypeSymbol typeSymbol, Location loc, SyntaxToken memberId, SyntaxToken typeId) { // If it's of the form int[], it has to be one dimensional - if (typeSymbol.TypeKind == TypeKind.Array) + if (typeSymbol.TypeKind == TypeKind.Array) { IArrayTypeSymbol arrTypeSym = (IArrayTypeSymbol)typeSymbol; // [,,]? - if (arrTypeSym.Rank > 1) - { + if (arrTypeSym.Rank > 1) + { Report(WinRTRules.MultiDimensionalArrayRule, loc, memberId, typeId); return; - } - // [][]? - if (arrTypeSym.ElementType.TypeKind == TypeKind.Array) - { + } + // [][]? + if (arrTypeSym.ElementType.TypeKind == TypeKind.Array) + { Report(WinRTRules.JaggedArrayRule, loc, memberId, typeId); return; } @@ -456,7 +456,7 @@ private void ReportIfInvalidType(ITypeSymbol typeSymbol, Location loc, SyntaxTok // NotValidTypes is an array of types that don't exist in Windows Runtime, so can't be passed between functions in Windows Runtime foreach (var typeName in NotValidTypes) - { + { var notValidTypeSym = GetTypeByMetadataName(typeName); if (SymEq(typeSymbol.OriginalDefinition, notValidTypeSym)) { @@ -470,21 +470,21 @@ private void ReportIfInvalidType(ITypeSymbol typeSymbol, Location loc, SyntaxTok if (typeSymbol.ContainingNamespace != null && !typeSymbol.ContainingNamespace.IsGlobalNamespace) { // ContainingNamespace for Enumerable is just System, but we need System.Linq which is the ContainingSymbol - qualifiedName += typeSymbol.ContainingSymbol + "."; + qualifiedName += typeSymbol.ContainingSymbol + "."; } // instead of TypeName, TypeName`1 qualifiedName += typeSymbol.MetadataName; // GetTypeByMetadataName fails on "System.Linq.Enumerable" & "System.Collections.ObjectModel.ReadOnlyDictionary`2" // Would be fixed by issue #678 on the dotnet/roslyn-sdk repo - foreach (var notValidType in WIPNotValidTypes) + foreach (var notValidType in WIPNotValidTypes) { if (qualifiedName == notValidType) - { + { Report(WinRTRules.UnsupportedTypeRule, loc, memberId, notValidType, SuggestType(notValidType)); return; } } - } + } } } diff --git a/src/Authoring/WinRT.SourceGenerator/Generator.cs b/src/Authoring/WinRT.SourceGenerator/Generator.cs index 303051597..41fadf47b 100644 --- a/src/Authoring/WinRT.SourceGenerator/Generator.cs +++ b/src/Authoring/WinRT.SourceGenerator/Generator.cs @@ -26,7 +26,7 @@ public ComponentGenerator(GeneratorExecutionContext context) { this.context = context; Logger = new Logger(context); - mapper = new(context.AnalyzerConfigOptions.GlobalOptions.GetUiXamlMode()); + mapper = new(context.AnalyzerConfigOptions.GlobalOptions.GetUIXamlProjectionsMode()); // TODO-WuxMux: output a module initializer that validates the MUX/WUX projection mode to ensure that things don't get out of sync. } diff --git a/src/Authoring/WinRT.SourceGenerator/TypeMapper.cs b/src/Authoring/WinRT.SourceGenerator/TypeMapper.cs index 722509cc9..bfec7684a 100644 --- a/src/Authoring/WinRT.SourceGenerator/TypeMapper.cs +++ b/src/Authoring/WinRT.SourceGenerator/TypeMapper.cs @@ -22,10 +22,10 @@ private static (string, string, string, bool, bool) GetSystemTypeCustomMapping(I ("Windows.UI.Xaml.Interop", "TypeName", "Windows.Foundation.UniversalApiContract", false, true); } - public TypeMapper(UiXamlMode xamlMode) + public TypeMapper(UIXamlProjectionsMode xamlMode) { // This should be in sync with the reverse mapping from WinRT.Runtime/Projections.cs and cswinrt/helpers.h. - if (xamlMode == UiXamlMode.WindowsUIXaml) + if (xamlMode == UIXamlProjectionsMode.WindowsUIXaml) { typeMapping = new(StringComparer.Ordinal) { diff --git a/src/Authoring/WinRT.SourceGenerator/UiXamlMode.cs b/src/Authoring/WinRT.SourceGenerator/UIXamlProjectionsMode.cs similarity index 55% rename from src/Authoring/WinRT.SourceGenerator/UiXamlMode.cs rename to src/Authoring/WinRT.SourceGenerator/UIXamlProjectionsMode.cs index dd04f5573..1bf4cc329 100644 --- a/src/Authoring/WinRT.SourceGenerator/UiXamlMode.cs +++ b/src/Authoring/WinRT.SourceGenerator/UIXamlProjectionsMode.cs @@ -5,7 +5,7 @@ namespace Generator { - internal enum UiXamlMode + internal enum UIXamlProjectionsMode { MicrosoftUIXaml, WindowsUIXaml, @@ -13,14 +13,14 @@ internal enum UiXamlMode internal static class OptionsHelper { - public static UiXamlMode GetUiXamlMode(this AnalyzerConfigOptions options) + public static UIXamlProjectionsMode GetUIXamlProjectionsMode(this AnalyzerConfigOptions options) { - if (options.TryGetValue("build_property.CsWinRTUIXamlProjections", out var value) && Enum.TryParse(value, out UiXamlMode mode)) + if (options.TryGetValue("build_property.CsWinRTUIXamlProjections", out var value) && Enum.TryParse(value, out UIXamlProjectionsMode mode)) { return mode; } - return UiXamlMode.MicrosoftUIXaml; + return UIXamlProjectionsMode.MicrosoftUIXaml; } } } From 9bb00c9a034c768670ee02470dc5ad0c9b042939 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Tue, 23 Jan 2024 13:42:52 -0800 Subject: [PATCH 16/46] PR feedback --- src/WinRT.Runtime/Projections/INotifyCollectionChanged.net5.cs | 1 - src/WinRT.Runtime/Projections/INotifyPropertyChanged.net5.cs | 3 --- 2 files changed, 4 deletions(-) diff --git a/src/WinRT.Runtime/Projections/INotifyCollectionChanged.net5.cs b/src/WinRT.Runtime/Projections/INotifyCollectionChanged.net5.cs index becd96930..19b71d297 100644 --- a/src/WinRT.Runtime/Projections/INotifyCollectionChanged.net5.cs +++ b/src/WinRT.Runtime/Projections/INotifyCollectionChanged.net5.cs @@ -3,7 +3,6 @@ using System; using System.ComponentModel; -using System.Reflection; using System.Runtime.InteropServices; using WinRT; using WinRT.Interop; diff --git a/src/WinRT.Runtime/Projections/INotifyPropertyChanged.net5.cs b/src/WinRT.Runtime/Projections/INotifyPropertyChanged.net5.cs index 2cde26bb3..ecff37455 100644 --- a/src/WinRT.Runtime/Projections/INotifyPropertyChanged.net5.cs +++ b/src/WinRT.Runtime/Projections/INotifyPropertyChanged.net5.cs @@ -2,7 +2,6 @@ // Licensed under the MIT License. using System; -using System.Reflection; using System.Runtime.InteropServices; using WinRT; using WinRT.Interop; @@ -36,7 +35,6 @@ internal unsafe interface INotifyPropertyChanged : global::System.ComponentModel [WuxMuxProjectedType(wuxIID: "CF75D69C-F2F4-486B-B302-BB4C09BAEBFA", muxIID: "90B17601-B065-586E-83D9-9ADC3A695284")] public struct Vftbl { - internal IInspectable.Vftbl IInspectableVftbl; private delegate* unmanaged _add_PropertyChanged_0; @@ -77,7 +75,6 @@ private static unsafe int Do_Abi_add_PropertyChanged_0(IntPtr thisPtr, IntPtr ha *token = default; try { - global::System.Diagnostics.Debugger.Launch(); var __this = global::WinRT.ComWrappersSupport.FindObject(thisPtr); var __handler = global::ABI.System.ComponentModel.PropertyChangedEventHandler.FromAbi(handler); *token = _PropertyChanged_TokenTables.GetOrCreateValue(__this).AddEventHandler(__handler); From ca2abfae441e1dda0d054ddb0636bcedfe15db23 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Mon, 29 Jan 2024 12:09:57 -0800 Subject: [PATCH 17/46] Revert binding changes (the types have the same identity in Wux and Mux and it was causing failures in AOT scenarios to have them split) --- src/WinRT.Runtime/Projections.cs | 4 +- .../Projections/Bindable.net5.cs | 2166 +++++++++-------- ...ndard2.0.cs => Bindable.netstandard2.0.cs} | 0 .../Projections/IEnumerable.net5.cs | 7 +- .../Microsoft.UI.Xaml.Bindable.net5.cs | 367 --- .../Windows.UI.Xaml.Bindable.net5.cs | 367 --- 6 files changed, 1131 insertions(+), 1780 deletions(-) rename src/WinRT.Runtime/Projections/{Microsoft.UI.Xaml.Bindable.netstandard2.0.cs => Bindable.netstandard2.0.cs} (100%) delete mode 100644 src/WinRT.Runtime/Projections/Microsoft.UI.Xaml.Bindable.net5.cs delete mode 100644 src/WinRT.Runtime/Projections/Windows.UI.Xaml.Bindable.net5.cs diff --git a/src/WinRT.Runtime/Projections.cs b/src/WinRT.Runtime/Projections.cs index ec4f0b1a5..592d17a6e 100644 --- a/src/WinRT.Runtime/Projections.cs +++ b/src/WinRT.Runtime/Projections.cs @@ -80,7 +80,6 @@ static Projections() RegisterCustomAbiTypeMappingNoLock(typeof(NotifyCollectionChangedAction), typeof(ABI.System.Collections.Specialized.NotifyCollectionChangedAction), "Microsoft.UI.Xaml.Interop.NotifyCollectionChangedAction"); RegisterCustomAbiTypeMappingNoLock(typeof(NotifyCollectionChangedEventArgs), typeof(ABI.System.Collections.Specialized.NotifyCollectionChangedEventArgs), "Microsoft.UI.Xaml.Interop.NotifyCollectionChangedEventArgs", isRuntimeClass: true); RegisterCustomAbiTypeMappingNoLock(typeof(NotifyCollectionChangedEventHandler), typeof(ABI.System.Collections.Specialized.NotifyCollectionChangedEventHandler), "Microsoft.UI.Xaml.Interop.NotifyCollectionChangedEventHandler"); - CustomTypeToHelperTypeMappings.Add(typeof(Microsoft.UI.Xaml.Interop.IBindableVector), typeof(ABI.System.Collections.IList)); } #if NET5_0_OR_GREATER else @@ -95,9 +94,10 @@ static Projections() RegisterCustomAbiTypeMappingNoLock(typeof(NotifyCollectionChangedAction), typeof(ABI.System.Collections.Specialized.NotifyCollectionChangedAction), "Windows.UI.Xaml.Interop.NotifyCollectionChangedAction"); RegisterCustomAbiTypeMappingNoLock(typeof(NotifyCollectionChangedEventArgs), typeof(ABI.System.Collections.Specialized.NotifyCollectionChangedEventArgs), "Windows.UI.Xaml.Interop.NotifyCollectionChangedEventArgs", isRuntimeClass: true); RegisterCustomAbiTypeMappingNoLock(typeof(NotifyCollectionChangedEventHandler), typeof(ABI.System.Collections.Specialized.NotifyCollectionChangedEventHandler), "Windows.UI.Xaml.Interop.NotifyCollectionChangedEventHandler"); - CustomTypeToHelperTypeMappings.Add(typeof(Windows.UI.Xaml.Interop.IBindableVector), typeof(ABI.System.Collections.IList)); } #endif + // The IBindable* types have the same IID on both MUX and WUX, so we can use the same type in both scenarios. + CustomTypeToHelperTypeMappings.Add(typeof(Microsoft.UI.Xaml.Interop.IBindableVector), typeof(ABI.System.Collections.IList)); RegisterCustomAbiTypeMappingNoLock(typeof(EventHandler<>), typeof(ABI.System.EventHandler<>), "Windows.Foundation.EventHandler`1"); diff --git a/src/WinRT.Runtime/Projections/Bindable.net5.cs b/src/WinRT.Runtime/Projections/Bindable.net5.cs index 47fb56870..721c00255 100644 --- a/src/WinRT.Runtime/Projections/Bindable.net5.cs +++ b/src/WinRT.Runtime/Projections/Bindable.net5.cs @@ -1,162 +1,101 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -using System; -using System.Collections; -using System.Collections.Generic; +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +using System; +using System.Collections; +using System.Collections.Generic; using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using WinRT; +using System.Runtime.InteropServices; +using WinRT; using WinRT.Interop; -#pragma warning disable 0169 // warning CS0169: The field '...' is never used -#pragma warning disable 0649 // warning CS0169: Field '...' is never assigned to - -namespace ABI.System.Collections -{ - using WUX = global::Windows.UI.Xaml.Interop; - using MUX = global::Microsoft.UI.Xaml.Interop; - using global::System; - using global::System.Runtime.CompilerServices; - using global::System.Diagnostics.CodeAnalysis; - -#if EMBED - internal -#else - public -#endif - static class IEnumerableMethods +#pragma warning disable 0169 // warning CS0169: The field '...' is never used +#pragma warning disable 0649 // warning CS0169: Field '...' is never assigned to + +namespace Microsoft.UI.Xaml.Interop +{ + [global::WinRT.WindowsRuntimeType] + [Guid("036D2C08-DF29-41AF-8AA2-D774BE62BA6F")] + [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Microsoft.UI.Xaml.Interop.IBindableIterable))] + internal interface IBindableIterable + { + IBindableIterator First(); + } + [global::WinRT.WindowsRuntimeType] + [Guid("6A1D6C07-076D-49F2-8314-F52C9C9A8331")] + [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Microsoft.UI.Xaml.Interop.IBindableIterator))] + internal interface IBindableIterator + { + bool MoveNext(); + // GetMany is not implemented by IBindableIterator, but it is here + // for compat purposes with WinUI where there are scenarios they do + // reinterpret_cast from IBindableIterator to IIterable. It is + // the last function in the vftable and shouldn't be called by anyone. + // If called, it will return NotImplementedException. + uint GetMany(ref object[] items); + object Current { get; } + bool HasCurrent { get; } + } + [global::WinRT.WindowsRuntimeType] + [Guid("393DE7DE-6FD0-4C0D-BB71-47244A113E93")] + internal interface IBindableVector : IEnumerable + { + object GetAt(uint index); + IBindableVectorView GetView(); + bool IndexOf(object value, out uint index); + void SetAt(uint index, object value); + void InsertAt(uint index, object value); + void RemoveAt(uint index); + void Append(object value); + void RemoveAtEnd(); + void Clear(); + uint Size { get; } + } + [global::WinRT.WindowsRuntimeType] + [Guid("346DD6E7-976E-4BC3-815D-ECE243BC0F33")] + [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Microsoft.UI.Xaml.Interop.IBindableVectorView))] + internal interface IBindableVectorView : IEnumerable + { + object GetAt(uint index); + bool IndexOf(object value, out uint index); + uint Size { get; } + } +} + +namespace ABI.Microsoft.UI.Xaml.Interop +{ + [DynamicInterfaceCastableImplementation] + [Guid("036D2C08-DF29-41AF-8AA2-D774BE62BA6F")] + internal unsafe interface IBindableIterable : global::Microsoft.UI.Xaml.Interop.IBindableIterable, ABI.System.Collections.IEnumerable + { + + } + + [DynamicInterfaceCastableImplementation] + [Guid("6A1D6C07-076D-49F2-8314-F52C9C9A8331")] + internal unsafe interface IBindableIterator : global::Microsoft.UI.Xaml.Interop.IBindableIterator { - public static global::System.Guid IID { get; } = new Guid(new global::System.ReadOnlySpan(new byte[] { 0x08, 0x2C, 0x6D, 0x03, 0x29, 0xDF, 0xAF, 0x41, 0x8A, 0xA2, 0xD7, 0x74, 0xBE, 0x62, 0xBA, 0x6F })); - - public static IntPtr AbiToProjectionVftablePtr => IEnumerable.AbiToProjectionVftablePtr; - } - - [DynamicInterfaceCastableImplementation] - [Guid("036D2C08-DF29-41AF-8AA2-D774BE62BA6F")] - internal unsafe interface IEnumerable : global::System.Collections.IEnumerable, WUX.IBindableIterable, MUX.IBindableIterable - { - public static string GetGuidSignature() => GuidGenerator.GetSignature(typeof(IEnumerable)); - - public sealed class AdaptiveFromAbiHelper : global::System.Collections.IEnumerable + public static readonly IntPtr AbiToProjectionVftablePtr; + static IBindableIterator() { - private readonly Func _enumerator; - private readonly IWinRTObject _winRTObject; - - [DynamicDependency(DynamicallyAccessedMemberTypes.PublicMethods, typeof(IEnumerable<>))] - [SuppressMessage("Trimming", "IL2070:'this' argument does not satisfy 'DynamicallyAccessedMembersAttribute' in call to target method. The parameter of method does not have matching annotations.", Justification = "We explicitly preserve the type we're looking for with the DynamicDependency attribute.")] - [SuppressMessage("Trimming", "IL2075:'this' argument does not satisfy 'DynamicallyAccessedMembersAttribute' in call to target method. The return value of the source method does not have matching annotations.", Justification = "We can't annotate this case (GetMethod on a type returned from GetInterface), so we use DynamicDependency to keep alive the one type we care about's public methods.")] - public AdaptiveFromAbiHelper( - Type runtimeType, IWinRTObject winRTObject) - : this(winRTObject) - { - Type enumGenericType = (runtimeType.IsGenericType && runtimeType.GetGenericTypeDefinition() == typeof(IEnumerable<>)) ? - runtimeType : runtimeType.GetInterface("System.Collections.Generic.IEnumerable`1"); - if(enumGenericType != null) - { - var getEnumerator = enumGenericType.GetMethod("GetEnumerator"); - _enumerator = (IWinRTObject obj) => (IEnumerator)getEnumerator.Invoke(obj, null); - } - } - - public AdaptiveFromAbiHelper(IWinRTObject winRTObject) - { - _winRTObject = winRTObject; - if (winRTObject is WUX.IBindableIterable) - { - _enumerator = (IWinRTObject obj) => new Generic.FromAbiEnumerator(new NonGenericToGenericWuxIterator(((WUX.IBindableIterable)obj).First())); - } - else if (winRTObject is MUX.IBindableIterable) - { - _enumerator = (IWinRTObject obj) => new Generic.FromAbiEnumerator(new NonGenericToGenericMuxIterator(((MUX.IBindableIterable)obj).First())); - } - } - - public IEnumerator GetEnumerator() => _enumerator(_winRTObject); - - private sealed class NonGenericToGenericWuxIterator : global::Windows.Foundation.Collections.IIterator - { - private readonly WUX.IBindableIterator iterator; - - public NonGenericToGenericWuxIterator(WUX.IBindableIterator iterator) => this.iterator = iterator; - - public object _Current => iterator.Current; - public bool HasCurrent => iterator.HasCurrent; - public bool _MoveNext() { return iterator.MoveNext(); } - public uint GetMany(ref object[] items) => throw new NotSupportedException(); - } - - private sealed class NonGenericToGenericMuxIterator : global::Windows.Foundation.Collections.IIterator - { - private readonly MUX.IBindableIterator iterator; - - public NonGenericToGenericMuxIterator(MUX.IBindableIterator iterator) => this.iterator = iterator; - - public object _Current => iterator.Current; - public bool HasCurrent => iterator.HasCurrent; - public bool _MoveNext() { return iterator.MoveNext(); } - public uint GetMany(ref object[] items) => throw new NotSupportedException(); - } + AbiToProjectionVftablePtr = ComWrappersSupport.AllocateVtableMemory(typeof(IBindableIterator), sizeof(IInspectable.Vftbl) + sizeof(IntPtr) * 4); + *(IInspectable.Vftbl*)AbiToProjectionVftablePtr = IInspectable.Vftbl.AbiToProjectionVftable; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[6] = &Do_Abi_get_Current_0; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[7] = &Do_Abi_get_HasCurrent_1; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[8] = &Do_Abi_MoveNext_2; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[9] = &Do_Abi_GetMany_3; } - private sealed class ToWuxAbiHelper : WUX.IBindableIterable - { - private readonly IEnumerable m_enumerable; - - internal ToWuxAbiHelper(IEnumerable enumerable) => m_enumerable = enumerable; - - WUX.IBindableIterator WUX.IBindableIterable.First() => MakeBindableIterator(m_enumerable.GetEnumerator()); - - internal static WUX.IBindableIterator MakeBindableIterator(IEnumerator enumerator) => - new Generic.IEnumerator.ToAbiHelper(new NonGenericToGenericEnumerator(enumerator)); - - private sealed class NonGenericToGenericEnumerator : IEnumerator - { - private readonly IEnumerator enumerator; - - public NonGenericToGenericEnumerator(IEnumerator enumerator) => this.enumerator = enumerator; - - public object Current => enumerator.Current; - public bool MoveNext() { return enumerator.MoveNext(); } - public void Reset() { enumerator.Reset(); } - public void Dispose() { } - } - } - - private sealed class ToMuxAbiHelper(IEnumerable enumerable) : MUX.IBindableIterable - { - MUX.IBindableIterator MUX.IBindableIterable.First() => MakeBindableIterator(enumerable.GetEnumerator()); - - internal static MUX.IBindableIterator MakeBindableIterator(IEnumerator enumerator) => - new Generic.IEnumerator.ToAbiHelper(new NonGenericToGenericEnumerator(enumerator)); - - private sealed class NonGenericToGenericEnumerator(IEnumerator enumerator) : IEnumerator - { - public object Current => enumerator.Current; - public bool MoveNext() { return enumerator.MoveNext(); } - public void Reset() { enumerator.Reset(); } - public void Dispose() { } - } - } - - public static readonly IntPtr AbiToProjectionVftablePtr; - static IEnumerable() - { - AbiToProjectionVftablePtr = ComWrappersSupport.AllocateVtableMemory(typeof(IEnumerable), sizeof(IInspectable.Vftbl) + sizeof(IntPtr) * 1); - *(IInspectable.Vftbl*)AbiToProjectionVftablePtr = IInspectable.Vftbl.AbiToProjectionVftable; - ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[6] = FeatureSwitches.IsWuxMode ? &Do_Wux_Abi_First_0 : &Do_Mux_Abi_First_0; - } - - [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] - private static unsafe int Do_Wux_Abi_First_0(IntPtr thisPtr, IntPtr* result) + [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] + private static unsafe int Do_Abi_MoveNext_2(IntPtr thisPtr, byte* result) { + bool __result = default; *result = default; try { - var __this = global::WinRT.ComWrappersSupport.FindObject(thisPtr); - var iterator = ToWuxAbiHelper.MakeBindableIterator(__this.GetEnumerator()); - *result = MarshalInterface.FromManaged(iterator); + __result = global::WinRT.ComWrappersSupport.FindObject(thisPtr).MoveNext(); + *result = (byte)(__result ? 1 : 0); } catch (Exception __exception__) { @@ -166,620 +105,931 @@ private static unsafe int Do_Wux_Abi_First_0(IntPtr thisPtr, IntPtr* result) return 0; } - [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] - private static unsafe int Do_Mux_Abi_First_0(IntPtr thisPtr, IntPtr* result) + [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] + private static unsafe int Do_Abi_GetMany_3(IntPtr thisPtr, int __itemsSize, IntPtr items, uint* result) { *result = default; + try { - var __this = global::WinRT.ComWrappersSupport.FindObject(thisPtr); - var iterator = ToMuxAbiHelper.MakeBindableIterator(__this.GetEnumerator()); - *result = MarshalInterface.FromManaged(iterator); + // Should never be called. + throw new NotImplementedException(); } catch (Exception __exception__) { global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); } - return 0; - } - - internal static ObjectReference ObjRefFromAbi(IntPtr thisPtr) - { - if (thisPtr == IntPtr.Zero) - { - return null; - } - return ObjectReference.FromAbi(thisPtr); } - private static AdaptiveFromAbiHelper _AbiHelper(IWinRTObject _this) + [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] + private static unsafe int Do_Abi_get_Current_0(IntPtr thisPtr, IntPtr* value) { - return (AdaptiveFromAbiHelper)_this.GetOrCreateTypeHelperData(typeof(global::System.Collections.IEnumerable).TypeHandle, - () => new AdaptiveFromAbiHelper(_this)); - } - - unsafe WUX.IBindableIterator WUX.IBindableIterable.First() - { - var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IEnumerable).TypeHandle); - var ThisPtr = _obj.ThisPtr; - IntPtr __retval = default; + object __value = default; + *value = default; try { - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[6](ThisPtr, &__retval)); - return MarshalInterface.FromAbi(__retval); + __value = global::WinRT.ComWrappersSupport.FindObject(thisPtr).Current; + *value = MarshalInspectable.FromManaged(__value); } - finally + catch (Exception __exception__) { - MarshalInterface.DisposeAbi(__retval); + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); } + return 0; } - unsafe MUX.IBindableIterator MUX.IBindableIterable.First() + [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] + private static unsafe int Do_Abi_get_HasCurrent_1(IntPtr thisPtr, byte* value) { - var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IEnumerable).TypeHandle); - var ThisPtr = _obj.ThisPtr; - IntPtr __retval = default; + bool __value = default; + *value = default; try { - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[6](ThisPtr, &__retval)); - return MarshalInterface.FromAbi(__retval); + __value = global::WinRT.ComWrappersSupport.FindObject(thisPtr).HasCurrent; + *value = (byte)(__value ? 1 : 0); } - finally + catch (Exception __exception__) { - MarshalInterface.DisposeAbi(__retval); + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); } - } - - IEnumerator global::System.Collections.IEnumerable.GetEnumerator() - { - return _AbiHelper((IWinRTObject)this).GetEnumerator(); - } - } - - [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] -#if EMBED - internal -#else - public -#endif - static class IEnumerable_Delegates - { - public unsafe delegate int First_0(IntPtr thisPtr, IntPtr* result); - } - -#if EMBED - internal -#else - public -#endif - static class IListMethods - { - public static Guid IID { get; } = new Guid(new global::System.ReadOnlySpan(new byte[] { 0xDE, 0xE7, 0x3D, 0x39, 0xD0, 0x6F, 0x0D, 0x4C, 0xBB, 0x71, 0x47, 0x24, 0x4A, 0x11, 0x3E, 0x93 })); - - public static IntPtr AbiToProjectionVftablePtr => IList.AbiToProjectionVftablePtr; - } - - [DynamicInterfaceCastableImplementation] - [Guid("393DE7DE-6FD0-4C0D-BB71-47244A113E93")] - internal unsafe interface IList : global::System.Collections.IList, WUX.IBindableVector, MUX.IBindableVector + return 0; + } + + internal static ObjectReference FromAbi(IntPtr thisPtr) => ObjectReference.FromAbi(thisPtr); + + unsafe bool global::Microsoft.UI.Xaml.Interop.IBindableIterator.MoveNext() + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::Microsoft.UI.Xaml.Interop.IBindableIterator).TypeHandle); + var ThisPtr = _obj.ThisPtr; + byte __retval = default; + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[8](ThisPtr, &__retval)); + return __retval != 0; + } + + unsafe uint global::Microsoft.UI.Xaml.Interop.IBindableIterator.GetMany(ref object[] items) + { + // Should never be called. + throw new NotImplementedException(); + } + + unsafe object global::Microsoft.UI.Xaml.Interop.IBindableIterator.Current + { + get + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::Microsoft.UI.Xaml.Interop.IBindableIterator).TypeHandle); + var ThisPtr = _obj.ThisPtr; + IntPtr __retval = default; + try + { + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[6](ThisPtr, &__retval)); + return MarshalInspectable.FromAbi(__retval); + } + finally + { + MarshalInspectable.DisposeAbi(__retval); + } + } + } + + unsafe bool global::Microsoft.UI.Xaml.Interop.IBindableIterator.HasCurrent + { + get + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::Microsoft.UI.Xaml.Interop.IBindableIterator).TypeHandle); + var ThisPtr = _obj.ThisPtr; + byte __retval = default; + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[7](ThisPtr, &__retval)); + return __retval != 0; + } + } + + } + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + internal static class IBindableIterator_Delegates + { + public unsafe delegate int get_Current_0(IntPtr thisPtr, IntPtr* result); + public unsafe delegate int get_HasCurrent_1(IntPtr thisPtr, byte* result); + public unsafe delegate int MoveNext_2(IntPtr thisPtr, byte* result); + public unsafe delegate int GetMany_3(IntPtr thisPtr, int itemSize, IntPtr items, uint* result); + } + + [DynamicInterfaceCastableImplementation] + [Guid("346DD6E7-976E-4BC3-815D-ECE243BC0F33")] + internal unsafe interface IBindableVectorView : global::Microsoft.UI.Xaml.Interop.IBindableVectorView { - public static string GetGuidSignature() => GuidGenerator.GetSignature(typeof(IList)); - - public interface IBindableVectorAdapter - { - object GetAt(uint index); - IBindableVectorViewAdapter GetView(); - bool IndexOf(object value, out uint index); - void SetAt(uint index, object value); - void InsertAt(uint index, object value); - void RemoveAt(uint index); - void Append(object value); - void RemoveAtEnd(); - void Clear(); - uint Size { get; } - } - - public interface IBindableVectorViewAdapter - { - object GetAt(uint index); - bool IndexOf(object value, out uint index); - uint Size { get; } - } - - private sealed class WuxBindableVectorAdapter(WUX.IBindableVector vector) : IBindableVectorAdapter - { - public object GetAt(uint index) => vector.GetAt(index); - public IBindableVectorViewAdapter GetView() => new WuxBindableVectorViewAdapter(vector.GetView()); - public bool IndexOf(object value, out uint index) => vector.IndexOf(value, out index); - public void SetAt(uint index, object value) => vector.SetAt(index, value); - public void InsertAt(uint index, object value) => vector.InsertAt(index, value); - public void RemoveAt(uint index) => vector.RemoveAt(index); - public void Append(object value) => vector.Append(value); - public void RemoveAtEnd() => vector.RemoveAtEnd(); - public void Clear() => vector.Clear(); - public uint Size => vector.Size; - - private sealed class WuxBindableVectorViewAdapter(WUX.IBindableVectorView vectorView) : IBindableVectorViewAdapter - { - public object GetAt(uint index) => vectorView.GetAt(index); - public bool IndexOf(object value, out uint index) => vectorView.IndexOf(value, out index); - public uint Size => vectorView.Size; - } - } + public static readonly IntPtr AbiToProjectionVftablePtr; - private sealed class MuxBindableVectorAdapter(MUX.IBindableVector vector) : IBindableVectorAdapter + internal static readonly Guid IID = new(new ReadOnlySpan(new byte[] { 0xE7, 0xD6, 0x6D, 0x34, 0x6E, 0x97, 0xC3, 0x4B, 0x81, 0x5D, 0xEC, 0xE2, 0x43, 0xBC, 0x0F, 0x33 })); + + static IBindableVectorView() { - public object GetAt(uint index) => vector.GetAt(index); - public IBindableVectorViewAdapter GetView() => new WuxBindableVectorViewAdapter(vector.GetView()); - public bool IndexOf(object value, out uint index) => vector.IndexOf(value, out index); - public void SetAt(uint index, object value) => vector.SetAt(index, value); - public void InsertAt(uint index, object value) => vector.InsertAt(index, value); - public void RemoveAt(uint index) => vector.RemoveAt(index); - public void Append(object value) => vector.Append(value); - public void RemoveAtEnd() => vector.RemoveAtEnd(); - public void Clear() => vector.Clear(); - public uint Size => vector.Size; - - private sealed class WuxBindableVectorViewAdapter(MUX.IBindableVectorView vectorView) : IBindableVectorViewAdapter - { - public object GetAt(uint index) => vectorView.GetAt(index); - public bool IndexOf(object value, out uint index) => vectorView.IndexOf(value, out index); - public uint Size => vectorView.Size; - } + AbiToProjectionVftablePtr = ComWrappersSupport.AllocateVtableMemory(typeof(IBindableVectorView), sizeof(IInspectable.Vftbl) + sizeof(IntPtr) * 3); + *(IInspectable.Vftbl*)AbiToProjectionVftablePtr = IInspectable.Vftbl.AbiToProjectionVftable; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[6] = &Do_Abi_GetAt_0; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[7] = &Do_Abi_get_Size_1; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[8] = &Do_Abi_IndexOf_2; } - public sealed class FromAbiHelper : global::System.Collections.IList + [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] + private static unsafe int Do_Abi_GetAt_0(IntPtr thisPtr, uint index, IntPtr* result) { - private readonly IBindableVectorAdapter _vector; - - public FromAbiHelper(IBindableVectorAdapter vector) - { - _vector = vector; - } - - public bool IsSynchronized => false; - - public object SyncRoot { get => this; } - - public int Count - { - get - { - uint size = _vector.Size; - if (((uint)int.MaxValue) < size) - { - throw new InvalidOperationException(WinRTRuntimeErrorStrings.InvalidOperation_CollectionBackingListTooLarge); - } - - return (int)size; - } - } - - public void CopyTo(Array array, int arrayIndex) - { - if (array == null) - throw new ArgumentNullException(nameof(array)); - - // ICollection expects the destination array to be single-dimensional. - if (array.Rank != 1) - throw new ArgumentException(WinRTRuntimeErrorStrings.Arg_RankMultiDimNotSupported); - - int destLB = array.GetLowerBound(0); - int srcLen = Count; - int destLen = array.GetLength(0); - - if (arrayIndex < destLB) - throw new ArgumentOutOfRangeException(nameof(arrayIndex)); - - // Does the dimension in question have sufficient space to copy the expected number of entries? - // We perform this check before valid index check to ensure the exception message is in sync with - // the following snippet that uses regular framework code: - // - // ArrayList list = new ArrayList(); - // list.Add(1); - // Array items = Array.CreateInstance(typeof(object), new int[] { 1 }, new int[] { -1 }); - // list.CopyTo(items, 0); - - if (srcLen > (destLen - (arrayIndex - destLB))) - throw new ArgumentException(WinRTRuntimeErrorStrings.Argument_InsufficientSpaceToCopyCollection); - - if (arrayIndex - destLB > destLen) - throw new ArgumentException(WinRTRuntimeErrorStrings.Argument_IndexOutOfArrayBounds); - - // We need to verify the index as we; - for (uint i = 0; i < srcLen; i++) - { - array.SetValue(_vector.GetAt(i), i + arrayIndex); - } - } - - public object this[int index] - { - get => Indexer_Get(index); - set => Indexer_Set(index, value); - } - - internal object Indexer_Get(int index) - { - if (index < 0) - throw new ArgumentOutOfRangeException(nameof(index)); - - return GetAt(_vector, (uint)index); - } - - internal void Indexer_Set(int index, object value) - { - if (index < 0) - throw new ArgumentOutOfRangeException(nameof(index)); - - SetAt(_vector, (uint)index, value); - } - - public int Add(object value) - { - _vector.Append(value); - - uint size = _vector.Size; - if (((uint)int.MaxValue) < size) - { - throw new InvalidOperationException(WinRTRuntimeErrorStrings.InvalidOperation_CollectionBackingListTooLarge); - } - - return (int)(size - 1); - } - - public bool Contains(object item) - { - return _vector.IndexOf(item, out _); - } - - public void Clear() - { - _vector.Clear(); - } - - public bool IsFixedSize { get => false; } - - public bool IsReadOnly { get => false; } - - public int IndexOf(object item) - { - uint index; - bool exists = _vector.IndexOf(item, out index); - - if (!exists) - return -1; - - if (((uint)int.MaxValue) < index) - { - throw new InvalidOperationException(WinRTRuntimeErrorStrings.InvalidOperation_CollectionBackingListTooLarge); - } - - return (int)index; - } - - public void Insert(int index, object item) - { - if (index < 0) - throw new ArgumentOutOfRangeException(nameof(index)); - - InsertAtHelper(_vector, (uint)index, item); - } - - public void Remove(object item) - { - uint index; - bool exists = _vector.IndexOf(item, out index); - - if (exists) - { - if (((uint)int.MaxValue) < index) - { - throw new InvalidOperationException(WinRTRuntimeErrorStrings.InvalidOperation_CollectionBackingListTooLarge); - } - - RemoveAtHelper(_vector, index); - } - } - - public void RemoveAt(int index) - { - if (index < 0) - throw new ArgumentOutOfRangeException(nameof(index)); - - RemoveAtHelper(_vector, (uint)index); - } - - private static object GetAt(IBindableVectorAdapter _this, uint index) - { - try - { - return _this.GetAt(index); - - // We delegate bounds checking to the underlying collection and if it detected a fault, - // we translate it to the right exception: - } - catch (Exception ex) - { - if (ExceptionHelpers.E_BOUNDS == ex.HResult) - throw new ArgumentOutOfRangeException(nameof(index)); - throw; - } - } - - private static void SetAt(IBindableVectorAdapter _this, uint index, object value) - { - try - { - _this.SetAt(index, value); - - // We delegate bounds checking to the underlying collection and if it detected a fault, - // we translate it to the right exception: - } - catch (Exception ex) - { - if (ExceptionHelpers.E_BOUNDS == ex.HResult) - throw new ArgumentOutOfRangeException(nameof(index)); - throw; - } - } - - private static void InsertAtHelper(IBindableVectorAdapter _this, uint index, object item) - { - try - { - _this.InsertAt(index, item); - - // We delegate bounds checking to the underlying collection and if it detected a fault, - // we translate it to the right exception: - } - catch (Exception ex) - { - if (ExceptionHelpers.E_BOUNDS == ex.HResult) - throw new ArgumentOutOfRangeException(nameof(index)); - throw; - } - } + object __result = default; - private static void RemoveAtHelper(IBindableVectorAdapter _this, uint index) + try { - try - { - _this.RemoveAt(index); + __result = global::WinRT.ComWrappersSupport.FindObject(thisPtr).GetAt(index); + *result = MarshalInspectable.FromManaged(__result); - // We delegate bounds checking to the underlying collection and if it detected a fault, - // we translate it to the right exception: - } - catch (Exception ex) - { - if (ExceptionHelpers.E_BOUNDS == ex.HResult) - throw new ArgumentOutOfRangeException(nameof(index)); - throw; - } } - - public IEnumerator GetEnumerator() + catch (Exception __exception__) { - return ((IEnumerable)(IWinRTObject)_vector).GetEnumerator(); + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); } + return 0; } - public sealed class ToAbiHelper : WUX.IBindableVector, MUX.IBindableVector, IBindableVectorAdapter + [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] + private static unsafe int Do_Abi_IndexOf_2(IntPtr thisPtr, IntPtr value, uint* index, byte* returnValue) { - private global::System.Collections.IList _list; - - public ToAbiHelper(global::System.Collections.IList list) => _list = list; - - public object GetAt(uint index) - { - EnsureIndexInt32(index, _list.Count); - - try - { - return _list[(int)index]; - } - catch (ArgumentOutOfRangeException ex) - { - throw ex.GetExceptionForHR(ExceptionHelpers.E_BOUNDS, WinRTRuntimeErrorStrings.ArgumentOutOfRange_Index); - } - } - - public uint Size { get => (uint)_list.Count; } - - IBindableVectorViewAdapter IBindableVectorAdapter.GetView() - { - return new ListToBindableVectorViewAdapter(_list); - } - - WUX.IBindableVectorView WUX.IBindableVector.GetView() - { - return new ListToBindableVectorViewAdapter(_list); - } - - MUX.IBindableVectorView MUX.IBindableVector.GetView() - { - return new ListToBindableVectorViewAdapter(_list); - } - - public bool IndexOf(object value, out uint index) - { - int ind = _list.IndexOf(value); - - if (-1 == ind) - { - index = 0; - return false; - } - - index = (uint)ind; - return true; - } - - public void SetAt(uint index, object value) - { - EnsureIndexInt32(index, _list.Count); - - try - { - _list[(int)index] = value; - } - catch (ArgumentOutOfRangeException ex) - { - throw ex.GetExceptionForHR(ExceptionHelpers.E_BOUNDS, WinRTRuntimeErrorStrings.ArgumentOutOfRange_Index); - } - } - - public void InsertAt(uint index, object value) - { - // Inserting at an index one past the end of the list is equivalent to appending - // so we need to ensure that we're within (0, count + 1). - EnsureIndexInt32(index, _list.Count + 1); + bool __returnValue = default; - try - { - _list.Insert((int)index, value); - } - catch (ArgumentOutOfRangeException ex) - { - // Change error code to match what WinRT expects - ex.SetHResult(ExceptionHelpers.E_BOUNDS); - throw; - } - } + *index = default; + *returnValue = default; + uint __index = default; - public void RemoveAt(uint index) + try { - EnsureIndexInt32(index, _list.Count); + __returnValue = global::WinRT.ComWrappersSupport.FindObject(thisPtr).IndexOf(MarshalInspectable.FromAbi(value), out __index); + *index = __index; + *returnValue = (byte)(__returnValue ? 1 : 0); - try - { - _list.RemoveAt((int)index); - } - catch (ArgumentOutOfRangeException ex) - { - // Change error code to match what WinRT expects - ex.SetHResult(ExceptionHelpers.E_BOUNDS); - throw; - } } - - public void Append(object value) + catch (Exception __exception__) { - _list.Add(value); + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); } + return 0; + } - public void RemoveAtEnd() - { - if (_list.Count == 0) - { - Exception e = new InvalidOperationException(WinRTRuntimeErrorStrings.InvalidOperation_CannotRemoveLastFromEmptyCollection); - e.SetHResult(ExceptionHelpers.E_BOUNDS); - throw e; - } + [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] + private static unsafe int Do_Abi_get_Size_1(IntPtr thisPtr, uint* value) + { + uint __value = default; - uint size = (uint)_list.Count; - RemoveAt(size - 1); - } + *value = default; - public void Clear() + try { - _list.Clear(); - } + __value = global::WinRT.ComWrappersSupport.FindObject(thisPtr).Size; + *value = __value; - private static void EnsureIndexInt32(uint index, int listCapacity) + } + catch (Exception __exception__) { - // We use '<=' and not '<' becasue int.MaxValue == index would imply - // that Size > int.MaxValue: - if (((uint)int.MaxValue) <= index || index >= (uint)listCapacity) - { - Exception e = new ArgumentOutOfRangeException(nameof(index), WinRTRuntimeErrorStrings.ArgumentOutOfRange_IndexLargerThanMaxValue); - e.SetHResult(ExceptionHelpers.E_BOUNDS); - throw e; - } + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); } + return 0; + } + + internal static ObjectReference FromAbi(IntPtr thisPtr) => ObjectReference.FromAbi(thisPtr); + + private static readonly global::System.Runtime.CompilerServices.ConditionalWeakTable _helperTable = new(); + + unsafe object global::Microsoft.UI.Xaml.Interop.IBindableVectorView.GetAt(uint index) + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::Microsoft.UI.Xaml.Interop.IBindableIterator).TypeHandle); + var ThisPtr = _obj.ThisPtr; + IntPtr __retval = default; + try + { + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[6](ThisPtr, index, &__retval)); + return MarshalInspectable.FromAbi(__retval); + } + finally + { + MarshalInspectable.DisposeAbi(__retval); + } + } + + unsafe bool global::Microsoft.UI.Xaml.Interop.IBindableVectorView.IndexOf(object value, out uint index) + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::Microsoft.UI.Xaml.Interop.IBindableIterator).TypeHandle); + var ThisPtr = _obj.ThisPtr; + ObjectReferenceValue __value = default; + uint __index = default; + byte __retval = default; + try + { + __value = MarshalInspectable.CreateMarshaler2(value); + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[8]( + ThisPtr, + MarshalInspectable.GetAbi(__value), + &__index, + &__retval)); + index = __index; + return __retval != 0; + } + finally + { + MarshalInspectable.DisposeMarshaler(__value); + } + } + + unsafe uint global::Microsoft.UI.Xaml.Interop.IBindableVectorView.Size + { + get + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::Microsoft.UI.Xaml.Interop.IBindableIterator).TypeHandle); + var ThisPtr = _obj.ThisPtr; + uint __retval = default; + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[7](ThisPtr, &__retval)); + return __retval; + } + } + + IEnumerator IEnumerable.GetEnumerator() + { + return _helperTable.GetValue((IWinRTObject)this, + (enumerable) => new ABI.System.Collections.IEnumerable.FromAbiHelper((global::System.Collections.IEnumerable)(IWinRTObject)enumerable) + ).GetEnumerator(); + } + } + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + internal static class IBindableVectorView_Delegates + { + public unsafe delegate int GetAt_0(IntPtr thisPtr, uint index, IntPtr* result); + public unsafe delegate int get_Size_1(IntPtr thisPtr, uint* result); + public unsafe delegate int IndexOf_2(IntPtr thisPtr, IntPtr value, uint* index, byte* returnValue); + } +} + +namespace ABI.System.Collections +{ + using global::Microsoft.UI.Xaml.Interop; + using global::System; + using global::System.Runtime.CompilerServices; - public IEnumerator GetEnumerator() => _list.GetEnumerator(); +#if EMBED + internal +#else + public +#endif + static class IEnumerableMethods + { + public static global::System.Guid IID { get; } = new Guid(new global::System.ReadOnlySpan(new byte[] { 0x08, 0x2C, 0x6D, 0x03, 0x29, 0xDF, 0xAF, 0x41, 0x8A, 0xA2, 0xD7, 0x74, 0xBE, 0x62, 0xBA, 0x6F })); - /// A Windows Runtime IBindableVectorView implementation that wraps around a managed IList exposing - /// it to Windows runtime interop. - internal sealed class ListToBindableVectorViewAdapter : WUX.IBindableVectorView, MUX.IBindableVectorView, IBindableVectorViewAdapter - { - private readonly global::System.Collections.IList list; + public static IntPtr AbiToProjectionVftablePtr => IEnumerable.AbiToProjectionVftablePtr; + } + + [DynamicInterfaceCastableImplementation] + [Guid("036D2C08-DF29-41AF-8AA2-D774BE62BA6F")] + internal unsafe interface IEnumerable : global::System.Collections.IEnumerable, global::Microsoft.UI.Xaml.Interop.IBindableIterable + { + public static string GetGuidSignature() => GuidGenerator.GetSignature(typeof(IEnumerable)); + + public sealed class AdaptiveFromAbiHelper : FromAbiHelper, global::System.Collections.IEnumerable + { + private readonly Func _enumerator; + + public AdaptiveFromAbiHelper(Type runtimeType, IWinRTObject winRTObject) + :base(winRTObject) + { + Type enumGenericType = (runtimeType.IsGenericType && runtimeType.GetGenericTypeDefinition() == typeof(global::System.Collections.Generic.IEnumerable<>)) ? + runtimeType : runtimeType.GetInterface("System.Collections.Generic.IEnumerable`1"); + if(enumGenericType != null) + { + var getEnumerator = enumGenericType.GetMethod("GetEnumerator"); + _enumerator = (IWinRTObject obj) => (global::System.Collections.IEnumerator)getEnumerator.Invoke(obj, null); + } + } + + public override global::System.Collections.IEnumerator GetEnumerator() => _enumerator != null ? _enumerator(_winrtObject) : base.GetEnumerator(); + } + + public class FromAbiHelper : global::System.Collections.IEnumerable + { + private readonly global::System.Collections.IEnumerable _iterable; + protected readonly IWinRTObject _winrtObject; + + public FromAbiHelper(global::System.Collections.IEnumerable iterable) + { + _iterable = iterable; + } + + protected FromAbiHelper(IWinRTObject winrtObject) + { + _iterable = null; + _winrtObject = winrtObject; + } + + private IWinRTObject GetIterable() + { + return (IWinRTObject)_iterable ?? _winrtObject; + } + + public virtual global::System.Collections.IEnumerator GetEnumerator() => + new Generic.FromAbiEnumerator(new NonGenericToGenericIterator(((global::Microsoft.UI.Xaml.Interop.IBindableIterable) GetIterable()).First())); + + private sealed class NonGenericToGenericIterator : global::Windows.Foundation.Collections.IIterator + { + private readonly IBindableIterator iterator; + + public NonGenericToGenericIterator(IBindableIterator iterator) => this.iterator = iterator; + + public object _Current => iterator.Current; + public bool HasCurrent => iterator.HasCurrent; + public bool _MoveNext() { return iterator.MoveNext(); } + public uint GetMany(ref object[] items) => throw new NotSupportedException(); + } + } + + public sealed class ToAbiHelper : IBindableIterable + { + private readonly IEnumerable m_enumerable; + + internal ToAbiHelper(IEnumerable enumerable) => m_enumerable = enumerable; + + IBindableIterator IBindableIterable.First() => MakeBindableIterator(m_enumerable.GetEnumerator()); + + internal static IBindableIterator MakeBindableIterator(IEnumerator enumerator) => + new Generic.IEnumerator.ToAbiHelper(new NonGenericToGenericEnumerator(enumerator)); + + private sealed class NonGenericToGenericEnumerator : IEnumerator + { + private readonly IEnumerator enumerator; + + public NonGenericToGenericEnumerator(IEnumerator enumerator) => this.enumerator = enumerator; + + public object Current => enumerator.Current; + public bool MoveNext() { return enumerator.MoveNext(); } + public void Reset() { enumerator.Reset(); } + public void Dispose() { } + } + } - internal ListToBindableVectorViewAdapter(global::System.Collections.IList list) - { - if (list == null) - throw new ArgumentNullException(nameof(list)); - this.list = list; - } + public static readonly IntPtr AbiToProjectionVftablePtr; + static IEnumerable() + { + AbiToProjectionVftablePtr = ComWrappersSupport.AllocateVtableMemory(typeof(IEnumerable), sizeof(IInspectable.Vftbl) + sizeof(IntPtr) * 1); + *(IInspectable.Vftbl*)AbiToProjectionVftablePtr = IInspectable.Vftbl.AbiToProjectionVftable; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[6] = &Do_Abi_First_0; + } - private static void EnsureIndexInt32(uint index, int listCapacity) - { - // We use '<=' and not '<' becasue int.MaxValue == index would imply - // that Size > int.MaxValue: - if (((uint)int.MaxValue) <= index || index >= (uint)listCapacity) - { - Exception e = new ArgumentOutOfRangeException(nameof(index), WinRTRuntimeErrorStrings.ArgumentOutOfRange_IndexLargerThanMaxValue); - e.SetHResult(ExceptionHelpers.E_BOUNDS); - throw e; - } - } + [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] + private static unsafe int Do_Abi_First_0(IntPtr thisPtr, IntPtr* result) + { + *result = default; + try + { + var __this = global::WinRT.ComWrappersSupport.FindObject(thisPtr); + var iterator = ToAbiHelper.MakeBindableIterator(__this.GetEnumerator()); + *result = MarshalInterface.FromManaged(iterator); + } + catch (Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + + internal static ObjectReference ObjRefFromAbi(IntPtr thisPtr) + { + if (thisPtr == IntPtr.Zero) + { + return null; + } + return ObjectReference.FromAbi(thisPtr); + } + + private static FromAbiHelper _AbiHelper(IWinRTObject _this) + { + return (FromAbiHelper)_this.GetOrCreateTypeHelperData(typeof(global::System.Collections.IEnumerable).TypeHandle, + () => new FromAbiHelper((global::System.Collections.IEnumerable)_this)); + } + + unsafe global::Microsoft.UI.Xaml.Interop.IBindableIterator global::Microsoft.UI.Xaml.Interop.IBindableIterable.First() + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IEnumerable).TypeHandle); + var ThisPtr = _obj.ThisPtr; + IntPtr __retval = default; + try + { + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[6](ThisPtr, &__retval)); + return MarshalInterface.FromAbi(__retval); + } + finally + { + MarshalInterface.DisposeAbi(__retval); + } + } + + IEnumerator global::System.Collections.IEnumerable.GetEnumerator() + { + return _AbiHelper((IWinRTObject)this).GetEnumerator(); + } + } + + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] +#if EMBED + internal +#else + public +#endif + static class IEnumerable_Delegates + { + public unsafe delegate int First_0(IntPtr thisPtr, IntPtr* result); + } - public object GetAt(uint index) - { - EnsureIndexInt32(index, list.Count); +#if EMBED + internal +#else + public +#endif + static class IListMethods + { + public static Guid IID { get; } = new Guid(new global::System.ReadOnlySpan(new byte[] { 0xDE, 0xE7, 0x3D, 0x39, 0xD0, 0x6F, 0x0D, 0x4C, 0xBB, 0x71, 0x47, 0x24, 0x4A, 0x11, 0x3E, 0x93 })); - try - { - return list[(int)index]; - } - catch (ArgumentOutOfRangeException ex) - { - throw ex.GetExceptionForHR(ExceptionHelpers.E_BOUNDS, WinRTRuntimeErrorStrings.ArgumentOutOfRange_Index); - } - } + public static IntPtr AbiToProjectionVftablePtr => IList.AbiToProjectionVftablePtr; + } - public uint Size => (uint)list.Count; + [DynamicInterfaceCastableImplementation] + [Guid("393DE7DE-6FD0-4C0D-BB71-47244A113E93")] + internal unsafe interface IList : global::System.Collections.IList, global::Microsoft.UI.Xaml.Interop.IBindableVector + { + public static string GetGuidSignature() => GuidGenerator.GetSignature(typeof(IList)); + + public sealed class FromAbiHelper : global::System.Collections.IList + { + private readonly global::Microsoft.UI.Xaml.Interop.IBindableVector _vector; + + public FromAbiHelper(global::Microsoft.UI.Xaml.Interop.IBindableVector vector) + { + _vector = vector; + } + + public bool IsSynchronized => false; + + public object SyncRoot { get => this; } + + public int Count + { + get + { + uint size = _vector.Size; + if (((uint)int.MaxValue) < size) + { + throw new InvalidOperationException(WinRTRuntimeErrorStrings.InvalidOperation_CollectionBackingListTooLarge); + } + + return (int)size; + } + } + + public void CopyTo(Array array, int arrayIndex) + { + if (array == null) + throw new ArgumentNullException(nameof(array)); + + // ICollection expects the destination array to be single-dimensional. + if (array.Rank != 1) + throw new ArgumentException(WinRTRuntimeErrorStrings.Arg_RankMultiDimNotSupported); + + int destLB = array.GetLowerBound(0); + int srcLen = Count; + int destLen = array.GetLength(0); + + if (arrayIndex < destLB) + throw new ArgumentOutOfRangeException(nameof(arrayIndex)); + + // Does the dimension in question have sufficient space to copy the expected number of entries? + // We perform this check before valid index check to ensure the exception message is in sync with + // the following snippet that uses regular framework code: + // + // ArrayList list = new ArrayList(); + // list.Add(1); + // Array items = Array.CreateInstance(typeof(object), new int[] { 1 }, new int[] { -1 }); + // list.CopyTo(items, 0); + + if (srcLen > (destLen - (arrayIndex - destLB))) + throw new ArgumentException(WinRTRuntimeErrorStrings.Argument_InsufficientSpaceToCopyCollection); + + if (arrayIndex - destLB > destLen) + throw new ArgumentException(WinRTRuntimeErrorStrings.Argument_IndexOutOfArrayBounds); + + // We need to verify the index as we; + for (uint i = 0; i < srcLen; i++) + { + array.SetValue(_vector.GetAt(i), i + arrayIndex); + } + } + + public object this[int index] + { + get => Indexer_Get(index); + set => Indexer_Set(index, value); + } + + internal object Indexer_Get(int index) + { + if (index < 0) + throw new ArgumentOutOfRangeException(nameof(index)); + + return GetAt(_vector, (uint)index); + } + + internal void Indexer_Set(int index, object value) + { + if (index < 0) + throw new ArgumentOutOfRangeException(nameof(index)); + + SetAt(_vector, (uint)index, value); + } + + public int Add(object value) + { + _vector.Append(value); + + uint size = _vector.Size; + if (((uint)int.MaxValue) < size) + { + throw new InvalidOperationException(WinRTRuntimeErrorStrings.InvalidOperation_CollectionBackingListTooLarge); + } + + return (int)(size - 1); + } + + public bool Contains(object item) + { + return _vector.IndexOf(item, out _); + } + + public void Clear() + { + _vector.Clear(); + } + + public bool IsFixedSize { get => false; } + + public bool IsReadOnly { get => false; } + + public int IndexOf(object item) + { + uint index; + bool exists = _vector.IndexOf(item, out index); + + if (!exists) + return -1; + + if (((uint)int.MaxValue) < index) + { + throw new InvalidOperationException(WinRTRuntimeErrorStrings.InvalidOperation_CollectionBackingListTooLarge); + } + + return (int)index; + } + + public void Insert(int index, object item) + { + if (index < 0) + throw new ArgumentOutOfRangeException(nameof(index)); + + InsertAtHelper(_vector, (uint)index, item); + } + + public void Remove(object item) + { + uint index; + bool exists = _vector.IndexOf(item, out index); + + if (exists) + { + if (((uint)int.MaxValue) < index) + { + throw new InvalidOperationException(WinRTRuntimeErrorStrings.InvalidOperation_CollectionBackingListTooLarge); + } + + RemoveAtHelper(_vector, index); + } + } + + public void RemoveAt(int index) + { + if (index < 0) + throw new ArgumentOutOfRangeException(nameof(index)); + + RemoveAtHelper(_vector, (uint)index); + } + + private static object GetAt(global::Microsoft.UI.Xaml.Interop.IBindableVector _this, uint index) + { + try + { + return _this.GetAt(index); + + // We delegate bounds checking to the underlying collection and if it detected a fault, + // we translate it to the right exception: + } + catch (Exception ex) + { + if (ExceptionHelpers.E_BOUNDS == ex.HResult) + throw new ArgumentOutOfRangeException(nameof(index)); + throw; + } + } + + private static void SetAt(global::Microsoft.UI.Xaml.Interop.IBindableVector _this, uint index, object value) + { + try + { + _this.SetAt(index, value); + + // We delegate bounds checking to the underlying collection and if it detected a fault, + // we translate it to the right exception: + } + catch (Exception ex) + { + if (ExceptionHelpers.E_BOUNDS == ex.HResult) + throw new ArgumentOutOfRangeException(nameof(index)); + throw; + } + } + + private static void InsertAtHelper(global::Microsoft.UI.Xaml.Interop.IBindableVector _this, uint index, object item) + { + try + { + _this.InsertAt(index, item); + + // We delegate bounds checking to the underlying collection and if it detected a fault, + // we translate it to the right exception: + } + catch (Exception ex) + { + if (ExceptionHelpers.E_BOUNDS == ex.HResult) + throw new ArgumentOutOfRangeException(nameof(index)); + throw; + } + } + + private static void RemoveAtHelper(global::Microsoft.UI.Xaml.Interop.IBindableVector _this, uint index) + { + try + { + _this.RemoveAt(index); + + // We delegate bounds checking to the underlying collection and if it detected a fault, + // we translate it to the right exception: + } + catch (Exception ex) + { + if (ExceptionHelpers.E_BOUNDS == ex.HResult) + throw new ArgumentOutOfRangeException(nameof(index)); + throw; + } + } + + public IEnumerator GetEnumerator() + { + return ((IEnumerable)(IWinRTObject)_vector).GetEnumerator(); + } + } + + public sealed class ToAbiHelper : IBindableVector + { + private global::System.Collections.IList _list; + + public ToAbiHelper(global::System.Collections.IList list) => _list = list; + + public object GetAt(uint index) + { + EnsureIndexInt32(index, _list.Count); + + try + { + return _list[(int)index]; + } + catch (ArgumentOutOfRangeException ex) + { + throw ex.GetExceptionForHR(ExceptionHelpers.E_BOUNDS, WinRTRuntimeErrorStrings.ArgumentOutOfRange_Index); + } + } + + public uint Size { get => (uint)_list.Count; } + + IBindableVectorView IBindableVector.GetView() + { + return new ListToBindableVectorViewAdapter(_list); + } + + public bool IndexOf(object value, out uint index) + { + int ind = _list.IndexOf(value); + + if (-1 == ind) + { + index = 0; + return false; + } + + index = (uint)ind; + return true; + } + + public void SetAt(uint index, object value) + { + EnsureIndexInt32(index, _list.Count); + + try + { + _list[(int)index] = value; + } + catch (ArgumentOutOfRangeException ex) + { + throw ex.GetExceptionForHR(ExceptionHelpers.E_BOUNDS, WinRTRuntimeErrorStrings.ArgumentOutOfRange_Index); + } + } + + public void InsertAt(uint index, object value) + { + // Inserting at an index one past the end of the list is equivalent to appending + // so we need to ensure that we're within (0, count + 1). + EnsureIndexInt32(index, _list.Count + 1); + + try + { + _list.Insert((int)index, value); + } + catch (ArgumentOutOfRangeException ex) + { + // Change error code to match what WinRT expects + ex.SetHResult(ExceptionHelpers.E_BOUNDS); + throw; + } + } + + public void RemoveAt(uint index) + { + EnsureIndexInt32(index, _list.Count); + + try + { + _list.RemoveAt((int)index); + } + catch (ArgumentOutOfRangeException ex) + { + // Change error code to match what WinRT expects + ex.SetHResult(ExceptionHelpers.E_BOUNDS); + throw; + } + } + + public void Append(object value) + { + _list.Add(value); + } + + public void RemoveAtEnd() + { + if (_list.Count == 0) + { + Exception e = new InvalidOperationException(WinRTRuntimeErrorStrings.InvalidOperation_CannotRemoveLastFromEmptyCollection); + e.SetHResult(ExceptionHelpers.E_BOUNDS); + throw e; + } + + uint size = (uint)_list.Count; + RemoveAt(size - 1); + } + + public void Clear() + { + _list.Clear(); + } + + private static void EnsureIndexInt32(uint index, int listCapacity) + { + // We use '<=' and not '<' becasue int.MaxValue == index would imply + // that Size > int.MaxValue: + if (((uint)int.MaxValue) <= index || index >= (uint)listCapacity) + { + Exception e = new ArgumentOutOfRangeException(nameof(index), WinRTRuntimeErrorStrings.ArgumentOutOfRange_IndexLargerThanMaxValue); + e.SetHResult(ExceptionHelpers.E_BOUNDS); + throw e; + } + } + + public IEnumerator GetEnumerator() => _list.GetEnumerator(); - public bool IndexOf(object value, out uint index) + internal sealed class ListToBindableVectorViewAdapterTypeDetails : IWinRTExposedTypeDetails + { + public ComWrappers.ComInterfaceEntry[] GetExposedInterfaces() { - int ind = list.IndexOf(value); - - if (-1 == ind) + return new ComWrappers.ComInterfaceEntry[] { - index = 0; - return false; - } - - index = (uint)ind; - return true; + new ComWrappers.ComInterfaceEntry + { + IID = ABI.Microsoft.UI.Xaml.Interop.IBindableVectorView.IID, + Vtable = ABI.Microsoft.UI.Xaml.Interop.IBindableVectorView.AbiToProjectionVftablePtr + }, + new ComWrappers.ComInterfaceEntry + { + IID = ABI.System.Collections.IEnumerableMethods.IID, + Vtable = ABI.System.Collections.IEnumerableMethods.AbiToProjectionVftablePtr + } + }; } - - public IEnumerator GetEnumerator() => list.GetEnumerator(); } + + /// A Windows Runtime IBindableVectorView implementation that wraps around a managed IList exposing + /// it to Windows runtime interop. + [global::WinRT.WinRTExposedType(typeof(ListToBindableVectorViewAdapterTypeDetails))] + internal sealed class ListToBindableVectorViewAdapter : IBindableVectorView + { + private readonly global::System.Collections.IList list; + + internal ListToBindableVectorViewAdapter(global::System.Collections.IList list) + { + if (list == null) + throw new ArgumentNullException(nameof(list)); + this.list = list; + } + + private static void EnsureIndexInt32(uint index, int listCapacity) + { + // We use '<=' and not '<' becasue int.MaxValue == index would imply + // that Size > int.MaxValue: + if (((uint)int.MaxValue) <= index || index >= (uint)listCapacity) + { + Exception e = new ArgumentOutOfRangeException(nameof(index), WinRTRuntimeErrorStrings.ArgumentOutOfRange_IndexLargerThanMaxValue); + e.SetHResult(ExceptionHelpers.E_BOUNDS); + throw e; + } + } + + public IBindableIterator First() => + IEnumerable.ToAbiHelper.MakeBindableIterator(list.GetEnumerator()); + + public object GetAt(uint index) + { + EnsureIndexInt32(index, list.Count); + + try + { + return list[(int)index]; + } + catch (ArgumentOutOfRangeException ex) + { + throw ex.GetExceptionForHR(ExceptionHelpers.E_BOUNDS, WinRTRuntimeErrorStrings.ArgumentOutOfRange_Index); + } + } + + public uint Size => (uint)list.Count; + + public bool IndexOf(object value, out uint index) + { + int ind = list.IndexOf(value); + + if (-1 == ind) + { + index = 0; + return false; + } + + index = (uint)ind; + return true; + } + + public IEnumerator GetEnumerator() => list.GetEnumerator(); + } } - public static readonly IntPtr AbiToProjectionVftablePtr; + public static readonly IntPtr AbiToProjectionVftablePtr; static IList() { - AbiToProjectionVftablePtr = ComWrappersSupport.AllocateVtableMemory(typeof(IList), sizeof(IInspectable.Vftbl) + sizeof(IntPtr) * 10); - *(IInspectable.Vftbl*)AbiToProjectionVftablePtr = IInspectable.Vftbl.AbiToProjectionVftable; + AbiToProjectionVftablePtr = ComWrappersSupport.AllocateVtableMemory(typeof(IList), sizeof(IInspectable.Vftbl) + sizeof(IntPtr) * 10); + *(IInspectable.Vftbl*)AbiToProjectionVftablePtr = IInspectable.Vftbl.AbiToProjectionVftable; ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[6] = &Do_Abi_GetAt_0; - ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[7] = &Do_Abi_get_Size_1; - ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[8] = FeatureSwitches.IsWuxMode ? &Do_Wux_Abi_GetView_2 : &Do_Mux_Abi_GetView_2; - ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[9] = &Do_Abi_IndexOf_3; - ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[10] = &Do_Abi_SetAt_4; - ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[11] = &Do_Abi_InsertAt_5; - ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[12] = &Do_Abi_RemoveAt_6; - ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[13] = &Do_Abi_Append_7; - ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[14] = &Do_Abi_RemoveAtEnd_8; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[7] = &Do_Abi_get_Size_1; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[8] = &Do_Abi_GetView_2; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[9] = &Do_Abi_IndexOf_3; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[10] = &Do_Abi_SetAt_4; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[11] = &Do_Abi_InsertAt_5; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[12] = &Do_Abi_RemoveAt_6; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[13] = &Do_Abi_Append_7; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[14] = &Do_Abi_RemoveAtEnd_8; ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[15] = &Do_Abi_Clear_9; } private static readonly ConditionalWeakTable _adapterTable = new(); - private static IBindableVectorAdapter FindAdapter(IntPtr thisPtr) + private static IBindableVector FindAdapter(IntPtr thisPtr) { var __this = global::WinRT.ComWrappersSupport.FindObject(thisPtr); return _adapterTable.GetValue(__this, (list) => new ToAbiHelper(list)); @@ -805,32 +1055,14 @@ private static unsafe int Do_Abi_GetAt_0(IntPtr thisPtr, uint index, IntPtr* res } [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] - private static unsafe int Do_Wux_Abi_GetView_2(IntPtr thisPtr, IntPtr* result) - { - IBindableVectorViewAdapter __result = default; - *result = default; - try - { - __result = FindAdapter(thisPtr).GetView(); - *result = MarshalInterface.FromManaged((WUX.IBindableVectorView)__result); - } - catch (Exception __exception__) - { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); - } - return 0; - } - - [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] - private static unsafe int Do_Mux_Abi_GetView_2(IntPtr thisPtr, IntPtr* result) + private static unsafe int Do_Abi_GetView_2(IntPtr thisPtr, IntPtr* result) { - IBindableVectorViewAdapter __result = default; + global::Microsoft.UI.Xaml.Interop.IBindableVectorView __result = default; *result = default; try { __result = FindAdapter(thisPtr).GetView(); - *result = MarshalInterface.FromManaged((MUX.IBindableVectorView)__result); + *result = MarshalInterface.FromManaged(__result); } catch (Exception __exception__) { @@ -969,344 +1201,202 @@ private static unsafe int Do_Abi_get_Size_1(IntPtr thisPtr, uint* value) return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); } return 0; - } - - internal static ObjectReference ObjRefFromAbi(IntPtr thisPtr) - { - if (thisPtr == IntPtr.Zero) - { - return null; - } - return ObjectReference.FromAbi(thisPtr); - } - - internal static FromAbiHelper _VectorToList(IWinRTObject _this) - { - IBindableVectorAdapter adapter = null; - if (FeatureSwitches.IsWuxMode) - { - adapter = new WuxBindableVectorAdapter((WUX.IBindableVector)_this); - } - else - { - adapter = new MuxBindableVectorAdapter((MUX.IBindableVector)_this); - } - return (FromAbiHelper)_this.GetOrCreateTypeHelperData(typeof(global::System.Collections.IList).TypeHandle, - () => new FromAbiHelper(adapter)); - } - - unsafe object WUX.IBindableVector.GetAt(uint index) - { - var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); - var ThisPtr = _obj.ThisPtr; - IntPtr __retval = default; - try - { - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[6](ThisPtr, index, &__retval)); - return MarshalInspectable.FromAbi(__retval); - } - finally - { - MarshalInspectable.DisposeAbi(__retval); - } - } - - unsafe WUX.IBindableVectorView WUX.IBindableVector.GetView() - { - var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); - var ThisPtr = _obj.ThisPtr; - IntPtr __retval = default; - try - { - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[8](ThisPtr, &__retval)); - return MarshalInterface.FromAbi(__retval); - } - finally - { - MarshalInterface.DisposeAbi(__retval); - } - } - - unsafe bool WUX.IBindableVector.IndexOf(object value, out uint index) - { - var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); - var ThisPtr = _obj.ThisPtr; - ObjectReferenceValue __value = default; - uint __index = default; - byte __retval = default; - try - { - __value = MarshalInspectable.CreateMarshaler2(value); - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[9](ThisPtr, MarshalInspectable.GetAbi(__value), &__index, &__retval)); - index = __index; - return __retval != 0; - } - finally - { - MarshalInspectable.DisposeMarshaler(__value); - } - } - - unsafe void WUX.IBindableVector.SetAt(uint index, object value) - { - var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); - var ThisPtr = _obj.ThisPtr; - ObjectReferenceValue __value = default; - try - { - __value = MarshalInspectable.CreateMarshaler2(value); - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[10](ThisPtr, index, MarshalInspectable.GetAbi(__value))); - } - finally - { - MarshalInspectable.DisposeMarshaler(__value); - } - } - - unsafe void WUX.IBindableVector.InsertAt(uint index, object value) - { - var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); - var ThisPtr = _obj.ThisPtr; - ObjectReferenceValue __value = default; - try - { - __value = MarshalInspectable.CreateMarshaler2(value); - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[11](ThisPtr, index, MarshalInspectable.GetAbi(__value))); - } - finally - { - MarshalInspectable.DisposeMarshaler(__value); - } - } - - unsafe void WUX.IBindableVector.RemoveAt(uint index) - { - var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); - var ThisPtr = _obj.ThisPtr; - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[12](ThisPtr, index)); - } - - unsafe void WUX.IBindableVector.Append(object value) - { - var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); - var ThisPtr = _obj.ThisPtr; - ObjectReferenceValue __value = default; - try - { - __value = MarshalInspectable.CreateMarshaler2(value); - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[13](ThisPtr, MarshalInspectable.GetAbi(__value))); - } - finally - { - MarshalInspectable.DisposeMarshaler(__value); - } - } - - unsafe void WUX.IBindableVector.RemoveAtEnd() - { - var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); - var ThisPtr = _obj.ThisPtr; - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[14](ThisPtr)); - } - - unsafe void WUX.IBindableVector.Clear() - { - var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); - var ThisPtr = _obj.ThisPtr; - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[15](ThisPtr)); - } - - unsafe uint WUX.IBindableVector.Size - { - get - { - var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); - var ThisPtr = _obj.ThisPtr; - uint __retval = default; - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[7](ThisPtr, &__retval)); - return __retval; - } - } - - unsafe object MUX.IBindableVector.GetAt(uint index) - { - var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); - var ThisPtr = _obj.ThisPtr; - IntPtr __retval = default; - try - { - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[6](ThisPtr, index, &__retval)); - return MarshalInspectable.FromAbi(__retval); - } - finally - { - MarshalInspectable.DisposeAbi(__retval); - } - } - - unsafe MUX.IBindableVectorView MUX.IBindableVector.GetView() - { - var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); - var ThisPtr = _obj.ThisPtr; - IntPtr __retval = default; - try - { - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[8](ThisPtr, &__retval)); - return MarshalInterface.FromAbi(__retval); - } - finally - { - MarshalInterface.DisposeAbi(__retval); - } - } - - unsafe bool MUX.IBindableVector.IndexOf(object value, out uint index) - { - var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); - var ThisPtr = _obj.ThisPtr; - ObjectReferenceValue __value = default; - uint __index = default; - byte __retval = default; - try - { + } + + internal static ObjectReference ObjRefFromAbi(IntPtr thisPtr) + { + if (thisPtr == IntPtr.Zero) + { + return null; + } + return ObjectReference.FromAbi(thisPtr); + } + + internal static FromAbiHelper _VectorToList(IWinRTObject _this) + { + return (FromAbiHelper)_this.GetOrCreateTypeHelperData(typeof(global::System.Collections.IList).TypeHandle, + () => new FromAbiHelper((global::Microsoft.UI.Xaml.Interop.IBindableVector)_this)); + } + + unsafe object global::Microsoft.UI.Xaml.Interop.IBindableVector.GetAt(uint index) + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); + var ThisPtr = _obj.ThisPtr; + IntPtr __retval = default; + try + { + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[6](ThisPtr, index, &__retval)); + return MarshalInspectable.FromAbi(__retval); + } + finally + { + MarshalInspectable.DisposeAbi(__retval); + } + } + + unsafe global::Microsoft.UI.Xaml.Interop.IBindableVectorView global::Microsoft.UI.Xaml.Interop.IBindableVector.GetView() + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); + var ThisPtr = _obj.ThisPtr; + IntPtr __retval = default; + try + { + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[8](ThisPtr, &__retval)); + return MarshalInterface.FromAbi(__retval); + } + finally + { + MarshalInterface.DisposeAbi(__retval); + } + } + + unsafe bool global::Microsoft.UI.Xaml.Interop.IBindableVector.IndexOf(object value, out uint index) + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); + var ThisPtr = _obj.ThisPtr; + ObjectReferenceValue __value = default; + uint __index = default; + byte __retval = default; + try + { __value = MarshalInspectable.CreateMarshaler2(value); - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[9](ThisPtr, MarshalInspectable.GetAbi(__value), &__index, &__retval)); - index = __index; - return __retval != 0; - } - finally - { - MarshalInspectable.DisposeMarshaler(__value); - } - } - - unsafe void MUX.IBindableVector.SetAt(uint index, object value) - { - var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); - var ThisPtr = _obj.ThisPtr; - ObjectReferenceValue __value = default; - try - { + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[9](ThisPtr, MarshalInspectable.GetAbi(__value), &__index, &__retval)); + index = __index; + return __retval != 0; + } + finally + { + MarshalInspectable.DisposeMarshaler(__value); + } + } + + unsafe void global::Microsoft.UI.Xaml.Interop.IBindableVector.SetAt(uint index, object value) + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); + var ThisPtr = _obj.ThisPtr; + ObjectReferenceValue __value = default; + try + { __value = MarshalInspectable.CreateMarshaler2(value); - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[10](ThisPtr, index, MarshalInspectable.GetAbi(__value))); - } - finally - { - MarshalInspectable.DisposeMarshaler(__value); - } - } - - unsafe void MUX.IBindableVector.InsertAt(uint index, object value) - { - var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); - var ThisPtr = _obj.ThisPtr; - ObjectReferenceValue __value = default; - try - { + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[10](ThisPtr, index, MarshalInspectable.GetAbi(__value))); + } + finally + { + MarshalInspectable.DisposeMarshaler(__value); + } + } + + unsafe void global::Microsoft.UI.Xaml.Interop.IBindableVector.InsertAt(uint index, object value) + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); + var ThisPtr = _obj.ThisPtr; + ObjectReferenceValue __value = default; + try + { __value = MarshalInspectable.CreateMarshaler2(value); - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[11](ThisPtr, index, MarshalInspectable.GetAbi(__value))); - } - finally - { - MarshalInspectable.DisposeMarshaler(__value); - } - } - - unsafe void MUX.IBindableVector.RemoveAt(uint index) - { - var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); - var ThisPtr = _obj.ThisPtr; - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[12](ThisPtr, index)); - } - - unsafe void MUX.IBindableVector.Append(object value) - { - var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[11](ThisPtr, index, MarshalInspectable.GetAbi(__value))); + } + finally + { + MarshalInspectable.DisposeMarshaler(__value); + } + } + + unsafe void global::Microsoft.UI.Xaml.Interop.IBindableVector.RemoveAt(uint index) + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); var ThisPtr = _obj.ThisPtr; - ObjectReferenceValue __value = default; - try - { + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[12](ThisPtr, index)); + } + + unsafe void global::Microsoft.UI.Xaml.Interop.IBindableVector.Append(object value) + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); + var ThisPtr = _obj.ThisPtr; + ObjectReferenceValue __value = default; + try + { __value = MarshalInspectable.CreateMarshaler2(value); - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[13](ThisPtr, MarshalInspectable.GetAbi(__value))); - } - finally - { - MarshalInspectable.DisposeMarshaler(__value); - } - } - - unsafe void MUX.IBindableVector.RemoveAtEnd() - { - var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[13](ThisPtr, MarshalInspectable.GetAbi(__value))); + } + finally + { + MarshalInspectable.DisposeMarshaler(__value); + } + } + + unsafe void global::Microsoft.UI.Xaml.Interop.IBindableVector.RemoveAtEnd() + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); var ThisPtr = _obj.ThisPtr; - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[14](ThisPtr)); - } - - unsafe void MUX.IBindableVector.Clear() - { - var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[14](ThisPtr)); + } + + unsafe void global::Microsoft.UI.Xaml.Interop.IBindableVector.Clear() + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); var ThisPtr = _obj.ThisPtr; - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[15](ThisPtr)); - } - - unsafe uint MUX.IBindableVector.Size - { - get - { - var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); - var ThisPtr = _obj.ThisPtr; + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[15](ThisPtr)); + } + + unsafe uint global::Microsoft.UI.Xaml.Interop.IBindableVector.Size + { + get + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); + var ThisPtr = _obj.ThisPtr; uint __retval = default; - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[7](ThisPtr, &__retval)); - return __retval; - } - } - - object global::System.Collections.IList.this[int index] - { - get => _VectorToList((IWinRTObject)this)[index]; - - set => _VectorToList((IWinRTObject)this)[index] = value; - } - - bool global::System.Collections.IList.IsFixedSize => _VectorToList((IWinRTObject)this).IsFixedSize; - - bool global::System.Collections.IList.IsReadOnly => _VectorToList((IWinRTObject)this).IsReadOnly; - - int global::System.Collections.ICollection.Count => _VectorToList((IWinRTObject)this).Count; - - bool global::System.Collections.ICollection.IsSynchronized => _VectorToList((IWinRTObject)this).IsSynchronized; - - object global::System.Collections.ICollection.SyncRoot => _VectorToList((IWinRTObject)this).SyncRoot; - - int global::System.Collections.IList.Add(object value) => _VectorToList((IWinRTObject)this).Add(value); - - void global::System.Collections.IList.Clear() => _VectorToList((IWinRTObject)this).Clear(); - - bool global::System.Collections.IList.Contains(object value) => _VectorToList((IWinRTObject)this).Contains(value); - - int global::System.Collections.IList.IndexOf(object value) => _VectorToList((IWinRTObject)this).IndexOf(value); - - void global::System.Collections.IList.Insert(int index, object value) => _VectorToList((IWinRTObject)this).Insert(index, value); - - void global::System.Collections.IList.Remove(object value) => _VectorToList((IWinRTObject)this).Remove(value); - - void global::System.Collections.IList.RemoveAt(int index) => _VectorToList((IWinRTObject)this).RemoveAt(index); - - void global::System.Collections.ICollection.CopyTo(Array array, int index) => _VectorToList((IWinRTObject)this).CopyTo(array, index); - - IEnumerator global::System.Collections.IEnumerable.GetEnumerator() => _VectorToList((IWinRTObject)this).GetEnumerator(); - } - internal static class IList_Delegates - { - public unsafe delegate int GetAt_0(IntPtr thisPtr, uint index, IntPtr* result); - public unsafe delegate int get_Size_1(IntPtr thisPtr, uint* result); - public unsafe delegate int GetView_2(IntPtr thisPtr, IntPtr* result); - public unsafe delegate int IndexOf_3(IntPtr thisPtr, IntPtr value, uint* index, byte* returnValue); - public unsafe delegate int SetAt_4(IntPtr thisPtr, uint index, IntPtr value); - public unsafe delegate int InsertAt_5(IntPtr thisPtr, uint index, IntPtr value); - public unsafe delegate int RemoveAt_6(IntPtr thisPtr, uint index); - public unsafe delegate int Append_7(IntPtr thisPtr, IntPtr value); - public unsafe delegate int RemoveAtEnd_8(IntPtr thisPtr); - public unsafe delegate int Clear_9(IntPtr thisPtr); - } -} + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[7](ThisPtr, &__retval)); + return __retval; + } + } + + object global::System.Collections.IList.this[int index] + { + get => _VectorToList((IWinRTObject)this)[index]; + + set => _VectorToList((IWinRTObject)this)[index] = value; + } + + bool global::System.Collections.IList.IsFixedSize => _VectorToList((IWinRTObject)this).IsFixedSize; + + bool global::System.Collections.IList.IsReadOnly => _VectorToList((IWinRTObject)this).IsReadOnly; + + int global::System.Collections.ICollection.Count => _VectorToList((IWinRTObject)this).Count; + + bool global::System.Collections.ICollection.IsSynchronized => _VectorToList((IWinRTObject)this).IsSynchronized; + + object global::System.Collections.ICollection.SyncRoot => _VectorToList((IWinRTObject)this).SyncRoot; + + int global::System.Collections.IList.Add(object value) => _VectorToList((IWinRTObject)this).Add(value); + + void global::System.Collections.IList.Clear() => _VectorToList((IWinRTObject)this).Clear(); + + bool global::System.Collections.IList.Contains(object value) => _VectorToList((IWinRTObject)this).Contains(value); + + int global::System.Collections.IList.IndexOf(object value) => _VectorToList((IWinRTObject)this).IndexOf(value); + + void global::System.Collections.IList.Insert(int index, object value) => _VectorToList((IWinRTObject)this).Insert(index, value); + + void global::System.Collections.IList.Remove(object value) => _VectorToList((IWinRTObject)this).Remove(value); + + void global::System.Collections.IList.RemoveAt(int index) => _VectorToList((IWinRTObject)this).RemoveAt(index); + + void global::System.Collections.ICollection.CopyTo(Array array, int index) => _VectorToList((IWinRTObject)this).CopyTo(array, index); + + IEnumerator global::System.Collections.IEnumerable.GetEnumerator() => _VectorToList((IWinRTObject)this).GetEnumerator(); + } + internal static class IList_Delegates + { + public unsafe delegate int GetAt_0(IntPtr thisPtr, uint index, IntPtr* result); + public unsafe delegate int get_Size_1(IntPtr thisPtr, uint* result); + public unsafe delegate int GetView_2(IntPtr thisPtr, IntPtr* result); + public unsafe delegate int IndexOf_3(IntPtr thisPtr, IntPtr value, uint* index, byte* returnValue); + public unsafe delegate int SetAt_4(IntPtr thisPtr, uint index, IntPtr value); + public unsafe delegate int InsertAt_5(IntPtr thisPtr, uint index, IntPtr value); + public unsafe delegate int RemoveAt_6(IntPtr thisPtr, uint index); + public unsafe delegate int Append_7(IntPtr thisPtr, IntPtr value); + public unsafe delegate int RemoveAtEnd_8(IntPtr thisPtr); + public unsafe delegate int Clear_9(IntPtr thisPtr); + } +} diff --git a/src/WinRT.Runtime/Projections/Microsoft.UI.Xaml.Bindable.netstandard2.0.cs b/src/WinRT.Runtime/Projections/Bindable.netstandard2.0.cs similarity index 100% rename from src/WinRT.Runtime/Projections/Microsoft.UI.Xaml.Bindable.netstandard2.0.cs rename to src/WinRT.Runtime/Projections/Bindable.netstandard2.0.cs diff --git a/src/WinRT.Runtime/Projections/IEnumerable.net5.cs b/src/WinRT.Runtime/Projections/IEnumerable.net5.cs index 334efee24..e27a07dc4 100644 --- a/src/WinRT.Runtime/Projections/IEnumerable.net5.cs +++ b/src/WinRT.Runtime/Projections/IEnumerable.net5.cs @@ -938,7 +938,7 @@ public static void DisposeAbi(IntPtr abi) => // In IEnumerator<> scenarios, we use this as a helper for the implementation and don't actually use it to // create a CCW. [global::WinRT.WinRTExposedType(typeof(IBindableIteratorTypeDetails))] - public sealed class ToAbiHelper : global::Windows.Foundation.Collections.IIterator, global::Microsoft.UI.Xaml.Interop.IBindableIterator, global::Windows.UI.Xaml.Interop.IBindableIterator + public sealed class ToAbiHelper : global::Windows.Foundation.Collections.IIterator, global::Microsoft.UI.Xaml.Interop.IBindableIterator { private readonly global::System.Collections.Generic.IEnumerator m_enumerator; private bool m_firstItem = true; @@ -1033,11 +1033,6 @@ public uint GetMany(ref T[] items) // Should not be called. throw new NotImplementedException(); } - uint global::Windows.UI.Xaml.Interop.IBindableIterator.GetMany(ref object[] items) - { - // Should not be called. - throw new NotImplementedException(); - } } public static readonly IntPtr AbiToProjectionVftablePtr; diff --git a/src/WinRT.Runtime/Projections/Microsoft.UI.Xaml.Bindable.net5.cs b/src/WinRT.Runtime/Projections/Microsoft.UI.Xaml.Bindable.net5.cs deleted file mode 100644 index 95397bad6..000000000 --- a/src/WinRT.Runtime/Projections/Microsoft.UI.Xaml.Bindable.net5.cs +++ /dev/null @@ -1,367 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using WinRT; -using WinRT.Interop; - - -#pragma warning disable 0169 // warning CS0169: The field '...' is never used -#pragma warning disable 0649 // warning CS0169: Field '...' is never assigned to - -namespace Microsoft.UI.Xaml.Interop -{ - [global::WinRT.WindowsRuntimeType] - [Guid("036D2C08-DF29-41AF-8AA2-D774BE62BA6F")] - [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Microsoft.UI.Xaml.Interop.IBindableIterable))] - internal interface IBindableIterable - { - IBindableIterator First(); - } - [global::WinRT.WindowsRuntimeType] - [Guid("6A1D6C07-076D-49F2-8314-F52C9C9A8331")] - [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Microsoft.UI.Xaml.Interop.IBindableIterator))] - internal interface IBindableIterator - { - bool MoveNext(); - // GetMany is not implemented by IBindableIterator, but it is here - // for compat purposes with WinUI where there are scenarios they do - // reinterpret_cast from IBindableIterator to IIterable. It is - // the last function in the vftable and shouldn't be called by anyone. - // If called, it will return NotImplementedException. - uint GetMany(ref object[] items); - object Current { get; } - bool HasCurrent { get; } - } - [global::WinRT.WindowsRuntimeType] - [Guid("393DE7DE-6FD0-4C0D-BB71-47244A113E93")] - internal interface IBindableVector : IEnumerable - { - object GetAt(uint index); - IBindableVectorView GetView(); - bool IndexOf(object value, out uint index); - void SetAt(uint index, object value); - void InsertAt(uint index, object value); - void RemoveAt(uint index); - void Append(object value); - void RemoveAtEnd(); - void Clear(); - uint Size { get; } - } - [global::WinRT.WindowsRuntimeType] - [Guid("346DD6E7-976E-4BC3-815D-ECE243BC0F33")] - [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Microsoft.UI.Xaml.Interop.IBindableVectorView))] - internal interface IBindableVectorView : IEnumerable - { - object GetAt(uint index); - bool IndexOf(object value, out uint index); - uint Size { get; } - } -} - -namespace ABI.Microsoft.UI.Xaml.Interop -{ - [DynamicInterfaceCastableImplementation] - [Guid("036D2C08-DF29-41AF-8AA2-D774BE62BA6F")] - internal unsafe interface IBindableIterable : global::Microsoft.UI.Xaml.Interop.IBindableIterable, ABI.System.Collections.IEnumerable - { - - } - - [DynamicInterfaceCastableImplementation] - [Guid("6A1D6C07-076D-49F2-8314-F52C9C9A8331")] - internal unsafe interface IBindableIterator : global::Microsoft.UI.Xaml.Interop.IBindableIterator - { - public static readonly IntPtr AbiToProjectionVftablePtr; - static IBindableIterator() - { - AbiToProjectionVftablePtr = ComWrappersSupport.AllocateVtableMemory(typeof(IBindableIterator), sizeof(IInspectable.Vftbl) + sizeof(IntPtr) * 4); - *(IInspectable.Vftbl*)AbiToProjectionVftablePtr = IInspectable.Vftbl.AbiToProjectionVftable; - ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[6] = &Do_Abi_get_Current_0; - ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[7] = &Do_Abi_get_HasCurrent_1; - ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[8] = &Do_Abi_MoveNext_2; - ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[9] = &Do_Abi_GetMany_3; - } - - [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] - private static unsafe int Do_Abi_MoveNext_2(IntPtr thisPtr, byte* result) - { - bool __result = default; - *result = default; - try - { - __result = global::WinRT.ComWrappersSupport.FindObject(thisPtr).MoveNext(); - *result = (byte)(__result ? 1 : 0); - } - catch (Exception __exception__) - { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); - } - return 0; - } - - [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] - private static unsafe int Do_Abi_GetMany_3(IntPtr thisPtr, int __itemsSize, IntPtr items, uint* result) - { - *result = default; - - try - { - // Should never be called. - throw new NotImplementedException(); - } - catch (Exception __exception__) - { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); - } - } - - [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] - private static unsafe int Do_Abi_get_Current_0(IntPtr thisPtr, IntPtr* value) - { - object __value = default; - *value = default; - try - { - __value = global::WinRT.ComWrappersSupport.FindObject(thisPtr).Current; - *value = MarshalInspectable.FromManaged(__value); - } - catch (Exception __exception__) - { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); - } - return 0; - } - - [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] - private static unsafe int Do_Abi_get_HasCurrent_1(IntPtr thisPtr, byte* value) - { - bool __value = default; - *value = default; - try - { - __value = global::WinRT.ComWrappersSupport.FindObject(thisPtr).HasCurrent; - *value = (byte)(__value ? 1 : 0); - } - catch (Exception __exception__) - { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); - } - return 0; - } - - internal static ObjectReference FromAbi(IntPtr thisPtr) => ObjectReference.FromAbi(thisPtr); - - unsafe bool global::Microsoft.UI.Xaml.Interop.IBindableIterator.MoveNext() - { - var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::Microsoft.UI.Xaml.Interop.IBindableIterator).TypeHandle); - var ThisPtr = _obj.ThisPtr; - byte __retval = default; - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[8](ThisPtr, &__retval)); - return __retval != 0; - } - - unsafe uint global::Microsoft.UI.Xaml.Interop.IBindableIterator.GetMany(ref object[] items) - { - // Should never be called. - throw new NotImplementedException(); - } - - unsafe object global::Microsoft.UI.Xaml.Interop.IBindableIterator.Current - { - get - { - var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::Microsoft.UI.Xaml.Interop.IBindableIterator).TypeHandle); - var ThisPtr = _obj.ThisPtr; - IntPtr __retval = default; - try - { - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[6](ThisPtr, &__retval)); - return MarshalInspectable.FromAbi(__retval); - } - finally - { - MarshalInspectable.DisposeAbi(__retval); - } - } - } - - unsafe bool global::Microsoft.UI.Xaml.Interop.IBindableIterator.HasCurrent - { - get - { - var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::Microsoft.UI.Xaml.Interop.IBindableIterator).TypeHandle); - var ThisPtr = _obj.ThisPtr; - byte __retval = default; - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[7](ThisPtr, &__retval)); - return __retval != 0; - } - } - - } - [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] - internal static class IBindableIterator_Delegates - { - public unsafe delegate int get_Current_0(IntPtr thisPtr, IntPtr* result); - public unsafe delegate int get_HasCurrent_1(IntPtr thisPtr, byte* result); - public unsafe delegate int MoveNext_2(IntPtr thisPtr, byte* result); - public unsafe delegate int GetMany_3(IntPtr thisPtr, int itemSize, IntPtr items, uint* result); - } - - [DynamicInterfaceCastableImplementation] - [Guid("346DD6E7-976E-4BC3-815D-ECE243BC0F33")] - internal unsafe interface IBindableVectorView : global::Microsoft.UI.Xaml.Interop.IBindableVectorView - { - public static readonly IntPtr AbiToProjectionVftablePtr; - static IBindableVectorView() - { - AbiToProjectionVftablePtr = ComWrappersSupport.AllocateVtableMemory(typeof(IBindableVectorView), sizeof(IInspectable.Vftbl) + sizeof(IntPtr) * 3); - *(IInspectable.Vftbl*)AbiToProjectionVftablePtr = IInspectable.Vftbl.AbiToProjectionVftable; - ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[6] = &Do_Abi_GetAt_0; - ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[7] = &Do_Abi_get_Size_1; - ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[8] = &Do_Abi_IndexOf_2; - } - - [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] - private static unsafe int Do_Abi_GetAt_0(IntPtr thisPtr, uint index, IntPtr* result) - { - object __result = default; - - try - { - __result = global::WinRT.ComWrappersSupport.FindObject(thisPtr).GetAt(index); - *result = MarshalInspectable.FromManaged(__result); - - } - catch (Exception __exception__) - { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); - } - return 0; - } - - [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] - private static unsafe int Do_Abi_IndexOf_2(IntPtr thisPtr, IntPtr value, uint* index, byte* returnValue) - { - bool __returnValue = default; - - *index = default; - *returnValue = default; - uint __index = default; - - try - { - __returnValue = global::WinRT.ComWrappersSupport.FindObject(thisPtr).IndexOf(MarshalInspectable.FromAbi(value), out __index); - *index = __index; - *returnValue = (byte)(__returnValue ? 1 : 0); - - } - catch (Exception __exception__) - { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); - } - return 0; - } - - [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] - private static unsafe int Do_Abi_get_Size_1(IntPtr thisPtr, uint* value) - { - uint __value = default; - - *value = default; - - try - { - __value = global::WinRT.ComWrappersSupport.FindObject(thisPtr).Size; - *value = __value; - - } - catch (Exception __exception__) - { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); - } - return 0; - } - - internal static ObjectReference FromAbi(IntPtr thisPtr) => ObjectReference.FromAbi(thisPtr); - - private static readonly global::System.Runtime.CompilerServices.ConditionalWeakTable _helperTable = new(); - - unsafe object global::Microsoft.UI.Xaml.Interop.IBindableVectorView.GetAt(uint index) - { - var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::Microsoft.UI.Xaml.Interop.IBindableIterator).TypeHandle); - var ThisPtr = _obj.ThisPtr; - IntPtr __retval = default; - try - { - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[6](ThisPtr, index, &__retval)); - return MarshalInspectable.FromAbi(__retval); - } - finally - { - MarshalInspectable.DisposeAbi(__retval); - } - } - - unsafe bool global::Microsoft.UI.Xaml.Interop.IBindableVectorView.IndexOf(object value, out uint index) - { - var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::Microsoft.UI.Xaml.Interop.IBindableIterator).TypeHandle); - var ThisPtr = _obj.ThisPtr; - ObjectReferenceValue __value = default; - uint __index = default; - byte __retval = default; - try - { - __value = MarshalInspectable.CreateMarshaler2(value); - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[8]( - ThisPtr, - MarshalInspectable.GetAbi(__value), - &__index, - &__retval)); - index = __index; - return __retval != 0; - } - finally - { - MarshalInspectable.DisposeMarshaler(__value); - } - } - - unsafe uint global::Microsoft.UI.Xaml.Interop.IBindableVectorView.Size - { - get - { - var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::Microsoft.UI.Xaml.Interop.IBindableIterator).TypeHandle); - var ThisPtr = _obj.ThisPtr; - uint __retval = default; - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[7](ThisPtr, &__retval)); - return __retval; - } - } - - IEnumerator IEnumerable.GetEnumerator() - { - return _helperTable.GetValue((IWinRTObject)this, - (enumerable) => new ABI.System.Collections.IEnumerable.AdaptiveFromAbiHelper(enumerable) - ).GetEnumerator(); - } - } - [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] - internal static class IBindableVectorView_Delegates - { - public unsafe delegate int GetAt_0(IntPtr thisPtr, uint index, IntPtr* result); - public unsafe delegate int get_Size_1(IntPtr thisPtr, uint* result); - public unsafe delegate int IndexOf_2(IntPtr thisPtr, IntPtr value, uint* index, byte* returnValue); - } -} diff --git a/src/WinRT.Runtime/Projections/Windows.UI.Xaml.Bindable.net5.cs b/src/WinRT.Runtime/Projections/Windows.UI.Xaml.Bindable.net5.cs deleted file mode 100644 index 7f54e9b25..000000000 --- a/src/WinRT.Runtime/Projections/Windows.UI.Xaml.Bindable.net5.cs +++ /dev/null @@ -1,367 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using WinRT; -using WinRT.Interop; - - -#pragma warning disable 0169 // warning CS0169: The field '...' is never used -#pragma warning disable 0649 // warning CS0169: Field '...' is never assigned to - -namespace Windows.UI.Xaml.Interop -{ - [global::WinRT.WindowsRuntimeType] - [Guid("036D2C08-DF29-41AF-8AA2-D774BE62BA6F")] - [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Windows.UI.Xaml.Interop.IBindableIterable))] - internal interface IBindableIterable - { - IBindableIterator First(); - } - [global::WinRT.WindowsRuntimeType] - [Guid("6A1D6C07-076D-49F2-8314-F52C9C9A8331")] - [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Windows.UI.Xaml.Interop.IBindableIterator))] - internal interface IBindableIterator - { - bool MoveNext(); - // GetMany is not implemented by IBindableIterator, but it is here - // for compat purposes with WinUI where there are scenarios they do - // reinterpret_cast from IBindableIterator to IIterable. It is - // the last function in the vftable and shouldn't be called by anyone. - // If called, it will return NotImplementedException. - uint GetMany(ref object[] items); - object Current { get; } - bool HasCurrent { get; } - } - [global::WinRT.WindowsRuntimeType] - [Guid("393DE7DE-6FD0-4C0D-BB71-47244A113E93")] - internal interface IBindableVector : IEnumerable - { - object GetAt(uint index); - IBindableVectorView GetView(); - bool IndexOf(object value, out uint index); - void SetAt(uint index, object value); - void InsertAt(uint index, object value); - void RemoveAt(uint index); - void Append(object value); - void RemoveAtEnd(); - void Clear(); - uint Size { get; } - } - [global::WinRT.WindowsRuntimeType] - [Guid("346DD6E7-976E-4BC3-815D-ECE243BC0F33")] - [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Windows.UI.Xaml.Interop.IBindableVectorView))] - internal interface IBindableVectorView : IEnumerable - { - object GetAt(uint index); - bool IndexOf(object value, out uint index); - uint Size { get; } - } -} - -namespace ABI.Windows.UI.Xaml.Interop -{ - [DynamicInterfaceCastableImplementation] - [Guid("036D2C08-DF29-41AF-8AA2-D774BE62BA6F")] - internal unsafe interface IBindableIterable : global::Windows.UI.Xaml.Interop.IBindableIterable, ABI.System.Collections.IEnumerable - { - - } - - [DynamicInterfaceCastableImplementation] - [Guid("6A1D6C07-076D-49F2-8314-F52C9C9A8331")] - internal unsafe interface IBindableIterator : global::Windows.UI.Xaml.Interop.IBindableIterator - { - public static readonly IntPtr AbiToProjectionVftablePtr; - static IBindableIterator() - { - AbiToProjectionVftablePtr = ComWrappersSupport.AllocateVtableMemory(typeof(IBindableIterator), sizeof(IInspectable.Vftbl) + sizeof(IntPtr) * 4); - *(IInspectable.Vftbl*)AbiToProjectionVftablePtr = IInspectable.Vftbl.AbiToProjectionVftable; - ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[6] = &Do_Abi_get_Current_0; - ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[7] = &Do_Abi_get_HasCurrent_1; - ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[8] = &Do_Abi_MoveNext_2; - ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[9] = &Do_Abi_GetMany_3; - } - - [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] - private static unsafe int Do_Abi_MoveNext_2(IntPtr thisPtr, byte* result) - { - bool __result = default; - *result = default; - try - { - __result = global::WinRT.ComWrappersSupport.FindObject(thisPtr).MoveNext(); - *result = (byte)(__result ? 1 : 0); - } - catch (Exception __exception__) - { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); - } - return 0; - } - - [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] - private static unsafe int Do_Abi_GetMany_3(IntPtr thisPtr, int __itemsSize, IntPtr items, uint* result) - { - *result = default; - - try - { - // Should never be called. - throw new NotImplementedException(); - } - catch (Exception __exception__) - { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); - } - } - - [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] - private static unsafe int Do_Abi_get_Current_0(IntPtr thisPtr, IntPtr* value) - { - object __value = default; - *value = default; - try - { - __value = global::WinRT.ComWrappersSupport.FindObject(thisPtr).Current; - *value = MarshalInspectable.FromManaged(__value); - } - catch (Exception __exception__) - { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); - } - return 0; - } - - [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] - private static unsafe int Do_Abi_get_HasCurrent_1(IntPtr thisPtr, byte* value) - { - bool __value = default; - *value = default; - try - { - __value = global::WinRT.ComWrappersSupport.FindObject(thisPtr).HasCurrent; - *value = (byte)(__value ? 1 : 0); - } - catch (Exception __exception__) - { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); - } - return 0; - } - - internal static ObjectReference FromAbi(IntPtr thisPtr) => ObjectReference.FromAbi(thisPtr); - - unsafe bool global::Windows.UI.Xaml.Interop.IBindableIterator.MoveNext() - { - var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::Windows.UI.Xaml.Interop.IBindableIterator).TypeHandle); - var ThisPtr = _obj.ThisPtr; - byte __retval = default; - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[8](ThisPtr, &__retval)); - return __retval != 0; - } - - unsafe uint global::Windows.UI.Xaml.Interop.IBindableIterator.GetMany(ref object[] items) - { - // Should never be called. - throw new NotImplementedException(); - } - - unsafe object global::Windows.UI.Xaml.Interop.IBindableIterator.Current - { - get - { - var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::Windows.UI.Xaml.Interop.IBindableIterator).TypeHandle); - var ThisPtr = _obj.ThisPtr; - IntPtr __retval = default; - try - { - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[6](ThisPtr, &__retval)); - return MarshalInspectable.FromAbi(__retval); - } - finally - { - MarshalInspectable.DisposeAbi(__retval); - } - } - } - - unsafe bool global::Windows.UI.Xaml.Interop.IBindableIterator.HasCurrent - { - get - { - var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::Windows.UI.Xaml.Interop.IBindableIterator).TypeHandle); - var ThisPtr = _obj.ThisPtr; - byte __retval = default; - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[7](ThisPtr, &__retval)); - return __retval != 0; - } - } - - } - [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] - internal static class IBindableIterator_Delegates - { - public unsafe delegate int get_Current_0(IntPtr thisPtr, IntPtr* result); - public unsafe delegate int get_HasCurrent_1(IntPtr thisPtr, byte* result); - public unsafe delegate int MoveNext_2(IntPtr thisPtr, byte* result); - public unsafe delegate int GetMany_3(IntPtr thisPtr, int itemSize, IntPtr items, uint* result); - } - - [DynamicInterfaceCastableImplementation] - [Guid("346DD6E7-976E-4BC3-815D-ECE243BC0F33")] - internal unsafe interface IBindableVectorView : global::Windows.UI.Xaml.Interop.IBindableVectorView - { - public static readonly IntPtr AbiToProjectionVftablePtr; - static IBindableVectorView() - { - AbiToProjectionVftablePtr = ComWrappersSupport.AllocateVtableMemory(typeof(IBindableVectorView), sizeof(IInspectable.Vftbl) + sizeof(IntPtr) * 3); - *(IInspectable.Vftbl*)AbiToProjectionVftablePtr = IInspectable.Vftbl.AbiToProjectionVftable; - ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[6] = &Do_Abi_GetAt_0; - ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[7] = &Do_Abi_get_Size_1; - ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[8] = &Do_Abi_IndexOf_2; - } - - [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] - private static unsafe int Do_Abi_GetAt_0(IntPtr thisPtr, uint index, IntPtr* result) - { - object __result = default; - - try - { - __result = global::WinRT.ComWrappersSupport.FindObject(thisPtr).GetAt(index); - *result = MarshalInspectable.FromManaged(__result); - - } - catch (Exception __exception__) - { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); - } - return 0; - } - - [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] - private static unsafe int Do_Abi_IndexOf_2(IntPtr thisPtr, IntPtr value, uint* index, byte* returnValue) - { - bool __returnValue = default; - - *index = default; - *returnValue = default; - uint __index = default; - - try - { - __returnValue = global::WinRT.ComWrappersSupport.FindObject(thisPtr).IndexOf(MarshalInspectable.FromAbi(value), out __index); - *index = __index; - *returnValue = (byte)(__returnValue ? 1 : 0); - - } - catch (Exception __exception__) - { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); - } - return 0; - } - - [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] - private static unsafe int Do_Abi_get_Size_1(IntPtr thisPtr, uint* value) - { - uint __value = default; - - *value = default; - - try - { - __value = global::WinRT.ComWrappersSupport.FindObject(thisPtr).Size; - *value = __value; - - } - catch (Exception __exception__) - { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); - } - return 0; - } - - internal static ObjectReference FromAbi(IntPtr thisPtr) => ObjectReference.FromAbi(thisPtr); - - private static readonly global::System.Runtime.CompilerServices.ConditionalWeakTable _helperTable = new(); - - unsafe object global::Windows.UI.Xaml.Interop.IBindableVectorView.GetAt(uint index) - { - var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::Windows.UI.Xaml.Interop.IBindableIterator).TypeHandle); - var ThisPtr = _obj.ThisPtr; - IntPtr __retval = default; - try - { - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[6](ThisPtr, index, &__retval)); - return MarshalInspectable.FromAbi(__retval); - } - finally - { - MarshalInspectable.DisposeAbi(__retval); - } - } - - unsafe bool global::Windows.UI.Xaml.Interop.IBindableVectorView.IndexOf(object value, out uint index) - { - var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::Windows.UI.Xaml.Interop.IBindableIterator).TypeHandle); - var ThisPtr = _obj.ThisPtr; - ObjectReferenceValue __value = default; - uint __index = default; - byte __retval = default; - try - { - __value = MarshalInspectable.CreateMarshaler2(value); - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[8]( - ThisPtr, - MarshalInspectable.GetAbi(__value), - &__index, - &__retval)); - index = __index; - return __retval != 0; - } - finally - { - MarshalInspectable.DisposeMarshaler(__value); - } - } - - unsafe uint global::Windows.UI.Xaml.Interop.IBindableVectorView.Size - { - get - { - var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::Windows.UI.Xaml.Interop.IBindableIterator).TypeHandle); - var ThisPtr = _obj.ThisPtr; - uint __retval = default; - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[7](ThisPtr, &__retval)); - return __retval; - } - } - - IEnumerator IEnumerable.GetEnumerator() - { - return _helperTable.GetValue((IWinRTObject)this, - (enumerable) => new ABI.System.Collections.IEnumerable.AdaptiveFromAbiHelper(enumerable) - ).GetEnumerator(); - } - } - [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] - internal static class IBindableVectorView_Delegates - { - public unsafe delegate int GetAt_0(IntPtr thisPtr, uint index, IntPtr* result); - public unsafe delegate int get_Size_1(IntPtr thisPtr, uint* result); - public unsafe delegate int IndexOf_2(IntPtr thisPtr, IntPtr value, uint* index, byte* returnValue); - } -} From 84bfe24da25ae55718d2a5ff92c73914ff0cb3a2 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Fri, 12 Apr 2024 16:39:59 -0700 Subject: [PATCH 18/46] Make it easier to debug the source generator --- .../WinRT.SourceGenerator/Properties/launchSettings.json | 8 ++++++++ .../WinRT.SourceGenerator/WinRT.SourceGenerator.csproj | 1 + 2 files changed, 9 insertions(+) create mode 100644 src/Authoring/WinRT.SourceGenerator/Properties/launchSettings.json diff --git a/src/Authoring/WinRT.SourceGenerator/Properties/launchSettings.json b/src/Authoring/WinRT.SourceGenerator/Properties/launchSettings.json new file mode 100644 index 000000000..ef608ed3b --- /dev/null +++ b/src/Authoring/WinRT.SourceGenerator/Properties/launchSettings.json @@ -0,0 +1,8 @@ +{ + "profiles": { + "WinRT.SourceGenerator": { + "commandName": "DebugRoslynComponent", + "targetProject": "..\\..\\Projections\\Windows\\Windows.csproj" + } + } +} \ No newline at end of file diff --git a/src/Authoring/WinRT.SourceGenerator/WinRT.SourceGenerator.csproj b/src/Authoring/WinRT.SourceGenerator/WinRT.SourceGenerator.csproj index f8c96c91a..2bd5100fc 100644 --- a/src/Authoring/WinRT.SourceGenerator/WinRT.SourceGenerator.csproj +++ b/src/Authoring/WinRT.SourceGenerator/WinRT.SourceGenerator.csproj @@ -15,6 +15,7 @@ C#/WinRT Authoring Source Generator Preview $(VersionString) C#/WinRT Authoring Source Generator Preview v$(VersionString) Copyright (c) Microsoft Corporation. All rights reserved. + true From 50191c22704078e392a00219c9d3363e0795d8f2 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Fri, 12 Apr 2024 17:14:06 -0700 Subject: [PATCH 19/46] Fix the build --- src/Authoring/WinRT.SourceGenerator/Helper.cs | 12 ++++----- .../WinRT.SourceGenerator/UiXamlMode.cs | 26 ------------------- .../WinRTAotCodeFixer.cs | 6 +++-- .../WinRT.SourceGenerator/WinRTTypeWriter.cs | 2 +- .../Configuration/FeatureSwitches.cs | 8 +++--- 5 files changed, 15 insertions(+), 39 deletions(-) delete mode 100644 src/Authoring/WinRT.SourceGenerator/UiXamlMode.cs diff --git a/src/Authoring/WinRT.SourceGenerator/Helper.cs b/src/Authoring/WinRT.SourceGenerator/Helper.cs index c5d06f5bb..61bb40e58 100644 --- a/src/Authoring/WinRT.SourceGenerator/Helper.cs +++ b/src/Authoring/WinRT.SourceGenerator/Helper.cs @@ -211,7 +211,7 @@ private static bool IsFundamentalType(ISymbol type) public static bool IsWinRTType(ISymbol type, TypeMapper mapper) { - return IsWinRTType(type, mapper, null); + return IsWinRTType(type, null, mapper); } public static bool IsWinRTType(ISymbol type, Func isAuthoringWinRTType, TypeMapper mapper) @@ -229,14 +229,14 @@ public static bool IsWinRTType(ISymbol type, Func isA if (isProjectedType && type is INamedTypeSymbol namedType && namedType.IsGenericType && !namedType.IsDefinition) { isProjectedType = namedType.TypeArguments.All(t => - IsWinRTType(t, mapper, isAuthoringWinRTType) || - (isAuthoringWinRTType != null && isAuthoringWinRTType(t))); + IsWinRTType(t, isAuthoringWinRTType, mapper) || + (isAuthoringWinRTType != null && isAuthoringWinRTType(t, mapper))); } return isProjectedType; } - public static bool IsWinRTType(ISymbol type, ITypeSymbol winrtRuntimeTypeAttribute, bool isComponentProject, IAssemblySymbol currentAssembly) + public static bool IsWinRTType(ISymbol type, ITypeSymbol winrtRuntimeTypeAttribute, TypeMapper mapper, bool isComponentProject, IAssemblySymbol currentAssembly) { if (IsFundamentalType(type)) { @@ -255,7 +255,7 @@ public static bool IsWinRTType(ISymbol type, ITypeSymbol winrtRuntimeTypeAttribu bool isProjectedType = HasAttributeWithType(type, winrtRuntimeTypeAttribute); if (!isProjectedType & type.ContainingNamespace != null) { - isProjectedType = MappedCSharpTypes.ContainsKey(string.Join(".", type.ContainingNamespace.ToDisplayString(), type.MetadataName)); + isProjectedType = mapper.HasMappingForType(string.Join(".", type.ContainingNamespace.ToDisplayString(), type.MetadataName)); } // Ensure all generic parameters are WinRT types. @@ -264,7 +264,7 @@ type is INamedTypeSymbol namedType && namedType.IsGenericType && !namedType.IsDefinition) { - isProjectedType = namedType.TypeArguments.All(t => IsWinRTType(t, winrtRuntimeTypeAttribute, isComponentProject, currentAssembly)); + isProjectedType = namedType.TypeArguments.All(t => IsWinRTType(t, winrtRuntimeTypeAttribute, mapper, isComponentProject, currentAssembly)); } return isProjectedType; diff --git a/src/Authoring/WinRT.SourceGenerator/UiXamlMode.cs b/src/Authoring/WinRT.SourceGenerator/UiXamlMode.cs deleted file mode 100644 index 7432a1075..000000000 --- a/src/Authoring/WinRT.SourceGenerator/UiXamlMode.cs +++ /dev/null @@ -1,26 +0,0 @@ -using Microsoft.CodeAnalysis.Diagnostics; -using System; -using System.Collections.Generic; -using System.Text; - -namespace Generator -{ - internal enum UiXamlMode - { - MicrosoftUiXaml, - WindowsUiXaml, - } - - internal static class OptionsHelper - { - public static UiXamlMode GetUiXamlMode(this AnalyzerConfigOptions options) - { - if (options.TryGetValue("build_property.CsWinRTUiXamlMode", out var value) && Enum.TryParse(value, out UiXamlMode mode)) - { - return mode; - } - - return UiXamlMode.MicrosoftUiXaml; - } - } -} diff --git a/src/Authoring/WinRT.SourceGenerator/WinRTAotCodeFixer.cs b/src/Authoring/WinRT.SourceGenerator/WinRTAotCodeFixer.cs index ed2c31bc1..81b73076b 100644 --- a/src/Authoring/WinRT.SourceGenerator/WinRTAotCodeFixer.cs +++ b/src/Authoring/WinRT.SourceGenerator/WinRTAotCodeFixer.cs @@ -42,6 +42,8 @@ public override void Initialize(AnalysisContext context) return; } + var typeMapper = new TypeMapper(context.Options.AnalyzerConfigOptionsProvider.GlobalOptions.GetUIXamlProjectionsMode()); + context.RegisterSymbolAction(context => { // Filter to classes that can be passed as objects. @@ -53,13 +55,13 @@ public override void Initialize(AnalysisContext context) // Make sure this is a class that we would generate the WinRTExposedType attribute on // and that it isn't already partial. if (!GeneratorHelper.IsPartial(namedType) && - !GeneratorHelper.IsWinRTType(namedType, winrtTypeAttribute, isComponentProject, context.Compilation.Assembly) && + !GeneratorHelper.IsWinRTType(namedType, winrtTypeAttribute, typeMapper, isComponentProject, context.Compilation.Assembly) && !GeneratorHelper.HasNonInstantiatedWinRTGeneric(namedType) && !GeneratorHelper.HasAttributeWithType(namedType, winrtExposedTypeAttribute)) { foreach (var iface in namedType.AllInterfaces) { - if (GeneratorHelper.IsWinRTType(iface, winrtTypeAttribute, isComponentProject, context.Compilation.Assembly)) + if (GeneratorHelper.IsWinRTType(iface, winrtTypeAttribute, typeMapper, isComponentProject, context.Compilation.Assembly)) { context.ReportDiagnostic(Diagnostic.Create(WinRTRules.ClassNotAotCompatible, namedType.Locations[0], namedType.Name)); return; diff --git a/src/Authoring/WinRT.SourceGenerator/WinRTTypeWriter.cs b/src/Authoring/WinRT.SourceGenerator/WinRTTypeWriter.cs index 2180d2b3f..73e57d859 100644 --- a/src/Authoring/WinRT.SourceGenerator/WinRTTypeWriter.cs +++ b/src/Authoring/WinRT.SourceGenerator/WinRTTypeWriter.cs @@ -2671,7 +2671,7 @@ bool IsWinRTType(ISymbol symbol, TypeMapper mapper) { if (!SymbolEqualityComparer.Default.Equals(symbol.ContainingAssembly, context.Compilation.Assembly)) { - return GeneratorHelper.IsWinRTType(symbol, mapper, symbol => IsWinRTType(symbol, mapper)); + return GeneratorHelper.IsWinRTType(symbol, (symbol, mapper) => IsWinRTType(symbol, mapper), mapper); } if (symbol is INamedTypeSymbol namedType) diff --git a/src/WinRT.Runtime/Configuration/FeatureSwitches.cs b/src/WinRT.Runtime/Configuration/FeatureSwitches.cs index 1ad3a7c98..b7a0fe5b0 100644 --- a/src/WinRT.Runtime/Configuration/FeatureSwitches.cs +++ b/src/WinRT.Runtime/Configuration/FeatureSwitches.cs @@ -54,8 +54,8 @@ internal static class FeatureSwitches /// /// The backing field for . /// - private static int _enableDefaultCustomTypeMappings; - + private static int _enableDefaultCustomTypeMappings; + /// /// The backing field for . /// @@ -125,7 +125,7 @@ private static bool GetConfigurationValue(string propertyName, ref int cachedRes // Get the configuration switch value, or its default. // All feature switches have a default set in the .targets file. if (!AppContext.TryGetSwitch(propertyName, out bool isEnabled)) - { + { isEnabled = defaultValue; } @@ -145,6 +145,6 @@ private static bool GetConfigurationValue(string propertyName, ref int cachedRes public static bool IsWuxMode { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => GetConfigurationValue("CSWINRT_ENABLE_WUX_MODE", ref _isWuxMode); + get => GetConfigurationValue("CSWINRT_ENABLE_WUX_MODE", ref _isWuxMode, false); } } \ No newline at end of file From d8f57f854be02b6db65a13aa7776a2785d82d042 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Tue, 21 May 2024 15:31:32 -0700 Subject: [PATCH 20/46] Finally fix the NRE --- src/Authoring/WinRT.SourceGenerator/AotOptimizer.cs | 2 +- src/Authoring/WinRT.SourceGenerator/Helper.cs | 4 ++-- src/Authoring/WinRT.SourceGenerator/WinRTAotCodeFixer.cs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Authoring/WinRT.SourceGenerator/AotOptimizer.cs b/src/Authoring/WinRT.SourceGenerator/AotOptimizer.cs index 8a324ac51..85e75d775 100644 --- a/src/Authoring/WinRT.SourceGenerator/AotOptimizer.cs +++ b/src/Authoring/WinRT.SourceGenerator/AotOptimizer.cs @@ -326,7 +326,7 @@ internal static VtableAttribute GetVtableAttributeToAdd( return default; } - if (GeneratorHelper.HasNonInstantiatedWinRTGeneric(symbol)) + if (GeneratorHelper.HasNonInstantiatedWinRTGeneric(symbol, mapper)) { return default; } diff --git a/src/Authoring/WinRT.SourceGenerator/Helper.cs b/src/Authoring/WinRT.SourceGenerator/Helper.cs index 31d9ff3b8..6169ede1e 100644 --- a/src/Authoring/WinRT.SourceGenerator/Helper.cs +++ b/src/Authoring/WinRT.SourceGenerator/Helper.cs @@ -341,14 +341,14 @@ public static bool IsInternalInterfaceFromReferences(INamedTypeSymbol iface, IAs // and is used by a WinRT interface. For instance, List where T is a generic. // If the generic isn't used by any WinRT interface, this returns false as for // instance, we can still generate the vtable attribute for it. - public static bool HasNonInstantiatedWinRTGeneric(ITypeSymbol symbol) + public static bool HasNonInstantiatedWinRTGeneric(ITypeSymbol symbol, TypeMapper mapper) { return symbol is INamedTypeSymbol namedType && (IsArgumentTypeParameter(namedType) || (namedType.TypeArguments.Any(IsArgumentTypeParameter) && namedType.AllInterfaces.Any(iface => iface.TypeArguments.Any(IsArgumentTypeParameter) && // Checks if without the non-instantiated generic, whether it would be a WinRT type. - IsWinRTType(iface.OriginalDefinition, null)))); + IsWinRTType(iface.OriginalDefinition, null, mapper)))); static bool IsArgumentTypeParameter(ITypeSymbol argument) { diff --git a/src/Authoring/WinRT.SourceGenerator/WinRTAotCodeFixer.cs b/src/Authoring/WinRT.SourceGenerator/WinRTAotCodeFixer.cs index 81b73076b..f0f009a15 100644 --- a/src/Authoring/WinRT.SourceGenerator/WinRTAotCodeFixer.cs +++ b/src/Authoring/WinRT.SourceGenerator/WinRTAotCodeFixer.cs @@ -56,7 +56,7 @@ public override void Initialize(AnalysisContext context) // and that it isn't already partial. if (!GeneratorHelper.IsPartial(namedType) && !GeneratorHelper.IsWinRTType(namedType, winrtTypeAttribute, typeMapper, isComponentProject, context.Compilation.Assembly) && - !GeneratorHelper.HasNonInstantiatedWinRTGeneric(namedType) && + !GeneratorHelper.HasNonInstantiatedWinRTGeneric(namedType, typeMapper) && !GeneratorHelper.HasAttributeWithType(namedType, winrtExposedTypeAttribute)) { foreach (var iface in namedType.AllInterfaces) From 8663e0ad5450d8f06bd9fb67b3339bdad92ff007 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Tue, 21 May 2024 16:24:55 -0700 Subject: [PATCH 21/46] Provide a mechanism to exclude additions (for use when different sections of the same namespace are emitted into multiple different projections, and only one should define the addition types) --- src/Projections/WinAppSDK/WinAppSDK.csproj | 1 + src/Projections/WinUI/WinUI.csproj | 3 ++- .../Windows.UI.Xaml/Windows.UI.Xaml.csproj | 3 +-- src/cswinrt/main.cpp | 11 ++++++++++- src/cswinrt/settings.h | 2 ++ 5 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/Projections/WinAppSDK/WinAppSDK.csproj b/src/Projections/WinAppSDK/WinAppSDK.csproj index b77e179c6..5fd5ae330 100644 --- a/src/Projections/WinAppSDK/WinAppSDK.csproj +++ b/src/Projections/WinAppSDK/WinAppSDK.csproj @@ -35,6 +35,7 @@ -include Windows.UI.Xaml.Media.Animation.ConditionallyIndependentlyAnimatableAttribute -include Windows.UI.Xaml.Media.Animation.IndependentlyAnimatableAttribute -include Windows.UI.Xaml.Media.Animation.ConditionallyIndependentlyAnimatableAttribute + -addition_exclude Windows.UI.Xaml.Media.Animation $([MSBuild]::NormalizeDirectory('$(NuGetPackageRoot)', 'microsoft.windowsappsdk', '$(MicrosoftWinAppSDKVersion)')) diff --git a/src/Projections/WinUI/WinUI.csproj b/src/Projections/WinUI/WinUI.csproj index a3b83d4f6..e5a1e4c35 100644 --- a/src/Projections/WinUI/WinUI.csproj +++ b/src/Projections/WinUI/WinUI.csproj @@ -37,7 +37,8 @@ -include Windows.UI.Xaml.Markup.MarkupExtensionReturnTypeAttribute -include Windows.UI.Xaml.Media.Animation.ConditionallyIndependentlyAnimatableAttribute -include Windows.UI.Xaml.Media.Animation.IndependentlyAnimatableAttribute --include Windows.UI.Xaml.Media.Animation.ConditionallyIndependentlyAnimatableAttribute +-include Windows.UI.Xaml.Media.Animation.ConditionallyIndependentlyAnimatableAttribute +-addition_exclude Windows.UI.Xaml.Media.Animation $([MSBuild]::NormalizeDirectory('$(NuGetPackageRoot)', 'microsoft.winui', '$(MicrosoftWinUIVersion)')) diff --git a/src/Projections/Windows.UI.Xaml/Windows.UI.Xaml.csproj b/src/Projections/Windows.UI.Xaml/Windows.UI.Xaml.csproj index 5bd3796fa..f4ca1fa5f 100644 --- a/src/Projections/Windows.UI.Xaml/Windows.UI.Xaml.csproj +++ b/src/Projections/Windows.UI.Xaml/Windows.UI.Xaml.csproj @@ -21,8 +21,7 @@ -exclude Windows -include Windows.UI.Xaml -exclude Windows.UI.Xaml.Media.Animation.ConditionallyIndependentlyAnimatableAttribute --exclude Windows.UI.Xaml.Media.Animation.KeyTime --exclude Windows.UI.Xaml.Media.Animation.RepeatBehavior +-addition_exclude Windows.UI.Xaml.Media.Animation diff --git a/src/cswinrt/main.cpp b/src/cswinrt/main.cpp index 2caa2a0fd..f9ce2764b 100644 --- a/src/cswinrt/main.cpp +++ b/src/cswinrt/main.cpp @@ -33,6 +33,7 @@ namespace cswinrt { "output", 0, 1, "", "Location of generated projection" }, { "include", 0, option::no_max, "", "One or more prefixes to include in projection" }, { "exclude", 0, option::no_max, "", "One or more prefixes to exclude from projection" }, + { "addition_exclude", 0, option::no_max, "", "One or more namespace prefixes to exclude from the projection additions" }, { "target", 0, 1, "", "Target TFM for projection. Omit for compatibility with .NET 6." }, { "component", 0, 0, {}, "Generate component projection." }, { "verbose", 0, 0, {}, "Show detailed progress information" }, @@ -113,6 +114,11 @@ Where is one or more of: settings.exclude.insert(exclude); } + for (auto&& addition_exclude : args.values("addition_exclude")) + { + settings.addition_exclude.insert(addition_exclude); + } + settings.output_folder = std::filesystem::absolute(args.value("output", "output")); create_directories(settings.output_folder); } @@ -137,6 +143,9 @@ Where is one or more of: cache c{ get_files_to_cache() }; settings.filter = { settings.include, settings.exclude }; + // Include all additions for included namespaces by default + settings.addition_filter = { settings.include, settings.addition_exclude }; + std::set componentActivatableClasses; if (settings.component) { @@ -322,7 +331,7 @@ Where is one or more of: // Custom additions to namespaces for (auto addition : strings::additions) { - if (ns == addition.name) + if (ns == addition.name && settings.addition_filter.includes(ns)) { w.write(addition.value); } diff --git a/src/cswinrt/settings.h b/src/cswinrt/settings.h index efdb304eb..b095f5d33 100644 --- a/src/cswinrt/settings.h +++ b/src/cswinrt/settings.h @@ -9,7 +9,9 @@ namespace cswinrt bool verbose{}; std::set include; std::set exclude; + std::set addition_exclude; winmd::reader::filter filter; + winmd::reader::filter addition_filter; bool netstandard_compat{}; bool net7_0_or_greater{}; bool component{}; From 14d285b7afbd295a4975581b54d39a3ce4110da4 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Thu, 23 May 2024 17:41:43 +0200 Subject: [PATCH 22/46] Fix property name in 'ILLink.Substitutions.xml' --- src/WinRT.Runtime/Configuration/FeatureSwitches.cs | 6 +++--- src/WinRT.Runtime/Configuration/ILLink.Substitutions.xml | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/WinRT.Runtime/Configuration/FeatureSwitches.cs b/src/WinRT.Runtime/Configuration/FeatureSwitches.cs index 128ea1440..b1a737b9b 100644 --- a/src/WinRT.Runtime/Configuration/FeatureSwitches.cs +++ b/src/WinRT.Runtime/Configuration/FeatureSwitches.cs @@ -24,7 +24,7 @@ internal static class FeatureSwitches /// /// The configuration property name for . /// - private const string EnablesDynamicObjectsSupportPropertyName = "CSWINRT_ENABLE_DYNAMIC_OBJECTS_SUPPORT"; + private const string EnableDynamicObjectsSupportPropertyName = "CSWINRT_ENABLE_DYNAMIC_OBJECTS_SUPPORT"; /// /// The configuration property name for . @@ -59,7 +59,7 @@ internal static class FeatureSwitches /// /// The backing field for . /// - private static int _enableDynamicObjectsSupportEnabled; + private static int _enableDynamicObjectsSupport; /// /// The backing field for . @@ -97,7 +97,7 @@ internal static class FeatureSwitches public static bool EnableDynamicObjectsSupport { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => GetConfigurationValue(EnablesDynamicObjectsSupportPropertyName, ref _enableDynamicObjectsSupportEnabled, true); + get => GetConfigurationValue(EnableDynamicObjectsSupportPropertyName, ref _enableDynamicObjectsSupport, true); } /// diff --git a/src/WinRT.Runtime/Configuration/ILLink.Substitutions.xml b/src/WinRT.Runtime/Configuration/ILLink.Substitutions.xml index f31e7caf0..7b6b0c941 100644 --- a/src/WinRT.Runtime/Configuration/ILLink.Substitutions.xml +++ b/src/WinRT.Runtime/Configuration/ILLink.Substitutions.xml @@ -3,8 +3,8 @@ - - + + From 8bc71ac437c12b1d09b035b5539dbeb13d87c7bf Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Thu, 23 May 2024 17:48:15 +0200 Subject: [PATCH 23/46] Rename 'FeatureSwitches' switch for WUX --- nuget/Microsoft.Windows.CsWinRT.targets | 20 ++++++------- .../Configuration/FeatureSwitches.cs | 28 +++++++++---------- .../Configuration/ILLink.Substitutions.xml | 8 +++--- src/WinRT.Runtime/GuidGenerator.cs | 2 +- src/WinRT.Runtime/Projections.cs | 2 +- .../INotifyCollectionChanged.net5.cs | 2 +- .../INotifyPropertyChanged.net5.cs | 2 +- .../NotifyCollectionChangedAction.cs | 2 +- .../NotifyCollectionChangedEventArgs.cs | 10 +++---- .../NotifyCollectionChangedEventHandler.cs | 2 +- .../Projections/PropertyChangedEventArgs.cs | 4 +-- .../PropertyChangedEventHandler.cs | 2 +- 12 files changed, 42 insertions(+), 42 deletions(-) diff --git a/nuget/Microsoft.Windows.CsWinRT.targets b/nuget/Microsoft.Windows.CsWinRT.targets index 483a8c7a4..38bcfaf60 100644 --- a/nuget/Microsoft.Windows.CsWinRT.targets +++ b/nuget/Microsoft.Windows.CsWinRT.targets @@ -295,16 +295,6 @@ $(CsWinRTInternalProjection) - - - - true - true - - - false - true - + + + + true + true + + + false + true + diff --git a/src/WinRT.Runtime/Configuration/FeatureSwitches.cs b/src/WinRT.Runtime/Configuration/FeatureSwitches.cs index b1a737b9b..41b785de5 100644 --- a/src/WinRT.Runtime/Configuration/FeatureSwitches.cs +++ b/src/WinRT.Runtime/Configuration/FeatureSwitches.cs @@ -52,9 +52,9 @@ internal static class FeatureSwitches private const string EnableIDynamicInterfaceCastableSupportPropertyName = "CSWINRT_ENABLE_IDYNAMICINTERFACECASTABLE"; /// - /// The configuration property name for . + /// The configuration property name for . /// - private const string IsWuxModePropertyName = "CSWINRT_ENABLE_WUX_MODE"; + private const string UseWindowsUIXamlProjectionsPropertyName = "CSWINRT_USE_WINDOWS_UI_XAML_PROJECTIONS"; /// /// The backing field for . @@ -87,9 +87,9 @@ internal static class FeatureSwitches private static int _enableIDynamicInterfaceCastableSupport; /// - /// The backing field for . + /// The backing field for . /// - private static int _isWuxMode; + private static int _useWindowsUIXamlProjections; /// /// Gets a value indicating whether or not projections support for dynamic objects is enabled (defaults to ). @@ -145,6 +145,15 @@ public static bool EnableIDynamicInterfaceCastableSupport get => GetConfigurationValue(EnableIDynamicInterfaceCastableSupportPropertyName, ref _enableIDynamicInterfaceCastableSupport, true); } + /// + /// Gets a value indicating whether to project .NET types to their Windows.UI.Xaml equivalents instead of their Microsoft.UI.Xaml equivalents. + /// + public static bool UseWindowsUIXamlProjections + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => GetConfigurationValue(UseWindowsUIXamlProjectionsPropertyName, ref _useWindowsUIXamlProjections, false); + } + /// /// Gets a configuration value for a specified property. /// @@ -180,16 +189,7 @@ private static bool GetConfigurationValue(string propertyName, ref int cachedRes // Update the cached result cachedResult = isEnabled ? 1 : -1; - return isEnabled; - } - - /// - /// true if types from .NET are projected to their Windows.UI.Xaml equivalents instead of their Microsoft.UI.Xaml equivalents. - /// - public static bool IsWuxMode - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => GetConfigurationValue(IsWuxModePropertyName, ref _isWuxMode, false); + return isEnabled; } } } \ No newline at end of file diff --git a/src/WinRT.Runtime/Configuration/ILLink.Substitutions.xml b/src/WinRT.Runtime/Configuration/ILLink.Substitutions.xml index 7b6b0c941..c962b9db2 100644 --- a/src/WinRT.Runtime/Configuration/ILLink.Substitutions.xml +++ b/src/WinRT.Runtime/Configuration/ILLink.Substitutions.xml @@ -5,10 +5,6 @@ - - - - @@ -29,6 +25,10 @@ + + + + diff --git a/src/WinRT.Runtime/GuidGenerator.cs b/src/WinRT.Runtime/GuidGenerator.cs index 967671e1d..4343fbdfc 100644 --- a/src/WinRT.Runtime/GuidGenerator.cs +++ b/src/WinRT.Runtime/GuidGenerator.cs @@ -51,7 +51,7 @@ public static Guid GetIID( internal static Guid GetWuxMuxIID(WuxMuxProjectedTypeAttribute wuxMuxAttribute) { - return FeatureSwitches.IsWuxMode + return FeatureSwitches.UseWindowsUIXamlProjections ? wuxMuxAttribute.WuxIID : wuxMuxAttribute.MuxIID; } diff --git a/src/WinRT.Runtime/Projections.cs b/src/WinRT.Runtime/Projections.cs index a1d6d6959..4115c3539 100644 --- a/src/WinRT.Runtime/Projections.cs +++ b/src/WinRT.Runtime/Projections.cs @@ -69,7 +69,7 @@ static Projections() RegisterCustomAbiTypeMappingNoLock(typeof(TimeSpan), typeof(ABI.System.TimeSpan), "Windows.Foundation.TimeSpan"); RegisterCustomAbiTypeMappingNoLock(typeof(Uri), typeof(ABI.System.Uri), "Windows.Foundation.Uri", isRuntimeClass: true); - if (!FeatureSwitches.IsWuxMode) + if (!FeatureSwitches.UseWindowsUIXamlProjections) { RegisterCustomAbiTypeMappingNoLock(typeof(DataErrorsChangedEventArgs), typeof(ABI.System.ComponentModel.DataErrorsChangedEventArgs), "Microsoft.UI.Xaml.Data.DataErrorsChangedEventArgs", isRuntimeClass: true); RegisterCustomAbiTypeMappingNoLock(typeof(PropertyChangedEventArgs), typeof(ABI.System.ComponentModel.PropertyChangedEventArgs), "Microsoft.UI.Xaml.Data.PropertyChangedEventArgs", isRuntimeClass: true); diff --git a/src/WinRT.Runtime/Projections/INotifyCollectionChanged.net5.cs b/src/WinRT.Runtime/Projections/INotifyCollectionChanged.net5.cs index 755459504..1666d828e 100644 --- a/src/WinRT.Runtime/Projections/INotifyCollectionChanged.net5.cs +++ b/src/WinRT.Runtime/Projections/INotifyCollectionChanged.net5.cs @@ -40,7 +40,7 @@ static class INotifyCollectionChangedMethods public static global::System.Guid IID { get; } = new(GetIID()); private static ReadOnlySpan GetIID() - => FeatureSwitches.IsWuxMode + => FeatureSwitches.UseWindowsUIXamlProjections ? new(new byte[] { 0xd5, 0x67, 0xb1, 0x28, 0x31, 0x1a, 0x5b, 0x46, 0x9b, 0x25, 0xd5, 0xc3, 0xae, 0x68, 0x6c, 0x40 }) : new(new byte[] { 0xe1, 0x55, 0x1, 0x53, 0xa5, 0x28, 0x93, 0x56, 0x87, 0xce, 0x30, 0x72, 0x4d, 0x95, 0xa0, 0x6d }); public static IntPtr AbiToProjectionVftablePtr => INotifyCollectionChanged.Vftbl.AbiToProjectionVftablePtr; diff --git a/src/WinRT.Runtime/Projections/INotifyPropertyChanged.net5.cs b/src/WinRT.Runtime/Projections/INotifyPropertyChanged.net5.cs index 2d42e6da2..08e2e69d8 100644 --- a/src/WinRT.Runtime/Projections/INotifyPropertyChanged.net5.cs +++ b/src/WinRT.Runtime/Projections/INotifyPropertyChanged.net5.cs @@ -19,7 +19,7 @@ static class INotifyPropertyChangedMethods public static global::System.Guid IID { get; } = new(GetIID()); private static ReadOnlySpan GetIID() - => FeatureSwitches.IsWuxMode + => FeatureSwitches.UseWindowsUIXamlProjections ? new(new byte[] { 0x9c, 0xd6, 0x75, 0xcf, 0xf4, 0xf2, 0x6b, 0x48, 0xb3, 0x2, 0xbb, 0x4c, 0x9, 0xba, 0xeb, 0xfa }) : new(new byte[] { 0x1, 0x76, 0xb1, 0x90, 0x65, 0xb0, 0x6e, 0x58, 0x83, 0xd9, 0x9a, 0xdc, 0x3a, 0x69, 0x52, 0x84 }); diff --git a/src/WinRT.Runtime/Projections/NotifyCollectionChangedAction.cs b/src/WinRT.Runtime/Projections/NotifyCollectionChangedAction.cs index 7d234390b..dccf0cc49 100644 --- a/src/WinRT.Runtime/Projections/NotifyCollectionChangedAction.cs +++ b/src/WinRT.Runtime/Projections/NotifyCollectionChangedAction.cs @@ -8,7 +8,7 @@ namespace ABI.System.Collections.Specialized static class NotifyCollectionChangedAction { public static string GetGuidSignature() => - FeatureSwitches.IsWuxMode + FeatureSwitches.UseWindowsUIXamlProjections ? "enum(Windows.UI.Xaml.Interop.NotifyCollectionChangedAction;i4)" : "enum(Microsoft.UI.Xaml.Interop.NotifyCollectionChangedAction;i4)"; } diff --git a/src/WinRT.Runtime/Projections/NotifyCollectionChangedEventArgs.cs b/src/WinRT.Runtime/Projections/NotifyCollectionChangedEventArgs.cs index 4f8632543..a8c947ac9 100644 --- a/src/WinRT.Runtime/Projections/NotifyCollectionChangedEventArgs.cs +++ b/src/WinRT.Runtime/Projections/NotifyCollectionChangedEventArgs.cs @@ -21,7 +21,7 @@ internal sealed unsafe class WinRTNotifyCollectionChangedEventArgsRuntimeClassFa public IntPtr ThisPtr => _obj.ThisPtr; private static readonly Guid Factory_IID = - FeatureSwitches.IsWuxMode + FeatureSwitches.UseWindowsUIXamlProjections ? IID.IID_WUX_INotifyCollectionChangedEventArgsFactory : IID.IID_MUX_INotifyCollectionChangedEventArgsFactory; @@ -30,11 +30,11 @@ internal sealed unsafe class WinRTNotifyCollectionChangedEventArgsRuntimeClassFa private WinRTNotifyCollectionChangedEventArgsRuntimeClassFactory() { #if NET - _obj = FeatureSwitches.IsWuxMode + _obj = FeatureSwitches.UseWindowsUIXamlProjections ? ActivationFactory.Get("Windows.UI.Xaml.Interop.NotifyCollectionChangedEventArgs") : ActivationFactory.Get("Microsoft.UI.Xaml.Interop.NotifyCollectionChangedEventArgs"); #else - _obj = FeatureSwitches.IsWuxMode + _obj = FeatureSwitches.UseWindowsUIXamlProjections ? ActivationFactory.Get("Windows.UI.Xaml.Interop.NotifyCollectionChangedEventArgs", Factory_IID) : ActivationFactory.Get("Microsoft.UI.Xaml.Interop.NotifyCollectionChangedEventArgs", Factory_IID); #endif @@ -90,7 +90,7 @@ namespace ABI.System.Collections.Specialized struct NotifyCollectionChangedEventArgs { private static readonly Guid Interface_IID = - FeatureSwitches.IsWuxMode + FeatureSwitches.UseWindowsUIXamlProjections ? IID.IID_WUX_INotifyCollectionChangedEventArgs : IID.IID_MUX_INotifyCollectionChangedEventArgs; @@ -212,7 +212,7 @@ public static IntPtr FromManaged(global::System.Collections.Specialized.NotifyCo public static string GetGuidSignature() { - if (FeatureSwitches.IsWuxMode) + if (FeatureSwitches.UseWindowsUIXamlProjections) { return "rc(Windows.UI.Xaml.Interop.NotifyCollectionChangedEventArgs;{4cf68d33-e3f2-4964-b85e-945b4f7e2f21})"; } diff --git a/src/WinRT.Runtime/Projections/NotifyCollectionChangedEventHandler.cs b/src/WinRT.Runtime/Projections/NotifyCollectionChangedEventHandler.cs index fedbd57e6..041ce1c31 100644 --- a/src/WinRT.Runtime/Projections/NotifyCollectionChangedEventHandler.cs +++ b/src/WinRT.Runtime/Projections/NotifyCollectionChangedEventHandler.cs @@ -44,7 +44,7 @@ static unsafe NotifyCollectionChangedEventHandler() AbiToProjectionVftablePtr = nativeVftbl; ComWrappersSupport.RegisterDelegateFactory(typeof(global::System.Collections.Specialized.NotifyCollectionChangedEventHandler), CreateRcw); - IID = FeatureSwitches.IsWuxMode + IID = FeatureSwitches.UseWindowsUIXamlProjections ? Guid.Parse("CA10B37C-F382-4591-8557-5E24965279B0") : Guid.Parse("8B0909DC-2005-5D93-BF8A-725F017BAA8D"); } diff --git a/src/WinRT.Runtime/Projections/PropertyChangedEventArgs.cs b/src/WinRT.Runtime/Projections/PropertyChangedEventArgs.cs index 84836f4c9..92f99a6ae 100644 --- a/src/WinRT.Runtime/Projections/PropertyChangedEventArgs.cs +++ b/src/WinRT.Runtime/Projections/PropertyChangedEventArgs.cs @@ -175,7 +175,7 @@ namespace ABI.System.ComponentModel unsafe struct PropertyChangedEventArgs { private static readonly ABI.Microsoft.UI.Xaml.Data.IWinRTPropertyChangedEventArgsRuntimeClassFactory Instance = - FeatureSwitches.IsWuxMode + FeatureSwitches.UseWindowsUIXamlProjections ? new ABI.Microsoft.UI.Xaml.Data.WUXPropertyChangedEventArgsRuntimeClassFactory(ActivationFactory.Get("Windows.UI.Xaml.Data.PropertyChangedEventArgs")) : new ABI.Microsoft.UI.Xaml.Data.MUXPropertyChangedEventArgsRuntimeClassFactory(ActivationFactory.Get("Microsoft.UI.Xaml.Data.PropertyChangedEventArgs")); @@ -249,7 +249,7 @@ public static IntPtr FromManaged(global::System.ComponentModel.PropertyChangedEv public static string GetGuidSignature() { - if (FeatureSwitches.IsWuxMode) + if (FeatureSwitches.UseWindowsUIXamlProjections) { return "rc(Windows.UI.Xaml.Data.NotifyPropertyChangedEventArgs;{4f33a9a0-5cf4-47a4-b16f-d7faaf17457e})"; } diff --git a/src/WinRT.Runtime/Projections/PropertyChangedEventHandler.cs b/src/WinRT.Runtime/Projections/PropertyChangedEventHandler.cs index 1f6a6be6d..2339955cc 100644 --- a/src/WinRT.Runtime/Projections/PropertyChangedEventHandler.cs +++ b/src/WinRT.Runtime/Projections/PropertyChangedEventHandler.cs @@ -42,7 +42,7 @@ static unsafe PropertyChangedEventHandler() *(IDelegateVftbl*)nativeVftbl = AbiToProjectionVftable; AbiToProjectionVftablePtr = nativeVftbl; ComWrappersSupport.RegisterDelegateFactory(typeof(global::System.ComponentModel.PropertyChangedEventHandler), CreateRcw); - IID = FeatureSwitches.IsWuxMode + IID = FeatureSwitches.UseWindowsUIXamlProjections ? Guid.Parse("50F19C16-0A22-4D8E-A089-1EA9951657D2") : Guid.Parse("E3DE52F6-1E32-5DA6-BB2D-B5B6096C962D"); } From c3ba19530f55a49d3049f5120c850d4dc519204c Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Fri, 24 May 2024 09:47:04 +0200 Subject: [PATCH 24/46] Remove unnecessary mapping collection --- src/WinRT.Runtime/Projections.cs | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/WinRT.Runtime/Projections.cs b/src/WinRT.Runtime/Projections.cs index 4115c3539..f6e6475ef 100644 --- a/src/WinRT.Runtime/Projections.cs +++ b/src/WinRT.Runtime/Projections.cs @@ -26,11 +26,9 @@ namespace WinRT #endif static partial class Projections { - private static readonly ReaderWriterLockSlim rwlock = new ReaderWriterLockSlim(); private static readonly Dictionary CustomTypeToHelperTypeMappings = new Dictionary(); - private static readonly Dictionary CustomTypeToIIDMappings = new Dictionary(); private static readonly Dictionary CustomAbiTypeToTypeMappings = new Dictionary(); private static readonly Dictionary CustomAbiTypeNameToTypeMappings = new Dictionary(StringComparer.Ordinal); private static readonly Dictionary CustomTypeToAbiTypeNameMappings = new Dictionary(); @@ -359,11 +357,6 @@ public static string FindCustomAbiTypeNameForType(Type type) } } - internal static Guid? FindCustomIIDForAbiType(Type type) - { - return CustomTypeToIIDMappings.TryGetValue(type, out Guid iid) ? iid : null; - } - private readonly static ConcurrentDictionary IsTypeWindowsRuntimeTypeCache = new(); public static bool IsTypeWindowsRuntimeType(Type type) { From 4fdcd114d8d46ed996e8572dc825e69bd1d2abe0 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Fri, 24 May 2024 09:49:41 +0200 Subject: [PATCH 25/46] Remove leftover 'Debugger.Launch' call --- src/WinRT.Runtime/Projections/INotifyPropertyChanged.net5.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/WinRT.Runtime/Projections/INotifyPropertyChanged.net5.cs b/src/WinRT.Runtime/Projections/INotifyPropertyChanged.net5.cs index 08e2e69d8..8e72c723c 100644 --- a/src/WinRT.Runtime/Projections/INotifyPropertyChanged.net5.cs +++ b/src/WinRT.Runtime/Projections/INotifyPropertyChanged.net5.cs @@ -2,7 +2,6 @@ // Licensed under the MIT License. using System; -using System.Reflection; using System.Runtime.InteropServices; using WinRT; using WinRT.Interop; @@ -99,7 +98,6 @@ private static unsafe int Do_Abi_add_PropertyChanged_0(IntPtr thisPtr, IntPtr ha *token = default; try { - global::System.Diagnostics.Debugger.Launch(); var __this = global::WinRT.ComWrappersSupport.FindObject(thisPtr); var __handler = global::ABI.System.ComponentModel.PropertyChangedEventHandler.FromAbi(handler); *token = _PropertyChanged_TokenTables.GetOrCreateValue(__this).AddEventHandler(__handler); From 4fe2d47347c416cf38497b06bc18069ec3284546 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Fri, 24 May 2024 11:37:47 +0200 Subject: [PATCH 26/46] Remove 'IPropertyChangedEventArgsVftbl' type --- .../Projections/PropertyChangedEventArgs.cs | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/src/WinRT.Runtime/Projections/PropertyChangedEventArgs.cs b/src/WinRT.Runtime/Projections/PropertyChangedEventArgs.cs index 92f99a6ae..a789b8611 100644 --- a/src/WinRT.Runtime/Projections/PropertyChangedEventArgs.cs +++ b/src/WinRT.Runtime/Projections/PropertyChangedEventArgs.cs @@ -9,15 +9,6 @@ namespace ABI.Microsoft.UI.Xaml.Data { - [Guid("63D0C952-396B-54F4-AF8C-BA8724A427BF")] - [StructLayout(LayoutKind.Sequential)] - internal unsafe struct IPropertyChangedEventArgsVftbl - { - internal IInspectable.Vftbl IInspectableVftbl; - private void* _get_PropertyName_0; - public delegate* unmanaged[Stdcall] get_PropertyName_0 => (delegate* unmanaged[Stdcall])_get_PropertyName_0; - } - internal interface IWinRTPropertyChangedEventArgsRuntimeClassFactory { IObjectReference CreateInstance(string name, object baseInterface, out IObjectReference innerInterface); @@ -213,7 +204,7 @@ public static ObjectReferenceValue CreateMarshaler2(global::System.ComponentMode { // We can use the Microsoft.UI.Xaml.Data.IPropertyChangedEventArgsVftbl here in both WUX and MUX because the vtables are laid out the same and we know // that we have either a MUX or WUX IPropertyChangedEventArgs pointer in ptr. - ExceptionHelpers.ThrowExceptionForHR((**(ABI.Microsoft.UI.Xaml.Data.IPropertyChangedEventArgsVftbl**)ptr).get_PropertyName_0(ptr, &propertyName)); + ExceptionHelpers.ThrowExceptionForHR(((delegate* unmanaged[Stdcall])(*(void***)ptr)[6])(ptr, &propertyName)); return new global::System.ComponentModel.PropertyChangedEventArgs(MarshalString.FromAbi(propertyName)); } finally From 61091cde64da23173cf703382035928ecc9c8d1f Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Fri, 24 May 2024 11:46:19 +0200 Subject: [PATCH 27/46] Optimize 'PropertyChangedEventArgsRuntimeClassFactory' --- .../Projections/PropertyChangedEventArgs.cs | 125 ++++-------------- 1 file changed, 26 insertions(+), 99 deletions(-) diff --git a/src/WinRT.Runtime/Projections/PropertyChangedEventArgs.cs b/src/WinRT.Runtime/Projections/PropertyChangedEventArgs.cs index a789b8611..22f6c9a04 100644 --- a/src/WinRT.Runtime/Projections/PropertyChangedEventArgs.cs +++ b/src/WinRT.Runtime/Projections/PropertyChangedEventArgs.cs @@ -9,106 +9,23 @@ namespace ABI.Microsoft.UI.Xaml.Data { - internal interface IWinRTPropertyChangedEventArgsRuntimeClassFactory + internal sealed unsafe class PropertyChangedEventArgsRuntimeClassFactory { - IObjectReference CreateInstance(string name, object baseInterface, out IObjectReference innerInterface); - ObjectReferenceValue CreateInstance(string name); - } -#if !NET - [global::WinRT.ObjectReferenceWrapper(nameof(_obj))] -#endif - [Guid("7C0C27A8-0B41-5070-B160-FC9AE960A36C")] - internal sealed unsafe class MUXPropertyChangedEventArgsRuntimeClassFactory : IWinRTPropertyChangedEventArgsRuntimeClassFactory - { - [Guid("7C0C27A8-0B41-5070-B160-FC9AE960A36C")] - [StructLayout(LayoutKind.Sequential)] - public struct Vftbl - { - internal IInspectable.Vftbl IInspectableVftbl; - private void* _CreateInstance_0; - public delegate* unmanaged[Stdcall] CreateInstance_0 => (delegate* unmanaged[Stdcall])_CreateInstance_0; - } - public static ObjectReference FromAbi(IntPtr thisPtr) => ObjectReference.FromAbi(thisPtr, global::WinRT.Interop.IID.IID_MUX_PropertyChangedEventArgsRuntimeClassFactory); - - public static implicit operator MUXPropertyChangedEventArgsRuntimeClassFactory(IObjectReference obj) => (obj != null) ? new MUXPropertyChangedEventArgsRuntimeClassFactory(obj) : null; - public static implicit operator MUXPropertyChangedEventArgsRuntimeClassFactory(ObjectReference obj) => (obj != null) ? new MUXPropertyChangedEventArgsRuntimeClassFactory(obj) : null; - private readonly ObjectReference _obj; - public IntPtr ThisPtr => _obj.ThisPtr; - public MUXPropertyChangedEventArgsRuntimeClassFactory(IObjectReference obj) : this(obj.As(IID.IID_MUX_PropertyChangedEventArgsRuntimeClassFactory)) { } - public MUXPropertyChangedEventArgsRuntimeClassFactory(ObjectReference obj) - { - _obj = obj; - } + private readonly ObjectReference _obj; - public unsafe IObjectReference CreateInstance(string name, object baseInterface, out IObjectReference innerInterface) + public PropertyChangedEventArgsRuntimeClassFactory() { - IObjectReference __baseInterface = default; - IntPtr __innerInterface = default; - IntPtr __retval = default; - try - { - MarshalString.Pinnable __name = new(name); - fixed (void* ___name = __name) - { - __baseInterface = MarshalInspectable.CreateMarshaler(baseInterface); - global::WinRT.ExceptionHelpers.ThrowExceptionForHR(_obj.Vftbl.CreateInstance_0(ThisPtr, MarshalString.GetAbi(ref __name), MarshalInspectable.GetAbi(__baseInterface), &__innerInterface, &__retval)); - innerInterface = ObjectReference.FromAbi(__innerInterface, IID.IID_IUnknown); - return ObjectReference.Attach(ref __retval, IID.IID_IUnknown); - } - } - finally - { - MarshalInspectable.DisposeMarshaler(__baseInterface); - MarshalInspectable.DisposeAbi(__innerInterface); - MarshalInspectable.DisposeAbi(__retval); - } - } - - public unsafe ObjectReferenceValue CreateInstance(string name) - { - IntPtr __innerInterface = default; - IntPtr __retval = default; - try + if (FeatureSwitches.UseWindowsUIXamlProjections) { - MarshalString.Pinnable __name = new(name); - fixed (void* ___name = __name) - { - global::WinRT.ExceptionHelpers.ThrowExceptionForHR(_obj.Vftbl.CreateInstance_0(ThisPtr, MarshalString.GetAbi(ref __name), IntPtr.Zero, &__innerInterface, &__retval)); - return new ObjectReferenceValue(__retval); - } + _obj = ActivationFactory.Get("Windows.UI.Xaml.Data.PropertyChangedEventArgs").As(IID.IID_WUX_PropertyChangedEventArgsRuntimeClassFactory); } - finally + else { - MarshalInspectable.DisposeAbi(__innerInterface); + _obj = ActivationFactory.Get("Microsoft.UI.Xaml.Data.PropertyChangedEventArgs").As(IID.IID_MUX_PropertyChangedEventArgsRuntimeClassFactory); } } - } - - - - [global::WinRT.ObjectReferenceWrapper(nameof(_obj))] - [Guid("6DCC9C03-E0C7-4EEE-8EA9-37E3406EEB1C")] - internal sealed unsafe class WUXPropertyChangedEventArgsRuntimeClassFactory : IWinRTPropertyChangedEventArgsRuntimeClassFactory - { - [Guid("6DCC9C03-E0C7-4EEE-8EA9-37E3406EEB1C")] - [StructLayout(LayoutKind.Sequential)] - public struct Vftbl - { - internal IInspectable.Vftbl IInspectableVftbl; - private void* _CreateInstance_0; - public delegate* unmanaged[Stdcall] CreateInstance_0 => (delegate* unmanaged[Stdcall])_CreateInstance_0; - } - public static ObjectReference FromAbi(IntPtr thisPtr) => ObjectReference.FromAbi(thisPtr, IID.IID_WUX_PropertyChangedEventArgsRuntimeClassFactory); - - private readonly ObjectReference _obj; - public IntPtr ThisPtr => _obj.ThisPtr; - public WUXPropertyChangedEventArgsRuntimeClassFactory(IObjectReference obj) : this(obj.As(IID.IID_WUX_PropertyChangedEventArgsRuntimeClassFactory)) { } - public WUXPropertyChangedEventArgsRuntimeClassFactory(ObjectReference obj) - { - _obj = obj; - } - public unsafe IObjectReference CreateInstance(string name, object baseInterface, out IObjectReference innerInterface) + public IObjectReference CreateInstance(string name, object baseInterface, out IObjectReference innerInterface) { IObjectReference __baseInterface = default; IntPtr __innerInterface = default; @@ -119,7 +36,14 @@ public unsafe IObjectReference CreateInstance(string name, object baseInterface, fixed (void* ___name = __name) { __baseInterface = MarshalInspectable.CreateMarshaler(baseInterface); - global::WinRT.ExceptionHelpers.ThrowExceptionForHR(_obj.Vftbl.CreateInstance_0(ThisPtr, MarshalString.GetAbi(ref __name), MarshalInspectable.GetAbi(__baseInterface), &__innerInterface, &__retval)); + IntPtr thisPtr = _obj.ThisPtr; + global::WinRT.ExceptionHelpers.ThrowExceptionForHR( + ((delegate* unmanaged[Stdcall])(*(void***)thisPtr)[6])( + thisPtr, + MarshalString.GetAbi(ref __name), + MarshalInspectable.GetAbi(__baseInterface), + &__innerInterface, + &__retval)); innerInterface = ObjectReference.FromAbi(__innerInterface, IID.IID_IUnknown); return ObjectReference.Attach(ref __retval, IID.IID_IUnknown); } @@ -132,7 +56,7 @@ public unsafe IObjectReference CreateInstance(string name, object baseInterface, } } - public unsafe ObjectReferenceValue CreateInstance(string name) + public ObjectReferenceValue CreateInstance(string name) { IntPtr __innerInterface = default; IntPtr __retval = default; @@ -141,7 +65,14 @@ public unsafe ObjectReferenceValue CreateInstance(string name) MarshalString.Pinnable __name = new(name); fixed (void* ___name = __name) { - global::WinRT.ExceptionHelpers.ThrowExceptionForHR(_obj.Vftbl.CreateInstance_0(ThisPtr, MarshalString.GetAbi(ref __name), IntPtr.Zero, &__innerInterface, &__retval)); + IntPtr thisPtr = _obj.ThisPtr; + global::WinRT.ExceptionHelpers.ThrowExceptionForHR( + ((delegate* unmanaged[Stdcall])(*(void***)thisPtr)[6])( + thisPtr, + MarshalString.GetAbi(ref __name), + IntPtr.Zero, + &__innerInterface, + &__retval)); return new ObjectReferenceValue(__retval); } } @@ -150,7 +81,6 @@ public unsafe ObjectReferenceValue CreateInstance(string name) MarshalInspectable.DisposeAbi(__innerInterface); } } - } } @@ -165,10 +95,7 @@ namespace ABI.System.ComponentModel #endif unsafe struct PropertyChangedEventArgs { - private static readonly ABI.Microsoft.UI.Xaml.Data.IWinRTPropertyChangedEventArgsRuntimeClassFactory Instance = - FeatureSwitches.UseWindowsUIXamlProjections - ? new ABI.Microsoft.UI.Xaml.Data.WUXPropertyChangedEventArgsRuntimeClassFactory(ActivationFactory.Get("Windows.UI.Xaml.Data.PropertyChangedEventArgs")) - : new ABI.Microsoft.UI.Xaml.Data.MUXPropertyChangedEventArgsRuntimeClassFactory(ActivationFactory.Get("Microsoft.UI.Xaml.Data.PropertyChangedEventArgs")); + private static readonly ABI.Microsoft.UI.Xaml.Data.PropertyChangedEventArgsRuntimeClassFactory Instance = new(); public static IObjectReference CreateMarshaler(global::System.ComponentModel.PropertyChangedEventArgs value) { From 3ade8ab60dc27752c5c9a56f12af230b7ef81397 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Wed, 5 Jun 2024 10:27:43 -0700 Subject: [PATCH 28/46] Fix merge conflicts --- src/Authoring/WinRT.SourceGenerator/Helper.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Authoring/WinRT.SourceGenerator/Helper.cs b/src/Authoring/WinRT.SourceGenerator/Helper.cs index cfcbcf01c..d06a1ff1c 100644 --- a/src/Authoring/WinRT.SourceGenerator/Helper.cs +++ b/src/Authoring/WinRT.SourceGenerator/Helper.cs @@ -411,14 +411,14 @@ public static bool HasAttributeWithType(ISymbol symbol, ITypeSymbol attributeTyp return false; } - public static Func IsWinRTTypeWithPotentialAuthoringComponentTypesFunc(Compilation compilation) + public static Func IsWinRTTypeWithPotentialAuthoringComponentTypesFunc(Compilation compilation) { var winrtTypeAttribute = compilation.GetTypeByMetadataName("WinRT.WindowsRuntimeTypeAttribute"); return IsWinRTTypeHelper; - bool IsWinRTTypeHelper(ISymbol type) + bool IsWinRTTypeHelper(ISymbol type, TypeMapper typeMapper) { - return IsWinRTType(type, winrtTypeAttribute, true, compilation.Assembly); + return IsWinRTType(type, winrtTypeAttribute, typeMapper, true, compilation.Assembly); } } From b6f74c29c0fc288ebae47d39c611e874fd8f692f Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Wed, 5 Jun 2024 10:29:10 -0700 Subject: [PATCH 29/46] Fix capitalization of an IID --- src/WinRT.Runtime/Interop/IID.g.cs | 2 +- src/WinRT.Runtime/Interop/IID.tt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/WinRT.Runtime/Interop/IID.g.cs b/src/WinRT.Runtime/Interop/IID.g.cs index 6578fe5e1..1908d90c1 100644 --- a/src/WinRT.Runtime/Interop/IID.g.cs +++ b/src/WinRT.Runtime/Interop/IID.g.cs @@ -465,7 +465,7 @@ internal static ref readonly Guid IID_MUX_INotifyCollectionChangedEventArgsFacto } } - /// The IID for WUX_INotifyCollectionChangedEventArgsFactory (b30c3e3a-df8d-44a5-9a38-7ac0d08ce63d). + /// The IID for WUX_INotifyCollectionChangedEventArgsFactory (B30C3E3A-DF8D-44A5-9A38-7AC0D08CE63D). internal static ref readonly Guid IID_WUX_INotifyCollectionChangedEventArgsFactory { [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/src/WinRT.Runtime/Interop/IID.tt b/src/WinRT.Runtime/Interop/IID.tt index 07ef5dbda..26bf4c795 100644 --- a/src/WinRT.Runtime/Interop/IID.tt +++ b/src/WinRT.Runtime/Interop/IID.tt @@ -40,7 +40,7 @@ var entries = new (string Name, string IID, bool IsPublic)[] ("ILanguageExceptionErrorInfo", "04A2DBF3-DF83-116C-0946-0812ABF6E07D", false), ("IRestrictedErrorInfo", "82BA7092-4C88-427D-A7BC-16DD93FEB67E", false), ("MUX_INotifyCollectionChangedEventArgsFactory", "5108EBA4-4892-5A20-8374-A96815E0FD27", false), - ("WUX_INotifyCollectionChangedEventArgsFactory", "b30c3e3a-df8d-44a5-9a38-7ac0d08ce63d", false), + ("WUX_INotifyCollectionChangedEventArgsFactory", "B30C3E3A-DF8D-44A5-9A38-7AC0D08CE63D", false), ("MUX_INotifyCollectionChangedEventArgs", "DA049FF2-D2E0-5FE8-8C7B-F87F26060B6F", false), ("WUX_INotifyCollectionChangedEventArgs", "4CF68D33-E3F2-4964-B85E-945B4F7E2F21", false), ("MUX_PropertyChangedEventArgsRuntimeClassFactory", "7C0C27A8-0B41-5070-B160-FC9AE960A36C", false), From 7cdd72cc98b56f718b1a36a2926ea463ec74452a Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Wed, 5 Jun 2024 10:43:41 -0700 Subject: [PATCH 30/46] Centralize last WUX/MUX IIDs --- src/WinRT.Runtime/Interop/IID.g.cs | 150 ++++++++++++------ src/WinRT.Runtime/Interop/IID.tt | 6 +- .../INotifyCollectionChanged.net5.cs | 9 +- .../INotifyPropertyChanged.net5.cs | 10 +- 4 files changed, 110 insertions(+), 65 deletions(-) diff --git a/src/WinRT.Runtime/Interop/IID.g.cs b/src/WinRT.Runtime/Interop/IID.g.cs index 1908d90c1..5bd40a182 100644 --- a/src/WinRT.Runtime/Interop/IID.g.cs +++ b/src/WinRT.Runtime/Interop/IID.g.cs @@ -440,6 +440,106 @@ internal static ref readonly Guid IID_IRestrictedErrorInfo } } + /// The IID for MUX_INotifyPropertyChanged (90B17601-B065-586E-83D9-9ADC3A695284). + internal static ref readonly Guid IID_MUX_INotifyPropertyChanged + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get + { + ReadOnlySpan data = new byte[] + { + 0x01, 0x76, 0xB1, 0x90, + 0x65, 0xB0, + 0x6E, 0x58, + 0x83, + 0xD9, + 0x9A, + 0xDC, + 0x3A, + 0x69, + 0x52, + 0x84 + }; + + return ref Unsafe.As(ref MemoryMarshal.GetReference(data)); + } + } + + /// The IID for WUX_INotifyPropertyChanged (CF75D69C-F2F4-486B-B302-BB4C09BAEBFA). + internal static ref readonly Guid IID_WUX_INotifyPropertyChanged + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get + { + ReadOnlySpan data = new byte[] + { + 0x9C, 0xD6, 0x75, 0xCF, + 0xF4, 0xF2, + 0x6B, 0x48, + 0xB3, + 0x02, + 0xBB, + 0x4C, + 0x09, + 0xBA, + 0xEB, + 0xFA + }; + + return ref Unsafe.As(ref MemoryMarshal.GetReference(data)); + } + } + + /// The IID for MUX_INotifyCollectionChanged (530155E1-28A5-5693-87CE-30724D95A06D). + internal static ref readonly Guid IID_MUX_INotifyCollectionChanged + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get + { + ReadOnlySpan data = new byte[] + { + 0xE1, 0x55, 0x01, 0x53, + 0xA5, 0x28, + 0x93, 0x56, + 0x87, + 0xCE, + 0x30, + 0x72, + 0x4D, + 0x95, + 0xA0, + 0x6D + }; + + return ref Unsafe.As(ref MemoryMarshal.GetReference(data)); + } + } + + /// The IID for WUX_INotifyCollectionChanged (28B167D5-1A31-465B-9B25-D5C3AE686C40). + internal static ref readonly Guid IID_WUX_INotifyCollectionChanged + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get + { + ReadOnlySpan data = new byte[] + { + 0xD5, 0x67, 0xB1, 0x28, + 0x31, 0x1A, + 0x5B, 0x46, + 0x9B, + 0x25, + 0xD5, + 0xC3, + 0xAE, + 0x68, + 0x6C, + 0x40 + }; + + return ref Unsafe.As(ref MemoryMarshal.GetReference(data)); + } + } + /// The IID for MUX_INotifyCollectionChangedEventArgsFactory (5108EBA4-4892-5A20-8374-A96815E0FD27). internal static ref readonly Guid IID_MUX_INotifyCollectionChangedEventArgsFactory { @@ -665,56 +765,6 @@ internal static ref readonly Guid IID_INotifyDataErrorInfo } } - /// The IID for INotifyPropertyChanged (90B17601-B065-586E-83D9-9ADC3A695284). - internal static ref readonly Guid IID_INotifyPropertyChanged - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get - { - ReadOnlySpan data = new byte[] - { - 0x01, 0x76, 0xB1, 0x90, - 0x65, 0xB0, - 0x6E, 0x58, - 0x83, - 0xD9, - 0x9A, - 0xDC, - 0x3A, - 0x69, - 0x52, - 0x84 - }; - - return ref Unsafe.As(ref MemoryMarshal.GetReference(data)); - } - } - - /// The IID for INotifyCollectionChanged (530155E1-28A5-5693-87CE-30724D95A06D). - internal static ref readonly Guid IID_INotifyCollectionChanged - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get - { - ReadOnlySpan data = new byte[] - { - 0xE1, 0x55, 0x01, 0x53, - 0xA5, 0x28, - 0x93, 0x56, - 0x87, - 0xCE, - 0x30, - 0x72, - 0x4D, - 0x95, - 0xA0, - 0x6D - }; - - return ref Unsafe.As(ref MemoryMarshal.GetReference(data)); - } - } - /// The IID for ICommand (E5AF3542-CA67-4081-995B-709DD13792DF). internal static ref readonly Guid IID_ICommand { diff --git a/src/WinRT.Runtime/Interop/IID.tt b/src/WinRT.Runtime/Interop/IID.tt index 26bf4c795..1781c2ea1 100644 --- a/src/WinRT.Runtime/Interop/IID.tt +++ b/src/WinRT.Runtime/Interop/IID.tt @@ -39,6 +39,10 @@ var entries = new (string Name, string IID, bool IsPublic)[] ("ISupportErrorInfo", "DF0B3D60-548F-101B-8E65-08002B2BD119", false), ("ILanguageExceptionErrorInfo", "04A2DBF3-DF83-116C-0946-0812ABF6E07D", false), ("IRestrictedErrorInfo", "82BA7092-4C88-427D-A7BC-16DD93FEB67E", false), + ("MUX_INotifyPropertyChanged", "90B17601-B065-586E-83D9-9ADC3A695284", false), + ("WUX_INotifyPropertyChanged", "CF75D69C-F2F4-486B-B302-BB4C09BAEBFA", false), + ("MUX_INotifyCollectionChanged", "530155E1-28A5-5693-87CE-30724D95A06D", false), + ("WUX_INotifyCollectionChanged", "28B167D5-1A31-465B-9B25-D5C3AE686C40", false), ("MUX_INotifyCollectionChangedEventArgsFactory", "5108EBA4-4892-5A20-8374-A96815E0FD27", false), ("WUX_INotifyCollectionChangedEventArgsFactory", "B30C3E3A-DF8D-44A5-9A38-7AC0D08CE63D", false), ("MUX_INotifyCollectionChangedEventArgs", "DA049FF2-D2E0-5FE8-8C7B-F87F26060B6F", false), @@ -48,8 +52,6 @@ var entries = new (string Name, string IID, bool IsPublic)[] ("DataErrorsChangedEventArgsRuntimeClassFactory", "62D0BD1E-B85F-5FCC-842A-7CB0DDA37FE5", false), ("UriRuntimeClassFactory", "44A9796F-723E-4FDF-A218-033E75B0C084", false), ("INotifyDataErrorInfo", "0EE6C2CC-273E-567D-BC0A-1DD87EE51EBA", false), - ("INotifyPropertyChanged", "90B17601-B065-586E-83D9-9ADC3A695284", false), - ("INotifyCollectionChanged", "530155E1-28A5-5693-87CE-30724D95A06D", false), ("ICommand", "E5AF3542-CA67-4081-995B-709DD13792DF", false), ("IGlobalInterfaceTable", "00000146-0000-0000-C000-000000000046", false), ("PropertyChangedEventHandler", "E3DE52F6-1E32-5DA6-BB2D-B5B6096C962D", false), diff --git a/src/WinRT.Runtime/Projections/INotifyCollectionChanged.net5.cs b/src/WinRT.Runtime/Projections/INotifyCollectionChanged.net5.cs index 1666d828e..a34bc86b6 100644 --- a/src/WinRT.Runtime/Projections/INotifyCollectionChanged.net5.cs +++ b/src/WinRT.Runtime/Projections/INotifyCollectionChanged.net5.cs @@ -37,12 +37,10 @@ static class INotifyCollectionChangedMethods }); } - public static global::System.Guid IID { get; } = new(GetIID()); + public static global::System.Guid IID => FeatureSwitches.UseWindowsUIXamlProjections + ? global::WinRT.Interop.IID.IID_WUX_INotifyCollectionChanged + : global::WinRT.Interop.IID.IID_MUX_INotifyCollectionChanged; - private static ReadOnlySpan GetIID() - => FeatureSwitches.UseWindowsUIXamlProjections - ? new(new byte[] { 0xd5, 0x67, 0xb1, 0x28, 0x31, 0x1a, 0x5b, 0x46, 0x9b, 0x25, 0xd5, 0xc3, 0xae, 0x68, 0x6c, 0x40 }) - : new(new byte[] { 0xe1, 0x55, 0x1, 0x53, 0xa5, 0x28, 0x93, 0x56, 0x87, 0xce, 0x30, 0x72, 0x4d, 0x95, 0xa0, 0x6d }); public static IntPtr AbiToProjectionVftablePtr => INotifyCollectionChanged.Vftbl.AbiToProjectionVftablePtr; } @@ -129,7 +127,6 @@ private static unsafe int Do_Abi_remove_CollectionChanged_1(IntPtr thisPtr, glob } } } - internal static ObjectReference FromAbi(IntPtr thisPtr) => ObjectReference.FromAbi(thisPtr, global::WinRT.Interop.IID.IID_INotifyCollectionChanged); private static global::ABI.WinRT.Interop.EventSource _CollectionChanged(IWinRTObject _this) { diff --git a/src/WinRT.Runtime/Projections/INotifyPropertyChanged.net5.cs b/src/WinRT.Runtime/Projections/INotifyPropertyChanged.net5.cs index 8e72c723c..b206aab6a 100644 --- a/src/WinRT.Runtime/Projections/INotifyPropertyChanged.net5.cs +++ b/src/WinRT.Runtime/Projections/INotifyPropertyChanged.net5.cs @@ -15,12 +15,9 @@ namespace ABI.System.ComponentModel #endif static class INotifyPropertyChangedMethods { - public static global::System.Guid IID { get; } = new(GetIID()); - - private static ReadOnlySpan GetIID() - => FeatureSwitches.UseWindowsUIXamlProjections - ? new(new byte[] { 0x9c, 0xd6, 0x75, 0xcf, 0xf4, 0xf2, 0x6b, 0x48, 0xb3, 0x2, 0xbb, 0x4c, 0x9, 0xba, 0xeb, 0xfa }) - : new(new byte[] { 0x1, 0x76, 0xb1, 0x90, 0x65, 0xb0, 0x6e, 0x58, 0x83, 0xd9, 0x9a, 0xdc, 0x3a, 0x69, 0x52, 0x84 }); + public static global::System.Guid IID => FeatureSwitches.UseWindowsUIXamlProjections + ? global::WinRT.Interop.IID.IID_WUX_INotifyPropertyChanged + : global::WinRT.Interop.IID.IID_MUX_INotifyPropertyChanged; public static IntPtr AbiToProjectionVftablePtr => INotifyPropertyChanged.Vftbl.AbiToProjectionVftablePtr; @@ -128,7 +125,6 @@ private static unsafe int Do_Abi_remove_PropertyChanged_1(IntPtr thisPtr, global } } } - internal static ObjectReference FromAbi(IntPtr thisPtr) => ObjectReference.FromAbi(thisPtr, global::WinRT.Interop.IID.IID_INotifyPropertyChanged); private static global::ABI.WinRT.Interop.EventSource _PropertyChanged(IWinRTObject _this) { From 630123a452ccb88478e4100fe8c42014cf769af0 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Wed, 5 Jun 2024 10:51:32 -0700 Subject: [PATCH 31/46] Remove runtime parsing of two IIDs --- src/WinRT.Runtime/Interop/IID.g.cs | 150 ++++++++++++------ src/WinRT.Runtime/Interop/IID.tt | 6 +- .../NotifyCollectionChangedEventHandler.cs | 8 +- .../PropertyChangedEventHandler.cs | 7 +- 4 files changed, 110 insertions(+), 61 deletions(-) diff --git a/src/WinRT.Runtime/Interop/IID.g.cs b/src/WinRT.Runtime/Interop/IID.g.cs index 5bd40a182..7365b3cd1 100644 --- a/src/WinRT.Runtime/Interop/IID.g.cs +++ b/src/WinRT.Runtime/Interop/IID.g.cs @@ -640,6 +640,56 @@ internal static ref readonly Guid IID_WUX_INotifyCollectionChangedEventArgs } } + /// The IID for MUX_NotifyCollectionChangedEventHandler (CA10B37C-F382-4591-8557-5E24965279B0). + internal static ref readonly Guid IID_MUX_NotifyCollectionChangedEventHandler + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get + { + ReadOnlySpan data = new byte[] + { + 0x7C, 0xB3, 0x10, 0xCA, + 0x82, 0xF3, + 0x91, 0x45, + 0x85, + 0x57, + 0x5E, + 0x24, + 0x96, + 0x52, + 0x79, + 0xB0 + }; + + return ref Unsafe.As(ref MemoryMarshal.GetReference(data)); + } + } + + /// The IID for WUX_NotifyCollectionChangedEventHandler (8B0909DC-2005-5D93-BF8A-725F017BAA8D). + internal static ref readonly Guid IID_WUX_NotifyCollectionChangedEventHandler + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get + { + ReadOnlySpan data = new byte[] + { + 0xDC, 0x09, 0x09, 0x8B, + 0x05, 0x20, + 0x93, 0x5D, + 0xBF, + 0x8A, + 0x72, + 0x5F, + 0x01, + 0x7B, + 0xAA, + 0x8D + }; + + return ref Unsafe.As(ref MemoryMarshal.GetReference(data)); + } + } + /// The IID for MUX_PropertyChangedEventArgsRuntimeClassFactory (7C0C27A8-0B41-5070-B160-FC9AE960A36C). internal static ref readonly Guid IID_MUX_PropertyChangedEventArgsRuntimeClassFactory { @@ -690,6 +740,56 @@ internal static ref readonly Guid IID_WUX_PropertyChangedEventArgsRuntimeClassFa } } + /// The IID for MUX_PropertyChangedEventHandler (E3DE52F6-1E32-5DA6-BB2D-B5B6096C962D). + internal static ref readonly Guid IID_MUX_PropertyChangedEventHandler + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get + { + ReadOnlySpan data = new byte[] + { + 0xF6, 0x52, 0xDE, 0xE3, + 0x32, 0x1E, + 0xA6, 0x5D, + 0xBB, + 0x2D, + 0xB5, + 0xB6, + 0x09, + 0x6C, + 0x96, + 0x2D + }; + + return ref Unsafe.As(ref MemoryMarshal.GetReference(data)); + } + } + + /// The IID for WUX_PropertyChangedEventHandler (50F19C16-0A22-4D8E-A089-1EA9951657D2). + internal static ref readonly Guid IID_WUX_PropertyChangedEventHandler + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get + { + ReadOnlySpan data = new byte[] + { + 0x16, 0x9C, 0xF1, 0x50, + 0x22, 0x0A, + 0x8E, 0x4D, + 0xA0, + 0x89, + 0x1E, + 0xA9, + 0x95, + 0x16, + 0x57, + 0xD2 + }; + + return ref Unsafe.As(ref MemoryMarshal.GetReference(data)); + } + } + /// The IID for DataErrorsChangedEventArgsRuntimeClassFactory (62D0BD1E-B85F-5FCC-842A-7CB0DDA37FE5). internal static ref readonly Guid IID_DataErrorsChangedEventArgsRuntimeClassFactory { @@ -815,56 +915,6 @@ internal static ref readonly Guid IID_IGlobalInterfaceTable } } - /// The IID for PropertyChangedEventHandler (E3DE52F6-1E32-5DA6-BB2D-B5B6096C962D). - internal static ref readonly Guid IID_PropertyChangedEventHandler - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get - { - ReadOnlySpan data = new byte[] - { - 0xF6, 0x52, 0xDE, 0xE3, - 0x32, 0x1E, - 0xA6, 0x5D, - 0xBB, - 0x2D, - 0xB5, - 0xB6, - 0x09, - 0x6C, - 0x96, - 0x2D - }; - - return ref Unsafe.As(ref MemoryMarshal.GetReference(data)); - } - } - - /// The IID for NotifyCollectionChangedEventHandler (8B0909DC-2005-5D93-BF8A-725F017BAA8D). - internal static ref readonly Guid IID_NotifyCollectionChangedEventHandler - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get - { - ReadOnlySpan data = new byte[] - { - 0xDC, 0x09, 0x09, 0x8B, - 0x05, 0x20, - 0x93, 0x5D, - 0xBF, - 0x8A, - 0x72, - 0x5F, - 0x01, - 0x7B, - 0xAA, - 0x8D - }; - - return ref Unsafe.As(ref MemoryMarshal.GetReference(data)); - } - } - /// The IID for EventHandler (C50898F6-C536-5F47-8583-8B2C2438A13B). internal static ref readonly Guid IID_EventHandler { diff --git a/src/WinRT.Runtime/Interop/IID.tt b/src/WinRT.Runtime/Interop/IID.tt index 1781c2ea1..dd852dc33 100644 --- a/src/WinRT.Runtime/Interop/IID.tt +++ b/src/WinRT.Runtime/Interop/IID.tt @@ -47,15 +47,17 @@ var entries = new (string Name, string IID, bool IsPublic)[] ("WUX_INotifyCollectionChangedEventArgsFactory", "B30C3E3A-DF8D-44A5-9A38-7AC0D08CE63D", false), ("MUX_INotifyCollectionChangedEventArgs", "DA049FF2-D2E0-5FE8-8C7B-F87F26060B6F", false), ("WUX_INotifyCollectionChangedEventArgs", "4CF68D33-E3F2-4964-B85E-945B4F7E2F21", false), + ("MUX_NotifyCollectionChangedEventHandler", "CA10B37C-F382-4591-8557-5E24965279B0", false), + ("WUX_NotifyCollectionChangedEventHandler", "8B0909DC-2005-5D93-BF8A-725F017BAA8D", false), ("MUX_PropertyChangedEventArgsRuntimeClassFactory", "7C0C27A8-0B41-5070-B160-FC9AE960A36C", false), ("WUX_PropertyChangedEventArgsRuntimeClassFactory", "6DCC9C03-E0C7-4EEE-8EA9-37E3406EEB1C", false), + ("MUX_PropertyChangedEventHandler", "E3DE52F6-1E32-5DA6-BB2D-B5B6096C962D", false), + ("WUX_PropertyChangedEventHandler", "50F19C16-0A22-4D8E-A089-1EA9951657D2", false), ("DataErrorsChangedEventArgsRuntimeClassFactory", "62D0BD1E-B85F-5FCC-842A-7CB0DDA37FE5", false), ("UriRuntimeClassFactory", "44A9796F-723E-4FDF-A218-033E75B0C084", false), ("INotifyDataErrorInfo", "0EE6C2CC-273E-567D-BC0A-1DD87EE51EBA", false), ("ICommand", "E5AF3542-CA67-4081-995B-709DD13792DF", false), ("IGlobalInterfaceTable", "00000146-0000-0000-C000-000000000046", false), - ("PropertyChangedEventHandler", "E3DE52F6-1E32-5DA6-BB2D-B5B6096C962D", false), - ("NotifyCollectionChangedEventHandler", "8B0909DC-2005-5D93-BF8A-725F017BAA8D", false), ("EventHandler", "C50898F6-C536-5F47-8583-8B2C2438A13B", false), ("IBindableVectorView", "346DD6E7-976E-4BC3-815D-ECE243BC0F33", false), ("IEnumerable", "036D2C08-DF29-41AF-8AA2-D774BE62BA6F", false), diff --git a/src/WinRT.Runtime/Projections/NotifyCollectionChangedEventHandler.cs b/src/WinRT.Runtime/Projections/NotifyCollectionChangedEventHandler.cs index 041ce1c31..c01b0d137 100644 --- a/src/WinRT.Runtime/Projections/NotifyCollectionChangedEventHandler.cs +++ b/src/WinRT.Runtime/Projections/NotifyCollectionChangedEventHandler.cs @@ -43,15 +43,13 @@ static unsafe NotifyCollectionChangedEventHandler() *(global::WinRT.Interop.IDelegateVftbl*)nativeVftbl = AbiToProjectionVftable; AbiToProjectionVftablePtr = nativeVftbl; ComWrappersSupport.RegisterDelegateFactory(typeof(global::System.Collections.Specialized.NotifyCollectionChangedEventHandler), CreateRcw); - - IID = FeatureSwitches.UseWindowsUIXamlProjections - ? Guid.Parse("CA10B37C-F382-4591-8557-5E24965279B0") - : Guid.Parse("8B0909DC-2005-5D93-BF8A-725F017BAA8D"); } public static global::System.Delegate AbiInvokeDelegate { get; } - public static readonly Guid IID; + public static Guid IID => FeatureSwitches.UseWindowsUIXamlProjections + ? global::WinRT.Interop.IID.IID_WUX_NotifyCollectionChangedEventHandler + : global::WinRT.Interop.IID.IID_MUX_NotifyCollectionChangedEventHandler; public static unsafe IObjectReference CreateMarshaler(global::System.Collections.Specialized.NotifyCollectionChangedEventHandler managedDelegate) => managedDelegate is null ? null : MarshalDelegate.CreateMarshaler(managedDelegate, IID); diff --git a/src/WinRT.Runtime/Projections/PropertyChangedEventHandler.cs b/src/WinRT.Runtime/Projections/PropertyChangedEventHandler.cs index 2339955cc..4e92503ce 100644 --- a/src/WinRT.Runtime/Projections/PropertyChangedEventHandler.cs +++ b/src/WinRT.Runtime/Projections/PropertyChangedEventHandler.cs @@ -42,14 +42,13 @@ static unsafe PropertyChangedEventHandler() *(IDelegateVftbl*)nativeVftbl = AbiToProjectionVftable; AbiToProjectionVftablePtr = nativeVftbl; ComWrappersSupport.RegisterDelegateFactory(typeof(global::System.ComponentModel.PropertyChangedEventHandler), CreateRcw); - IID = FeatureSwitches.UseWindowsUIXamlProjections - ? Guid.Parse("50F19C16-0A22-4D8E-A089-1EA9951657D2") - : Guid.Parse("E3DE52F6-1E32-5DA6-BB2D-B5B6096C962D"); } public static global::System.Delegate AbiInvokeDelegate { get; } - private static readonly Guid IID; + private static Guid IID => FeatureSwitches.UseWindowsUIXamlProjections + ? global::WinRT.Interop.IID.IID_WUX_PropertyChangedEventHandler + : global::WinRT.Interop.IID.IID_MUX_PropertyChangedEventHandler; public static unsafe IObjectReference CreateMarshaler(global::System.ComponentModel.PropertyChangedEventHandler managedDelegate) => managedDelegate is null ? null : MarshalDelegate.CreateMarshaler(managedDelegate, IID); From 3234a232cc6f2222042e4ee51a33fdc01240a27a Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Wed, 5 Jun 2024 11:39:59 -0700 Subject: [PATCH 32/46] Fix WUX IID for 'INotifyCollectionChanged' --- .../Projections/INotifyCollectionChanged.net5.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/WinRT.Runtime/Projections/INotifyCollectionChanged.net5.cs b/src/WinRT.Runtime/Projections/INotifyCollectionChanged.net5.cs index a34bc86b6..905ced14d 100644 --- a/src/WinRT.Runtime/Projections/INotifyCollectionChanged.net5.cs +++ b/src/WinRT.Runtime/Projections/INotifyCollectionChanged.net5.cs @@ -47,11 +47,11 @@ static class INotifyCollectionChangedMethods [DynamicInterfaceCastableImplementation] [EditorBrowsable(EditorBrowsableState.Never)] [Guid("530155E1-28A5-5693-87CE-30724D95A06D")] - [WuxMuxProjectedType(wuxIID: "CF75D69C-F2F4-486B-B302-BB4C09BAEBFA", muxIID: "530155E1-28A5-5693-87CE-30724D95A06D")] + [WuxMuxProjectedType(wuxIID: "28B167D5-1A31-465B-9B25-D5C3AE686C40", muxIID: "530155E1-28A5-5693-87CE-30724D95A06D")] internal unsafe interface INotifyCollectionChanged : global::System.Collections.Specialized.INotifyCollectionChanged { [Guid("530155E1-28A5-5693-87CE-30724D95A06D")] - [WuxMuxProjectedType(wuxIID: "CF75D69C-F2F4-486B-B302-BB4C09BAEBFA", muxIID: "530155E1-28A5-5693-87CE-30724D95A06D")] + [WuxMuxProjectedType(wuxIID: "28B167D5-1A31-465B-9B25-D5C3AE686C40", muxIID: "530155E1-28A5-5693-87CE-30724D95A06D")] #pragma warning disable CA2257 // This member is a type (so it cannot be invoked) public struct Vftbl #pragma warning restore CA2257 From 72d47a11151bf5118ea21a5321ab867a972cb305 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Wed, 5 Jun 2024 11:41:18 -0700 Subject: [PATCH 33/46] Remove unnecessary [WuxMux] from vtable types --- src/WinRT.Runtime/Projections/INotifyCollectionChanged.net5.cs | 1 - src/WinRT.Runtime/Projections/INotifyPropertyChanged.net5.cs | 1 - 2 files changed, 2 deletions(-) diff --git a/src/WinRT.Runtime/Projections/INotifyCollectionChanged.net5.cs b/src/WinRT.Runtime/Projections/INotifyCollectionChanged.net5.cs index 905ced14d..83ed394ad 100644 --- a/src/WinRT.Runtime/Projections/INotifyCollectionChanged.net5.cs +++ b/src/WinRT.Runtime/Projections/INotifyCollectionChanged.net5.cs @@ -51,7 +51,6 @@ static class INotifyCollectionChangedMethods internal unsafe interface INotifyCollectionChanged : global::System.Collections.Specialized.INotifyCollectionChanged { [Guid("530155E1-28A5-5693-87CE-30724D95A06D")] - [WuxMuxProjectedType(wuxIID: "28B167D5-1A31-465B-9B25-D5C3AE686C40", muxIID: "530155E1-28A5-5693-87CE-30724D95A06D")] #pragma warning disable CA2257 // This member is a type (so it cannot be invoked) public struct Vftbl #pragma warning restore CA2257 diff --git a/src/WinRT.Runtime/Projections/INotifyPropertyChanged.net5.cs b/src/WinRT.Runtime/Projections/INotifyPropertyChanged.net5.cs index b206aab6a..a9ade0372 100644 --- a/src/WinRT.Runtime/Projections/INotifyPropertyChanged.net5.cs +++ b/src/WinRT.Runtime/Projections/INotifyPropertyChanged.net5.cs @@ -50,7 +50,6 @@ internal unsafe interface INotifyPropertyChanged : global::System.ComponentModel #pragma warning disable CA2257 [Guid("90B17601-B065-586E-83D9-9ADC3A695284")] [StructLayout(LayoutKind.Sequential)] - [WuxMuxProjectedType(wuxIID: "CF75D69C-F2F4-486B-B302-BB4C09BAEBFA", muxIID: "90B17601-B065-586E-83D9-9ADC3A695284")] public struct Vftbl #pragma warning restore CA2257 { From a94f90c90d1922ba0f89890177812beec13e154a Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Wed, 5 Jun 2024 11:51:02 -0700 Subject: [PATCH 34/46] Tweak 'NotifyCollectionChangedEventArgs' --- .../Projections/NotifyCollectionChangedEventArgs.cs | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/src/WinRT.Runtime/Projections/NotifyCollectionChangedEventArgs.cs b/src/WinRT.Runtime/Projections/NotifyCollectionChangedEventArgs.cs index fbcebf1c1..855653cf4 100644 --- a/src/WinRT.Runtime/Projections/NotifyCollectionChangedEventArgs.cs +++ b/src/WinRT.Runtime/Projections/NotifyCollectionChangedEventArgs.cs @@ -20,23 +20,16 @@ internal sealed unsafe class WinRTNotifyCollectionChangedEventArgsRuntimeClassFa private readonly IObjectReference _obj; public IntPtr ThisPtr => _obj.ThisPtr; - private static readonly Guid Factory_IID = - FeatureSwitches.UseWindowsUIXamlProjections - ? IID.IID_WUX_INotifyCollectionChangedEventArgsFactory - : IID.IID_MUX_INotifyCollectionChangedEventArgsFactory; - public static readonly WinRTNotifyCollectionChangedEventArgsRuntimeClassFactory Instance = new(); private WinRTNotifyCollectionChangedEventArgsRuntimeClassFactory() { #if NET _obj = FeatureSwitches.UseWindowsUIXamlProjections - ? ActivationFactory.Get("Windows.UI.Xaml.Interop.NotifyCollectionChangedEventArgs") - : ActivationFactory.Get("Microsoft.UI.Xaml.Interop.NotifyCollectionChangedEventArgs"); + ? ActivationFactory.Get("Windows.UI.Xaml.Interop.NotifyCollectionChangedEventArgs", IID.IID_WUX_INotifyCollectionChangedEventArgsFactory) + : ActivationFactory.Get("Microsoft.UI.Xaml.Interop.NotifyCollectionChangedEventArgs", IID.IID_MUX_INotifyCollectionChangedEventArgsFactory); #else - _obj = FeatureSwitches.UseWindowsUIXamlProjections - ? ActivationFactory.Get("Windows.UI.Xaml.Interop.NotifyCollectionChangedEventArgs", Factory_IID) - : ActivationFactory.Get("Microsoft.UI.Xaml.Interop.NotifyCollectionChangedEventArgs", Factory_IID); + _obj = ActivationFactory.Get("Microsoft.UI.Xaml.Interop.NotifyCollectionChangedEventArgs", IID.IID_MUX_INotifyCollectionChangedEventArgsFactory); #endif } From 0addb86d8182a02202496dc180c7d25b29a80d36 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Wed, 5 Jun 2024 11:52:28 -0700 Subject: [PATCH 35/46] Tweak 'NotifyCollectionChangedEventArgs' --- .../Projections/NotifyCollectionChangedEventArgs.cs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/WinRT.Runtime/Projections/NotifyCollectionChangedEventArgs.cs b/src/WinRT.Runtime/Projections/NotifyCollectionChangedEventArgs.cs index 855653cf4..a20f3228b 100644 --- a/src/WinRT.Runtime/Projections/NotifyCollectionChangedEventArgs.cs +++ b/src/WinRT.Runtime/Projections/NotifyCollectionChangedEventArgs.cs @@ -82,10 +82,9 @@ namespace ABI.System.Collections.Specialized #endif struct NotifyCollectionChangedEventArgs { - private static readonly Guid Interface_IID = - FeatureSwitches.UseWindowsUIXamlProjections - ? IID.IID_WUX_INotifyCollectionChangedEventArgs - : IID.IID_MUX_INotifyCollectionChangedEventArgs; + private static ref readonly Guid Interface_IID => ref FeatureSwitches.UseWindowsUIXamlProjections + ? ref IID.IID_WUX_INotifyCollectionChangedEventArgs + : ref IID.IID_MUX_INotifyCollectionChangedEventArgs; public static IObjectReference CreateMarshaler(global::System.Collections.Specialized.NotifyCollectionChangedEventArgs value) { From a508614f9f859ffcc7dd22d5007d12f36e40d9c6 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Thu, 6 Jun 2024 09:49:17 -0700 Subject: [PATCH 36/46] Simplify 'WuxMuxProjectedTypeAttribute' --- src/WinRT.Runtime/GuidGenerator.cs | 64 ++++++++++++++++--- ...ute.cs => WuxMuxProjectedTypeAttribute.cs} | 17 ++--- .../INotifyCollectionChanged.net5.cs | 2 +- .../INotifyPropertyChanged.net5.cs | 2 +- .../NotifyCollectionChangedEventArgs.cs | 2 +- .../NotifyCollectionChangedEventHandler.cs | 2 +- .../PropertyChangedEventHandler.cs | 2 +- 7 files changed, 66 insertions(+), 25 deletions(-) rename src/WinRT.Runtime/Interop/{WuxMuxProjectedInterfaceAttribute.cs => WuxMuxProjectedTypeAttribute.cs} (56%) diff --git a/src/WinRT.Runtime/GuidGenerator.cs b/src/WinRT.Runtime/GuidGenerator.cs index cafadcc57..b8514f537 100644 --- a/src/WinRT.Runtime/GuidGenerator.cs +++ b/src/WinRT.Runtime/GuidGenerator.cs @@ -24,10 +24,17 @@ static class GuidGenerator public static Guid GetGUID(Type type) { type = type.GetGuidType(); - if (type.GetCustomAttribute() is {} wuxMuxAttribute) + + // Only check the WUX/MUX types if the feature switch is set, to avoid introducing + // performance regressions in the standard case where MUX is targeted (default). + if (FeatureSwitches.UseWindowsUIXamlProjections) { - return GetWuxMuxIID(wuxMuxAttribute); + if (TryGetWindowsUIXamlIID(type, out Guid iid)) + { + return iid; + } } + return type.GUID; } @@ -38,10 +45,16 @@ public static Guid GetIID( Type type) { type = type.GetGuidType(); - if (type.GetCustomAttribute() is {} wuxMuxAttribute) + + // Same optional check as above + if (FeatureSwitches.UseWindowsUIXamlProjections) { - return GetWuxMuxIID(wuxMuxAttribute); + if (TryGetWindowsUIXamlIID(type, out Guid iid)) + { + return iid; + } } + if (!type.IsGenericType) { return type.GUID; @@ -49,11 +62,46 @@ public static Guid GetIID( return (Guid)type.GetField("PIID").GetValue(null); } - internal static Guid GetWuxMuxIID(WuxMuxProjectedTypeAttribute wuxMuxAttribute) + internal static bool TryGetWindowsUIXamlIID(Type type, out Guid iid) { - return FeatureSwitches.UseWindowsUIXamlProjections - ? wuxMuxAttribute.WuxIID - : wuxMuxAttribute.MuxIID; + if (type == typeof(global::ABI.System.Collections.Specialized.INotifyCollectionChanged)) + { + iid = IID.IID_WUX_INotifyCollectionChanged; + + return true; + } + + if (type == typeof(global::ABI.System.ComponentModel.INotifyPropertyChanged)) + { + iid = IID.IID_WUX_INotifyPropertyChanged; + + return true; + } + + if (type == typeof(global::ABI.System.Collections.Specialized.NotifyCollectionChangedEventArgs)) + { + iid = IID.IID_WUX_INotifyCollectionChangedEventArgs; + + return true; + } + + if (type == typeof(global::ABI.System.Collections.Specialized.NotifyCollectionChangedEventHandler)) + { + iid = IID.IID_WUX_NotifyCollectionChangedEventHandler; + + return true; + } + + if (type == typeof(global::ABI.System.ComponentModel.PropertyChangedEventHandler)) + { + iid = IID.IID_WUX_PropertyChangedEventHandler; + + return true; + } + + iid = default; + + return false; } public static string GetSignature( diff --git a/src/WinRT.Runtime/Interop/WuxMuxProjectedInterfaceAttribute.cs b/src/WinRT.Runtime/Interop/WuxMuxProjectedTypeAttribute.cs similarity index 56% rename from src/WinRT.Runtime/Interop/WuxMuxProjectedInterfaceAttribute.cs rename to src/WinRT.Runtime/Interop/WuxMuxProjectedTypeAttribute.cs index b30aa7dc4..3f56b6dc7 100644 --- a/src/WinRT.Runtime/Interop/WuxMuxProjectedInterfaceAttribute.cs +++ b/src/WinRT.Runtime/Interop/WuxMuxProjectedTypeAttribute.cs @@ -1,24 +1,17 @@ using System; -using System.Collections.Generic; -using System.Text; namespace WinRT.Interop { + // This attribute is only used by the IIDOptimizer for resolving the signature of a type that has different + // IIDs on WUX/MUX targets. The actual IIDs are hardcoded in WinRT.Runtime, so they are not needed here. + // TODO: remove this entirely when either IIDOptimizer is removed, or when the option to hardcode IIDs is added. + /// /// This type signals that the type it is applied to is projected into .NET from either a Windows.UI.Xaml type or a Microsoft.UI.Xaml type. /// For this type, the GuidAttribute is not used and instead the GetGuidSignature method must be called to get the IID or generic IID signature part of the type. /// - [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface, AllowMultiple = false, Inherited = false)] internal sealed class WuxMuxProjectedTypeAttribute : Attribute { - public Guid WuxIID { get; } - - public Guid MuxIID { get; } - - public WuxMuxProjectedTypeAttribute(string wuxIID, string muxIID) - { - WuxIID = Guid.Parse(wuxIID); - MuxIID = Guid.Parse(muxIID); - } } } diff --git a/src/WinRT.Runtime/Projections/INotifyCollectionChanged.net5.cs b/src/WinRT.Runtime/Projections/INotifyCollectionChanged.net5.cs index 83ed394ad..b812db480 100644 --- a/src/WinRT.Runtime/Projections/INotifyCollectionChanged.net5.cs +++ b/src/WinRT.Runtime/Projections/INotifyCollectionChanged.net5.cs @@ -47,7 +47,7 @@ static class INotifyCollectionChangedMethods [DynamicInterfaceCastableImplementation] [EditorBrowsable(EditorBrowsableState.Never)] [Guid("530155E1-28A5-5693-87CE-30724D95A06D")] - [WuxMuxProjectedType(wuxIID: "28B167D5-1A31-465B-9B25-D5C3AE686C40", muxIID: "530155E1-28A5-5693-87CE-30724D95A06D")] + [WuxMuxProjectedType] internal unsafe interface INotifyCollectionChanged : global::System.Collections.Specialized.INotifyCollectionChanged { [Guid("530155E1-28A5-5693-87CE-30724D95A06D")] diff --git a/src/WinRT.Runtime/Projections/INotifyPropertyChanged.net5.cs b/src/WinRT.Runtime/Projections/INotifyPropertyChanged.net5.cs index a9ade0372..1b72b7de9 100644 --- a/src/WinRT.Runtime/Projections/INotifyPropertyChanged.net5.cs +++ b/src/WinRT.Runtime/Projections/INotifyPropertyChanged.net5.cs @@ -44,7 +44,7 @@ static class INotifyPropertyChangedMethods [DynamicInterfaceCastableImplementation] [Guid("90B17601-B065-586E-83D9-9ADC3A695284")] - [WuxMuxProjectedType(wuxIID: "CF75D69C-F2F4-486B-B302-BB4C09BAEBFA", muxIID: "90B17601-B065-586E-83D9-9ADC3A695284")] + [WuxMuxProjectedType] internal unsafe interface INotifyPropertyChanged : global::System.ComponentModel.INotifyPropertyChanged { #pragma warning disable CA2257 diff --git a/src/WinRT.Runtime/Projections/NotifyCollectionChangedEventArgs.cs b/src/WinRT.Runtime/Projections/NotifyCollectionChangedEventArgs.cs index a20f3228b..5cb24a1e6 100644 --- a/src/WinRT.Runtime/Projections/NotifyCollectionChangedEventArgs.cs +++ b/src/WinRT.Runtime/Projections/NotifyCollectionChangedEventArgs.cs @@ -74,7 +74,7 @@ namespace ABI.System.Collections.Specialized { [EditorBrowsable(EditorBrowsableState.Never)] [StructLayout(LayoutKind.Sequential)] - [WuxMuxProjectedType(wuxIID: "4cf68d33-e3f2-4964-b85e-945b4f7e2f21", muxIID: "DA049FF2-D2E0-5FE8-8C7B-F87F26060B6F")] + [WuxMuxProjectedType] #if EMBED internal #else diff --git a/src/WinRT.Runtime/Projections/NotifyCollectionChangedEventHandler.cs b/src/WinRT.Runtime/Projections/NotifyCollectionChangedEventHandler.cs index c01b0d137..18333338d 100644 --- a/src/WinRT.Runtime/Projections/NotifyCollectionChangedEventHandler.cs +++ b/src/WinRT.Runtime/Projections/NotifyCollectionChangedEventHandler.cs @@ -13,7 +13,7 @@ namespace ABI.System.Collections.Specialized [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] [Guid("8B0909DC-2005-5D93-BF8A-725F017BAA8D")] - [WuxMuxProjectedType(wuxIID: "CA10B37C-F382-4591-8557-5E24965279B0", muxIID: "8B0909DC-2005-5D93-BF8A-725F017BAA8D")] + [WuxMuxProjectedType] #if EMBED internal #else diff --git a/src/WinRT.Runtime/Projections/PropertyChangedEventHandler.cs b/src/WinRT.Runtime/Projections/PropertyChangedEventHandler.cs index 4e92503ce..58cb5cdc2 100644 --- a/src/WinRT.Runtime/Projections/PropertyChangedEventHandler.cs +++ b/src/WinRT.Runtime/Projections/PropertyChangedEventHandler.cs @@ -12,7 +12,7 @@ namespace ABI.System.ComponentModel { [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] [Guid("E3DE52F6-1E32-5DA6-BB2D-B5B6096C962D")] - [WuxMuxProjectedType(wuxIID: "50F19C16-0A22-4D8E-A089-1EA9951657D2", muxIID: "E3DE52F6-1E32-5DA6-BB2D-B5B6096C962D")] + [WuxMuxProjectedType] #if EMBED internal #else From 336649feeec44fd15998effe2a122cbd2f38645a Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Thu, 6 Jun 2024 10:57:27 -0700 Subject: [PATCH 37/46] Fix 'MatchingRefApiCompatBaseline' --- src/WinRT.Runtime/MatchingRefApiCompatBaseline.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/WinRT.Runtime/MatchingRefApiCompatBaseline.txt b/src/WinRT.Runtime/MatchingRefApiCompatBaseline.txt index 6bb4681a3..1276f8957 100644 --- a/src/WinRT.Runtime/MatchingRefApiCompatBaseline.txt +++ b/src/WinRT.Runtime/MatchingRefApiCompatBaseline.txt @@ -267,5 +267,4 @@ MembersMustExist : Member 'public void WinRT.ComWrappersHelper.Init(System.Boole MembersMustExist : Member 'public System.Guid ABI.System.EventHandler.IID.get()' does not exist in the reference but it does exist in the implementation. MembersMustExist : Member 'public System.Guid ABI.System.Collections.Specialized.NotifyCollectionChangedEventHandler.IID.get()' does not exist in the reference but it does exist in the implementation. MembersMustExist : Member 'public System.Guid ABI.System.ComponentModel.PropertyChangedEventHandler.IID.get()' does not exist in the reference but it does exist in the implementation. -MembersMustExist : Member 'public System.Guid System.Guid ABI.System.Collections.Specialized.NotifyCollectionChangedEventHandler.IID' does not exist in the reference but it does exist in the implementation. -Total Issues: 269 +Total Issues: 268 From f9a76d0ffd492cffb29cd05ae532fda2c9884f6a Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Thu, 6 Jun 2024 10:58:12 -0700 Subject: [PATCH 38/46] Fix 'PropertyChangedEventHandler.IID' accessibility --- src/WinRT.Runtime/Projections/PropertyChangedEventHandler.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/WinRT.Runtime/Projections/PropertyChangedEventHandler.cs b/src/WinRT.Runtime/Projections/PropertyChangedEventHandler.cs index 58cb5cdc2..9d821c102 100644 --- a/src/WinRT.Runtime/Projections/PropertyChangedEventHandler.cs +++ b/src/WinRT.Runtime/Projections/PropertyChangedEventHandler.cs @@ -46,7 +46,7 @@ static unsafe PropertyChangedEventHandler() public static global::System.Delegate AbiInvokeDelegate { get; } - private static Guid IID => FeatureSwitches.UseWindowsUIXamlProjections + public static Guid IID => FeatureSwitches.UseWindowsUIXamlProjections ? global::WinRT.Interop.IID.IID_WUX_PropertyChangedEventHandler : global::WinRT.Interop.IID.IID_MUX_PropertyChangedEventHandler; From b88e4025dfd3fc786afc18273ff45de93b95ef86 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Fri, 7 Jun 2024 11:10:40 -0700 Subject: [PATCH 39/46] Throw 'NotSupportedException' for WUX downlevel --- src/WinRT.Runtime/Projections.cs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/WinRT.Runtime/Projections.cs b/src/WinRT.Runtime/Projections.cs index d7c72db6f..0cd751692 100644 --- a/src/WinRT.Runtime/Projections.cs +++ b/src/WinRT.Runtime/Projections.cs @@ -57,6 +57,15 @@ static Projections() } #endif +#if !NET + // Sanity check: always throw downlevel if System XAML projections are used, as this scenario is not supported. + // This also allows other code in WinRT.Runtime to simplify downlevel paths by just assuming this configuration. + if (FeatureSwitches.UseWindowsUIXamlProjections) + { + throw new NotSupportedException("Using System XAML projections is only supported on modern .NET (make sure the 'CsWinRTUseWindowsUIXamlProjections' property is not set to 'true')."); + } +#endif + // This should be in sync with cswinrt/helpers.h and the reverse mapping from WinRT.SourceGenerator/WinRTTypeWriter.cs. RegisterCustomAbiTypeMappingNoLock(typeof(EventRegistrationToken), typeof(ABI.WinRT.EventRegistrationToken), "Windows.Foundation.EventRegistrationToken"); From 3e4f2bc7933d1ab28eeaef1b87230569a8634861 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Fri, 7 Jun 2024 11:16:59 -0700 Subject: [PATCH 40/46] Remove unnecessary ifdef --- src/WinRT.Runtime/Projections.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/WinRT.Runtime/Projections.cs b/src/WinRT.Runtime/Projections.cs index 0cd751692..21e992799 100644 --- a/src/WinRT.Runtime/Projections.cs +++ b/src/WinRT.Runtime/Projections.cs @@ -92,7 +92,6 @@ static Projections() RegisterCustomAbiTypeMappingNoLock(typeof(NotifyCollectionChangedEventArgs), typeof(ABI.System.Collections.Specialized.NotifyCollectionChangedEventArgs), "Microsoft.UI.Xaml.Interop.NotifyCollectionChangedEventArgs", isRuntimeClass: true); RegisterCustomAbiTypeMappingNoLock(typeof(NotifyCollectionChangedEventHandler), typeof(ABI.System.Collections.Specialized.NotifyCollectionChangedEventHandler), "Microsoft.UI.Xaml.Interop.NotifyCollectionChangedEventHandler"); } -#if NET5_0_OR_GREATER else { RegisterCustomAbiTypeMappingNoLock(typeof(PropertyChangedEventArgs), typeof(ABI.System.ComponentModel.PropertyChangedEventArgs), "Windows.UI.Xaml.Data.PropertyChangedEventArgs", isRuntimeClass: true); @@ -106,7 +105,7 @@ static Projections() RegisterCustomAbiTypeMappingNoLock(typeof(NotifyCollectionChangedEventArgs), typeof(ABI.System.Collections.Specialized.NotifyCollectionChangedEventArgs), "Windows.UI.Xaml.Interop.NotifyCollectionChangedEventArgs", isRuntimeClass: true); RegisterCustomAbiTypeMappingNoLock(typeof(NotifyCollectionChangedEventHandler), typeof(ABI.System.Collections.Specialized.NotifyCollectionChangedEventHandler), "Windows.UI.Xaml.Interop.NotifyCollectionChangedEventHandler"); } -#endif + RegisterCustomAbiTypeMappingNoLock(typeof(EventHandler<>), typeof(ABI.System.EventHandler<>), "Windows.Foundation.EventHandler`1"); RegisterCustomAbiTypeMappingNoLock(typeof(KeyValuePair<,>), typeof(ABI.System.Collections.Generic.KeyValuePair<,>), "Windows.Foundation.Collections.IKeyValuePair`2"); From c5238550e6fc7972024d97ed35a8838fe8104e78 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Fri, 7 Jun 2024 11:17:08 -0700 Subject: [PATCH 41/46] Simplify 'Projections.CustomTypeMappings.tt' --- .../Projections.CustomTypeMappings.tt | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/src/WinRT.Runtime/Projections.CustomTypeMappings.tt b/src/WinRT.Runtime/Projections.CustomTypeMappings.tt index 3d244beb8..3ee4710ba 100644 --- a/src/WinRT.Runtime/Projections.CustomTypeMappings.tt +++ b/src/WinRT.Runtime/Projections.CustomTypeMappings.tt @@ -145,8 +145,6 @@ foreach (var type in registerCustomAbiTypeMappings) { WriteLine(""); - if (type.Name != null) - { #> /// Registers the custom ABI type mapping for the "<#=type.Name#>" WinRT type. public static void <#=GetMethodName(type.Public, type.Hint)#>() @@ -162,23 +160,6 @@ foreach (var type in registerCustomAbiTypeMappings) isRuntimeClass: <#=type.IsRuntimeClass.ToString().ToLowerInvariant()#>); } <# - } - else - { -#> - /// Registers the custom ABI type mapping for the type. - public static void <#=GetMethodName(type.Public, type.Hint)#>() - { -<# - WriteGuardStatements(type.Public); -#> - - RegisterCustomAbiTypeMapping( - typeof(<#=type.Public#>), - typeof(<#=type.Abi#>)); - } -<# - } } // 'RegisterCustomTypeToHelperTypeMapping' methods From e0adf7e813bb8f48b313f50d0437e02ad437bfed Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Fri, 7 Jun 2024 11:21:56 -0700 Subject: [PATCH 42/46] Throw when trying to register invalid custom mappings --- .../Projections.CustomTypeMappings.g.cs | 15 +++++++++++++++ .../Projections.CustomTypeMappings.tt | 15 +++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/src/WinRT.Runtime/Projections.CustomTypeMappings.g.cs b/src/WinRT.Runtime/Projections.CustomTypeMappings.g.cs index a45d5e0e8..7a070b7a0 100644 --- a/src/WinRT.Runtime/Projections.CustomTypeMappings.g.cs +++ b/src/WinRT.Runtime/Projections.CustomTypeMappings.g.cs @@ -506,6 +506,11 @@ public static void RegisterDataErrorsChangedEventArgsMapping() return; } + if (FeatureSwitches.UseWindowsUIXamlProjections) + { + throw new NotSupportedException("The 'DataErrorsChangedEventArgs' type is only supported for WinUI, and not when using System XAML projections (make sure the 'CsWinRTUseWindowsUIXamlProjections' property is not set to 'true')."); + } + if (Interlocked.CompareExchange(ref _DataErrorsChangedEventArgs, 1, 0) == 1) { return; @@ -566,6 +571,11 @@ public static void RegisterINotifyDataErrorInfoMapping() return; } + if (FeatureSwitches.UseWindowsUIXamlProjections) + { + throw new NotSupportedException("The 'INotifyDataErrorInfo' type is only supported for WinUI, and not when using System XAML projections (make sure the 'CsWinRTUseWindowsUIXamlProjections' property is not set to 'true')."); + } + if (Interlocked.CompareExchange(ref _INotifyDataErrorInfo, 1, 0) == 1) { return; @@ -626,6 +636,11 @@ public static void RegisterIServiceProviderMapping() return; } + if (FeatureSwitches.UseWindowsUIXamlProjections) + { + throw new NotSupportedException("The 'IServiceProvider' type is only supported for WinUI, and not when using System XAML projections (make sure the 'CsWinRTUseWindowsUIXamlProjections' property is not set to 'true')."); + } + if (Interlocked.CompareExchange(ref _IServiceProvider, 1, 0) == 1) { return; diff --git a/src/WinRT.Runtime/Projections.CustomTypeMappings.tt b/src/WinRT.Runtime/Projections.CustomTypeMappings.tt index 3ee4710ba..acf45b303 100644 --- a/src/WinRT.Runtime/Projections.CustomTypeMappings.tt +++ b/src/WinRT.Runtime/Projections.CustomTypeMappings.tt @@ -50,6 +50,21 @@ void WriteGuardStatements(string name) { return; } +<# + + if (name == "DataErrorsChangedEventArgs" || + name == "INotifyDataErrorInfo" || + name == "IServiceProvider") + { + WriteLine(""); +#> + if (FeatureSwitches.UseWindowsUIXamlProjections) + { + throw new NotSupportedException("The '<#=name#>' type is only supported for WinUI, and not when using System XAML projections (make sure the 'CsWinRTUseWindowsUIXamlProjections' property is not set to 'true')."); + } +<# + } +#> if (Interlocked.CompareExchange(ref _<#=Regex.Replace(name, "[?<>,]", "_")#>, 1, 0) == 1) { From fac074d52f32131f348747f0d03c356980e353c1 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Fri, 7 Jun 2024 11:31:30 -0700 Subject: [PATCH 43/46] Support WUX for custom type mapping APIs --- .../Projections.CustomTypeMappings.g.cs | 210 +++++++++++++----- .../Projections.CustomTypeMappings.tt | 48 +++- 2 files changed, 206 insertions(+), 52 deletions(-) diff --git a/src/WinRT.Runtime/Projections.CustomTypeMappings.g.cs b/src/WinRT.Runtime/Projections.CustomTypeMappings.g.cs index 7a070b7a0..86e3658ec 100644 --- a/src/WinRT.Runtime/Projections.CustomTypeMappings.g.cs +++ b/src/WinRT.Runtime/Projections.CustomTypeMappings.g.cs @@ -536,11 +536,22 @@ public static void RegisterPropertyChangedEventArgsMapping() return; } - RegisterCustomAbiTypeMapping( - typeof(PropertyChangedEventArgs), - typeof(ABI.System.ComponentModel.PropertyChangedEventArgs), - "Microsoft.UI.Xaml.Data.PropertyChangedEventArgs", - isRuntimeClass: true); + if (FeatureSwitches.UseWindowsUIXamlProjections) + { + RegisterCustomAbiTypeMapping( + typeof(PropertyChangedEventArgs), + typeof(ABI.System.ComponentModel.PropertyChangedEventArgs), + "Windows.UI.Xaml.Data.PropertyChangedEventArgs", + isRuntimeClass: true); + } + else + { + RegisterCustomAbiTypeMapping( + typeof(PropertyChangedEventArgs), + typeof(ABI.System.ComponentModel.PropertyChangedEventArgs), + "Microsoft.UI.Xaml.Data.PropertyChangedEventArgs", + isRuntimeClass: true); + } } /// Registers the custom ABI type mapping for the "Microsoft.UI.Xaml.Data.PropertyChangedEventHandler" WinRT type. @@ -556,11 +567,22 @@ public static void RegisterPropertyChangedEventHandlerMapping() return; } - RegisterCustomAbiTypeMapping( - typeof(PropertyChangedEventHandler), - typeof(ABI.System.ComponentModel.PropertyChangedEventHandler), - "Microsoft.UI.Xaml.Data.PropertyChangedEventHandler", - isRuntimeClass: false); + if (FeatureSwitches.UseWindowsUIXamlProjections) + { + RegisterCustomAbiTypeMapping( + typeof(PropertyChangedEventHandler), + typeof(ABI.System.ComponentModel.PropertyChangedEventHandler), + "Windows.UI.Xaml.Data.PropertyChangedEventHandler", + isRuntimeClass: false); + } + else + { + RegisterCustomAbiTypeMapping( + typeof(PropertyChangedEventHandler), + typeof(ABI.System.ComponentModel.PropertyChangedEventHandler), + "Microsoft.UI.Xaml.Data.PropertyChangedEventHandler", + isRuntimeClass: false); + } } /// Registers the custom ABI type mapping for the "Microsoft.UI.Xaml.Data.INotifyDataErrorInfo" WinRT type. @@ -601,11 +623,22 @@ public static void RegisterINotifyPropertyChangedMapping() return; } - RegisterCustomAbiTypeMapping( - typeof(INotifyPropertyChanged), - typeof(ABI.System.ComponentModel.INotifyPropertyChanged), - "Microsoft.UI.Xaml.Data.INotifyPropertyChanged", - isRuntimeClass: false); + if (FeatureSwitches.UseWindowsUIXamlProjections) + { + RegisterCustomAbiTypeMapping( + typeof(INotifyPropertyChanged), + typeof(ABI.System.ComponentModel.INotifyPropertyChanged), + "Windows.UI.Xaml.Data.INotifyPropertyChanged", + isRuntimeClass: false); + } + else + { + RegisterCustomAbiTypeMapping( + typeof(INotifyPropertyChanged), + typeof(ABI.System.ComponentModel.INotifyPropertyChanged), + "Microsoft.UI.Xaml.Data.INotifyPropertyChanged", + isRuntimeClass: false); + } } /// Registers the custom ABI type mapping for the "Microsoft.UI.Xaml.Interop.ICommand" WinRT type. @@ -621,11 +654,22 @@ public static void RegisterICommandMapping() return; } - RegisterCustomAbiTypeMapping( - typeof(ICommand), - typeof(ABI.System.Windows.Input.ICommand), - "Microsoft.UI.Xaml.Interop.ICommand", - isRuntimeClass: false); + if (FeatureSwitches.UseWindowsUIXamlProjections) + { + RegisterCustomAbiTypeMapping( + typeof(ICommand), + typeof(ABI.System.Windows.Input.ICommand), + "Windows.UI.Xaml.Interop.ICommand", + isRuntimeClass: false); + } + else + { + RegisterCustomAbiTypeMapping( + typeof(ICommand), + typeof(ABI.System.Windows.Input.ICommand), + "Microsoft.UI.Xaml.Interop.ICommand", + isRuntimeClass: false); + } } /// Registers the custom ABI type mapping for the "Microsoft.UI.Xaml.IXamlServiceProvider" WinRT type. @@ -846,11 +890,22 @@ public static void RegisterIEnumerableMapping() return; } - RegisterCustomAbiTypeMapping( - typeof(IEnumerable), - typeof(ABI.System.Collections.IEnumerable), - "Microsoft.UI.Xaml.Interop.IBindableIterable", - isRuntimeClass: false); + if (FeatureSwitches.UseWindowsUIXamlProjections) + { + RegisterCustomAbiTypeMapping( + typeof(IEnumerable), + typeof(ABI.System.Collections.IEnumerable), + "Windows.UI.Xaml.Interop.IBindableIterable", + isRuntimeClass: false); + } + else + { + RegisterCustomAbiTypeMapping( + typeof(IEnumerable), + typeof(ABI.System.Collections.IEnumerable), + "Microsoft.UI.Xaml.Interop.IBindableIterable", + isRuntimeClass: false); + } } /// Registers the custom ABI type mapping for the "Microsoft.UI.Xaml.Interop.IBindableVector" WinRT type. @@ -866,11 +921,22 @@ public static void RegisterIListMapping() return; } - RegisterCustomAbiTypeMapping( - typeof(IList), - typeof(ABI.System.Collections.IList), - "Microsoft.UI.Xaml.Interop.IBindableVector", - isRuntimeClass: false); + if (FeatureSwitches.UseWindowsUIXamlProjections) + { + RegisterCustomAbiTypeMapping( + typeof(IList), + typeof(ABI.System.Collections.IList), + "Windows.UI.Xaml.Interop.IBindableVector", + isRuntimeClass: false); + } + else + { + RegisterCustomAbiTypeMapping( + typeof(IList), + typeof(ABI.System.Collections.IList), + "Microsoft.UI.Xaml.Interop.IBindableVector", + isRuntimeClass: false); + } } /// Registers the custom ABI type mapping for the "Microsoft.UI.Xaml.Interop.INotifyCollectionChanged" WinRT type. @@ -886,11 +952,22 @@ public static void RegisterINotifyCollectionChangedMapping() return; } - RegisterCustomAbiTypeMapping( - typeof(INotifyCollectionChanged), - typeof(ABI.System.Collections.Specialized.INotifyCollectionChanged), - "Microsoft.UI.Xaml.Interop.INotifyCollectionChanged", - isRuntimeClass: false); + if (FeatureSwitches.UseWindowsUIXamlProjections) + { + RegisterCustomAbiTypeMapping( + typeof(INotifyCollectionChanged), + typeof(ABI.System.Collections.Specialized.INotifyCollectionChanged), + "Windows.UI.Xaml.Interop.INotifyCollectionChanged", + isRuntimeClass: false); + } + else + { + RegisterCustomAbiTypeMapping( + typeof(INotifyCollectionChanged), + typeof(ABI.System.Collections.Specialized.INotifyCollectionChanged), + "Microsoft.UI.Xaml.Interop.INotifyCollectionChanged", + isRuntimeClass: false); + } } /// Registers the custom ABI type mapping for the "Microsoft.UI.Xaml.Interop.NotifyCollectionChangedAction" WinRT type. @@ -906,11 +983,22 @@ public static void RegisterNotifyCollectionChangedActionMapping() return; } - RegisterCustomAbiTypeMapping( - typeof(NotifyCollectionChangedAction), - typeof(ABI.System.Collections.Specialized.NotifyCollectionChangedAction), - "Microsoft.UI.Xaml.Interop.NotifyCollectionChangedAction", - isRuntimeClass: false); + if (FeatureSwitches.UseWindowsUIXamlProjections) + { + RegisterCustomAbiTypeMapping( + typeof(NotifyCollectionChangedAction), + typeof(ABI.System.Collections.Specialized.NotifyCollectionChangedAction), + "Windows.UI.Xaml.Interop.NotifyCollectionChangedAction", + isRuntimeClass: false); + } + else + { + RegisterCustomAbiTypeMapping( + typeof(NotifyCollectionChangedAction), + typeof(ABI.System.Collections.Specialized.NotifyCollectionChangedAction), + "Microsoft.UI.Xaml.Interop.NotifyCollectionChangedAction", + isRuntimeClass: false); + } } /// Registers the custom ABI type mapping for the "Microsoft.UI.Xaml.Interop.NotifyCollectionChangedEventArgs" WinRT type. @@ -926,11 +1014,22 @@ public static void RegisterNotifyCollectionChangedEventArgsMapping() return; } - RegisterCustomAbiTypeMapping( - typeof(NotifyCollectionChangedEventArgs), - typeof(ABI.System.Collections.Specialized.NotifyCollectionChangedEventArgs), - "Microsoft.UI.Xaml.Interop.NotifyCollectionChangedEventArgs", - isRuntimeClass: true); + if (FeatureSwitches.UseWindowsUIXamlProjections) + { + RegisterCustomAbiTypeMapping( + typeof(NotifyCollectionChangedEventArgs), + typeof(ABI.System.Collections.Specialized.NotifyCollectionChangedEventArgs), + "Windows.UI.Xaml.Interop.NotifyCollectionChangedEventArgs", + isRuntimeClass: true); + } + else + { + RegisterCustomAbiTypeMapping( + typeof(NotifyCollectionChangedEventArgs), + typeof(ABI.System.Collections.Specialized.NotifyCollectionChangedEventArgs), + "Microsoft.UI.Xaml.Interop.NotifyCollectionChangedEventArgs", + isRuntimeClass: true); + } } /// Registers the custom ABI type mapping for the "Microsoft.UI.Xaml.Interop.NotifyCollectionChangedEventHandler" WinRT type. @@ -946,11 +1045,22 @@ public static void RegisterNotifyCollectionChangedEventHandlerMapping() return; } - RegisterCustomAbiTypeMapping( - typeof(NotifyCollectionChangedEventHandler), - typeof(ABI.System.Collections.Specialized.NotifyCollectionChangedEventHandler), - "Microsoft.UI.Xaml.Interop.NotifyCollectionChangedEventHandler", - isRuntimeClass: false); + if (FeatureSwitches.UseWindowsUIXamlProjections) + { + RegisterCustomAbiTypeMapping( + typeof(NotifyCollectionChangedEventHandler), + typeof(ABI.System.Collections.Specialized.NotifyCollectionChangedEventHandler), + "Windows.UI.Xaml.Interop.NotifyCollectionChangedEventHandler", + isRuntimeClass: false); + } + else + { + RegisterCustomAbiTypeMapping( + typeof(NotifyCollectionChangedEventHandler), + typeof(ABI.System.Collections.Specialized.NotifyCollectionChangedEventHandler), + "Microsoft.UI.Xaml.Interop.NotifyCollectionChangedEventHandler", + isRuntimeClass: false); + } } /// Registers the custom ABI type mapping for the "Windows.Foundation.Numerics.Matrix3x2" WinRT type. diff --git a/src/WinRT.Runtime/Projections.CustomTypeMappings.tt b/src/WinRT.Runtime/Projections.CustomTypeMappings.tt index acf45b303..8457dc046 100644 --- a/src/WinRT.Runtime/Projections.CustomTypeMappings.tt +++ b/src/WinRT.Runtime/Projections.CustomTypeMappings.tt @@ -125,7 +125,7 @@ var registerCustomAbiTypeMappings = new (string Public, string Abi, string Name, ("Quaternion", "ABI.System.Numerics.Quaternion", "Windows.Foundation.Numerics.Quaternion", null, false), ("Vector2", "ABI.System.Numerics.Vector2", "Windows.Foundation.Numerics.Vector2", null, false), ("Vector3", "ABI.System.Numerics.Vector3", "Windows.Foundation.Numerics.Vector3", null, false), - ("Vector4", "ABI.System.Numerics.Vector4", "Windows.Foundation.Numerics.Vector4", null, false), + ("Vector4", "ABI.System.Numerics.Vector4", "Windows.Foundation.Numerics.Vector4", null, false) }; // Types for 'RegisterCustomTypeToHelperTypeMapping' @@ -141,6 +141,21 @@ var registerCustomTypeToHelperTypeMapping = new (string Public, string Helper)[] ("ICollection", "ABI.System.Collections.ICollection") }; +// Types that have different projections for System XAML +var systemXamlProjectionTypeMapping = new(string Public, string Name)[] +{ + ("PropertyChangedEventArgs", "Windows.UI.Xaml.Data.PropertyChangedEventArgs"), + ("PropertyChangedEventHandler", "Windows.UI.Xaml.Data.PropertyChangedEventHandler"), + ("INotifyPropertyChanged", "Windows.UI.Xaml.Data.INotifyPropertyChanged"), + ("ICommand", "Windows.UI.Xaml.Interop.ICommand"), + ("IEnumerable", "Windows.UI.Xaml.Interop.IBindableIterable"), + ("IList", "Windows.UI.Xaml.Interop.IBindableVector"), + ("INotifyCollectionChanged", "Windows.UI.Xaml.Interop.INotifyCollectionChanged"), + ("NotifyCollectionChangedAction", "Windows.UI.Xaml.Interop.NotifyCollectionChangedAction"), + ("NotifyCollectionChangedEventArgs", "Windows.UI.Xaml.Interop.NotifyCollectionChangedEventArgs"), + ("NotifyCollectionChangedEventHandler", "Windows.UI.Xaml.Interop.NotifyCollectionChangedEventHandler") +}; + // Declare all fields foreach (string fieldName in registerCustomAbiTypeMappings @@ -166,13 +181,42 @@ foreach (var type in registerCustomAbiTypeMappings) { <# WriteGuardStatements(type.Public); -#> + WriteLine(""); + + int indexOfSystemXamlTypeMapping = Array.FindIndex(systemXamlProjectionTypeMapping, t => t.Public == type.Public); + if (indexOfSystemXamlTypeMapping != -1) + { +#> + if (FeatureSwitches.UseWindowsUIXamlProjections) + { + RegisterCustomAbiTypeMapping( + typeof(<#=type.Public#>), + typeof(<#=type.Abi#>), + "<#=systemXamlProjectionTypeMapping[indexOfSystemXamlTypeMapping].Name#>", + isRuntimeClass: <#=type.IsRuntimeClass.ToString().ToLowerInvariant()#>); + } + else + { + RegisterCustomAbiTypeMapping( + typeof(<#=type.Public#>), + typeof(<#=type.Abi#>), + "<#=type.Name#>", + isRuntimeClass: <#=type.IsRuntimeClass.ToString().ToLowerInvariant()#>); + } +<# + } + else + { +#> RegisterCustomAbiTypeMapping( typeof(<#=type.Public#>), typeof(<#=type.Abi#>), "<#=type.Name#>", isRuntimeClass: <#=type.IsRuntimeClass.ToString().ToLowerInvariant()#>); +<# + } +#> } <# } From c3c4aea1aced3d25e6f142096e599e3000f0740a Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Mon, 24 Jun 2024 13:52:12 -0700 Subject: [PATCH 44/46] Fix IIDs --- src/WinRT.Runtime/Interop/IID.g.cs | 48 +++++++++++++++--------------- src/WinRT.Runtime/Interop/IID.tt | 4 +-- 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/src/WinRT.Runtime/Interop/IID.g.cs b/src/WinRT.Runtime/Interop/IID.g.cs index 7365b3cd1..1929b3cd8 100644 --- a/src/WinRT.Runtime/Interop/IID.g.cs +++ b/src/WinRT.Runtime/Interop/IID.g.cs @@ -640,7 +640,7 @@ internal static ref readonly Guid IID_WUX_INotifyCollectionChangedEventArgs } } - /// The IID for MUX_NotifyCollectionChangedEventHandler (CA10B37C-F382-4591-8557-5E24965279B0). + /// The IID for WUX_MotifyCollectionChangedEventHandler (8B0909DC-2005-5D93-BF8A-725F017BAA8D). internal static ref readonly Guid IID_MUX_NotifyCollectionChangedEventHandler { [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -648,24 +648,24 @@ internal static ref readonly Guid IID_MUX_NotifyCollectionChangedEventHandler { ReadOnlySpan data = new byte[] { - 0x7C, 0xB3, 0x10, 0xCA, - 0x82, 0xF3, - 0x91, 0x45, - 0x85, - 0x57, - 0x5E, - 0x24, - 0x96, - 0x52, - 0x79, - 0xB0 + 0xDC, 0x09, 0x09, 0x8B, + 0x05, 0x20, + 0x93, 0x5D, + 0xBF, + 0x8A, + 0x72, + 0x5F, + 0x01, + 0x7B, + 0xAA, + 0x8D }; return ref Unsafe.As(ref MemoryMarshal.GetReference(data)); } } - /// The IID for WUX_NotifyCollectionChangedEventHandler (8B0909DC-2005-5D93-BF8A-725F017BAA8D). + /// The IID for WUX_NotifyCollectionChangedEventHandler (CA10B37C-F382-4591-8557-5E24965279B0). internal static ref readonly Guid IID_WUX_NotifyCollectionChangedEventHandler { [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -673,17 +673,17 @@ internal static ref readonly Guid IID_WUX_NotifyCollectionChangedEventHandler { ReadOnlySpan data = new byte[] { - 0xDC, 0x09, 0x09, 0x8B, - 0x05, 0x20, - 0x93, 0x5D, - 0xBF, - 0x8A, - 0x72, - 0x5F, - 0x01, - 0x7B, - 0xAA, - 0x8D + 0x7C, 0xB3, 0x10, 0xCA, + 0x82, 0xF3, + 0x91, 0x45, + 0x85, + 0x57, + 0x5E, + 0x24, + 0x96, + 0x52, + 0x79, + 0xB0 }; return ref Unsafe.As(ref MemoryMarshal.GetReference(data)); diff --git a/src/WinRT.Runtime/Interop/IID.tt b/src/WinRT.Runtime/Interop/IID.tt index dd852dc33..17d48ca84 100644 --- a/src/WinRT.Runtime/Interop/IID.tt +++ b/src/WinRT.Runtime/Interop/IID.tt @@ -47,8 +47,8 @@ var entries = new (string Name, string IID, bool IsPublic)[] ("WUX_INotifyCollectionChangedEventArgsFactory", "B30C3E3A-DF8D-44A5-9A38-7AC0D08CE63D", false), ("MUX_INotifyCollectionChangedEventArgs", "DA049FF2-D2E0-5FE8-8C7B-F87F26060B6F", false), ("WUX_INotifyCollectionChangedEventArgs", "4CF68D33-E3F2-4964-B85E-945B4F7E2F21", false), - ("MUX_NotifyCollectionChangedEventHandler", "CA10B37C-F382-4591-8557-5E24965279B0", false), - ("WUX_NotifyCollectionChangedEventHandler", "8B0909DC-2005-5D93-BF8A-725F017BAA8D", false), + ("MUX_NotifyCollectionChangedEventHandler", "8B0909DC-2005-5D93-BF8A-725F017BAA8D", false), + ("WUX_NotifyCollectionChangedEventHandler", "CA10B37C-F382-4591-8557-5E24965279B0", false), ("MUX_PropertyChangedEventArgsRuntimeClassFactory", "7C0C27A8-0B41-5070-B160-FC9AE960A36C", false), ("WUX_PropertyChangedEventArgsRuntimeClassFactory", "6DCC9C03-E0C7-4EEE-8EA9-37E3406EEB1C", false), ("MUX_PropertyChangedEventHandler", "E3DE52F6-1E32-5DA6-BB2D-B5B6096C962D", false), From 000ca9bef419e0fdb3e90df1696e8b0ca341043a Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Mon, 24 Jun 2024 15:13:29 -0700 Subject: [PATCH 45/46] Remove unnecessary 'As' calls for activation --- .../Projections/PropertyChangedEventArgs.cs | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/WinRT.Runtime/Projections/PropertyChangedEventArgs.cs b/src/WinRT.Runtime/Projections/PropertyChangedEventArgs.cs index 22f6c9a04..61116de9d 100644 --- a/src/WinRT.Runtime/Projections/PropertyChangedEventArgs.cs +++ b/src/WinRT.Runtime/Projections/PropertyChangedEventArgs.cs @@ -11,18 +11,17 @@ namespace ABI.Microsoft.UI.Xaml.Data { internal sealed unsafe class PropertyChangedEventArgsRuntimeClassFactory { - private readonly ObjectReference _obj; + private readonly IObjectReference _obj; public PropertyChangedEventArgsRuntimeClassFactory() { - if (FeatureSwitches.UseWindowsUIXamlProjections) - { - _obj = ActivationFactory.Get("Windows.UI.Xaml.Data.PropertyChangedEventArgs").As(IID.IID_WUX_PropertyChangedEventArgsRuntimeClassFactory); - } - else - { - _obj = ActivationFactory.Get("Microsoft.UI.Xaml.Data.PropertyChangedEventArgs").As(IID.IID_MUX_PropertyChangedEventArgsRuntimeClassFactory); - } +#if NET + _obj = FeatureSwitches.UseWindowsUIXamlProjections + ? ActivationFactory.Get("Windows.UI.Xaml.Data.PropertyChangedEventArgs", IID.IID_WUX_PropertyChangedEventArgsRuntimeClassFactory) + : ActivationFactory.Get("Microsoft.UI.Xaml.Data.PropertyChangedEventArgs", IID.IID_MUX_PropertyChangedEventArgsRuntimeClassFactory); +#else + _obj = ActivationFactory.Get("Microsoft.UI.Xaml.Data.PropertyChangedEventArgs", IID.IID_MUX_PropertyChangedEventArgsRuntimeClassFactory); +#endif } public IObjectReference CreateInstance(string name, object baseInterface, out IObjectReference innerInterface) From 579b5e1049f48da77603990cae5d50fe66e4ea2b Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Mon, 24 Jun 2024 15:14:31 -0700 Subject: [PATCH 46/46] Reorder props, fix indendation --- .../WinRT.SourceGenerator/WinRT.SourceGenerator.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Authoring/WinRT.SourceGenerator/WinRT.SourceGenerator.csproj b/src/Authoring/WinRT.SourceGenerator/WinRT.SourceGenerator.csproj index e6bce6382..357e76314 100644 --- a/src/Authoring/WinRT.SourceGenerator/WinRT.SourceGenerator.csproj +++ b/src/Authoring/WinRT.SourceGenerator/WinRT.SourceGenerator.csproj @@ -15,9 +15,9 @@ C#/WinRT Authoring Source Generator Preview $(VersionString) C#/WinRT Authoring Source Generator Preview v$(VersionString) Copyright (c) Microsoft Corporation. All rights reserved. - true true $(SolutionDir)WinRT.Runtime\key.snk + true true