From 2dbe65056b18da403b2a9cc9c0157df124e0ffcd Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Thu, 30 Jan 2025 11:23:04 -0800 Subject: [PATCH] Use specialized marshallers for generic instantiations --- .../WinRT.SourceGenerator/AotOptimizer.cs | 39 +- .../Extensions/SymbolExtensions.cs | 23 + .../GenericVtableInitializerStrings.cs | 3488 +++++++++-------- src/Authoring/WinRT.SourceGenerator/Helper.cs | 2511 ++++++------ .../ApiCompatBaseline.net6.0.txt | 3 +- .../ApiCompatBaseline.net8.0.txt | 3 +- src/WinRT.Runtime/Marshalers.cs | 15 +- .../MatchingRefApiCompatBaseline.net6.0.txt | 3 +- .../MatchingRefApiCompatBaseline.net8.0.txt | 3 +- 9 files changed, 3091 insertions(+), 2997 deletions(-) diff --git a/src/Authoring/WinRT.SourceGenerator/AotOptimizer.cs b/src/Authoring/WinRT.SourceGenerator/AotOptimizer.cs index 409feac81b..24ef0df373 100644 --- a/src/Authoring/WinRT.SourceGenerator/AotOptimizer.cs +++ b/src/Authoring/WinRT.SourceGenerator/AotOptimizer.cs @@ -740,7 +740,8 @@ genericParameter is INamedTypeSymbol genericParameterIface && genericParameters.Add(new GenericParameter( ToFullyQualifiedString(genericParameter), GeneratorHelper.GetAbiType(genericParameter, mapper), - isNullable ? TypeKind.Interface : genericParameter.TypeKind)); + isNullable ? TypeKind.Interface : genericParameter.TypeKind, + ComputeTypeFlags(genericParameter, compilation))); } genericInterfacesToAddToVtable.Add(new GenericInterface( @@ -773,6 +774,25 @@ void CheckForInterfaceToUseForRuntimeClassName(INamedTypeSymbol iface) } } + private static TypeFlags ComputeTypeFlags(ITypeSymbol symbol, Compilation compilation) + { + TypeFlags typeFlags = TypeFlags.None; + + // Check for exception types + if (symbol.TypeKind is TypeKind.Class) + { + var exceptionType = compilation.GetTypeByMetadataName("System.Exception")!; + + if (SymbolEqualityComparer.Default.Equals(symbol, exceptionType) || + symbol.InheritsFromType(exceptionType)) + { + typeFlags |= TypeFlags.Exception; + } + } + + return typeFlags; + } + private static bool TryGetCompatibleWindowsRuntimeTypesForVariantType(INamedTypeSymbol type, TypeMapper mapper, Stack typeStack, Func isWinRTType, INamedTypeSymbol objectType, out IList compatibleTypes) { compatibleTypes = null; @@ -1873,7 +1893,8 @@ namespace {{bindableCustomProperties.Namespace}} internal readonly record struct GenericParameter( string ProjectedType, string AbiType, - TypeKind TypeKind); + TypeKind TypeKind, + TypeFlags TypeFlags); internal readonly record struct GenericInterface( string Interface, @@ -1923,6 +1944,20 @@ internal readonly record struct CsWinRTAotOptimizerProperties( bool IsCsWinRTCcwLookupTableGeneratorEnabled, bool IsCsWinRTAotOptimizerInAutoMode); + /// + /// Additional flags for discovered types. + /// + [Flags] + internal enum TypeFlags + { + None = 0x0, + + /// + /// The type derives from . + /// + Exception = 0x1 << 0 + } + /// /// A model describing a type info in a type hierarchy. /// diff --git a/src/Authoring/WinRT.SourceGenerator/Extensions/SymbolExtensions.cs b/src/Authoring/WinRT.SourceGenerator/Extensions/SymbolExtensions.cs index 215729e827..4b1f9f1242 100644 --- a/src/Authoring/WinRT.SourceGenerator/Extensions/SymbolExtensions.cs +++ b/src/Authoring/WinRT.SourceGenerator/Extensions/SymbolExtensions.cs @@ -87,4 +87,27 @@ public static bool IsAccessibleFromCompilationAssembly(this ISymbol symbol, Comp { return compilation.IsSymbolAccessibleWithin(symbol, compilation.Assembly); } + + /// + /// Checks whether or not a given inherits from a specified type. + /// + /// The target instance to check. + /// The instane to check for inheritance from. + /// Whether or not inherits from . + public static bool InheritsFromType(this ITypeSymbol typeSymbol, ITypeSymbol baseTypeSymbol) + { + INamedTypeSymbol? currentBaseTypeSymbol = typeSymbol.BaseType; + + while (currentBaseTypeSymbol is not null) + { + if (SymbolEqualityComparer.Default.Equals(currentBaseTypeSymbol, baseTypeSymbol)) + { + return true; + } + + currentBaseTypeSymbol = currentBaseTypeSymbol.BaseType; + } + + return false; + } } diff --git a/src/Authoring/WinRT.SourceGenerator/GenericVtableInitializerStrings.cs b/src/Authoring/WinRT.SourceGenerator/GenericVtableInitializerStrings.cs index d9d4d048fc..d2c95eaf6a 100644 --- a/src/Authoring/WinRT.SourceGenerator/GenericVtableInitializerStrings.cs +++ b/src/Authoring/WinRT.SourceGenerator/GenericVtableInitializerStrings.cs @@ -1,1738 +1,1750 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -using Microsoft.CodeAnalysis; -using System.Collections.Immutable; -using System.Linq; -using WinRT.SourceGenerator; - -namespace Generator -{ - internal static class GenericVtableInitializerStrings - { - public static string GetInstantiation(string genericInterface, EquatableArray genericParameters) - { - if (genericInterface == "System.Collections.Generic.IEnumerable`1") - { - return GetIEnumerableInstantiation(genericParameters[0].ProjectedType, genericParameters[0].AbiType); - } - else if (genericInterface == "System.Collections.Generic.IList`1") - { - return GetIListInstantiation(genericParameters[0].ProjectedType, genericParameters[0].AbiType, genericParameters[0].TypeKind); - } - else if (genericInterface == "System.Collections.Generic.IReadOnlyList`1") - { - return GetIReadOnlyListInstantiation(genericParameters[0].ProjectedType, genericParameters[0].AbiType, genericParameters[0].TypeKind); - } - else if (genericInterface == "System.Collections.Generic.IDictionary`2") - { - return GetIDictionaryInstantiation( - genericParameters[0].ProjectedType, - genericParameters[0].AbiType, - genericParameters[0].TypeKind, - genericParameters[1].ProjectedType, - genericParameters[1].AbiType, - genericParameters[1].TypeKind); - } - else if (genericInterface == "System.Collections.Generic.IReadOnlyDictionary`2") - { - return GetIReadOnlyDictionaryInstantiation( - genericParameters[0].ProjectedType, - genericParameters[0].AbiType, - genericParameters[0].TypeKind, - genericParameters[1].ProjectedType, - genericParameters[1].AbiType, - genericParameters[1].TypeKind); - } - else if (genericInterface == "System.Collections.Generic.IEnumerator`1") - { - return GetIEnumeratorInstantiation(genericParameters[0].ProjectedType, genericParameters[0].AbiType, genericParameters[0].TypeKind); - } - else if (genericInterface == "System.Collections.Generic.KeyValuePair`2") - { - return GetKeyValuePairInstantiation( - genericParameters[0].ProjectedType, - genericParameters[0].AbiType, - genericParameters[0].TypeKind, - genericParameters[1].ProjectedType, - genericParameters[1].AbiType, - genericParameters[1].TypeKind); - } - else if (genericInterface == "System.EventHandler`1") - { - return GetEventHandlerInstantiation(genericParameters[0].ProjectedType, genericParameters[0].AbiType, genericParameters[0].TypeKind); - } - else if (genericInterface == "Windows.Foundation.AsyncActionWithProgressCompletedHandler`1") - { - return GetCompletedHandlerInstantiation("Windows.Foundation.AsyncActionWithProgressCompletedHandler", "Windows.Foundation.IAsyncActionWithProgress", genericParameters); - } - else if (genericInterface == "Windows.Foundation.AsyncOperationCompletedHandler`1") - { - return GetCompletedHandlerInstantiation("Windows.Foundation.AsyncOperationCompletedHandler", "Windows.Foundation.IAsyncOperation", genericParameters); - } - else if (genericInterface == "Windows.Foundation.AsyncOperationWithProgressCompletedHandler`2") - { - return GetCompletedHandlerInstantiation("Windows.Foundation.AsyncOperationWithProgressCompletedHandler", "Windows.Foundation.IAsyncOperationWithProgress", genericParameters); - } - else if (genericInterface == "Windows.Foundation.Collections.MapChangedEventHandler`2") - { - string senderInterface = $"global::Windows.Foundation.Collections.IObservableMap<{genericParameters[0].ProjectedType}, {genericParameters[1].ProjectedType}>"; - string changedEventArgsInterface = $"global::Windows.Foundation.Collections.IMapChangedEventArgs<{genericParameters[0].ProjectedType}>"; - return GetChangedHandlerInstantiation("Windows.Foundation.Collections.MapChangedEventHandler", senderInterface, changedEventArgsInterface, genericParameters); - } - else if (genericInterface == "Windows.Foundation.Collections.VectorChangedEventHandler`1") - { - string senderInterface = $"global::Windows.Foundation.Collections.IObservableVector<{genericParameters[0].ProjectedType}>"; - string changedEventArgsInterface = $"global::Windows.Foundation.Collections.IVectorChangedEventArgs"; - return GetChangedHandlerInstantiation("Windows.Foundation.Collections.VectorChangedEventHandler", senderInterface, changedEventArgsInterface, genericParameters); - } - else if (genericInterface == "Windows.Foundation.AsyncActionProgressHandler`1") - { - return GetProgressHandlerInstantiation("Windows.Foundation.AsyncActionProgressHandler", "Windows.Foundation.IAsyncActionWithProgress", genericParameters); - } - else if (genericInterface == "Windows.Foundation.AsyncOperationProgressHandler`2") - { - return GetProgressHandlerInstantiation("Windows.Foundation.AsyncOperationProgressHandler", "Windows.Foundation.IAsyncOperationWithProgress", genericParameters); - } - else if (genericInterface == "Windows.Foundation.TypedEventHandler`2") - { - return GetTypedEventHandlerInstantiation(genericParameters); - } - else if (genericInterface == "Windows.Foundation.IAsyncActionWithProgress`1") - { - return GetIAsyncActionWithProgressInstantiation(genericParameters); - } - else if (genericInterface == "Windows.Foundation.IAsyncOperationWithProgress`2") - { - return GetIAsyncOperationWithProgressInstantiation(genericParameters); - } - else if (genericInterface == "Windows.Foundation.IAsyncOperation`1") - { - return GetIAsyncOperationInstantiation(genericParameters); - } - else if (genericInterface == "Windows.Foundation.Collections.IMapChangedEventArgs`1") - { - return GetIMapChangedEventArgsInstantiation(genericParameters); - } - else if (genericInterface == "Windows.Foundation.Collections.IObservableMap`2") - { - return GetIObservableMapInstantiation(genericParameters); - } - else if (genericInterface == "Windows.Foundation.Collections.IObservableVector`1") - { - return GetIObservableVectorInstantiation(genericParameters); - } - - return ""; - } - - public static ImmutableHashSet AddDependentGenericInterfaces(ImmutableHashSet genericInterfaces) - { - var genericInterfacesList = genericInterfaces.ToList(); - - foreach (var genericInterface in genericInterfaces) - { - if (genericInterface.GenericDefinition == "Windows.Foundation.IAsyncActionWithProgress`1") - { - AddReplacedGenericInterface(genericInterface, "Windows.Foundation.AsyncActionProgressHandler"); - AddReplacedGenericInterface(genericInterface, "Windows.Foundation.AsyncActionWithProgressCompletedHandler"); - } - else if (genericInterface.GenericDefinition == "Windows.Foundation.IAsyncOperationWithProgress`2") - { - AddReplacedGenericInterface(genericInterface, "Windows.Foundation.AsyncOperationProgressHandler"); - AddReplacedGenericInterface(genericInterface, "Windows.Foundation.AsyncOperationWithProgressCompletedHandler"); - } - else if (genericInterface.GenericDefinition == "Windows.Foundation.IAsyncOperation`1") - { - AddReplacedGenericInterface(genericInterface, "Windows.Foundation.AsyncOperationCompletedHandler"); - } - else if (genericInterface.GenericDefinition == "Windows.Foundation.Collections.IObservableMap`2") - { - AddReplacedGenericInterface(genericInterface, "Windows.Foundation.Collections.MapChangedEventHandler"); - } - else if (genericInterface.GenericDefinition == "Windows.Foundation.Collections.IObservableVector`1") - { - AddReplacedGenericInterface(genericInterface, "Windows.Foundation.Collections.VectorChangedEventHandler"); - } - } - - return genericInterfacesList.ToImmutableHashSet(); - - void AddReplacedGenericInterface(GenericInterface genericInterfaceToReplace, string newInterfaceToReplaceWith) - { - // Replace the old interface name with the new one. - // We know this is an generic interface, so we want to replace the string before the generics (<). - string newQualifiedInterfaceName = newInterfaceToReplaceWith + genericInterfaceToReplace.Interface[genericInterfaceToReplace.Interface.IndexOf('<')..]; - - // The metadata name includes the number of generics which we get from the last character of the one we are replacing - // since they are the same in the scenarios we care about. - string newInterfaceMetadataName = newInterfaceToReplaceWith + "`" + genericInterfaceToReplace.GenericDefinition[^1]; - - genericInterfacesList.Add(new GenericInterface( - newQualifiedInterfaceName, - newInterfaceMetadataName, - genericInterfaceToReplace.GenericParameters - )); - } - } - - public static string GetInstantiationInitFunction(string genericInterface, EquatableArray genericParameters, string escapedAssemblyName) - { - // Get the class name from a string like System.Collections.Generic.IEnumerator`1. - // Splitting on the dots and the generic specifier (`) will get us the class name - // in the 2nd last element. - var interfaceName = genericInterface.Split('.', '`')[^2]; - var genericParametersStr = string.Join("_", genericParameters.Select(static genericParameter => GeneratorHelper.EscapeTypeNameForIdentifier(genericParameter.ProjectedType))); - return $$""" _ = global::WinRT.{{escapedAssemblyName}}GenericHelpers.{{interfaceName}}_{{genericParametersStr}}.Initialized;"""; - } - - private static string GetIEnumerableInstantiation(string genericType, string abiType) - { - string iEnumerableInstantiation = $$""" - internal static class IEnumerable_{{GeneratorHelper.EscapeTypeNameForIdentifier(genericType)}} - { - private static readonly bool _initialized = Init(); - internal static bool Initialized => _initialized; - - private static unsafe bool Init() - { - return global::ABI.System.Collections.Generic.IEnumerableMethods<{{genericType}}, {{abiType}}>.InitCcw( - &Do_Abi_First_0 - ); - } - - [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] - private static unsafe int Do_Abi_First_0(IntPtr thisPtr, IntPtr* __return_value__) - { - *__return_value__ = default; - try - { - *__return_value__ = MarshalInterface>. - FromManaged(global::ABI.System.Collections.Generic.IEnumerableMethods<{{genericType}}>.Abi_First_0(thisPtr)); - } - catch (global::System.Exception __exception__) - { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); - } - return 0; - } - } - """; - return iEnumerableInstantiation; - } - - private static string GetIEnumeratorInstantiation(string genericType, string abiType, TypeKind typeKind) - { - string iEnumeratorInstantiation = $$""" - internal static class IEnumerator_{{GeneratorHelper.EscapeTypeNameForIdentifier(genericType)}} - { - private static readonly bool _initialized = Init(); - internal static bool Initialized => _initialized; - - private static unsafe bool Init() - { - return global::ABI.System.Collections.Generic.IEnumeratorMethods<{{genericType}}, {{abiType}}>.InitCcw( - &Do_Abi_get_Current_0, - &Do_Abi_get_HasCurrent_1, - &Do_Abi_MoveNext_2, - &Do_Abi_GetMany_3 - ); - } - - [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] - private static unsafe int Do_Abi_MoveNext_2(IntPtr thisPtr, byte* __return_value__) - { - bool ____return_value__ = default; - - *__return_value__ = default; - - try - { - ____return_value__ = global::ABI.System.Collections.Generic.IEnumeratorMethods<{{genericType}}>.Abi_MoveNext_2(thisPtr); - *__return_value__ = (byte)(____return_value__ ? 1 : 0); - } - catch (global::System.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* __return_value__) - { - uint ____return_value__ = default; - - *__return_value__ = default; - {{genericType}}[] __items = {{GeneratorHelper.GetMarshalerClass(genericType, abiType, typeKind, true)}}.FromAbiArray((__itemsSize, items)); - - try - { - ____return_value__ = global::ABI.System.Collections.Generic.IEnumeratorMethods<{{genericType}}>.Abi_GetMany_3(thisPtr, ref __items); - {{GeneratorHelper.GetCopyManagedArrayMarshaler(genericType, abiType, typeKind)}}.CopyManagedArray(__items, items); - *__return_value__ = ____return_value__; - } - catch (global::System.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, {{abiType}}* __return_value__) - { - {{genericType}} ____return_value__ = default; - - *__return_value__ = default; - - try - { - ____return_value__ = global::ABI.System.Collections.Generic.IEnumeratorMethods<{{genericType}}>.Abi_get_Current_0(thisPtr); - *__return_value__ = {{GeneratorHelper.GetFromManagedMarshaler(genericType, abiType, typeKind, "____return_value__")}}; - } - catch (global::System.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* __return_value__) - { - bool ____return_value__ = default; - - *__return_value__ = default; - - try - { - ____return_value__ = global::ABI.System.Collections.Generic.IEnumeratorMethods<{{genericType}}>.Abi_get_HasCurrent_1(thisPtr); - *__return_value__ = (byte)(____return_value__ ? 1 : 0); - } - catch (global::System.Exception __exception__) - { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); - } - return 0; - } - } - """; - return iEnumeratorInstantiation; - } - - private static string GetIListInstantiation(string genericType, string abiType, TypeKind typeKind) - { - string iListInstantiation = $$""" - internal static class IList_{{GeneratorHelper.EscapeTypeNameForIdentifier(genericType)}} - { - private static readonly bool _initialized = Init(); - internal static bool Initialized => _initialized; - - private static unsafe bool Init() - { - return global::ABI.System.Collections.Generic.IListMethods<{{genericType}}, {{abiType}}>.InitCcw( - &Do_Abi_GetAt_0, - &Do_Abi_get_Size_1, - &Do_Abi_GetView_2, - &Do_Abi_IndexOf_3, - &Do_Abi_SetAt_4, - &Do_Abi_InsertAt_5, - &Do_Abi_RemoveAt_6, - &Do_Abi_Append_7, - &Do_Abi_RemoveAtEnd_8, - &Do_Abi_Clear_9, - &Do_Abi_GetMany_10, - &Do_Abi_ReplaceAll_11 - ); - } - - [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] - private static unsafe int Do_Abi_GetAt_0(IntPtr thisPtr, uint index, {{abiType}}* __return_value__) - { - {{genericType}} ____return_value__ = default; - *__return_value__ = default; - try - { - ____return_value__ = global::ABI.System.Collections.Generic.IListMethods<{{genericType}}>.Abi_GetAt_0(thisPtr, index); - *__return_value__ = {{GeneratorHelper.GetFromManagedMarshaler(genericType, abiType, typeKind, "____return_value__")}}; - } - catch (global::System.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_GetView_2(IntPtr thisPtr, IntPtr* __return_value__) - { - global::System.Collections.Generic.IReadOnlyList<{{genericType}}> ____return_value__ = default; - *__return_value__ = default; - - try - { - ____return_value__ = global::ABI.System.Collections.Generic.IListMethods<{{genericType}}>.Abi_GetView_2(thisPtr); - *__return_value__ = MarshalInterface>.FromManaged(____return_value__); - } - catch (global::System.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_3(IntPtr thisPtr, {{abiType}} value, uint* index, byte* __return_value__) - { - bool ____return_value__ = default; - - *index = default; - *__return_value__ = default; - uint __index = default; - - try - { - ____return_value__ = global::ABI.System.Collections.Generic.IListMethods<{{genericType}}>.Abi_IndexOf_3(thisPtr, {{GeneratorHelper.GetFromAbiMarshaler(genericType, abiType, typeKind, "value")}}, out __index); - *index = __index; - *__return_value__ = (byte)(____return_value__ ? 1 : 0); - } - catch (global::System.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_SetAt_4(IntPtr thisPtr, uint index, {{abiType}} value) - { - try - { - global::ABI.System.Collections.Generic.IListMethods<{{genericType}}>.Abi_SetAt_4(thisPtr, index, {{GeneratorHelper.GetFromAbiMarshaler(genericType, abiType, typeKind, "value")}}); - } - catch (global::System.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_InsertAt_5(IntPtr thisPtr, uint index, {{abiType}} value) - { - try - { - global::ABI.System.Collections.Generic.IListMethods<{{genericType}}>.Abi_InsertAt_5(thisPtr, index, {{GeneratorHelper.GetFromAbiMarshaler(genericType, abiType, typeKind, "value")}}); - } - catch (global::System.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_RemoveAt_6(IntPtr thisPtr, uint index) - { - try - { - global::ABI.System.Collections.Generic.IListMethods<{{genericType}}>.Abi_RemoveAt_6(thisPtr, index); - } - catch (global::System.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_Append_7(IntPtr thisPtr, {{abiType}} value) - { - try - { - global::ABI.System.Collections.Generic.IListMethods<{{genericType}}>.Abi_Append_7(thisPtr, {{GeneratorHelper.GetFromAbiMarshaler(genericType, abiType, typeKind, "value")}}); - } - catch (global::System.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_RemoveAtEnd_8(IntPtr thisPtr) - { - try - { - global::ABI.System.Collections.Generic.IListMethods<{{genericType}}>.Abi_RemoveAtEnd_8(thisPtr); - } - catch (global::System.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_Clear_9(IntPtr thisPtr) - { - try - { - global::ABI.System.Collections.Generic.IListMethods<{{genericType}}>.Abi_Clear_9(thisPtr); - } - catch (global::System.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_10(IntPtr thisPtr, uint startIndex, int __itemsSize, IntPtr items, uint* __return_value__) - { - uint ____return_value__ = default; - - *__return_value__ = default; - {{genericType}}[] __items = {{GeneratorHelper.GetMarshalerClass(genericType, abiType, typeKind, true)}}.FromAbiArray((__itemsSize, items)); - - try - { - ____return_value__ = global::ABI.System.Collections.Generic.IListMethods<{{genericType}}>.Abi_GetMany_10(thisPtr, startIndex, ref __items); - {{GeneratorHelper.GetCopyManagedArrayMarshaler(genericType, abiType, typeKind)}}.CopyManagedArray(__items, items); - *__return_value__ = ____return_value__; - } - catch (global::System.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_ReplaceAll_11(IntPtr thisPtr, int __itemsSize, IntPtr items) - { - try - { - global::ABI.System.Collections.Generic.IListMethods<{{genericType}}>.Abi_ReplaceAll_11(thisPtr, {{GeneratorHelper.GetMarshalerClass(genericType, abiType, typeKind, true)}}.FromAbiArray((__itemsSize, items))); - } - catch (global::System.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* __return_value__) - { - uint ____return_value__ = default; - - *__return_value__ = default; - - try - { - ____return_value__ = global::ABI.System.Collections.Generic.IListMethods<{{genericType}}>.Abi_get_Size_1(thisPtr); - *__return_value__ = ____return_value__; - } - catch (global::System.Exception __exception__) - { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); - } - return 0; - } - } - """; - return iListInstantiation; - } - - private static string GetIReadOnlyListInstantiation(string genericType, string abiType, TypeKind typeKind) - { - string iReadOnlylistInstantiation = $$""" - internal static class IReadOnlyList_{{GeneratorHelper.EscapeTypeNameForIdentifier(genericType)}} - { - private static readonly bool _initialized = Init(); - internal static bool Initialized => _initialized; - - private static unsafe bool Init() - { - return global::ABI.System.Collections.Generic.IReadOnlyListMethods<{{genericType}}, {{abiType}}>.InitCcw( - &Do_Abi_GetAt_0, - &Do_Abi_get_Size_1, - &Do_Abi_IndexOf_2, - &Do_Abi_GetMany_3 - ); - } - - [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] - private static unsafe int Do_Abi_GetAt_0(IntPtr thisPtr, uint index, {{abiType}}* __return_value__) - { - {{genericType}} ____return_value__ = default; - *__return_value__ = default; - try - { - ____return_value__ = global::ABI.System.Collections.Generic.IReadOnlyListMethods<{{genericType}}>.Abi_GetAt_0(thisPtr, index); - *__return_value__ = {{GeneratorHelper.GetFromManagedMarshaler(genericType, abiType, typeKind, "____return_value__")}}; - } - catch (global::System.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, {{abiType}} value, uint* index, byte* __return_value__) - { - bool ____return_value__ = default; - - *index = default; - *__return_value__ = default; - uint __index = default; - - try - { - ____return_value__ = global::ABI.System.Collections.Generic.IReadOnlyListMethods<{{genericType}}>.Abi_IndexOf_2(thisPtr, {{GeneratorHelper.GetFromAbiMarshaler(genericType, abiType, typeKind, "value")}}, out __index); - *index = __index; - *__return_value__ = (byte)(____return_value__ ? 1 : 0); - } - catch (global::System.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, uint startIndex, int __itemsSize, IntPtr items, uint* __return_value__) - { - uint ____return_value__ = default; - - *__return_value__ = default; - {{genericType}}[] __items = {{GeneratorHelper.GetMarshalerClass(genericType, abiType, typeKind, true)}}.FromAbiArray((__itemsSize, items)); - - try - { - ____return_value__ = global::ABI.System.Collections.Generic.IReadOnlyListMethods<{{genericType}}>.Abi_GetMany_3(thisPtr, startIndex, ref __items); - {{GeneratorHelper.GetCopyManagedArrayMarshaler(genericType, abiType, typeKind)}}.CopyManagedArray(__items, items); - *__return_value__ = ____return_value__; - } - catch (global::System.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* __return_value__) - { - uint ____return_value__ = default; - - *__return_value__ = default; - - try - { - ____return_value__ = global::ABI.System.Collections.Generic.IReadOnlyListMethods<{{genericType}}>.Abi_get_Size_1(thisPtr); - *__return_value__ = ____return_value__; - } - catch (global::System.Exception __exception__) - { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); - } - return 0; - } - } - """; - return iReadOnlylistInstantiation; - } - - private static string GetIDictionaryInstantiation(string genericKeyType, string abiKeyType, TypeKind keyTypeKind, string genericValueType, string abiValueType, TypeKind valueTypeKind) - { - string iDictionaryInstantiation = $$""" - internal static class IDictionary_{{GeneratorHelper.EscapeTypeNameForIdentifier(genericKeyType)}}_{{GeneratorHelper.EscapeTypeNameForIdentifier(genericValueType)}} - { - private static readonly bool _initialized = Init(); - internal static bool Initialized => _initialized; - - private static unsafe bool Init() - { - return global::ABI.System.Collections.Generic.IDictionaryMethods<{{genericKeyType}}, {{abiKeyType}}, {{genericValueType}}, {{abiValueType}}>.InitCcw( - &Do_Abi_Lookup_0, - &Do_Abi_get_Size_1, - &Do_Abi_HasKey_2, - &Do_Abi_GetView_3, - &Do_Abi_Insert_4, - &Do_Abi_Remove_5, - &Do_Abi_Clear_6 - ); - } - - [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] - private static unsafe int Do_Abi_Lookup_0(IntPtr thisPtr, {{abiKeyType}} key, {{abiValueType}}* __return_value__) - { - {{genericValueType}} ____return_value__ = default; - - *__return_value__ = default; - - try - { - ____return_value__ = global::ABI.System.Collections.Generic.IDictionaryMethods<{{genericKeyType}}, {{genericValueType}}>.Abi_Lookup_0(thisPtr, {{GeneratorHelper.GetFromAbiMarshaler(genericKeyType, abiKeyType, keyTypeKind, "key")}}); - *__return_value__ = {{GeneratorHelper.GetFromManagedMarshaler(genericValueType, abiValueType, valueTypeKind, "____return_value__")}}; - } - catch (global::System.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_HasKey_2(IntPtr thisPtr, {{abiKeyType}} key, byte* __return_value__) - { - bool ____return_value__ = default; - - *__return_value__ = default; - - try - { - ____return_value__ = global::ABI.System.Collections.Generic.IDictionaryMethods<{{genericKeyType}}, {{genericValueType}}>.Abi_HasKey_2(thisPtr, {{GeneratorHelper.GetFromAbiMarshaler(genericKeyType, abiKeyType, keyTypeKind, "key")}}); - *__return_value__ = (byte)(____return_value__ ? 1 : 0); - } - catch (global::System.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_GetView_3(IntPtr thisPtr, IntPtr* __return_value__) - { - global::System.Collections.Generic.IReadOnlyDictionary<{{genericKeyType}}, {{genericValueType}}> ____return_value__ = default; - - *__return_value__ = default; - - try - { - ____return_value__ = global::ABI.System.Collections.Generic.IDictionaryMethods<{{genericKeyType}}, {{genericValueType}}>.Abi_GetView_3(thisPtr); - *__return_value__ = MarshalInterface>.FromManaged(____return_value__); - } - catch (global::System.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_Insert_4(IntPtr thisPtr, {{abiKeyType}} key, {{abiValueType}} value, byte* __return_value__) - { - bool ____return_value__ = default; - - *__return_value__ = default; - - try - { - ____return_value__ = global::ABI.System.Collections.Generic.IDictionaryMethods<{{genericKeyType}}, {{genericValueType}}>.Abi_Insert_4(thisPtr, {{GeneratorHelper.GetFromAbiMarshaler(genericKeyType, abiKeyType, keyTypeKind, "key")}}, {{GeneratorHelper.GetFromAbiMarshaler(genericValueType, abiValueType, valueTypeKind, "value")}}); - *__return_value__ = (byte)(____return_value__ ? 1 : 0); - } - catch (global::System.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_Remove_5(IntPtr thisPtr, {{abiKeyType}} key) - { - try - { - global::ABI.System.Collections.Generic.IDictionaryMethods<{{genericKeyType}}, {{genericValueType}}>.Abi_Remove_5(thisPtr, {{GeneratorHelper.GetFromAbiMarshaler(genericKeyType, abiKeyType, keyTypeKind, "key")}}); - } - catch (global::System.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_Clear_6(IntPtr thisPtr) - { - try - { - global::ABI.System.Collections.Generic.IDictionaryMethods<{{genericKeyType}}, {{genericValueType}}>.Abi_Clear_6(thisPtr); - } - catch (global::System.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* __return_value__) - { - uint ____return_value__ = default; - - *__return_value__ = default; - - try - { - ____return_value__ = global::ABI.System.Collections.Generic.IDictionaryMethods<{{genericKeyType}}, {{genericValueType}}>.Abi_get_Size_1(thisPtr); - *__return_value__ = ____return_value__; - } - catch (global::System.Exception __exception__) - { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); - } - return 0; - } - } - """; - return iDictionaryInstantiation; - } - - private static string GetIReadOnlyDictionaryInstantiation(string genericKeyType, string abiKeyType, TypeKind keyTypeKind, string genericValueType, string abiValueType, TypeKind valueTypeKind) - { - string iReadOnlyDictionaryInstantiation = $$""" - internal static class IReadOnlyDictionary_{{GeneratorHelper.EscapeTypeNameForIdentifier(genericKeyType)}}_{{GeneratorHelper.EscapeTypeNameForIdentifier(genericValueType)}} - { - private static readonly bool _initialized = Init(); - internal static bool Initialized => _initialized; - - private static unsafe bool Init() - { - return global::ABI.System.Collections.Generic.IReadOnlyDictionaryMethods<{{genericKeyType}}, {{abiKeyType}}, {{genericValueType}}, {{abiValueType}}>.InitCcw( - &Do_Abi_Lookup_0, - &Do_Abi_get_Size_1, - &Do_Abi_HasKey_2, - &Do_Abi_Split_3 - ); - } - - [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] - private static unsafe int Do_Abi_Lookup_0(IntPtr thisPtr, {{abiKeyType}} key, {{abiValueType}}* __return_value__) - { - {{genericValueType}} ____return_value__ = default; - - *__return_value__ = default; - - try - { - ____return_value__ = global::ABI.System.Collections.Generic.IReadOnlyDictionaryMethods<{{genericKeyType}}, {{genericValueType}}>.Abi_Lookup_0(thisPtr, {{GeneratorHelper.GetFromAbiMarshaler(genericKeyType, abiKeyType, keyTypeKind, "key")}}); - *__return_value__ = {{GeneratorHelper.GetFromManagedMarshaler(genericValueType, abiValueType, valueTypeKind, "____return_value__")}}; - } - catch (global::System.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_HasKey_2(IntPtr thisPtr, {{abiKeyType}} key, byte* __return_value__) - { - bool ____return_value__ = default; - - *__return_value__ = default; - - try - { - ____return_value__ = global::ABI.System.Collections.Generic.IReadOnlyDictionaryMethods<{{genericKeyType}}, {{genericValueType}}>.Abi_HasKey_2(thisPtr, {{GeneratorHelper.GetFromAbiMarshaler(genericKeyType, abiKeyType, keyTypeKind, "key")}}); - *__return_value__ = (byte)(____return_value__ ? 1 : 0); - } - catch (global::System.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_Split_3(IntPtr thisPtr, IntPtr* first, IntPtr* second) - { - *first = default; - *second = default; - IntPtr __first = default; - IntPtr __second = default; - - try - { - global::ABI.System.Collections.Generic.IReadOnlyDictionaryMethods<{{genericKeyType}}, {{genericValueType}}>.Abi_Split_3(thisPtr, out __first, out __second); - *first = __first; - *second = __second; - } - catch (global::System.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* __return_value__) - { - uint ____return_value__ = default; - - *__return_value__ = default; - - try - { - ____return_value__ = global::ABI.System.Collections.Generic.IReadOnlyDictionaryMethods<{{genericKeyType}}, {{genericValueType}}>.Abi_get_Size_1(thisPtr); - *__return_value__ = ____return_value__; - } - catch (global::System.Exception __exception__) - { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); - } - return 0; - } - } - """; - return iReadOnlyDictionaryInstantiation; - } - - private static string GetKeyValuePairInstantiation(string genericKeyType, string abiKeyType, TypeKind keyTypeKind, string genericValueType, string abiValueType, TypeKind valueTypeKind) - { - string keyValuePairInstantiation = $$""" - internal static class KeyValuePair_{{GeneratorHelper.EscapeTypeNameForIdentifier(genericKeyType)}}_{{GeneratorHelper.EscapeTypeNameForIdentifier(genericValueType)}} - { - private static readonly bool _initialized = Init(); - internal static bool Initialized => _initialized; - - private static unsafe bool Init() - { - return global::ABI.System.Collections.Generic.KeyValuePairMethods<{{genericKeyType}}, {{abiKeyType}}, {{genericValueType}}, {{abiValueType}}>.InitCcw( - &Do_Abi_get_Key_0, - &Do_Abi_get_Value_1 - ); - } - - [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] - private static unsafe int Do_Abi_get_Key_0(IntPtr thisPtr, {{abiKeyType}}* __return_value__) - { - {{genericKeyType}} ____return_value__ = default; - *__return_value__ = default; - try - { - ____return_value__ = global::ABI.System.Collections.Generic.KeyValuePairMethods<{{genericKeyType}}, {{genericValueType}}>.Abi_get_Key_0(thisPtr); - *__return_value__ = {{GeneratorHelper.GetFromManagedMarshaler(genericKeyType, abiKeyType, keyTypeKind, "____return_value__")}}; - } - catch (global::System.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_Value_1(IntPtr thisPtr, {{abiValueType}}* __return_value__) - { - {{genericValueType}} ____return_value__ = default; - *__return_value__ = default; - try - { - ____return_value__ = global::ABI.System.Collections.Generic.KeyValuePairMethods<{{genericKeyType}}, {{genericValueType}}>.Abi_get_Value_1(thisPtr); - *__return_value__ = {{GeneratorHelper.GetFromManagedMarshaler(genericValueType, abiValueType, valueTypeKind, "____return_value__")}}; - } - catch (global::System.Exception __exception__) - { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); - } - return 0; - } - } - """; - return keyValuePairInstantiation; - } - - // Delegates are special and initialize both the RCW and CCW. - private static string GetEventHandlerInstantiation(string genericType, string abiType, TypeKind typeKind) - { - string eventHandlerInstantiation = $$""" - internal static class EventHandler_{{GeneratorHelper.EscapeTypeNameForIdentifier(genericType)}} - { - private static readonly bool _initialized = Init(); - internal static bool Initialized => _initialized; - - private static unsafe bool Init() - { - _ = global::ABI.System.EventHandlerMethods<{{genericType}}, {{abiType}}>.InitCcw( - &Do_Abi_Invoke - ); - _ = global::ABI.System.EventHandlerMethods<{{genericType}}, {{abiType}}>.InitRcwHelper( - &Invoke - ); - return true; - } - - [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] - private static unsafe int Do_Abi_Invoke(IntPtr thisPtr, IntPtr sender, {{abiType}} args) - { - try - { - global::ABI.System.EventHandlerMethods<{{genericType}}, {{abiType}}>.Abi_Invoke(thisPtr, MarshalInspectable.FromAbi(sender), {{GeneratorHelper.GetFromAbiMarshaler(genericType, abiType, typeKind, "args")}}); - } - catch (global::System.Exception __exception__) - { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); - } - return 0; - } - - private static unsafe void Invoke(IObjectReference objRef, object sender, {{genericType}} args) - { - IntPtr ThisPtr = objRef.ThisPtr; - ObjectReferenceValue __sender = default; - {{GeneratorHelper.GetMarshalerDeclaration(genericType, abiType, typeKind, "args")}} - try - { - __sender = MarshalInspectable.CreateMarshaler2(sender); - IntPtr abiSender = MarshalInspectable.GetAbi(__sender); - {{GeneratorHelper.GetCreateMarshaler(genericType, abiType, typeKind, "args")}} - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[3](ThisPtr, abiSender, {{GeneratorHelper.GetAbiFromMarshaler(genericType, abiType, typeKind, "args")}})); - global::System.GC.KeepAlive(objRef); - } - finally - { - MarshalInspectable.DisposeMarshaler(__sender); - {{GeneratorHelper.GetDisposeMarshaler(genericType, abiType, typeKind, "args")}} - } - } - } - """; - return eventHandlerInstantiation; - } - - private static string GetTypedEventHandlerInstantiation(EquatableArray genericParameters) - { - string staticMethodsClass = $"global::ABI.Windows.Foundation.TypedEventHandlerMethods<{GetGenericParametersAsString(genericParameters, ", ", true, false)}>"; - string typedEventHandlerInstantiation = $$""" - internal static class TypedEventHandler_{{GetGenericParametersAsString(genericParameters, "_", false)}} - { - private static readonly bool _initialized = Init(); - internal static bool Initialized => _initialized; - - private static unsafe bool Init() - { - _ = {{staticMethodsClass}}.InitCcw( - &Do_Abi_Invoke - ); - _ = {{staticMethodsClass}}.InitRcwHelper( - &Invoke - ); - return true; - } - - [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] - private static unsafe int Do_Abi_Invoke(IntPtr thisPtr, {{genericParameters[0].AbiType}} sender, {{genericParameters[1].AbiType}} args) - { - try - { - {{staticMethodsClass}}.Abi_Invoke(thisPtr, {{GeneratorHelper.GetFromAbiMarshaler(genericParameters[0], "sender")}}, {{GeneratorHelper.GetFromAbiMarshaler(genericParameters[1], "args")}}); - } - catch (global::System.Exception __exception__) - { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); - } - return 0; - } - - private static unsafe void Invoke(IObjectReference objRef, {{genericParameters[0].ProjectedType}} sender, {{genericParameters[1].ProjectedType}} args) - { - IntPtr ThisPtr = objRef.ThisPtr; - {{GeneratorHelper.GetMarshalerDeclaration(genericParameters[0], "sender")}} - {{GeneratorHelper.GetMarshalerDeclaration(genericParameters[1], "args")}} - try - { - {{GeneratorHelper.GetCreateMarshaler(genericParameters[0], "sender")}} - {{GeneratorHelper.GetCreateMarshaler(genericParameters[1], "args")}} - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[3](ThisPtr, {{GeneratorHelper.GetAbiFromMarshaler(genericParameters[0], "sender")}}, {{GeneratorHelper.GetAbiFromMarshaler(genericParameters[1], "args")}})); - global::System.GC.KeepAlive(objRef); - } - finally - { - {{GeneratorHelper.GetDisposeMarshaler(genericParameters[0], "sender")}} - {{GeneratorHelper.GetDisposeMarshaler(genericParameters[1], "args")}} - } - } - } - """; - return typedEventHandlerInstantiation; - } - - private static string GetCompletedHandlerInstantiation(string completedHandler, string asyncInfoInterface, EquatableArray genericParameters) - { - string staticMethodsClass = $"global::ABI.{completedHandler}Methods<{GetGenericParametersAsString(genericParameters, ", ", true, false)}>"; - string interfaceWithGeneric = $"global::{asyncInfoInterface}<{GetGenericParametersAsString(genericParameters, ", ", false, false)}>"; - string completedHandlerInstantiation = $$""" - internal static class {{completedHandler.Split('.')[^1]}}_{{GetGenericParametersAsString(genericParameters, "_", false)}} - { - private static readonly bool _initialized = Init(); - internal static bool Initialized => _initialized; - - private static unsafe bool Init() - { - return {{staticMethodsClass}}.InitCcw( - &Do_Abi_Invoke - ); - } - - [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] - private static unsafe int Do_Abi_Invoke(IntPtr thisPtr, IntPtr asyncInfo, global::Windows.Foundation.AsyncStatus asyncStatus) - { - try - { - {{staticMethodsClass}}.Abi_Invoke(thisPtr, MarshalInterface<{{interfaceWithGeneric}}>.FromAbi(asyncInfo), asyncStatus); - } - catch (global::System.Exception __exception__) - { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); - } - return 0; - } - } - """; - return completedHandlerInstantiation; - } - - private static string GetChangedHandlerInstantiation(string changedHandler, string senderInterface, string changedEventArgsInterface, EquatableArray genericParameters) - { - string staticMethodsClass = $"global::ABI.{changedHandler}Methods<{GetGenericParametersAsString(genericParameters, ", ", true, false)}>"; - string changedHandlerInstantiation = $$""" - internal static class {{changedHandler.Split('.')[^1]}}_{{GetGenericParametersAsString(genericParameters, "_", false)}} - { - private static readonly bool _initialized = Init(); - internal static bool Initialized => _initialized; - - private static unsafe bool Init() - { - return {{staticMethodsClass}}.InitCcw( - &Do_Abi_Invoke - ); - } - - [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] - private static unsafe int Do_Abi_Invoke(IntPtr thisPtr, IntPtr sender, IntPtr @event) - { - try - { - {{staticMethodsClass}}.Abi_Invoke(thisPtr, MarshalInterface<{{senderInterface}}>.FromAbi(sender), MarshalInterface<{{changedEventArgsInterface}}>.FromAbi(@event)); - } - catch (global::System.Exception __exception__) - { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); - } - return 0; - } - } - """; - return changedHandlerInstantiation; - } - - private static string GetProgressHandlerInstantiation(string progressHandler, string asyncInfoInterface, EquatableArray genericParameters) - { - string staticMethodsClass = $"global::ABI.{progressHandler}Methods<{GetGenericParametersAsString(genericParameters, ", ", true, false)}>"; - string asyncInfoInterfaceWithGeneric = $"global::{asyncInfoInterface}<{GetGenericParametersAsString(genericParameters, ", ", false, false)}>"; - string asyncInfoInterfaceWithGenericMethodsClass = $"global::ABI.{asyncInfoInterface}Methods<{GetGenericParametersAsString(genericParameters, ", ", false, false)}>"; - var progressParameter = genericParameters.Last(); - string progressHandlerInstantiation = $$""" - internal static class {{progressHandler.Split('.')[^1]}}_{{GetGenericParametersAsString(genericParameters, "_", false)}} - { - private static readonly bool _initialized = Init(); - internal static bool Initialized => _initialized; - - private static unsafe bool Init() - { - _ = {{staticMethodsClass}}.InitCcw( - &Do_Abi_Invoke - ); - _ = {{staticMethodsClass}}.InitRcwHelper( - &Invoke - ); - return true; - } - - [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] - private static unsafe int Do_Abi_Invoke(IntPtr thisPtr, IntPtr asyncInfo, {{progressParameter.AbiType}} progressInfo) - { - try - { - {{staticMethodsClass}}.Abi_Invoke(thisPtr, MarshalInterface<{{asyncInfoInterfaceWithGeneric}}>.FromAbi(asyncInfo), {{GeneratorHelper.GetFromAbiMarshaler(progressParameter.ProjectedType, progressParameter.AbiType, progressParameter.TypeKind, "progressInfo")}}); - } - catch (global::System.Exception __exception__) - { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); - } - return 0; - } - - private static unsafe void Invoke(IObjectReference objRef, {{asyncInfoInterfaceWithGeneric}} asyncInfo, {{progressParameter.ProjectedType}} progressInfo) - { - IntPtr ThisPtr = objRef.ThisPtr; - ObjectReferenceValue __asyncInfo = default; - {{GeneratorHelper.GetMarshalerDeclaration(progressParameter.ProjectedType, progressParameter.AbiType, progressParameter.TypeKind, "progressInfo")}} - try - { - __asyncInfo = MarshalInterface<{{asyncInfoInterfaceWithGeneric}}>.CreateMarshaler2(asyncInfo, {{asyncInfoInterfaceWithGenericMethodsClass}}.IID); - IntPtr abiAsyncInfo = MarshalInspectable.GetAbi(__asyncInfo); - {{GeneratorHelper.GetCreateMarshaler(progressParameter.ProjectedType, progressParameter.AbiType, progressParameter.TypeKind, "progressInfo")}} - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[3](ThisPtr, abiAsyncInfo, {{GeneratorHelper.GetAbiFromMarshaler(progressParameter.ProjectedType, progressParameter.AbiType, progressParameter.TypeKind, "progressInfo")}})); - global::System.GC.KeepAlive(objRef); - } - finally - { - MarshalInterface<{{asyncInfoInterfaceWithGeneric}}>.DisposeMarshaler(__asyncInfo); - {{GeneratorHelper.GetDisposeMarshaler(progressParameter.ProjectedType, progressParameter.AbiType, progressParameter.TypeKind, "progressInfo")}} - } - } - } - """; - return progressHandlerInstantiation; - } - - private static string GetIAsyncActionWithProgressInstantiation(EquatableArray genericParameters) - { - string staticMethodsClass = $"global::ABI.Windows.Foundation.IAsyncActionWithProgressMethods<{GetGenericParametersAsString(genericParameters, ", ", false, false)}>"; - string abiStaticMethodsClass = $"global::ABI.Windows.Foundation.IAsyncActionWithProgressMethods<{GetGenericParametersAsString(genericParameters, ", ", true, false)}>"; - string instantiation = $$""" - internal static class IAsyncActionWithProgress_{{GetGenericParametersAsString(genericParameters, "_", false)}} - { - private static readonly bool _initialized = Init(); - internal static bool Initialized => _initialized; - - private static unsafe bool Init() - { - return {{abiStaticMethodsClass}}.InitCcw( - &Do_Abi_put_Progress_0, - &Do_Abi_get_Progress_1, - &Do_Abi_put_Completed_2, - &Do_Abi_get_Completed_3, - &Do_Abi_GetResults_4 - ); - } - - [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] - private static unsafe int Do_Abi_GetResults_4(IntPtr thisPtr) - { - try - { - {{staticMethodsClass}}.Do_Abi_GetResults_4(thisPtr); - } - 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_put_Progress_0(IntPtr thisPtr, IntPtr handler) - { - _ = AsyncActionProgressHandler_{{GetGenericParametersAsString(genericParameters, "_", false)}}.Initialized; - try - { - {{staticMethodsClass}}.Do_Abi_put_Progress_0(thisPtr, global::ABI.Windows.Foundation.AsyncActionProgressHandler<{{genericParameters[0].ProjectedType}}>.FromAbi(handler)); - } - 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_Progress_1(IntPtr thisPtr, IntPtr* __return_value__) - { - _ = AsyncActionProgressHandler_{{GetGenericParametersAsString(genericParameters, "_", false)}}.Initialized; - global::Windows.Foundation.AsyncActionProgressHandler<{{genericParameters[0].ProjectedType}}> ____return_value__ = default; - - *__return_value__ = default; - - try - { - ____return_value__ = {{staticMethodsClass}}.Do_Abi_get_Progress_1(thisPtr); - *__return_value__ = global::ABI.Windows.Foundation.AsyncActionProgressHandler<{{genericParameters[0].ProjectedType}}>.FromManaged(____return_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_put_Completed_2(IntPtr thisPtr, IntPtr handler) - { - _ = AsyncActionWithProgressCompletedHandler_{{GetGenericParametersAsString(genericParameters, "_", false)}}.Initialized; - try - { - {{staticMethodsClass}}.Do_Abi_put_Completed_2(thisPtr, global::ABI.Windows.Foundation.AsyncActionWithProgressCompletedHandler<{{genericParameters[0].ProjectedType}}>.FromAbi(handler)); - } - 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_Completed_3(IntPtr thisPtr, IntPtr* __return_value__) - { - _ = AsyncActionWithProgressCompletedHandler_{{GetGenericParametersAsString(genericParameters, "_", false)}}.Initialized; - global::Windows.Foundation.AsyncActionWithProgressCompletedHandler<{{genericParameters[0].ProjectedType}}> ____return_value__ = default; - - *__return_value__ = default; - - try - { - ____return_value__ = {{staticMethodsClass}}.Do_Abi_get_Completed_3(thisPtr); - *__return_value__ = global::ABI.Windows.Foundation.AsyncActionWithProgressCompletedHandler<{{genericParameters[0].ProjectedType}}>.FromManaged(____return_value__); - } - catch (Exception __exception__) - { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); - } - return 0; - } - } - """; - return instantiation; - } - - private static string GetIAsyncOperationWithProgressInstantiation(EquatableArray genericParameters) - { - string staticMethodsClass = $"global::ABI.Windows.Foundation.IAsyncOperationWithProgressMethods<{GetGenericParametersAsString(genericParameters, ", ", false, false)}>"; - string abiStaticMethodsClass = $"global::ABI.Windows.Foundation.IAsyncOperationWithProgressMethods<{GetGenericParametersAsString(genericParameters, ", ", true, false)}>"; - string instantiation = $$""" - internal static class IAsyncOperationWithProgress_{{GetGenericParametersAsString(genericParameters, "_", false)}} - { - private static readonly bool _initialized = Init(); - internal static bool Initialized => _initialized; - - private static unsafe bool Init() - { - return {{abiStaticMethodsClass}}.InitCcw( - &Do_Abi_put_Progress_0, - &Do_Abi_get_Progress_1, - &Do_Abi_put_Completed_2, - &Do_Abi_get_Completed_3, - &Do_Abi_GetResults_4 - ); - } - - [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] - private static unsafe int Do_Abi_GetResults_4(IntPtr thisPtr, {{genericParameters[0].AbiType}}* __return_value__) - { - {{genericParameters[0].ProjectedType}} ____return_value__ = default; - - *__return_value__ = default; - - try - { - ____return_value__ = {{staticMethodsClass}}.Do_Abi_GetResults_4(thisPtr); - *__return_value__ = {{GeneratorHelper.GetFromManagedMarshaler(genericParameters[0], "____return_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_put_Progress_0(IntPtr thisPtr, IntPtr handler) - { - _ = AsyncOperationProgressHandler_{{GetGenericParametersAsString(genericParameters, "_", false)}}.Initialized; - try - { - {{staticMethodsClass}}.Do_Abi_put_Progress_0(thisPtr, global::ABI.Windows.Foundation.AsyncOperationProgressHandler<{{genericParameters[0].ProjectedType}}, {{genericParameters[1].ProjectedType}}>.FromAbi(handler)); - } - 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_Progress_1(IntPtr thisPtr, IntPtr* __return_value__) - { - _ = AsyncOperationProgressHandler_{{GetGenericParametersAsString(genericParameters, "_", false)}}.Initialized; - global::Windows.Foundation.AsyncOperationProgressHandler<{{genericParameters[0].ProjectedType}}, {{genericParameters[1].ProjectedType}}> ____return_value__ = default; - - *__return_value__ = default; - - try - { - ____return_value__ = {{staticMethodsClass}}.Do_Abi_get_Progress_1(thisPtr); - *__return_value__ = global::ABI.Windows.Foundation.AsyncOperationProgressHandler<{{genericParameters[0].ProjectedType}}, {{genericParameters[1].ProjectedType}}>.FromManaged(____return_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_put_Completed_2(IntPtr thisPtr, IntPtr handler) - { - _ = AsyncOperationWithProgressCompletedHandler_{{GetGenericParametersAsString(genericParameters, "_", false)}}.Initialized; - try - { - {{staticMethodsClass}}.Do_Abi_put_Completed_2(thisPtr, global::ABI.Windows.Foundation.AsyncOperationWithProgressCompletedHandler<{{genericParameters[0].ProjectedType}}, {{genericParameters[1].ProjectedType}}>.FromAbi(handler)); - } - 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_Completed_3(IntPtr thisPtr, IntPtr* __return_value__) - { - _ = AsyncOperationWithProgressCompletedHandler_{{GetGenericParametersAsString(genericParameters, "_", false)}}.Initialized; - global::Windows.Foundation.AsyncOperationWithProgressCompletedHandler<{{genericParameters[0].ProjectedType}}, {{genericParameters[1].ProjectedType}}> ____return_value__ = default; - - *__return_value__ = default; - - try - { - ____return_value__ = {{staticMethodsClass}}.Do_Abi_get_Completed_3(thisPtr); - *__return_value__ = global::ABI.Windows.Foundation.AsyncOperationWithProgressCompletedHandler<{{genericParameters[0].ProjectedType}}, {{genericParameters[1].ProjectedType}}>.FromManaged(____return_value__); - } - catch (Exception __exception__) - { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); - } - return 0; - } - } - """; - return instantiation; - } - - private static string GetIAsyncOperationInstantiation(EquatableArray genericParameters) - { - string staticMethodsClass = $"global::ABI.Windows.Foundation.IAsyncOperationMethods<{GetGenericParametersAsString(genericParameters, ", ", false, false)}>"; - string abiStaticMethodsClass = $"global::ABI.Windows.Foundation.IAsyncOperationMethods<{GetGenericParametersAsString(genericParameters, ", ", true, false)}>"; - string instantiation = $$""" - internal static class IAsyncOperation_{{GetGenericParametersAsString(genericParameters, "_", false)}} - { - private static readonly bool _initialized = Init(); - internal static bool Initialized => _initialized; - - private static unsafe bool Init() - { - return {{abiStaticMethodsClass}}.InitCcw( - &Do_Abi_put_Completed_0, - &Do_Abi_get_Completed_1, - &Do_Abi_GetResults_2 - ); - } - - [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] - private static unsafe int Do_Abi_GetResults_2(IntPtr thisPtr, {{genericParameters[0].AbiType}}* __return_value__) - { - {{genericParameters[0].ProjectedType}} ____return_value__ = default; - - *__return_value__ = default; - - try - { - ____return_value__ = {{staticMethodsClass}}.Do_Abi_GetResults_2(thisPtr); - *__return_value__ = {{GeneratorHelper.GetFromManagedMarshaler(genericParameters[0], "____return_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_put_Completed_0(IntPtr thisPtr, IntPtr handler) - { - _ = AsyncOperationCompletedHandler_{{GetGenericParametersAsString(genericParameters, "_", false)}}.Initialized; - try - { - {{staticMethodsClass}}.Do_Abi_put_Completed_0(thisPtr, global::ABI.Windows.Foundation.AsyncOperationCompletedHandler<{{genericParameters[0].ProjectedType}}>.FromAbi(handler)); - } - 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_Completed_1(IntPtr thisPtr, IntPtr* __return_value__) - { - _ = AsyncOperationCompletedHandler_{{GetGenericParametersAsString(genericParameters, "_", false)}}.Initialized; - global::Windows.Foundation.AsyncOperationCompletedHandler<{{genericParameters[0].ProjectedType}}> ____return_value__ = default; - - *__return_value__ = default; - - try - { - ____return_value__ = {{staticMethodsClass}}.Do_Abi_get_Completed_1(thisPtr); - *__return_value__ = global::ABI.Windows.Foundation.AsyncOperationCompletedHandler<{{genericParameters[0].ProjectedType}}>.FromManaged(____return_value__); - } - catch (Exception __exception__) - { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); - } - return 0; - } - } - """; - return instantiation; - } - - private static string GetIMapChangedEventArgsInstantiation(EquatableArray genericParameters) - { - string staticMethodsClass = $"global::ABI.Windows.Foundation.Collections.IMapChangedEventArgsMethods<{GetGenericParametersAsString(genericParameters, ", ", false, false)}>"; - string abiStaticMethodsClass = $"global::ABI.Windows.Foundation.Collections.IMapChangedEventArgsMethods<{GetGenericParametersAsString(genericParameters, ", ", true, false)}>"; - string instantiation = $$""" - internal static class IMapChangedEventArgs_{{GetGenericParametersAsString(genericParameters, "_", false)}} - { - private static readonly bool _initialized = Init(); - internal static bool Initialized => _initialized; - - private static unsafe bool Init() - { - return {{abiStaticMethodsClass}}.InitCcw( - &Do_Abi_get_CollectionChange_0, - &Do_Abi_get_Key_1 - ); - } - - [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] - private static unsafe int Do_Abi_get_CollectionChange_0(IntPtr thisPtr, global::Windows.Foundation.Collections.CollectionChange* __return_value__) - { - *__return_value__ = default; - - try - { - *__return_value__ = {{staticMethodsClass}}.Do_Abi_get_CollectionChange_0(thisPtr); - } - 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_Key_1(IntPtr thisPtr, {{genericParameters[0].AbiType}}* __return_value__) - { - {{genericParameters[0].ProjectedType}} ____return_value__ = default; - - *__return_value__ = default; - - try - { - ____return_value__ = {{staticMethodsClass}}.Do_Abi_get_Key_1(thisPtr); - *__return_value__ = {{GeneratorHelper.GetFromManagedMarshaler(genericParameters[0], "____return_value__")}}; - } - catch (Exception __exception__) - { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); - } - return 0; - } - } - """; - return instantiation; - } - - private static string GetIObservableMapInstantiation(EquatableArray genericParameters) - { - string staticMethodsClass = $"global::ABI.Windows.Foundation.Collections.IObservableMapMethods<{GetGenericParametersAsString(genericParameters, ", ", false, false)}>"; - string abiStaticMethodsClass = $"global::ABI.Windows.Foundation.Collections.IObservableMapMethods<{GetGenericParametersAsString(genericParameters, ", ", true, false)}>"; - string instantiation = $$""" - internal static class IObservableMap_{{GetGenericParametersAsString(genericParameters, "_", false)}} - { - private static readonly bool _initialized = Init(); - internal static bool Initialized => _initialized; - - private static unsafe bool Init() - { - return {{abiStaticMethodsClass}}.InitCcw( - &Do_Abi_add_MapChanged_0, - &Do_Abi_remove_MapChanged_1 - ); - } - - [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] - private static unsafe int Do_Abi_add_MapChanged_0(IntPtr thisPtr, IntPtr vhnd, global::WinRT.EventRegistrationToken* __return_value__) - { - *__return_value__ = default; - _ = MapChangedEventHandler_{{GetGenericParametersAsString(genericParameters, "_", false)}}.Initialized; - try - { - *__return_value__ = {{staticMethodsClass}}.Do_Abi_add_MapChanged_0(thisPtr, global::ABI.Windows.Foundation.Collections.MapChangedEventHandler<{{genericParameters[0].ProjectedType}}, {{genericParameters[1].ProjectedType}}>.FromAbi(vhnd)); - } - 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_remove_MapChanged_1(IntPtr thisPtr, global::WinRT.EventRegistrationToken token) - { - try - { - {{staticMethodsClass}}.Do_Abi_remove_MapChanged_1(thisPtr, token); - } - catch (Exception __exception__) - { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); - } - return 0; - } - } - """; - return instantiation; - } - - private static string GetIObservableVectorInstantiation(EquatableArray genericParameters) - { - string staticMethodsClass = $"global::ABI.Windows.Foundation.Collections.IObservableVectorMethods<{GetGenericParametersAsString(genericParameters, ", ", false, false)}>"; - string abiStaticMethodsClass = $"global::ABI.Windows.Foundation.Collections.IObservableVectorMethods<{GetGenericParametersAsString(genericParameters, ", ", true, false)}>"; - string instantiation = $$""" - internal static class IObservableVector_{{GetGenericParametersAsString(genericParameters, "_", false)}} - { - private static readonly bool _initialized = Init(); - internal static bool Initialized => _initialized; - - private static unsafe bool Init() - { - return {{abiStaticMethodsClass}}.InitCcw( - &Do_Abi_add_VectorChanged_0, - &Do_Abi_remove_VectorChanged_1 - ); - } - - [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] - private static unsafe int Do_Abi_add_VectorChanged_0(IntPtr thisPtr, IntPtr vhnd, global::WinRT.EventRegistrationToken* __return_value__) - { - *__return_value__ = default; - _ = VectorChangedEventHandler_{{GetGenericParametersAsString(genericParameters, "_", false)}}.Initialized; - try - { - *__return_value__ = {{staticMethodsClass}}.Do_Abi_add_VectorChanged_0(thisPtr, global::ABI.Windows.Foundation.Collections.VectorChangedEventHandler<{{genericParameters[0].ProjectedType}}>.FromAbi(vhnd)); - } - 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_remove_VectorChanged_1(IntPtr thisPtr, global::WinRT.EventRegistrationToken token) - { - try - { - {{staticMethodsClass}}.Do_Abi_remove_VectorChanged_1(thisPtr, token); - } - catch (Exception __exception__) - { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); - } - return 0; - } - } - """; - return instantiation; - } - - private static string GetGenericParametersAsString(EquatableArray genericParameters, string separator, bool includeAbiTypes, bool escape = true) - { - string genericParametersStr = string.Join(separator, - genericParameters.Select(genericParameter => - { - if (includeAbiTypes) - { - return string.Join( - separator, - escape ? GeneratorHelper.EscapeTypeNameForIdentifier(genericParameter.ProjectedType) : genericParameter.ProjectedType, - escape ? GeneratorHelper.EscapeTypeNameForIdentifier(genericParameter.AbiType) : genericParameter.AbiType); - } - else - { - return escape ? GeneratorHelper.EscapeTypeNameForIdentifier(genericParameter.ProjectedType) : genericParameter.ProjectedType; - } - })); - return genericParametersStr; - } - } -} +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +using Microsoft.CodeAnalysis; +using System.Collections.Immutable; +using System.Linq; +using WinRT.SourceGenerator; + +namespace Generator +{ + internal static class GenericVtableInitializerStrings + { + public static string GetInstantiation(string genericInterface, EquatableArray genericParameters) + { + if (genericInterface == "System.Collections.Generic.IEnumerable`1") + { + return GetIEnumerableInstantiation(genericParameters[0].ProjectedType, genericParameters[0].AbiType); + } + else if (genericInterface == "System.Collections.Generic.IList`1") + { + return GetIListInstantiation( + genericParameters[0].ProjectedType, + genericParameters[0].AbiType, + genericParameters[0].TypeKind, + genericParameters[0].TypeFlags); + } + else if (genericInterface == "System.Collections.Generic.IReadOnlyList`1") + { + return GetIReadOnlyListInstantiation( + genericParameters[0].ProjectedType, + genericParameters[0].AbiType, + genericParameters[0].TypeKind, + genericParameters[0].TypeFlags); + } + else if (genericInterface == "System.Collections.Generic.IDictionary`2") + { + return GetIDictionaryInstantiation( + genericParameters[0].ProjectedType, + genericParameters[0].AbiType, + genericParameters[0].TypeKind, + genericParameters[1].ProjectedType, + genericParameters[1].AbiType, + genericParameters[1].TypeKind); + } + else if (genericInterface == "System.Collections.Generic.IReadOnlyDictionary`2") + { + return GetIReadOnlyDictionaryInstantiation( + genericParameters[0].ProjectedType, + genericParameters[0].AbiType, + genericParameters[0].TypeKind, + genericParameters[1].ProjectedType, + genericParameters[1].AbiType, + genericParameters[1].TypeKind); + } + else if (genericInterface == "System.Collections.Generic.IEnumerator`1") + { + return GetIEnumeratorInstantiation( + genericParameters[0].ProjectedType, + genericParameters[0].AbiType, + genericParameters[0].TypeKind, + genericParameters[0].TypeFlags); + } + else if (genericInterface == "System.Collections.Generic.KeyValuePair`2") + { + return GetKeyValuePairInstantiation( + genericParameters[0].ProjectedType, + genericParameters[0].AbiType, + genericParameters[0].TypeKind, + genericParameters[1].ProjectedType, + genericParameters[1].AbiType, + genericParameters[1].TypeKind); + } + else if (genericInterface == "System.EventHandler`1") + { + return GetEventHandlerInstantiation(genericParameters[0].ProjectedType, genericParameters[0].AbiType, genericParameters[0].TypeKind); + } + else if (genericInterface == "Windows.Foundation.AsyncActionWithProgressCompletedHandler`1") + { + return GetCompletedHandlerInstantiation("Windows.Foundation.AsyncActionWithProgressCompletedHandler", "Windows.Foundation.IAsyncActionWithProgress", genericParameters); + } + else if (genericInterface == "Windows.Foundation.AsyncOperationCompletedHandler`1") + { + return GetCompletedHandlerInstantiation("Windows.Foundation.AsyncOperationCompletedHandler", "Windows.Foundation.IAsyncOperation", genericParameters); + } + else if (genericInterface == "Windows.Foundation.AsyncOperationWithProgressCompletedHandler`2") + { + return GetCompletedHandlerInstantiation("Windows.Foundation.AsyncOperationWithProgressCompletedHandler", "Windows.Foundation.IAsyncOperationWithProgress", genericParameters); + } + else if (genericInterface == "Windows.Foundation.Collections.MapChangedEventHandler`2") + { + string senderInterface = $"global::Windows.Foundation.Collections.IObservableMap<{genericParameters[0].ProjectedType}, {genericParameters[1].ProjectedType}>"; + string changedEventArgsInterface = $"global::Windows.Foundation.Collections.IMapChangedEventArgs<{genericParameters[0].ProjectedType}>"; + return GetChangedHandlerInstantiation("Windows.Foundation.Collections.MapChangedEventHandler", senderInterface, changedEventArgsInterface, genericParameters); + } + else if (genericInterface == "Windows.Foundation.Collections.VectorChangedEventHandler`1") + { + string senderInterface = $"global::Windows.Foundation.Collections.IObservableVector<{genericParameters[0].ProjectedType}>"; + string changedEventArgsInterface = $"global::Windows.Foundation.Collections.IVectorChangedEventArgs"; + return GetChangedHandlerInstantiation("Windows.Foundation.Collections.VectorChangedEventHandler", senderInterface, changedEventArgsInterface, genericParameters); + } + else if (genericInterface == "Windows.Foundation.AsyncActionProgressHandler`1") + { + return GetProgressHandlerInstantiation("Windows.Foundation.AsyncActionProgressHandler", "Windows.Foundation.IAsyncActionWithProgress", genericParameters); + } + else if (genericInterface == "Windows.Foundation.AsyncOperationProgressHandler`2") + { + return GetProgressHandlerInstantiation("Windows.Foundation.AsyncOperationProgressHandler", "Windows.Foundation.IAsyncOperationWithProgress", genericParameters); + } + else if (genericInterface == "Windows.Foundation.TypedEventHandler`2") + { + return GetTypedEventHandlerInstantiation(genericParameters); + } + else if (genericInterface == "Windows.Foundation.IAsyncActionWithProgress`1") + { + return GetIAsyncActionWithProgressInstantiation(genericParameters); + } + else if (genericInterface == "Windows.Foundation.IAsyncOperationWithProgress`2") + { + return GetIAsyncOperationWithProgressInstantiation(genericParameters); + } + else if (genericInterface == "Windows.Foundation.IAsyncOperation`1") + { + return GetIAsyncOperationInstantiation(genericParameters); + } + else if (genericInterface == "Windows.Foundation.Collections.IMapChangedEventArgs`1") + { + return GetIMapChangedEventArgsInstantiation(genericParameters); + } + else if (genericInterface == "Windows.Foundation.Collections.IObservableMap`2") + { + return GetIObservableMapInstantiation(genericParameters); + } + else if (genericInterface == "Windows.Foundation.Collections.IObservableVector`1") + { + return GetIObservableVectorInstantiation(genericParameters); + } + + return ""; + } + + public static ImmutableHashSet AddDependentGenericInterfaces(ImmutableHashSet genericInterfaces) + { + var genericInterfacesList = genericInterfaces.ToList(); + + foreach (var genericInterface in genericInterfaces) + { + if (genericInterface.GenericDefinition == "Windows.Foundation.IAsyncActionWithProgress`1") + { + AddReplacedGenericInterface(genericInterface, "Windows.Foundation.AsyncActionProgressHandler"); + AddReplacedGenericInterface(genericInterface, "Windows.Foundation.AsyncActionWithProgressCompletedHandler"); + } + else if (genericInterface.GenericDefinition == "Windows.Foundation.IAsyncOperationWithProgress`2") + { + AddReplacedGenericInterface(genericInterface, "Windows.Foundation.AsyncOperationProgressHandler"); + AddReplacedGenericInterface(genericInterface, "Windows.Foundation.AsyncOperationWithProgressCompletedHandler"); + } + else if (genericInterface.GenericDefinition == "Windows.Foundation.IAsyncOperation`1") + { + AddReplacedGenericInterface(genericInterface, "Windows.Foundation.AsyncOperationCompletedHandler"); + } + else if (genericInterface.GenericDefinition == "Windows.Foundation.Collections.IObservableMap`2") + { + AddReplacedGenericInterface(genericInterface, "Windows.Foundation.Collections.MapChangedEventHandler"); + } + else if (genericInterface.GenericDefinition == "Windows.Foundation.Collections.IObservableVector`1") + { + AddReplacedGenericInterface(genericInterface, "Windows.Foundation.Collections.VectorChangedEventHandler"); + } + } + + return genericInterfacesList.ToImmutableHashSet(); + + void AddReplacedGenericInterface(GenericInterface genericInterfaceToReplace, string newInterfaceToReplaceWith) + { + // Replace the old interface name with the new one. + // We know this is an generic interface, so we want to replace the string before the generics (<). + string newQualifiedInterfaceName = newInterfaceToReplaceWith + genericInterfaceToReplace.Interface[genericInterfaceToReplace.Interface.IndexOf('<')..]; + + // The metadata name includes the number of generics which we get from the last character of the one we are replacing + // since they are the same in the scenarios we care about. + string newInterfaceMetadataName = newInterfaceToReplaceWith + "`" + genericInterfaceToReplace.GenericDefinition[^1]; + + genericInterfacesList.Add(new GenericInterface( + newQualifiedInterfaceName, + newInterfaceMetadataName, + genericInterfaceToReplace.GenericParameters + )); + } + } + + public static string GetInstantiationInitFunction(string genericInterface, EquatableArray genericParameters, string escapedAssemblyName) + { + // Get the class name from a string like System.Collections.Generic.IEnumerator`1. + // Splitting on the dots and the generic specifier (`) will get us the class name + // in the 2nd last element. + var interfaceName = genericInterface.Split('.', '`')[^2]; + var genericParametersStr = string.Join("_", genericParameters.Select(static genericParameter => GeneratorHelper.EscapeTypeNameForIdentifier(genericParameter.ProjectedType))); + return $$""" _ = global::WinRT.{{escapedAssemblyName}}GenericHelpers.{{interfaceName}}_{{genericParametersStr}}.Initialized;"""; + } + + private static string GetIEnumerableInstantiation(string genericType, string abiType) + { + string iEnumerableInstantiation = $$""" + internal static class IEnumerable_{{GeneratorHelper.EscapeTypeNameForIdentifier(genericType)}} + { + private static readonly bool _initialized = Init(); + internal static bool Initialized => _initialized; + + private static unsafe bool Init() + { + return global::ABI.System.Collections.Generic.IEnumerableMethods<{{genericType}}, {{abiType}}>.InitCcw( + &Do_Abi_First_0 + ); + } + + [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] + private static unsafe int Do_Abi_First_0(IntPtr thisPtr, IntPtr* __return_value__) + { + *__return_value__ = default; + try + { + *__return_value__ = MarshalInterface>. + FromManaged(global::ABI.System.Collections.Generic.IEnumerableMethods<{{genericType}}>.Abi_First_0(thisPtr)); + } + catch (global::System.Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + } + """; + return iEnumerableInstantiation; + } + + private static string GetIEnumeratorInstantiation(string genericType, string abiType, TypeKind typeKind, TypeFlags typeFlags) + { + string iEnumeratorInstantiation = $$""" + internal static class IEnumerator_{{GeneratorHelper.EscapeTypeNameForIdentifier(genericType)}} + { + private static readonly bool _initialized = Init(); + internal static bool Initialized => _initialized; + + private static unsafe bool Init() + { + return global::ABI.System.Collections.Generic.IEnumeratorMethods<{{genericType}}, {{abiType}}>.InitCcw( + &Do_Abi_get_Current_0, + &Do_Abi_get_HasCurrent_1, + &Do_Abi_MoveNext_2, + &Do_Abi_GetMany_3 + ); + } + + [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] + private static unsafe int Do_Abi_MoveNext_2(IntPtr thisPtr, byte* __return_value__) + { + bool ____return_value__ = default; + + *__return_value__ = default; + + try + { + ____return_value__ = global::ABI.System.Collections.Generic.IEnumeratorMethods<{{genericType}}>.Abi_MoveNext_2(thisPtr); + *__return_value__ = (byte)(____return_value__ ? 1 : 0); + } + catch (global::System.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* __return_value__) + { + uint ____return_value__ = default; + + *__return_value__ = default; + {{genericType}}[] __items = {{GeneratorHelper.GetMarshalerClass(genericType, abiType, typeKind, true)}}.FromAbiArray((__itemsSize, items)); + + try + { + ____return_value__ = global::ABI.System.Collections.Generic.IEnumeratorMethods<{{genericType}}>.Abi_GetMany_3(thisPtr, ref __items); + {{GeneratorHelper.GetCopyManagedArrayMarshaler(genericType, abiType, typeKind, typeFlags)}}.CopyManagedArray(__items, items); + *__return_value__ = ____return_value__; + } + catch (global::System.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, {{abiType}}* __return_value__) + { + {{genericType}} ____return_value__ = default; + + *__return_value__ = default; + + try + { + ____return_value__ = global::ABI.System.Collections.Generic.IEnumeratorMethods<{{genericType}}>.Abi_get_Current_0(thisPtr); + *__return_value__ = {{GeneratorHelper.GetFromManagedMarshaler(genericType, abiType, typeKind, "____return_value__")}}; + } + catch (global::System.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* __return_value__) + { + bool ____return_value__ = default; + + *__return_value__ = default; + + try + { + ____return_value__ = global::ABI.System.Collections.Generic.IEnumeratorMethods<{{genericType}}>.Abi_get_HasCurrent_1(thisPtr); + *__return_value__ = (byte)(____return_value__ ? 1 : 0); + } + catch (global::System.Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + } + """; + return iEnumeratorInstantiation; + } + + private static string GetIListInstantiation(string genericType, string abiType, TypeKind typeKind, TypeFlags typeFlags) + { + string iListInstantiation = $$""" + internal static class IList_{{GeneratorHelper.EscapeTypeNameForIdentifier(genericType)}} + { + private static readonly bool _initialized = Init(); + internal static bool Initialized => _initialized; + + private static unsafe bool Init() + { + return global::ABI.System.Collections.Generic.IListMethods<{{genericType}}, {{abiType}}>.InitCcw( + &Do_Abi_GetAt_0, + &Do_Abi_get_Size_1, + &Do_Abi_GetView_2, + &Do_Abi_IndexOf_3, + &Do_Abi_SetAt_4, + &Do_Abi_InsertAt_5, + &Do_Abi_RemoveAt_6, + &Do_Abi_Append_7, + &Do_Abi_RemoveAtEnd_8, + &Do_Abi_Clear_9, + &Do_Abi_GetMany_10, + &Do_Abi_ReplaceAll_11 + ); + } + + [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] + private static unsafe int Do_Abi_GetAt_0(IntPtr thisPtr, uint index, {{abiType}}* __return_value__) + { + {{genericType}} ____return_value__ = default; + *__return_value__ = default; + try + { + ____return_value__ = global::ABI.System.Collections.Generic.IListMethods<{{genericType}}>.Abi_GetAt_0(thisPtr, index); + *__return_value__ = {{GeneratorHelper.GetFromManagedMarshaler(genericType, abiType, typeKind, "____return_value__")}}; + } + catch (global::System.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_GetView_2(IntPtr thisPtr, IntPtr* __return_value__) + { + global::System.Collections.Generic.IReadOnlyList<{{genericType}}> ____return_value__ = default; + *__return_value__ = default; + + try + { + ____return_value__ = global::ABI.System.Collections.Generic.IListMethods<{{genericType}}>.Abi_GetView_2(thisPtr); + *__return_value__ = MarshalInterface>.FromManaged(____return_value__); + } + catch (global::System.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_3(IntPtr thisPtr, {{abiType}} value, uint* index, byte* __return_value__) + { + bool ____return_value__ = default; + + *index = default; + *__return_value__ = default; + uint __index = default; + + try + { + ____return_value__ = global::ABI.System.Collections.Generic.IListMethods<{{genericType}}>.Abi_IndexOf_3(thisPtr, {{GeneratorHelper.GetFromAbiMarshaler(genericType, abiType, typeKind, "value")}}, out __index); + *index = __index; + *__return_value__ = (byte)(____return_value__ ? 1 : 0); + } + catch (global::System.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_SetAt_4(IntPtr thisPtr, uint index, {{abiType}} value) + { + try + { + global::ABI.System.Collections.Generic.IListMethods<{{genericType}}>.Abi_SetAt_4(thisPtr, index, {{GeneratorHelper.GetFromAbiMarshaler(genericType, abiType, typeKind, "value")}}); + } + catch (global::System.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_InsertAt_5(IntPtr thisPtr, uint index, {{abiType}} value) + { + try + { + global::ABI.System.Collections.Generic.IListMethods<{{genericType}}>.Abi_InsertAt_5(thisPtr, index, {{GeneratorHelper.GetFromAbiMarshaler(genericType, abiType, typeKind, "value")}}); + } + catch (global::System.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_RemoveAt_6(IntPtr thisPtr, uint index) + { + try + { + global::ABI.System.Collections.Generic.IListMethods<{{genericType}}>.Abi_RemoveAt_6(thisPtr, index); + } + catch (global::System.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_Append_7(IntPtr thisPtr, {{abiType}} value) + { + try + { + global::ABI.System.Collections.Generic.IListMethods<{{genericType}}>.Abi_Append_7(thisPtr, {{GeneratorHelper.GetFromAbiMarshaler(genericType, abiType, typeKind, "value")}}); + } + catch (global::System.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_RemoveAtEnd_8(IntPtr thisPtr) + { + try + { + global::ABI.System.Collections.Generic.IListMethods<{{genericType}}>.Abi_RemoveAtEnd_8(thisPtr); + } + catch (global::System.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_Clear_9(IntPtr thisPtr) + { + try + { + global::ABI.System.Collections.Generic.IListMethods<{{genericType}}>.Abi_Clear_9(thisPtr); + } + catch (global::System.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_10(IntPtr thisPtr, uint startIndex, int __itemsSize, IntPtr items, uint* __return_value__) + { + uint ____return_value__ = default; + + *__return_value__ = default; + {{genericType}}[] __items = {{GeneratorHelper.GetMarshalerClass(genericType, abiType, typeKind, true)}}.FromAbiArray((__itemsSize, items)); + + try + { + ____return_value__ = global::ABI.System.Collections.Generic.IListMethods<{{genericType}}>.Abi_GetMany_10(thisPtr, startIndex, ref __items); + {{GeneratorHelper.GetCopyManagedArrayMarshaler(genericType, abiType, typeKind, typeFlags)}}.CopyManagedArray(__items, items); + *__return_value__ = ____return_value__; + } + catch (global::System.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_ReplaceAll_11(IntPtr thisPtr, int __itemsSize, IntPtr items) + { + try + { + global::ABI.System.Collections.Generic.IListMethods<{{genericType}}>.Abi_ReplaceAll_11(thisPtr, {{GeneratorHelper.GetMarshalerClass(genericType, abiType, typeKind, true)}}.FromAbiArray((__itemsSize, items))); + } + catch (global::System.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* __return_value__) + { + uint ____return_value__ = default; + + *__return_value__ = default; + + try + { + ____return_value__ = global::ABI.System.Collections.Generic.IListMethods<{{genericType}}>.Abi_get_Size_1(thisPtr); + *__return_value__ = ____return_value__; + } + catch (global::System.Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + } + """; + return iListInstantiation; + } + + private static string GetIReadOnlyListInstantiation(string genericType, string abiType, TypeKind typeKind, TypeFlags typeFlags) + { + string iReadOnlylistInstantiation = $$""" + internal static class IReadOnlyList_{{GeneratorHelper.EscapeTypeNameForIdentifier(genericType)}} + { + private static readonly bool _initialized = Init(); + internal static bool Initialized => _initialized; + + private static unsafe bool Init() + { + return global::ABI.System.Collections.Generic.IReadOnlyListMethods<{{genericType}}, {{abiType}}>.InitCcw( + &Do_Abi_GetAt_0, + &Do_Abi_get_Size_1, + &Do_Abi_IndexOf_2, + &Do_Abi_GetMany_3 + ); + } + + [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] + private static unsafe int Do_Abi_GetAt_0(IntPtr thisPtr, uint index, {{abiType}}* __return_value__) + { + {{genericType}} ____return_value__ = default; + *__return_value__ = default; + try + { + ____return_value__ = global::ABI.System.Collections.Generic.IReadOnlyListMethods<{{genericType}}>.Abi_GetAt_0(thisPtr, index); + *__return_value__ = {{GeneratorHelper.GetFromManagedMarshaler(genericType, abiType, typeKind, "____return_value__")}}; + } + catch (global::System.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, {{abiType}} value, uint* index, byte* __return_value__) + { + bool ____return_value__ = default; + + *index = default; + *__return_value__ = default; + uint __index = default; + + try + { + ____return_value__ = global::ABI.System.Collections.Generic.IReadOnlyListMethods<{{genericType}}>.Abi_IndexOf_2(thisPtr, {{GeneratorHelper.GetFromAbiMarshaler(genericType, abiType, typeKind, "value")}}, out __index); + *index = __index; + *__return_value__ = (byte)(____return_value__ ? 1 : 0); + } + catch (global::System.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, uint startIndex, int __itemsSize, IntPtr items, uint* __return_value__) + { + uint ____return_value__ = default; + + *__return_value__ = default; + {{genericType}}[] __items = {{GeneratorHelper.GetMarshalerClass(genericType, abiType, typeKind, true)}}.FromAbiArray((__itemsSize, items)); + + try + { + ____return_value__ = global::ABI.System.Collections.Generic.IReadOnlyListMethods<{{genericType}}>.Abi_GetMany_3(thisPtr, startIndex, ref __items); + {{GeneratorHelper.GetCopyManagedArrayMarshaler(genericType, abiType, typeKind, typeFlags)}}.CopyManagedArray(__items, items); + *__return_value__ = ____return_value__; + } + catch (global::System.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* __return_value__) + { + uint ____return_value__ = default; + + *__return_value__ = default; + + try + { + ____return_value__ = global::ABI.System.Collections.Generic.IReadOnlyListMethods<{{genericType}}>.Abi_get_Size_1(thisPtr); + *__return_value__ = ____return_value__; + } + catch (global::System.Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + } + """; + return iReadOnlylistInstantiation; + } + + private static string GetIDictionaryInstantiation(string genericKeyType, string abiKeyType, TypeKind keyTypeKind, string genericValueType, string abiValueType, TypeKind valueTypeKind) + { + string iDictionaryInstantiation = $$""" + internal static class IDictionary_{{GeneratorHelper.EscapeTypeNameForIdentifier(genericKeyType)}}_{{GeneratorHelper.EscapeTypeNameForIdentifier(genericValueType)}} + { + private static readonly bool _initialized = Init(); + internal static bool Initialized => _initialized; + + private static unsafe bool Init() + { + return global::ABI.System.Collections.Generic.IDictionaryMethods<{{genericKeyType}}, {{abiKeyType}}, {{genericValueType}}, {{abiValueType}}>.InitCcw( + &Do_Abi_Lookup_0, + &Do_Abi_get_Size_1, + &Do_Abi_HasKey_2, + &Do_Abi_GetView_3, + &Do_Abi_Insert_4, + &Do_Abi_Remove_5, + &Do_Abi_Clear_6 + ); + } + + [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] + private static unsafe int Do_Abi_Lookup_0(IntPtr thisPtr, {{abiKeyType}} key, {{abiValueType}}* __return_value__) + { + {{genericValueType}} ____return_value__ = default; + + *__return_value__ = default; + + try + { + ____return_value__ = global::ABI.System.Collections.Generic.IDictionaryMethods<{{genericKeyType}}, {{genericValueType}}>.Abi_Lookup_0(thisPtr, {{GeneratorHelper.GetFromAbiMarshaler(genericKeyType, abiKeyType, keyTypeKind, "key")}}); + *__return_value__ = {{GeneratorHelper.GetFromManagedMarshaler(genericValueType, abiValueType, valueTypeKind, "____return_value__")}}; + } + catch (global::System.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_HasKey_2(IntPtr thisPtr, {{abiKeyType}} key, byte* __return_value__) + { + bool ____return_value__ = default; + + *__return_value__ = default; + + try + { + ____return_value__ = global::ABI.System.Collections.Generic.IDictionaryMethods<{{genericKeyType}}, {{genericValueType}}>.Abi_HasKey_2(thisPtr, {{GeneratorHelper.GetFromAbiMarshaler(genericKeyType, abiKeyType, keyTypeKind, "key")}}); + *__return_value__ = (byte)(____return_value__ ? 1 : 0); + } + catch (global::System.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_GetView_3(IntPtr thisPtr, IntPtr* __return_value__) + { + global::System.Collections.Generic.IReadOnlyDictionary<{{genericKeyType}}, {{genericValueType}}> ____return_value__ = default; + + *__return_value__ = default; + + try + { + ____return_value__ = global::ABI.System.Collections.Generic.IDictionaryMethods<{{genericKeyType}}, {{genericValueType}}>.Abi_GetView_3(thisPtr); + *__return_value__ = MarshalInterface>.FromManaged(____return_value__); + } + catch (global::System.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_Insert_4(IntPtr thisPtr, {{abiKeyType}} key, {{abiValueType}} value, byte* __return_value__) + { + bool ____return_value__ = default; + + *__return_value__ = default; + + try + { + ____return_value__ = global::ABI.System.Collections.Generic.IDictionaryMethods<{{genericKeyType}}, {{genericValueType}}>.Abi_Insert_4(thisPtr, {{GeneratorHelper.GetFromAbiMarshaler(genericKeyType, abiKeyType, keyTypeKind, "key")}}, {{GeneratorHelper.GetFromAbiMarshaler(genericValueType, abiValueType, valueTypeKind, "value")}}); + *__return_value__ = (byte)(____return_value__ ? 1 : 0); + } + catch (global::System.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_Remove_5(IntPtr thisPtr, {{abiKeyType}} key) + { + try + { + global::ABI.System.Collections.Generic.IDictionaryMethods<{{genericKeyType}}, {{genericValueType}}>.Abi_Remove_5(thisPtr, {{GeneratorHelper.GetFromAbiMarshaler(genericKeyType, abiKeyType, keyTypeKind, "key")}}); + } + catch (global::System.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_Clear_6(IntPtr thisPtr) + { + try + { + global::ABI.System.Collections.Generic.IDictionaryMethods<{{genericKeyType}}, {{genericValueType}}>.Abi_Clear_6(thisPtr); + } + catch (global::System.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* __return_value__) + { + uint ____return_value__ = default; + + *__return_value__ = default; + + try + { + ____return_value__ = global::ABI.System.Collections.Generic.IDictionaryMethods<{{genericKeyType}}, {{genericValueType}}>.Abi_get_Size_1(thisPtr); + *__return_value__ = ____return_value__; + } + catch (global::System.Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + } + """; + return iDictionaryInstantiation; + } + + private static string GetIReadOnlyDictionaryInstantiation(string genericKeyType, string abiKeyType, TypeKind keyTypeKind, string genericValueType, string abiValueType, TypeKind valueTypeKind) + { + string iReadOnlyDictionaryInstantiation = $$""" + internal static class IReadOnlyDictionary_{{GeneratorHelper.EscapeTypeNameForIdentifier(genericKeyType)}}_{{GeneratorHelper.EscapeTypeNameForIdentifier(genericValueType)}} + { + private static readonly bool _initialized = Init(); + internal static bool Initialized => _initialized; + + private static unsafe bool Init() + { + return global::ABI.System.Collections.Generic.IReadOnlyDictionaryMethods<{{genericKeyType}}, {{abiKeyType}}, {{genericValueType}}, {{abiValueType}}>.InitCcw( + &Do_Abi_Lookup_0, + &Do_Abi_get_Size_1, + &Do_Abi_HasKey_2, + &Do_Abi_Split_3 + ); + } + + [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] + private static unsafe int Do_Abi_Lookup_0(IntPtr thisPtr, {{abiKeyType}} key, {{abiValueType}}* __return_value__) + { + {{genericValueType}} ____return_value__ = default; + + *__return_value__ = default; + + try + { + ____return_value__ = global::ABI.System.Collections.Generic.IReadOnlyDictionaryMethods<{{genericKeyType}}, {{genericValueType}}>.Abi_Lookup_0(thisPtr, {{GeneratorHelper.GetFromAbiMarshaler(genericKeyType, abiKeyType, keyTypeKind, "key")}}); + *__return_value__ = {{GeneratorHelper.GetFromManagedMarshaler(genericValueType, abiValueType, valueTypeKind, "____return_value__")}}; + } + catch (global::System.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_HasKey_2(IntPtr thisPtr, {{abiKeyType}} key, byte* __return_value__) + { + bool ____return_value__ = default; + + *__return_value__ = default; + + try + { + ____return_value__ = global::ABI.System.Collections.Generic.IReadOnlyDictionaryMethods<{{genericKeyType}}, {{genericValueType}}>.Abi_HasKey_2(thisPtr, {{GeneratorHelper.GetFromAbiMarshaler(genericKeyType, abiKeyType, keyTypeKind, "key")}}); + *__return_value__ = (byte)(____return_value__ ? 1 : 0); + } + catch (global::System.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_Split_3(IntPtr thisPtr, IntPtr* first, IntPtr* second) + { + *first = default; + *second = default; + IntPtr __first = default; + IntPtr __second = default; + + try + { + global::ABI.System.Collections.Generic.IReadOnlyDictionaryMethods<{{genericKeyType}}, {{genericValueType}}>.Abi_Split_3(thisPtr, out __first, out __second); + *first = __first; + *second = __second; + } + catch (global::System.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* __return_value__) + { + uint ____return_value__ = default; + + *__return_value__ = default; + + try + { + ____return_value__ = global::ABI.System.Collections.Generic.IReadOnlyDictionaryMethods<{{genericKeyType}}, {{genericValueType}}>.Abi_get_Size_1(thisPtr); + *__return_value__ = ____return_value__; + } + catch (global::System.Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + } + """; + return iReadOnlyDictionaryInstantiation; + } + + private static string GetKeyValuePairInstantiation(string genericKeyType, string abiKeyType, TypeKind keyTypeKind, string genericValueType, string abiValueType, TypeKind valueTypeKind) + { + string keyValuePairInstantiation = $$""" + internal static class KeyValuePair_{{GeneratorHelper.EscapeTypeNameForIdentifier(genericKeyType)}}_{{GeneratorHelper.EscapeTypeNameForIdentifier(genericValueType)}} + { + private static readonly bool _initialized = Init(); + internal static bool Initialized => _initialized; + + private static unsafe bool Init() + { + return global::ABI.System.Collections.Generic.KeyValuePairMethods<{{genericKeyType}}, {{abiKeyType}}, {{genericValueType}}, {{abiValueType}}>.InitCcw( + &Do_Abi_get_Key_0, + &Do_Abi_get_Value_1 + ); + } + + [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] + private static unsafe int Do_Abi_get_Key_0(IntPtr thisPtr, {{abiKeyType}}* __return_value__) + { + {{genericKeyType}} ____return_value__ = default; + *__return_value__ = default; + try + { + ____return_value__ = global::ABI.System.Collections.Generic.KeyValuePairMethods<{{genericKeyType}}, {{genericValueType}}>.Abi_get_Key_0(thisPtr); + *__return_value__ = {{GeneratorHelper.GetFromManagedMarshaler(genericKeyType, abiKeyType, keyTypeKind, "____return_value__")}}; + } + catch (global::System.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_Value_1(IntPtr thisPtr, {{abiValueType}}* __return_value__) + { + {{genericValueType}} ____return_value__ = default; + *__return_value__ = default; + try + { + ____return_value__ = global::ABI.System.Collections.Generic.KeyValuePairMethods<{{genericKeyType}}, {{genericValueType}}>.Abi_get_Value_1(thisPtr); + *__return_value__ = {{GeneratorHelper.GetFromManagedMarshaler(genericValueType, abiValueType, valueTypeKind, "____return_value__")}}; + } + catch (global::System.Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + } + """; + return keyValuePairInstantiation; + } + + // Delegates are special and initialize both the RCW and CCW. + private static string GetEventHandlerInstantiation(string genericType, string abiType, TypeKind typeKind) + { + string eventHandlerInstantiation = $$""" + internal static class EventHandler_{{GeneratorHelper.EscapeTypeNameForIdentifier(genericType)}} + { + private static readonly bool _initialized = Init(); + internal static bool Initialized => _initialized; + + private static unsafe bool Init() + { + _ = global::ABI.System.EventHandlerMethods<{{genericType}}, {{abiType}}>.InitCcw( + &Do_Abi_Invoke + ); + _ = global::ABI.System.EventHandlerMethods<{{genericType}}, {{abiType}}>.InitRcwHelper( + &Invoke + ); + return true; + } + + [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] + private static unsafe int Do_Abi_Invoke(IntPtr thisPtr, IntPtr sender, {{abiType}} args) + { + try + { + global::ABI.System.EventHandlerMethods<{{genericType}}, {{abiType}}>.Abi_Invoke(thisPtr, MarshalInspectable.FromAbi(sender), {{GeneratorHelper.GetFromAbiMarshaler(genericType, abiType, typeKind, "args")}}); + } + catch (global::System.Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + + private static unsafe void Invoke(IObjectReference objRef, object sender, {{genericType}} args) + { + IntPtr ThisPtr = objRef.ThisPtr; + ObjectReferenceValue __sender = default; + {{GeneratorHelper.GetMarshalerDeclaration(genericType, abiType, typeKind, "args")}} + try + { + __sender = MarshalInspectable.CreateMarshaler2(sender); + IntPtr abiSender = MarshalInspectable.GetAbi(__sender); + {{GeneratorHelper.GetCreateMarshaler(genericType, abiType, typeKind, "args")}} + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[3](ThisPtr, abiSender, {{GeneratorHelper.GetAbiFromMarshaler(genericType, abiType, typeKind, "args")}})); + global::System.GC.KeepAlive(objRef); + } + finally + { + MarshalInspectable.DisposeMarshaler(__sender); + {{GeneratorHelper.GetDisposeMarshaler(genericType, abiType, typeKind, "args")}} + } + } + } + """; + return eventHandlerInstantiation; + } + + private static string GetTypedEventHandlerInstantiation(EquatableArray genericParameters) + { + string staticMethodsClass = $"global::ABI.Windows.Foundation.TypedEventHandlerMethods<{GetGenericParametersAsString(genericParameters, ", ", true, false)}>"; + string typedEventHandlerInstantiation = $$""" + internal static class TypedEventHandler_{{GetGenericParametersAsString(genericParameters, "_", false)}} + { + private static readonly bool _initialized = Init(); + internal static bool Initialized => _initialized; + + private static unsafe bool Init() + { + _ = {{staticMethodsClass}}.InitCcw( + &Do_Abi_Invoke + ); + _ = {{staticMethodsClass}}.InitRcwHelper( + &Invoke + ); + return true; + } + + [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] + private static unsafe int Do_Abi_Invoke(IntPtr thisPtr, {{genericParameters[0].AbiType}} sender, {{genericParameters[1].AbiType}} args) + { + try + { + {{staticMethodsClass}}.Abi_Invoke(thisPtr, {{GeneratorHelper.GetFromAbiMarshaler(genericParameters[0], "sender")}}, {{GeneratorHelper.GetFromAbiMarshaler(genericParameters[1], "args")}}); + } + catch (global::System.Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + + private static unsafe void Invoke(IObjectReference objRef, {{genericParameters[0].ProjectedType}} sender, {{genericParameters[1].ProjectedType}} args) + { + IntPtr ThisPtr = objRef.ThisPtr; + {{GeneratorHelper.GetMarshalerDeclaration(genericParameters[0], "sender")}} + {{GeneratorHelper.GetMarshalerDeclaration(genericParameters[1], "args")}} + try + { + {{GeneratorHelper.GetCreateMarshaler(genericParameters[0], "sender")}} + {{GeneratorHelper.GetCreateMarshaler(genericParameters[1], "args")}} + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[3](ThisPtr, {{GeneratorHelper.GetAbiFromMarshaler(genericParameters[0], "sender")}}, {{GeneratorHelper.GetAbiFromMarshaler(genericParameters[1], "args")}})); + global::System.GC.KeepAlive(objRef); + } + finally + { + {{GeneratorHelper.GetDisposeMarshaler(genericParameters[0], "sender")}} + {{GeneratorHelper.GetDisposeMarshaler(genericParameters[1], "args")}} + } + } + } + """; + return typedEventHandlerInstantiation; + } + + private static string GetCompletedHandlerInstantiation(string completedHandler, string asyncInfoInterface, EquatableArray genericParameters) + { + string staticMethodsClass = $"global::ABI.{completedHandler}Methods<{GetGenericParametersAsString(genericParameters, ", ", true, false)}>"; + string interfaceWithGeneric = $"global::{asyncInfoInterface}<{GetGenericParametersAsString(genericParameters, ", ", false, false)}>"; + string completedHandlerInstantiation = $$""" + internal static class {{completedHandler.Split('.')[^1]}}_{{GetGenericParametersAsString(genericParameters, "_", false)}} + { + private static readonly bool _initialized = Init(); + internal static bool Initialized => _initialized; + + private static unsafe bool Init() + { + return {{staticMethodsClass}}.InitCcw( + &Do_Abi_Invoke + ); + } + + [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] + private static unsafe int Do_Abi_Invoke(IntPtr thisPtr, IntPtr asyncInfo, global::Windows.Foundation.AsyncStatus asyncStatus) + { + try + { + {{staticMethodsClass}}.Abi_Invoke(thisPtr, MarshalInterface<{{interfaceWithGeneric}}>.FromAbi(asyncInfo), asyncStatus); + } + catch (global::System.Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + } + """; + return completedHandlerInstantiation; + } + + private static string GetChangedHandlerInstantiation(string changedHandler, string senderInterface, string changedEventArgsInterface, EquatableArray genericParameters) + { + string staticMethodsClass = $"global::ABI.{changedHandler}Methods<{GetGenericParametersAsString(genericParameters, ", ", true, false)}>"; + string changedHandlerInstantiation = $$""" + internal static class {{changedHandler.Split('.')[^1]}}_{{GetGenericParametersAsString(genericParameters, "_", false)}} + { + private static readonly bool _initialized = Init(); + internal static bool Initialized => _initialized; + + private static unsafe bool Init() + { + return {{staticMethodsClass}}.InitCcw( + &Do_Abi_Invoke + ); + } + + [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] + private static unsafe int Do_Abi_Invoke(IntPtr thisPtr, IntPtr sender, IntPtr @event) + { + try + { + {{staticMethodsClass}}.Abi_Invoke(thisPtr, MarshalInterface<{{senderInterface}}>.FromAbi(sender), MarshalInterface<{{changedEventArgsInterface}}>.FromAbi(@event)); + } + catch (global::System.Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + } + """; + return changedHandlerInstantiation; + } + + private static string GetProgressHandlerInstantiation(string progressHandler, string asyncInfoInterface, EquatableArray genericParameters) + { + string staticMethodsClass = $"global::ABI.{progressHandler}Methods<{GetGenericParametersAsString(genericParameters, ", ", true, false)}>"; + string asyncInfoInterfaceWithGeneric = $"global::{asyncInfoInterface}<{GetGenericParametersAsString(genericParameters, ", ", false, false)}>"; + string asyncInfoInterfaceWithGenericMethodsClass = $"global::ABI.{asyncInfoInterface}Methods<{GetGenericParametersAsString(genericParameters, ", ", false, false)}>"; + var progressParameter = genericParameters.Last(); + string progressHandlerInstantiation = $$""" + internal static class {{progressHandler.Split('.')[^1]}}_{{GetGenericParametersAsString(genericParameters, "_", false)}} + { + private static readonly bool _initialized = Init(); + internal static bool Initialized => _initialized; + + private static unsafe bool Init() + { + _ = {{staticMethodsClass}}.InitCcw( + &Do_Abi_Invoke + ); + _ = {{staticMethodsClass}}.InitRcwHelper( + &Invoke + ); + return true; + } + + [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] + private static unsafe int Do_Abi_Invoke(IntPtr thisPtr, IntPtr asyncInfo, {{progressParameter.AbiType}} progressInfo) + { + try + { + {{staticMethodsClass}}.Abi_Invoke(thisPtr, MarshalInterface<{{asyncInfoInterfaceWithGeneric}}>.FromAbi(asyncInfo), {{GeneratorHelper.GetFromAbiMarshaler(progressParameter.ProjectedType, progressParameter.AbiType, progressParameter.TypeKind, "progressInfo")}}); + } + catch (global::System.Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + + private static unsafe void Invoke(IObjectReference objRef, {{asyncInfoInterfaceWithGeneric}} asyncInfo, {{progressParameter.ProjectedType}} progressInfo) + { + IntPtr ThisPtr = objRef.ThisPtr; + ObjectReferenceValue __asyncInfo = default; + {{GeneratorHelper.GetMarshalerDeclaration(progressParameter.ProjectedType, progressParameter.AbiType, progressParameter.TypeKind, "progressInfo")}} + try + { + __asyncInfo = MarshalInterface<{{asyncInfoInterfaceWithGeneric}}>.CreateMarshaler2(asyncInfo, {{asyncInfoInterfaceWithGenericMethodsClass}}.IID); + IntPtr abiAsyncInfo = MarshalInspectable.GetAbi(__asyncInfo); + {{GeneratorHelper.GetCreateMarshaler(progressParameter.ProjectedType, progressParameter.AbiType, progressParameter.TypeKind, "progressInfo")}} + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[3](ThisPtr, abiAsyncInfo, {{GeneratorHelper.GetAbiFromMarshaler(progressParameter.ProjectedType, progressParameter.AbiType, progressParameter.TypeKind, "progressInfo")}})); + global::System.GC.KeepAlive(objRef); + } + finally + { + MarshalInterface<{{asyncInfoInterfaceWithGeneric}}>.DisposeMarshaler(__asyncInfo); + {{GeneratorHelper.GetDisposeMarshaler(progressParameter.ProjectedType, progressParameter.AbiType, progressParameter.TypeKind, "progressInfo")}} + } + } + } + """; + return progressHandlerInstantiation; + } + + private static string GetIAsyncActionWithProgressInstantiation(EquatableArray genericParameters) + { + string staticMethodsClass = $"global::ABI.Windows.Foundation.IAsyncActionWithProgressMethods<{GetGenericParametersAsString(genericParameters, ", ", false, false)}>"; + string abiStaticMethodsClass = $"global::ABI.Windows.Foundation.IAsyncActionWithProgressMethods<{GetGenericParametersAsString(genericParameters, ", ", true, false)}>"; + string instantiation = $$""" + internal static class IAsyncActionWithProgress_{{GetGenericParametersAsString(genericParameters, "_", false)}} + { + private static readonly bool _initialized = Init(); + internal static bool Initialized => _initialized; + + private static unsafe bool Init() + { + return {{abiStaticMethodsClass}}.InitCcw( + &Do_Abi_put_Progress_0, + &Do_Abi_get_Progress_1, + &Do_Abi_put_Completed_2, + &Do_Abi_get_Completed_3, + &Do_Abi_GetResults_4 + ); + } + + [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] + private static unsafe int Do_Abi_GetResults_4(IntPtr thisPtr) + { + try + { + {{staticMethodsClass}}.Do_Abi_GetResults_4(thisPtr); + } + 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_put_Progress_0(IntPtr thisPtr, IntPtr handler) + { + _ = AsyncActionProgressHandler_{{GetGenericParametersAsString(genericParameters, "_", false)}}.Initialized; + try + { + {{staticMethodsClass}}.Do_Abi_put_Progress_0(thisPtr, global::ABI.Windows.Foundation.AsyncActionProgressHandler<{{genericParameters[0].ProjectedType}}>.FromAbi(handler)); + } + 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_Progress_1(IntPtr thisPtr, IntPtr* __return_value__) + { + _ = AsyncActionProgressHandler_{{GetGenericParametersAsString(genericParameters, "_", false)}}.Initialized; + global::Windows.Foundation.AsyncActionProgressHandler<{{genericParameters[0].ProjectedType}}> ____return_value__ = default; + + *__return_value__ = default; + + try + { + ____return_value__ = {{staticMethodsClass}}.Do_Abi_get_Progress_1(thisPtr); + *__return_value__ = global::ABI.Windows.Foundation.AsyncActionProgressHandler<{{genericParameters[0].ProjectedType}}>.FromManaged(____return_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_put_Completed_2(IntPtr thisPtr, IntPtr handler) + { + _ = AsyncActionWithProgressCompletedHandler_{{GetGenericParametersAsString(genericParameters, "_", false)}}.Initialized; + try + { + {{staticMethodsClass}}.Do_Abi_put_Completed_2(thisPtr, global::ABI.Windows.Foundation.AsyncActionWithProgressCompletedHandler<{{genericParameters[0].ProjectedType}}>.FromAbi(handler)); + } + 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_Completed_3(IntPtr thisPtr, IntPtr* __return_value__) + { + _ = AsyncActionWithProgressCompletedHandler_{{GetGenericParametersAsString(genericParameters, "_", false)}}.Initialized; + global::Windows.Foundation.AsyncActionWithProgressCompletedHandler<{{genericParameters[0].ProjectedType}}> ____return_value__ = default; + + *__return_value__ = default; + + try + { + ____return_value__ = {{staticMethodsClass}}.Do_Abi_get_Completed_3(thisPtr); + *__return_value__ = global::ABI.Windows.Foundation.AsyncActionWithProgressCompletedHandler<{{genericParameters[0].ProjectedType}}>.FromManaged(____return_value__); + } + catch (Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + } + """; + return instantiation; + } + + private static string GetIAsyncOperationWithProgressInstantiation(EquatableArray genericParameters) + { + string staticMethodsClass = $"global::ABI.Windows.Foundation.IAsyncOperationWithProgressMethods<{GetGenericParametersAsString(genericParameters, ", ", false, false)}>"; + string abiStaticMethodsClass = $"global::ABI.Windows.Foundation.IAsyncOperationWithProgressMethods<{GetGenericParametersAsString(genericParameters, ", ", true, false)}>"; + string instantiation = $$""" + internal static class IAsyncOperationWithProgress_{{GetGenericParametersAsString(genericParameters, "_", false)}} + { + private static readonly bool _initialized = Init(); + internal static bool Initialized => _initialized; + + private static unsafe bool Init() + { + return {{abiStaticMethodsClass}}.InitCcw( + &Do_Abi_put_Progress_0, + &Do_Abi_get_Progress_1, + &Do_Abi_put_Completed_2, + &Do_Abi_get_Completed_3, + &Do_Abi_GetResults_4 + ); + } + + [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] + private static unsafe int Do_Abi_GetResults_4(IntPtr thisPtr, {{genericParameters[0].AbiType}}* __return_value__) + { + {{genericParameters[0].ProjectedType}} ____return_value__ = default; + + *__return_value__ = default; + + try + { + ____return_value__ = {{staticMethodsClass}}.Do_Abi_GetResults_4(thisPtr); + *__return_value__ = {{GeneratorHelper.GetFromManagedMarshaler(genericParameters[0], "____return_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_put_Progress_0(IntPtr thisPtr, IntPtr handler) + { + _ = AsyncOperationProgressHandler_{{GetGenericParametersAsString(genericParameters, "_", false)}}.Initialized; + try + { + {{staticMethodsClass}}.Do_Abi_put_Progress_0(thisPtr, global::ABI.Windows.Foundation.AsyncOperationProgressHandler<{{genericParameters[0].ProjectedType}}, {{genericParameters[1].ProjectedType}}>.FromAbi(handler)); + } + 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_Progress_1(IntPtr thisPtr, IntPtr* __return_value__) + { + _ = AsyncOperationProgressHandler_{{GetGenericParametersAsString(genericParameters, "_", false)}}.Initialized; + global::Windows.Foundation.AsyncOperationProgressHandler<{{genericParameters[0].ProjectedType}}, {{genericParameters[1].ProjectedType}}> ____return_value__ = default; + + *__return_value__ = default; + + try + { + ____return_value__ = {{staticMethodsClass}}.Do_Abi_get_Progress_1(thisPtr); + *__return_value__ = global::ABI.Windows.Foundation.AsyncOperationProgressHandler<{{genericParameters[0].ProjectedType}}, {{genericParameters[1].ProjectedType}}>.FromManaged(____return_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_put_Completed_2(IntPtr thisPtr, IntPtr handler) + { + _ = AsyncOperationWithProgressCompletedHandler_{{GetGenericParametersAsString(genericParameters, "_", false)}}.Initialized; + try + { + {{staticMethodsClass}}.Do_Abi_put_Completed_2(thisPtr, global::ABI.Windows.Foundation.AsyncOperationWithProgressCompletedHandler<{{genericParameters[0].ProjectedType}}, {{genericParameters[1].ProjectedType}}>.FromAbi(handler)); + } + 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_Completed_3(IntPtr thisPtr, IntPtr* __return_value__) + { + _ = AsyncOperationWithProgressCompletedHandler_{{GetGenericParametersAsString(genericParameters, "_", false)}}.Initialized; + global::Windows.Foundation.AsyncOperationWithProgressCompletedHandler<{{genericParameters[0].ProjectedType}}, {{genericParameters[1].ProjectedType}}> ____return_value__ = default; + + *__return_value__ = default; + + try + { + ____return_value__ = {{staticMethodsClass}}.Do_Abi_get_Completed_3(thisPtr); + *__return_value__ = global::ABI.Windows.Foundation.AsyncOperationWithProgressCompletedHandler<{{genericParameters[0].ProjectedType}}, {{genericParameters[1].ProjectedType}}>.FromManaged(____return_value__); + } + catch (Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + } + """; + return instantiation; + } + + private static string GetIAsyncOperationInstantiation(EquatableArray genericParameters) + { + string staticMethodsClass = $"global::ABI.Windows.Foundation.IAsyncOperationMethods<{GetGenericParametersAsString(genericParameters, ", ", false, false)}>"; + string abiStaticMethodsClass = $"global::ABI.Windows.Foundation.IAsyncOperationMethods<{GetGenericParametersAsString(genericParameters, ", ", true, false)}>"; + string instantiation = $$""" + internal static class IAsyncOperation_{{GetGenericParametersAsString(genericParameters, "_", false)}} + { + private static readonly bool _initialized = Init(); + internal static bool Initialized => _initialized; + + private static unsafe bool Init() + { + return {{abiStaticMethodsClass}}.InitCcw( + &Do_Abi_put_Completed_0, + &Do_Abi_get_Completed_1, + &Do_Abi_GetResults_2 + ); + } + + [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] + private static unsafe int Do_Abi_GetResults_2(IntPtr thisPtr, {{genericParameters[0].AbiType}}* __return_value__) + { + {{genericParameters[0].ProjectedType}} ____return_value__ = default; + + *__return_value__ = default; + + try + { + ____return_value__ = {{staticMethodsClass}}.Do_Abi_GetResults_2(thisPtr); + *__return_value__ = {{GeneratorHelper.GetFromManagedMarshaler(genericParameters[0], "____return_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_put_Completed_0(IntPtr thisPtr, IntPtr handler) + { + _ = AsyncOperationCompletedHandler_{{GetGenericParametersAsString(genericParameters, "_", false)}}.Initialized; + try + { + {{staticMethodsClass}}.Do_Abi_put_Completed_0(thisPtr, global::ABI.Windows.Foundation.AsyncOperationCompletedHandler<{{genericParameters[0].ProjectedType}}>.FromAbi(handler)); + } + 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_Completed_1(IntPtr thisPtr, IntPtr* __return_value__) + { + _ = AsyncOperationCompletedHandler_{{GetGenericParametersAsString(genericParameters, "_", false)}}.Initialized; + global::Windows.Foundation.AsyncOperationCompletedHandler<{{genericParameters[0].ProjectedType}}> ____return_value__ = default; + + *__return_value__ = default; + + try + { + ____return_value__ = {{staticMethodsClass}}.Do_Abi_get_Completed_1(thisPtr); + *__return_value__ = global::ABI.Windows.Foundation.AsyncOperationCompletedHandler<{{genericParameters[0].ProjectedType}}>.FromManaged(____return_value__); + } + catch (Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + } + """; + return instantiation; + } + + private static string GetIMapChangedEventArgsInstantiation(EquatableArray genericParameters) + { + string staticMethodsClass = $"global::ABI.Windows.Foundation.Collections.IMapChangedEventArgsMethods<{GetGenericParametersAsString(genericParameters, ", ", false, false)}>"; + string abiStaticMethodsClass = $"global::ABI.Windows.Foundation.Collections.IMapChangedEventArgsMethods<{GetGenericParametersAsString(genericParameters, ", ", true, false)}>"; + string instantiation = $$""" + internal static class IMapChangedEventArgs_{{GetGenericParametersAsString(genericParameters, "_", false)}} + { + private static readonly bool _initialized = Init(); + internal static bool Initialized => _initialized; + + private static unsafe bool Init() + { + return {{abiStaticMethodsClass}}.InitCcw( + &Do_Abi_get_CollectionChange_0, + &Do_Abi_get_Key_1 + ); + } + + [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] + private static unsafe int Do_Abi_get_CollectionChange_0(IntPtr thisPtr, global::Windows.Foundation.Collections.CollectionChange* __return_value__) + { + *__return_value__ = default; + + try + { + *__return_value__ = {{staticMethodsClass}}.Do_Abi_get_CollectionChange_0(thisPtr); + } + 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_Key_1(IntPtr thisPtr, {{genericParameters[0].AbiType}}* __return_value__) + { + {{genericParameters[0].ProjectedType}} ____return_value__ = default; + + *__return_value__ = default; + + try + { + ____return_value__ = {{staticMethodsClass}}.Do_Abi_get_Key_1(thisPtr); + *__return_value__ = {{GeneratorHelper.GetFromManagedMarshaler(genericParameters[0], "____return_value__")}}; + } + catch (Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + } + """; + return instantiation; + } + + private static string GetIObservableMapInstantiation(EquatableArray genericParameters) + { + string staticMethodsClass = $"global::ABI.Windows.Foundation.Collections.IObservableMapMethods<{GetGenericParametersAsString(genericParameters, ", ", false, false)}>"; + string abiStaticMethodsClass = $"global::ABI.Windows.Foundation.Collections.IObservableMapMethods<{GetGenericParametersAsString(genericParameters, ", ", true, false)}>"; + string instantiation = $$""" + internal static class IObservableMap_{{GetGenericParametersAsString(genericParameters, "_", false)}} + { + private static readonly bool _initialized = Init(); + internal static bool Initialized => _initialized; + + private static unsafe bool Init() + { + return {{abiStaticMethodsClass}}.InitCcw( + &Do_Abi_add_MapChanged_0, + &Do_Abi_remove_MapChanged_1 + ); + } + + [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] + private static unsafe int Do_Abi_add_MapChanged_0(IntPtr thisPtr, IntPtr vhnd, global::WinRT.EventRegistrationToken* __return_value__) + { + *__return_value__ = default; + _ = MapChangedEventHandler_{{GetGenericParametersAsString(genericParameters, "_", false)}}.Initialized; + try + { + *__return_value__ = {{staticMethodsClass}}.Do_Abi_add_MapChanged_0(thisPtr, global::ABI.Windows.Foundation.Collections.MapChangedEventHandler<{{genericParameters[0].ProjectedType}}, {{genericParameters[1].ProjectedType}}>.FromAbi(vhnd)); + } + 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_remove_MapChanged_1(IntPtr thisPtr, global::WinRT.EventRegistrationToken token) + { + try + { + {{staticMethodsClass}}.Do_Abi_remove_MapChanged_1(thisPtr, token); + } + catch (Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + } + """; + return instantiation; + } + + private static string GetIObservableVectorInstantiation(EquatableArray genericParameters) + { + string staticMethodsClass = $"global::ABI.Windows.Foundation.Collections.IObservableVectorMethods<{GetGenericParametersAsString(genericParameters, ", ", false, false)}>"; + string abiStaticMethodsClass = $"global::ABI.Windows.Foundation.Collections.IObservableVectorMethods<{GetGenericParametersAsString(genericParameters, ", ", true, false)}>"; + string instantiation = $$""" + internal static class IObservableVector_{{GetGenericParametersAsString(genericParameters, "_", false)}} + { + private static readonly bool _initialized = Init(); + internal static bool Initialized => _initialized; + + private static unsafe bool Init() + { + return {{abiStaticMethodsClass}}.InitCcw( + &Do_Abi_add_VectorChanged_0, + &Do_Abi_remove_VectorChanged_1 + ); + } + + [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] + private static unsafe int Do_Abi_add_VectorChanged_0(IntPtr thisPtr, IntPtr vhnd, global::WinRT.EventRegistrationToken* __return_value__) + { + *__return_value__ = default; + _ = VectorChangedEventHandler_{{GetGenericParametersAsString(genericParameters, "_", false)}}.Initialized; + try + { + *__return_value__ = {{staticMethodsClass}}.Do_Abi_add_VectorChanged_0(thisPtr, global::ABI.Windows.Foundation.Collections.VectorChangedEventHandler<{{genericParameters[0].ProjectedType}}>.FromAbi(vhnd)); + } + 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_remove_VectorChanged_1(IntPtr thisPtr, global::WinRT.EventRegistrationToken token) + { + try + { + {{staticMethodsClass}}.Do_Abi_remove_VectorChanged_1(thisPtr, token); + } + catch (Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + } + """; + return instantiation; + } + + private static string GetGenericParametersAsString(EquatableArray genericParameters, string separator, bool includeAbiTypes, bool escape = true) + { + string genericParametersStr = string.Join(separator, + genericParameters.Select(genericParameter => + { + if (includeAbiTypes) + { + return string.Join( + separator, + escape ? GeneratorHelper.EscapeTypeNameForIdentifier(genericParameter.ProjectedType) : genericParameter.ProjectedType, + escape ? GeneratorHelper.EscapeTypeNameForIdentifier(genericParameter.AbiType) : genericParameter.AbiType); + } + else + { + return escape ? GeneratorHelper.EscapeTypeNameForIdentifier(genericParameter.ProjectedType) : genericParameter.ProjectedType; + } + })); + return genericParametersStr; + } + } +} diff --git a/src/Authoring/WinRT.SourceGenerator/Helper.cs b/src/Authoring/WinRT.SourceGenerator/Helper.cs index 83f5e67cf7..53e2e60158 100644 --- a/src/Authoring/WinRT.SourceGenerator/Helper.cs +++ b/src/Authoring/WinRT.SourceGenerator/Helper.cs @@ -1,1252 +1,1261 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp; -using Microsoft.CodeAnalysis.CSharp.Syntax; -using Microsoft.CodeAnalysis.Diagnostics; -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; -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; - } - - [SuppressMessage("MicrosoftCodeAnalysisCorrectness", "RS1035", Justification = "We need to do file IO to invoke the 'cswinrt' tool.")] - public static string GetGeneratedFilesDir(this GeneratorExecutionContext context) - { - context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.CsWinRTGeneratedFilesDir", out var generatedFilesDir); - Directory.CreateDirectory(generatedFilesDir); - return generatedFilesDir; - } - - public static string GetCsWinRTExeTFM(this GeneratorExecutionContext context) - { - context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.CsWinRTExeTFM", out var csWinRTExeTFM); - return csWinRTExeTFM; - } - - 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) || - string.Equals(isCsWinRTAotOptimizerEnabledStr, "OptIn", StringComparison.OrdinalIgnoreCase) || - string.Equals(isCsWinRTAotOptimizerEnabledStr, "Auto", StringComparison.OrdinalIgnoreCase); - } - - return false; - } - - private enum CsWinRTAotOptimizerMode - { - Disabled = 0, - OptIn = 1, - Auto = 2, - Default = 3, - } - - public static bool IsCsWinRTAotOptimizerInAutoMode(AnalyzerConfigOptionsProvider provider, Compilation compilation) - { - var mode = GetMode(provider); - - if (mode == CsWinRTAotOptimizerMode.Default) - { - // If mode is default and this is a WinUI or UWP project, which we detect by using the Button type as a marker, - // then AOT optimizer is running in auto mode because in both projects the main API boundary is WinRT. - // For CsWinRT components, we also run by default in auto mode. - return provider.IsCsWinRTComponent() || - compilation.GetTypeByMetadataName("Microsoft.UI.Xaml.Controls.Button") is not null || - compilation.GetTypeByMetadataName("Windows.UI.Xaml.Controls.Button") is not null || - // If warning level was explicitly set to 2 without a mode set, - // we don't want to change the behavior of those projects who were - // relying on it running. If they set the mode, then the mode would - // be respected. - provider.GetCsWinRTAotWarningLevel() == 2; - } - - // If mode is not the default, check if it is set explicitly to Auto. - return mode == CsWinRTAotOptimizerMode.Auto; - - static CsWinRTAotOptimizerMode GetMode(AnalyzerConfigOptionsProvider provider) - { - if (provider.GlobalOptions.TryGetValue("build_property.CsWinRTAotOptimizerEnabled", out var isCsWinRTAotOptimizerEnabledStr)) - { - if (string.Equals(isCsWinRTAotOptimizerEnabledStr, "OptIn", StringComparison.OrdinalIgnoreCase)) - { - return CsWinRTAotOptimizerMode.OptIn; - } - - if (string.Equals(isCsWinRTAotOptimizerEnabledStr, "Auto", StringComparison.OrdinalIgnoreCase)) - { - return CsWinRTAotOptimizerMode.Auto; - } - - if (bool.TryParse(isCsWinRTAotOptimizerEnabledStr, out var isCsWinRTAotOptimizerEnabled) && isCsWinRTAotOptimizerEnabled) - { - return CsWinRTAotOptimizerMode.Default; - } - } - - return CsWinRTAotOptimizerMode.Disabled; - } - } - - public static bool GetCsWinRTRcwFactoryFallbackGeneratorForceOptIn(this AnalyzerConfigOptionsProvider provider) - { - if (provider.GlobalOptions.TryGetValue("build_property.CsWinRTRcwFactoryFallbackGeneratorForceOptIn", out var csWinRTRcwFactoryFallbackGeneratorForceOptIn)) - { - return bool.TryParse(csWinRTRcwFactoryFallbackGeneratorForceOptIn, out var isCsWinRTRcwFactoryFallbackGeneratorForceOptIn) && isCsWinRTRcwFactoryFallbackGeneratorForceOptIn; - } - - return false; - } - - public static bool GetCsWinRTMergeReferencedActivationFactories(this AnalyzerConfigOptionsProvider provider) - { - if (provider.GlobalOptions.TryGetValue("build_property.CsWinRTMergeReferencedActivationFactories", out var csWinRTMergeReferencedActivationFactories)) - { - return bool.TryParse(csWinRTMergeReferencedActivationFactories, out var isCsWinRTMergeReferencedActivationFactories) && isCsWinRTMergeReferencedActivationFactories; - } - - return false; - } - - public static bool GetCsWinRTRcwFactoryFallbackGeneratorForceOptOut(this AnalyzerConfigOptionsProvider provider) - { - if (provider.GlobalOptions.TryGetValue("build_property.CsWinRTRcwFactoryFallbackGeneratorForceOptOut", out var csWinRTRcwFactoryFallbackGeneratorForceOptOut)) - { - return bool.TryParse(csWinRTRcwFactoryFallbackGeneratorForceOptOut, out var isCsWinRTRcwFactoryFallbackGeneratorForceOptOut) && isCsWinRTRcwFactoryFallbackGeneratorForceOptOut; - } - - return false; - } - - public static bool IsCsWinRTCcwLookupTableGeneratorEnabled(this AnalyzerConfigOptionsProvider provider) - { - if (provider.GlobalOptions.TryGetValue("build_property.CsWinRTCcwLookupTableGeneratorEnabled", out var csWinRTCcwLookupTableGeneratorEnabled)) - { - return bool.TryParse(csWinRTCcwLookupTableGeneratorEnabled, out var isCsWinRTCcwLookupTableGeneratorEnabled) && isCsWinRTCcwLookupTableGeneratorEnabled; - } - - return false; - } - - public static bool GetCsWinRTUseWindowsUIXamlProjections(this AnalyzerConfigOptionsProvider provider) - { - if (provider.GlobalOptions.TryGetValue("build_property.CsWinRTUseWindowsUIXamlProjections", out var csWinRTUseWindowsUIXamlProjections)) - { - return bool.TryParse(csWinRTUseWindowsUIXamlProjections, out var isCsWinRTUseWindowsUIXamlProjectionsEnabled) && isCsWinRTUseWindowsUIXamlProjectionsEnabled; - } - - return false; - } - - public static int GetCsWinRTAotWarningLevel(this AnalyzerConfigOptionsProvider provider) - { - if (provider.GlobalOptions.TryGetValue("build_property.CsWinRTAotWarningLevel", out var csWinRTAotWarningLevelStr) && - int.TryParse(csWinRTAotWarningLevelStr, out var csWinRTAotWarningLevel)) - { - return csWinRTAotWarningLevel; - } - - return 0; - } - - 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; - } - - /// - /// Gets whether the "CsWinRTAotExportsEnabled" MSBuild property is defined. - /// - /// 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) - { - var fileName = context.GetAssemblyName(); - if (context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.CsWinRTWinMDOutputFile", out var ret)) - { - fileName = ret!; - } - return Path.Combine(context.GetGeneratedFilesDir(), fileName + ".winmd"); - } - - public static bool GetCsWinRTMergeReferencedActivationFactories(this GeneratorExecutionContext context) - { - if (context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.CsWinRTMergeReferencedActivationFactories", out var csWinRTMergeReferencedActivationFactories)) - { - return bool.TryParse(csWinRTMergeReferencedActivationFactories, out var isCsWinRTMergeReferencedActivationFactories) && isCsWinRTMergeReferencedActivationFactories; - } - - return false; - } - } - - static class GeneratorHelper - { - private static bool IsFundamentalType(ISymbol type) - { - if (type is INamedTypeSymbol namedTypeSymbol) - { - switch (namedTypeSymbol.SpecialType) - { - case SpecialType.System_Boolean: - case SpecialType.System_String: - case SpecialType.System_Single: - case SpecialType.System_Double: - case SpecialType.System_UInt16: - case SpecialType.System_UInt32: - case SpecialType.System_UInt64: - case SpecialType.System_Int16: - case SpecialType.System_Int32: - case SpecialType.System_Int64: - case SpecialType.System_Char: - case SpecialType.System_Byte: - case SpecialType.System_Object: - return true; - } - } - - return type.ToDisplayString() == "System.Guid"; - } - - /// - /// Checks whether an assembly contains old projections. - /// - /// The assembly to inspect. - /// Whether contains old projections. - public static bool IsOldProjectionAssembly(IAssemblySymbol assemblySymbol) - { - // We only care about assemblies that have some dependent assemblies - if (assemblySymbol.Modules.First() is not { ReferencedAssemblies: { Length: > 0 } dependentAssemblies }) - { - return false; - } - - // Scan all dependent assemblies to look for CsWinRT with version < 2.0.8 - foreach (AssemblyIdentity assemblyIdentity in dependentAssemblies) - { - if (assemblyIdentity.Name == "WinRT.Runtime") - { - return assemblyIdentity.Version < new Version(2, 0, 8) && - assemblyIdentity.Version != new Version(0, 0, 0, 0); - } - } - - // This assembly is not a projection assembly - return false; - } - - public static bool IsOldCsWinRTExe(GeneratorExecutionContext context) - { - string cswinrtExe = context.GetCsWinRTExe(); - var cswinrtExeVersion = new Version(FileVersionInfo.GetVersionInfo(cswinrtExe).FileVersion); - return cswinrtExeVersion < new Version(2, 1, 0) && cswinrtExeVersion != new Version(0, 0, 0, 0); - } - - public static bool AllowUnsafe(Compilation compilation) - { - return compilation is CSharpCompilation csharpCompilation && csharpCompilation.Options.AllowUnsafe; - } - - // Returns whether it is a WinRT class or interface. - // If the bool parameter is true, then custom mapped interfaces are also considered. - // This function is similar to whether it is a WinRT type, but custom type mapped - // classes are excluded given those are C# implemented classes such as string. - public static Func IsWinRTClassOrInterface(Compilation compilation, Func isWinRTType, TypeMapper mapper) - { - var winrtRuntimeTypeAttribute = compilation.GetTypeByMetadataName("WinRT.WindowsRuntimeTypeAttribute"); - return IsWinRTClassOrInterfaceHelper; - - bool IsWinRTClassOrInterfaceHelper(ISymbol type, bool includeMappedInterfaces) - { - if (type is ITypeSymbol typeSymbol && typeSymbol.TypeKind == TypeKind.Interface) - { - return isWinRTType(type, mapper); - } - - return HasAttributeWithType(type, winrtRuntimeTypeAttribute); - } - } - - public static bool IsWinRTType(ISymbol type, TypeMapper mapper) - { - return IsWinRTType(type, null, mapper); - } - - public static bool IsWinRTType(ISymbol type, Func isAuthoringWinRTType, TypeMapper mapper) - { - bool isProjectedType = type.GetAttributes(). - Any(static attribute => string.CompareOrdinal(attribute.AttributeClass.Name, "WindowsRuntimeTypeAttribute") == 0) || - IsFundamentalType(type); - - if (!isProjectedType & type.ContainingNamespace != null) - { - 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, mapper) || - (isAuthoringWinRTType != null && isAuthoringWinRTType(t, mapper))); - } - - return isProjectedType; - } - - public static bool IsWinRTType(ISymbol type, ITypeSymbol winrtRuntimeTypeAttribute, TypeMapper mapper, bool isComponentProject, IAssemblySymbol currentAssembly) - { - if (IsFundamentalType(type)) - { - return true; - } - - if (isComponentProject && - // Make sure type is in component project. - SymbolEqualityComparer.Default.Equals(type.ContainingAssembly, currentAssembly) && - type.DeclaredAccessibility == Accessibility.Public) - { - // Authoring diagnostics will make sure all public types are valid WinRT types. - return true; - } - - bool isProjectedType = HasAttributeWithType(type, winrtRuntimeTypeAttribute); - if (!isProjectedType & type.ContainingNamespace != null) - { - 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, winrtRuntimeTypeAttribute, mapper, isComponentProject, currentAssembly)); - } - - return isProjectedType; - } - - public static bool IsWinRTTypeOrImplementsWinRTType(ISymbol type, ITypeSymbol winrtRuntimeTypeAttribute, TypeMapper mapper, bool isComponentProject, IAssemblySymbol currentAssembly) - { - if (IsWinRTType(type, winrtRuntimeTypeAttribute, mapper, isComponentProject, currentAssembly)) - { - return true; - } - - if (type is INamedTypeSymbol namedType && - namedType.AllInterfaces.Any(iface => IsWinRTType(iface, winrtRuntimeTypeAttribute, mapper, isComponentProject, currentAssembly))) - { - return true; - } - - return false; - } - - // Assuming a type is a WinRT type, this determines whether it is a WinRT type from custom type mappings. - // i.e Whether it is a built-in type that is also a WinRT type. - public static bool IsCustomMappedType(ISymbol type, TypeMapper mapper) - { - if (IsFundamentalType(type)) - { - return true; - } - - bool isCustomMappedType = false; - if (type.ContainingNamespace != null) - { - isCustomMappedType = mapper.HasMappingForType(string.Join(".", type.ContainingNamespace.ToDisplayString(), type.MetadataName)); - } - - // Ensure all generic parameters are WinRT types. - if (isCustomMappedType && - type is INamedTypeSymbol namedType && - namedType.IsGenericType && - !namedType.IsDefinition) - { - isCustomMappedType = namedType.TypeArguments.All(t => IsCustomMappedType(t, mapper)); - } - - return isCustomMappedType; - } - - // Checks if the interface references any internal types (either the interface itself or within its generic types). - public static bool IsInternalInterfaceFromReferences(INamedTypeSymbol iface, IAssemblySymbol currentAssembly) - { - if (iface.DeclaredAccessibility == Accessibility.Internal && - !SymbolEqualityComparer.Default.Equals(iface.ContainingAssembly, currentAssembly)) - { - return true; - } - - if (iface.IsGenericType) - { - // Making use of HashSet to avoid checking multiple times for same type and to avoid doing recursive calls. - HashSet genericArgumentsToProcess = new(iface.TypeArguments, SymbolEqualityComparer.Default); - HashSet visitedTypes = new(SymbolEqualityComparer.Default); - while (genericArgumentsToProcess.Count != 0) - { - var currentType = genericArgumentsToProcess.First(); - visitedTypes.Add(currentType); - genericArgumentsToProcess.Remove(currentType); - - if (currentType.DeclaredAccessibility == Accessibility.Internal && - !SymbolEqualityComparer.Default.Equals(currentType.ContainingAssembly, currentAssembly)) - { - return true; - } - - if (currentType is INamedTypeSymbol currentNamedTypeSymbol) - { - if (currentNamedTypeSymbol.IsGenericType) - { - foreach (var typeArgument in currentNamedTypeSymbol.TypeArguments) - { - if (!visitedTypes.Contains(typeArgument)) - { - genericArgumentsToProcess.Add(typeArgument); - } - } - } - } - } - } - - return false; - } - - // Checks whether the symbol references any generic that hasn't been instantiated - // 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, 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, mapper)))); - - static bool IsArgumentTypeParameter(ITypeSymbol argument) - { - return argument.TypeKind == TypeKind.TypeParameter; - } - } - - public static bool IsPartial(INamedTypeSymbol symbol) - { - bool isPartial = true; - for (ITypeSymbol parent = symbol; parent is not null; parent = parent.ContainingType) - { - isPartial &= parent.DeclaringSyntaxReferences.Any( - static syntax => syntax.GetSyntax() is BaseTypeDeclarationSyntax declaration && - declaration.Modifiers.Any(SyntaxKind.PartialKeyword)); - } - return isPartial; - } - - public static bool IsPartial(TypeDeclarationSyntax node) - { - bool isPartial = true; - for (TypeDeclarationSyntax parent = node; parent is not null; parent = parent.Parent as TypeDeclarationSyntax) - { - isPartial &= parent.Modifiers.Any(static m => m.IsKind(SyntaxKind.PartialKeyword)); - } - return isPartial; - } - - public static bool HasPrivateclass(ITypeSymbol symbol) - { - return symbol is INamedTypeSymbol namedType && - (namedType.DeclaredAccessibility == Accessibility.Private || - namedType.TypeArguments.Any(static argument => argument.DeclaredAccessibility == Accessibility.Private)); - } - - public static bool HasWinRTExposedTypeAttribute(ISymbol type) - { - return type.GetAttributes(). - Any(static attribute => string.CompareOrdinal(attribute.AttributeClass.Name, "WinRTExposedTypeAttribute") == 0); - } - - public static bool HasWinRTRuntimeClassNameAttribute(ISymbol type, Compilation compilation) - { - var winrtRuntimeClassNameAttribute = compilation.GetTypeByMetadataName("WinRT.WinRTRuntimeClassNameAttribute"); - if (winrtRuntimeClassNameAttribute is null) - { - return false; - } - - return HasAttributeWithType(type, winrtRuntimeClassNameAttribute); - } - - public static bool IsWinRTType(MemberDeclarationSyntax node) - { - bool isProjectedType = node.AttributeLists.SelectMany(static list => list.Attributes). - Any(static attribute => string.CompareOrdinal(attribute.Name.NormalizeWhitespace().ToFullString(), "global::WinRT.WindowsRuntimeType") == 0); - return isProjectedType; - } - - public static bool HasBindableCustomPropertyAttribute(MemberDeclarationSyntax node) - { - return node.AttributeLists.SelectMany(static list => list.Attributes).Any(IsBindableCustomPropertyAttribute); - - // Check based on identifier name if this is the GeneratedBindableCustomProperty attribute. - // Technically this can be a different namespace, but we will confirm later once - // we have access to the semantic model. - static bool IsBindableCustomPropertyAttribute(AttributeSyntax attribute) - { - var nameSyntax = attribute.Name; - if (nameSyntax is QualifiedNameSyntax qualifiedName) - { - // Right would have the attribute while left is the namespace. - nameSyntax = qualifiedName.Right; - } - - return nameSyntax is IdentifierNameSyntax name && - (name.Identifier.ValueText == "GeneratedBindableCustomProperty" || - name.Identifier.ValueText == "GeneratedBindableCustomPropertyAttribute"); - } - } - - /// - /// Checks whether or not a given symbol has an attribute with the specified type. - /// - /// The input instance to check. - /// The instance for the attribute type to look for. - /// Whether or not has an attribute with the specified type. - public static bool HasAttributeWithType(ISymbol symbol, ITypeSymbol attributeTypeSymbol) - { - foreach (AttributeData attribute in symbol.GetAttributes()) - { - if (SymbolEqualityComparer.Default.Equals(attribute.AttributeClass, attributeTypeSymbol)) - { - return true; - } - } - - return false; - } - - /// - /// Checks whether a symbol is annotated with [WinRTExposedType(typeof(WinRTManagedOnlyTypeDetails))]. - /// - public static bool IsManagedOnlyType(ISymbol symbol, ITypeSymbol winrtExposedTypeAttribute, ITypeSymbol winrtManagedOnlyTypeDetails) - { - foreach (AttributeData attribute in symbol.GetAttributes()) - { - if (SymbolEqualityComparer.Default.Equals(attribute.AttributeClass, winrtExposedTypeAttribute)) - { - if (attribute.ConstructorArguments is [{ Kind: TypedConstantKind.Type, Type: ITypeSymbol exposedTypeDetails }] && - SymbolEqualityComparer.Default.Equals(exposedTypeDetails, winrtManagedOnlyTypeDetails)) - { - return true; - } - - // A type can have just one [WinRTExposedType] attribute. If the details are not WinRTManagedOnlyTypeDetails, - // we can immediatley stop here and avoid checking all remaining attributes, as we couldn't possibly match. - return false; - } - } - - return false; - } - - public static Func IsWinRTType(Compilation compilation, bool isComponentProject) - { - var winrtTypeAttribute = compilation.GetTypeByMetadataName("WinRT.WindowsRuntimeTypeAttribute"); - return IsWinRTTypeHelper; - - bool IsWinRTTypeHelper(ISymbol type, TypeMapper typeMapper) - { - return IsWinRTType(type, winrtTypeAttribute, typeMapper, isComponentProject, compilation.Assembly); - } - } - - public static Func IsManagedOnlyType(Compilation compilation) - { - var winrtExposedTypeAttribute = compilation.GetTypeByMetadataName("WinRT.WinRTExposedTypeAttribute"); - var winrtManagedOnlyTypeDetails = compilation.GetTypeByMetadataName("WinRT.WinRTManagedOnlyTypeDetails"); - - return IsManagedOnlyTypeHelper; - - bool IsManagedOnlyTypeHelper(ISymbol type) - { - return IsManagedOnlyType(type, winrtExposedTypeAttribute, winrtManagedOnlyTypeDetails); - } - } - - private static string GetAbiTypeForFundamentalType(ISymbol type) - { - if (type is INamedTypeSymbol namedTypeSymbol) - { - switch (namedTypeSymbol.SpecialType) - { - case SpecialType.System_Boolean: - return "byte"; - case SpecialType.System_String: - return "IntPtr"; - case SpecialType.System_Char: - return "ushort"; - case SpecialType.System_Object: - return "IntPtr"; - case SpecialType.System_Single: - case SpecialType.System_Double: - case SpecialType.System_UInt16: - case SpecialType.System_UInt32: - case SpecialType.System_UInt64: - case SpecialType.System_Int16: - case SpecialType.System_Int32: - case SpecialType.System_Int64: - case SpecialType.System_Byte: - return type.ToDisplayString(); - } - } - - return type.ToDisplayString(); - } - - public static bool IsBlittableValueType(ITypeSymbol type, TypeMapper typeMapper) - { - if (!type.IsValueType) - { - return false; - } - - if (type.SpecialType != SpecialType.None) - { - switch (type.SpecialType) - { - case SpecialType.System_Single: - case SpecialType.System_Double: - case SpecialType.System_UInt16: - case SpecialType.System_UInt32: - case SpecialType.System_UInt64: - case SpecialType.System_Int16: - case SpecialType.System_Int32: - case SpecialType.System_Int64: - case SpecialType.System_Byte: - case SpecialType.System_SByte: - case SpecialType.System_IntPtr: - case SpecialType.System_UIntPtr: - return true; - default: - return false; - } - } - - if (type.ContainingNamespace != null) - { - string customTypeMapKey = string.Join(".", type.ContainingNamespace.ToDisplayString(), type.MetadataName); - if (typeMapper.HasMappingForType(customTypeMapKey)) - { - return typeMapper.GetMappedType(customTypeMapKey).IsBlittable(); - } - } - - if (type.TypeKind == TypeKind.Enum) - { - return true; - } - - if (type.TypeKind == TypeKind.Struct) - { - foreach (var typeMember in type.GetMembers()) - { - if (typeMember is IFieldSymbol field && - !field.IsStatic && - !IsBlittableValueType(field.Type, typeMapper)) - { - return false; - } - } - } - return true; - } - - public static string GetAbiType(ITypeSymbol type, TypeMapper mapper) - { - if (IsFundamentalType(type)) - { - return GetAbiTypeForFundamentalType(type); - } - - var typeStr = type.ToDisplayString(); - if (typeStr == "System.Type") - { - return "ABI.System.Type"; - } - else if (typeStr.StartsWith("System.Collections.Generic.KeyValuePair<")) - { - return "IntPtr"; - } - else if (typeStr == "System.Exception") - { - return "ABI.System.Exception"; - } - - if (type.IsValueType && !type.NullableAnnotation.HasFlag(NullableAnnotation.Annotated)) - { - string customTypeMapKey = string.Join(".", type.ContainingNamespace.ToDisplayString(), type.MetadataName); - if (mapper.HasMappingForType(customTypeMapKey)) - { - string prefix = mapper.GetMappedType(customTypeMapKey).IsBlittable() ? "" : "ABI."; - return prefix + typeStr; - } - - if (!IsBlittableValueType(type, mapper)) - { - var winrtHelperAttribute = type.GetAttributes(). - Where(static attribute => string.CompareOrdinal(attribute.AttributeClass.Name, "WindowsRuntimeHelperTypeAttribute") == 0). - FirstOrDefault(); - if (winrtHelperAttribute != null && - winrtHelperAttribute.ConstructorArguments.Any()) - { - return winrtHelperAttribute.ConstructorArguments[0].Value.ToString(); - } - // 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 - { - return "ABI." + typeStr; - } - } - else - { - return typeStr; - } - } - - return "IntPtr"; - } - - public static string GetMarshalerClass(string type, string abiType, TypeKind kind, bool isArray, bool useGenericMarshaler = false) - { - if (type == "System.String" || type == "string") - { - return "MarshalString"; - } - else if (type == "System.Type" || type == "Type") - { - if (isArray) - { - return "MarshalNonBlittable"; - } - else - { - return "global::ABI.System.Type"; - } - } - else if (type == "System.Exception" || type == "Exception") - { - if (isArray) - { - return "MarshalNonBlittable"; - } - else - { - return "global::ABI.System.Exception"; - } - } - else if (type == "System.Object" || type == "object") - { - return "MarshalInspectable"; - } - else if (type.StartsWith("System.Collections.Generic.KeyValuePair<")) - { - return $$"""MarshalInterface<{{type}}>"""; - } - else if (kind == TypeKind.Enum) - { - if (isArray) - { - return $$"""MarshalBlittable<{{type}}>"""; - } - else - { - return ""; - } - } - else if (kind == TypeKind.Struct) - { - if (type == abiType) - { - if (isArray) - { - return $$"""MarshalBlittable<{{type}}>"""; - } - else - { - return ""; - } - } - else - { - if (isArray) - { - return $$"""MarshalNonBlittable<{{type}}>"""; - } - else - { - return "global::ABI." + type; - } - } - } - else if (kind == TypeKind.Interface) - { - return $$"""MarshalInterface<{{type}}>"""; - } - else if (kind == TypeKind.Class || kind == TypeKind.Delegate) - { - return useGenericMarshaler ? "MarshalInspectable" : "global::ABI." + type; - } - - throw new ArgumentException(); - } - - public static string GetFromAbiMarshaler(GenericParameter genericParameter, string arg) - { - return GetFromAbiMarshaler( - genericParameter.ProjectedType, - genericParameter.AbiType, - genericParameter.TypeKind, - arg); - } - - public static string GetFromAbiMarshaler(string type, string abiType, TypeKind kind, string arg) - { - string marshalerType = GetMarshalerClass(type, abiType, kind, false); - if (kind == TypeKind.Enum || (kind == TypeKind.Struct && type == abiType)) - { - return arg; - } - else if (type == "bool") - { - return $$"""({{arg}} != 0)"""; - } - else if (type == "char") - { - return $$"""(char){{arg}}"""; - } - else - { - return $$"""{{marshalerType}}.FromAbi({{arg}})"""; - } - } - - public static string GetFromManagedMarshaler(GenericParameter genericParameter, string arg) - { - return GetFromManagedMarshaler( - genericParameter.ProjectedType, - genericParameter.AbiType, - genericParameter.TypeKind, - arg); - } - - public static string GetFromManagedMarshaler(string type, string abiType, TypeKind kind, string arg) - { - string marshalerType = GetMarshalerClass(type, abiType, kind, false); - if (kind == TypeKind.Enum || (kind == TypeKind.Struct && type == abiType)) - { - return arg; - } - else if (type == "bool") - { - return $$"""(byte)({{arg}} ? 1 : 0)"""; - } - else if (type == "char") - { - return $$"""(ushort){{arg}}"""; - } - else - { - return $$"""{{marshalerType}}.FromManaged({{arg}})"""; - } - } - - public static string GetCopyManagedArrayMarshaler(string type, string abiType, TypeKind kind) - { - if (kind == TypeKind.Class || kind == TypeKind.Delegate) - { - // TODO: Classes and delegates are missing CopyManagedArray. - return $$"""Marshaler<{{type}}>"""; - } - else - { - return GetMarshalerClass(type, abiType, kind, true); - } - } - - public static string GetCreateMarshaler(GenericParameter genericParameter, string arg) - { - return GetCreateMarshaler( - genericParameter.ProjectedType, - genericParameter.AbiType, - genericParameter.TypeKind, - arg); - } - - public static string GetCreateMarshaler(string type, string abiType, TypeKind kind, string arg) - { - if (kind == TypeKind.Enum || (kind == TypeKind.Struct && type == abiType) || - type == "bool" || - type == "char") - { - return ""; - } - else if (type == "System.String" || type == "string") - { - // TODO: Consider switching to pinning - return $$"""__{{arg}} = MarshalString.CreateMarshaler({{arg}});"""; - } - else if (kind == TypeKind.Struct) - { - string marshalerClass = GetMarshalerClass(type, abiType, kind, false); - return $$"""__{{arg}} = {{marshalerClass}}.CreateMarshaler({{arg}});"""; - } - else - { - string marshalerClass = GetMarshalerClass(type, abiType, kind, false); - return $$"""__{{arg}} = {{marshalerClass}}.CreateMarshaler2({{arg}});"""; - } - } - - public static string GetDisposeMarshaler(GenericParameter genericParameter, string arg) - { - return GetDisposeMarshaler( - genericParameter.ProjectedType, - genericParameter.AbiType, - genericParameter.TypeKind, - arg); - } - - public static string GetDisposeMarshaler(string type, string abiType, TypeKind kind, string arg) - { - if (kind == TypeKind.Enum || (kind == TypeKind.Struct && type == abiType) || - type == "bool" || - type == "char") - { - return ""; - } - else - { - string marshalerClass = GetMarshalerClass(type, abiType, kind, false, true); - return $$"""{{marshalerClass}}.DisposeMarshaler(__{{arg}});"""; - } - } - - public static string GetAbiFromMarshaler(GenericParameter genericParameter, string arg) - { - return GetAbiFromMarshaler( - genericParameter.ProjectedType, - genericParameter.AbiType, - genericParameter.TypeKind, - arg); - } - - public static string GetAbiFromMarshaler(string type, string abiType, TypeKind kind, string arg) - { - if (kind == TypeKind.Enum || (kind == TypeKind.Struct && type == abiType)) - { - return arg; - } - else if (type == "bool") - { - return $"(byte){arg}"; - } - else if (type == "char") - { - return $"(ushort){arg}"; - } - else - { - string marshalerClass = GetMarshalerClass(type, abiType, kind, false, true); - return $"{marshalerClass}.GetAbi(__{arg})"; - } - } - - public static string GetMarshalerDeclaration(GenericParameter genericParameter, string arg) - { - return GetMarshalerDeclaration( - genericParameter.ProjectedType, - genericParameter.AbiType, - genericParameter.TypeKind, - arg); - } - - public static string GetMarshalerDeclaration(string type, string abiType, TypeKind kind, string arg) - { - if (kind == TypeKind.Enum || (kind == TypeKind.Struct && type == abiType) || - type == "bool" || - type == "char") - { - return ""; - } - else if (kind == TypeKind.Struct) - { - return $"{GetAbiMarshalerType(type, abiType, kind, false)}.Marshaler __{arg} = default;"; - } - else - { - return $"{GetAbiMarshalerType(type, abiType, kind, false)} __{arg} = default;"; - } - } - - public static string GetAbiMarshalerType(string type, string abiType, TypeKind kind, bool isArray) - { - if (type == "System.String" || type == "string") - { - return isArray ? "MarshalString.MarshalerArray" : "MarshalString"; - } - else if (type == "System.Type" || type == "Type") - { - if (isArray) - { - return "MarshalNonBlittable.MarshalerArray"; - } - else - { - return "global::ABI.System.Type.Marshaler"; - } - } - else if (type.StartsWith("System.Collections.Generic.KeyValuePair<")) - { - return isArray ? $$"""MarshalInterfaceHelper<{{type}}>.MarshalerArray""" : "ObjectReferenceValue"; - } - else if (kind == TypeKind.Enum) - { - return isArray ? $$"""MarshalBlittable<{{type}}>.MarshalerArray""" : type; - } - else if (kind == TypeKind.Struct) - { - if (type == abiType) - { - return isArray ? $$"""MarshalBlittable<{{type}}>.MarshalerArray""" : type; - } - else - { - return isArray ? $$"""MarshalNonBlittable<{{type}}>.MarshalerArray""" : "ABI." + type; - } - } - else if (type == "System.Object" || type == "object" || kind == TypeKind.Class || kind == TypeKind.Interface || kind == TypeKind.Delegate) - { - return isArray ? $$"""MarshalInterfaceHelper<{{type}}>.MarshalerArray""" : "ObjectReferenceValue"; - } - - throw new ArgumentException(); - } - - public static string EscapeAssemblyNameForIdentifier(string typeName) - { - return Regex.Replace(typeName, """[^a-zA-Z0-9_]""", "_"); - } - - public static string EscapeTypeNameForIdentifier(string typeName) - { - return Regex.Replace(typeName, """[(\ |:<>,\.\-@;+'^!`)]""", "_"); - } - - public readonly struct MappedType - { - private readonly string @namespace; - private readonly string name; - private readonly string assembly; - private readonly bool isSystemType; - private readonly bool isValueType; - private readonly bool isBlittable; - private readonly Func multipleMappingFunc; - - public MappedType(string @namespace, string name, string assembly, bool isValueType = false, bool isBlittable = false) - { - this.@namespace = @namespace; - this.name = name; - this.assembly = assembly; - isSystemType = string.CompareOrdinal(this.assembly, "mscorlib") == 0; - this.isValueType = isValueType; - this.isBlittable = isBlittable; - multipleMappingFunc = null; - } - - public MappedType(Func multipleMappingFunc) - { - @namespace = null; - name = null; - assembly = null; - isSystemType = false; - isValueType = false; - this.multipleMappingFunc = multipleMappingFunc; - } - - public (string, string, string, bool, bool) GetMapping(ISymbol containingType = null) - { - return multipleMappingFunc != null ? - multipleMappingFunc(containingType) : (@namespace, name, assembly, isSystemType, isValueType); - } - - public bool IsBlittable() - { - return isValueType && isBlittable; - } - } - - private static readonly Dictionary AsyncMethodToTaskAdapter = new() - { - // AsAsyncOperation is an extension method, due to that using the format of ReducedFrom. - { "System.WindowsRuntimeSystemExtensions.AsAsyncOperation(System.Threading.Tasks.Task)", "System.Threading.Tasks.TaskToAsyncOperationAdapter`1" }, - { "System.Runtime.InteropServices.WindowsRuntime.AsyncInfo.Run(System.Func>)", "System.Threading.Tasks.TaskToAsyncOperationAdapter`1"}, - { "System.Runtime.InteropServices.WindowsRuntime.AsyncInfo.FromResult(TResult)", "System.Threading.Tasks.TaskToAsyncOperationAdapter`1" }, - { "System.Runtime.InteropServices.WindowsRuntime.AsyncInfo.FromException(System.Exception)", "System.Threading.Tasks.TaskToAsyncOperationAdapter`1" }, - { "System.Runtime.InteropServices.WindowsRuntime.AsyncInfo.CanceledOperation()", "System.Threading.Tasks.TaskToAsyncOperationAdapter`1" }, - { "System.Runtime.InteropServices.WindowsRuntime.AsyncInfo.Run(System.Func, System.Threading.Tasks.Task>)", "System.Threading.Tasks.TaskToAsyncOperationWithProgressAdapter`2" }, - { "System.Runtime.InteropServices.WindowsRuntime.AsyncInfo.FromResultWithProgress(TResult)", "System.Threading.Tasks.TaskToAsyncOperationWithProgressAdapter`2" }, - { "System.Runtime.InteropServices.WindowsRuntime.AsyncInfo.FromExceptionWithProgress(System.Exception)", "System.Threading.Tasks.TaskToAsyncOperationWithProgressAdapter`2" }, - { "System.Runtime.InteropServices.WindowsRuntime.AsyncInfo.CanceledOperationWithProgress()", "System.Threading.Tasks.TaskToAsyncOperationWithProgressAdapter`2" }, - { "System.Runtime.InteropServices.WindowsRuntime.AsyncInfo.Run(System.Func, System.Threading.Tasks.Task>)", "System.Threading.Tasks.TaskToAsyncActionWithProgressAdapter`1" }, - { "System.Runtime.InteropServices.WindowsRuntime.AsyncInfo.CompletedActionWithProgress()", "System.Threading.Tasks.TaskToAsyncActionWithProgressAdapter`1" }, - { "System.Runtime.InteropServices.WindowsRuntime.AsyncInfo.FromExceptionWithProgress(System.Exception)", "System.Threading.Tasks.TaskToAsyncActionWithProgressAdapter`1" }, - { "System.Runtime.InteropServices.WindowsRuntime.AsyncInfo.CanceledActionWithProgress()", "System.Threading.Tasks.TaskToAsyncActionWithProgressAdapter`1" } - }; - - public static string GetTaskAdapterIfAsyncMethod(IMethodSymbol symbol) - { - var symbolStr = symbol.IsExtensionMethod ? symbol.ReducedFrom?.ToDisplayString() : symbol.OriginalDefinition?.ToDisplayString(); - if (!string.IsNullOrEmpty(symbolStr)) - { - if (AsyncMethodToTaskAdapter.TryGetValue(symbolStr, out var adapterTypeStr)) - { - return adapterTypeStr; - } - } - - return null; - } - - public static string TrimGlobalFromTypeName(string typeName) - { - return typeName.StartsWith("global::") ? typeName[8..] : typeName; - } - } +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.CodeAnalysis.Diagnostics; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; +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; + } + + [SuppressMessage("MicrosoftCodeAnalysisCorrectness", "RS1035", Justification = "We need to do file IO to invoke the 'cswinrt' tool.")] + public static string GetGeneratedFilesDir(this GeneratorExecutionContext context) + { + context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.CsWinRTGeneratedFilesDir", out var generatedFilesDir); + Directory.CreateDirectory(generatedFilesDir); + return generatedFilesDir; + } + + public static string GetCsWinRTExeTFM(this GeneratorExecutionContext context) + { + context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.CsWinRTExeTFM", out var csWinRTExeTFM); + return csWinRTExeTFM; + } + + 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) || + string.Equals(isCsWinRTAotOptimizerEnabledStr, "OptIn", StringComparison.OrdinalIgnoreCase) || + string.Equals(isCsWinRTAotOptimizerEnabledStr, "Auto", StringComparison.OrdinalIgnoreCase); + } + + return false; + } + + private enum CsWinRTAotOptimizerMode + { + Disabled = 0, + OptIn = 1, + Auto = 2, + Default = 3, + } + + public static bool IsCsWinRTAotOptimizerInAutoMode(AnalyzerConfigOptionsProvider provider, Compilation compilation) + { + var mode = GetMode(provider); + + if (mode == CsWinRTAotOptimizerMode.Default) + { + // If mode is default and this is a WinUI or UWP project, which we detect by using the Button type as a marker, + // then AOT optimizer is running in auto mode because in both projects the main API boundary is WinRT. + // For CsWinRT components, we also run by default in auto mode. + return provider.IsCsWinRTComponent() || + compilation.GetTypeByMetadataName("Microsoft.UI.Xaml.Controls.Button") is not null || + compilation.GetTypeByMetadataName("Windows.UI.Xaml.Controls.Button") is not null || + // If warning level was explicitly set to 2 without a mode set, + // we don't want to change the behavior of those projects who were + // relying on it running. If they set the mode, then the mode would + // be respected. + provider.GetCsWinRTAotWarningLevel() == 2; + } + + // If mode is not the default, check if it is set explicitly to Auto. + return mode == CsWinRTAotOptimizerMode.Auto; + + static CsWinRTAotOptimizerMode GetMode(AnalyzerConfigOptionsProvider provider) + { + if (provider.GlobalOptions.TryGetValue("build_property.CsWinRTAotOptimizerEnabled", out var isCsWinRTAotOptimizerEnabledStr)) + { + if (string.Equals(isCsWinRTAotOptimizerEnabledStr, "OptIn", StringComparison.OrdinalIgnoreCase)) + { + return CsWinRTAotOptimizerMode.OptIn; + } + + if (string.Equals(isCsWinRTAotOptimizerEnabledStr, "Auto", StringComparison.OrdinalIgnoreCase)) + { + return CsWinRTAotOptimizerMode.Auto; + } + + if (bool.TryParse(isCsWinRTAotOptimizerEnabledStr, out var isCsWinRTAotOptimizerEnabled) && isCsWinRTAotOptimizerEnabled) + { + return CsWinRTAotOptimizerMode.Default; + } + } + + return CsWinRTAotOptimizerMode.Disabled; + } + } + + public static bool GetCsWinRTRcwFactoryFallbackGeneratorForceOptIn(this AnalyzerConfigOptionsProvider provider) + { + if (provider.GlobalOptions.TryGetValue("build_property.CsWinRTRcwFactoryFallbackGeneratorForceOptIn", out var csWinRTRcwFactoryFallbackGeneratorForceOptIn)) + { + return bool.TryParse(csWinRTRcwFactoryFallbackGeneratorForceOptIn, out var isCsWinRTRcwFactoryFallbackGeneratorForceOptIn) && isCsWinRTRcwFactoryFallbackGeneratorForceOptIn; + } + + return false; + } + + public static bool GetCsWinRTMergeReferencedActivationFactories(this AnalyzerConfigOptionsProvider provider) + { + if (provider.GlobalOptions.TryGetValue("build_property.CsWinRTMergeReferencedActivationFactories", out var csWinRTMergeReferencedActivationFactories)) + { + return bool.TryParse(csWinRTMergeReferencedActivationFactories, out var isCsWinRTMergeReferencedActivationFactories) && isCsWinRTMergeReferencedActivationFactories; + } + + return false; + } + + public static bool GetCsWinRTRcwFactoryFallbackGeneratorForceOptOut(this AnalyzerConfigOptionsProvider provider) + { + if (provider.GlobalOptions.TryGetValue("build_property.CsWinRTRcwFactoryFallbackGeneratorForceOptOut", out var csWinRTRcwFactoryFallbackGeneratorForceOptOut)) + { + return bool.TryParse(csWinRTRcwFactoryFallbackGeneratorForceOptOut, out var isCsWinRTRcwFactoryFallbackGeneratorForceOptOut) && isCsWinRTRcwFactoryFallbackGeneratorForceOptOut; + } + + return false; + } + + public static bool IsCsWinRTCcwLookupTableGeneratorEnabled(this AnalyzerConfigOptionsProvider provider) + { + if (provider.GlobalOptions.TryGetValue("build_property.CsWinRTCcwLookupTableGeneratorEnabled", out var csWinRTCcwLookupTableGeneratorEnabled)) + { + return bool.TryParse(csWinRTCcwLookupTableGeneratorEnabled, out var isCsWinRTCcwLookupTableGeneratorEnabled) && isCsWinRTCcwLookupTableGeneratorEnabled; + } + + return false; + } + + public static bool GetCsWinRTUseWindowsUIXamlProjections(this AnalyzerConfigOptionsProvider provider) + { + if (provider.GlobalOptions.TryGetValue("build_property.CsWinRTUseWindowsUIXamlProjections", out var csWinRTUseWindowsUIXamlProjections)) + { + return bool.TryParse(csWinRTUseWindowsUIXamlProjections, out var isCsWinRTUseWindowsUIXamlProjectionsEnabled) && isCsWinRTUseWindowsUIXamlProjectionsEnabled; + } + + return false; + } + + public static int GetCsWinRTAotWarningLevel(this AnalyzerConfigOptionsProvider provider) + { + if (provider.GlobalOptions.TryGetValue("build_property.CsWinRTAotWarningLevel", out var csWinRTAotWarningLevelStr) && + int.TryParse(csWinRTAotWarningLevelStr, out var csWinRTAotWarningLevel)) + { + return csWinRTAotWarningLevel; + } + + return 0; + } + + 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; + } + + /// + /// Gets whether the "CsWinRTAotExportsEnabled" MSBuild property is defined. + /// + /// 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) + { + var fileName = context.GetAssemblyName(); + if (context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.CsWinRTWinMDOutputFile", out var ret)) + { + fileName = ret!; + } + return Path.Combine(context.GetGeneratedFilesDir(), fileName + ".winmd"); + } + + public static bool GetCsWinRTMergeReferencedActivationFactories(this GeneratorExecutionContext context) + { + if (context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.CsWinRTMergeReferencedActivationFactories", out var csWinRTMergeReferencedActivationFactories)) + { + return bool.TryParse(csWinRTMergeReferencedActivationFactories, out var isCsWinRTMergeReferencedActivationFactories) && isCsWinRTMergeReferencedActivationFactories; + } + + return false; + } + } + + static class GeneratorHelper + { + private static bool IsFundamentalType(ISymbol type) + { + if (type is INamedTypeSymbol namedTypeSymbol) + { + switch (namedTypeSymbol.SpecialType) + { + case SpecialType.System_Boolean: + case SpecialType.System_String: + case SpecialType.System_Single: + case SpecialType.System_Double: + case SpecialType.System_UInt16: + case SpecialType.System_UInt32: + case SpecialType.System_UInt64: + case SpecialType.System_Int16: + case SpecialType.System_Int32: + case SpecialType.System_Int64: + case SpecialType.System_Char: + case SpecialType.System_Byte: + case SpecialType.System_Object: + return true; + } + } + + return type.ToDisplayString() == "System.Guid"; + } + + /// + /// Checks whether an assembly contains old projections. + /// + /// The assembly to inspect. + /// Whether contains old projections. + public static bool IsOldProjectionAssembly(IAssemblySymbol assemblySymbol) + { + // We only care about assemblies that have some dependent assemblies + if (assemblySymbol.Modules.First() is not { ReferencedAssemblies: { Length: > 0 } dependentAssemblies }) + { + return false; + } + + // Scan all dependent assemblies to look for CsWinRT with version < 2.0.8 + foreach (AssemblyIdentity assemblyIdentity in dependentAssemblies) + { + if (assemblyIdentity.Name == "WinRT.Runtime") + { + return assemblyIdentity.Version < new Version(2, 0, 8) && + assemblyIdentity.Version != new Version(0, 0, 0, 0); + } + } + + // This assembly is not a projection assembly + return false; + } + + public static bool IsOldCsWinRTExe(GeneratorExecutionContext context) + { + string cswinrtExe = context.GetCsWinRTExe(); + var cswinrtExeVersion = new Version(FileVersionInfo.GetVersionInfo(cswinrtExe).FileVersion); + return cswinrtExeVersion < new Version(2, 1, 0) && cswinrtExeVersion != new Version(0, 0, 0, 0); + } + + public static bool AllowUnsafe(Compilation compilation) + { + return compilation is CSharpCompilation csharpCompilation && csharpCompilation.Options.AllowUnsafe; + } + + // Returns whether it is a WinRT class or interface. + // If the bool parameter is true, then custom mapped interfaces are also considered. + // This function is similar to whether it is a WinRT type, but custom type mapped + // classes are excluded given those are C# implemented classes such as string. + public static Func IsWinRTClassOrInterface(Compilation compilation, Func isWinRTType, TypeMapper mapper) + { + var winrtRuntimeTypeAttribute = compilation.GetTypeByMetadataName("WinRT.WindowsRuntimeTypeAttribute"); + return IsWinRTClassOrInterfaceHelper; + + bool IsWinRTClassOrInterfaceHelper(ISymbol type, bool includeMappedInterfaces) + { + if (type is ITypeSymbol typeSymbol && typeSymbol.TypeKind == TypeKind.Interface) + { + return isWinRTType(type, mapper); + } + + return HasAttributeWithType(type, winrtRuntimeTypeAttribute); + } + } + + public static bool IsWinRTType(ISymbol type, TypeMapper mapper) + { + return IsWinRTType(type, null, mapper); + } + + public static bool IsWinRTType(ISymbol type, Func isAuthoringWinRTType, TypeMapper mapper) + { + bool isProjectedType = type.GetAttributes(). + Any(static attribute => string.CompareOrdinal(attribute.AttributeClass.Name, "WindowsRuntimeTypeAttribute") == 0) || + IsFundamentalType(type); + + if (!isProjectedType & type.ContainingNamespace != null) + { + 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, mapper) || + (isAuthoringWinRTType != null && isAuthoringWinRTType(t, mapper))); + } + + return isProjectedType; + } + + public static bool IsWinRTType(ISymbol type, ITypeSymbol winrtRuntimeTypeAttribute, TypeMapper mapper, bool isComponentProject, IAssemblySymbol currentAssembly) + { + if (IsFundamentalType(type)) + { + return true; + } + + if (isComponentProject && + // Make sure type is in component project. + SymbolEqualityComparer.Default.Equals(type.ContainingAssembly, currentAssembly) && + type.DeclaredAccessibility == Accessibility.Public) + { + // Authoring diagnostics will make sure all public types are valid WinRT types. + return true; + } + + bool isProjectedType = HasAttributeWithType(type, winrtRuntimeTypeAttribute); + if (!isProjectedType & type.ContainingNamespace != null) + { + 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, winrtRuntimeTypeAttribute, mapper, isComponentProject, currentAssembly)); + } + + return isProjectedType; + } + + public static bool IsWinRTTypeOrImplementsWinRTType(ISymbol type, ITypeSymbol winrtRuntimeTypeAttribute, TypeMapper mapper, bool isComponentProject, IAssemblySymbol currentAssembly) + { + if (IsWinRTType(type, winrtRuntimeTypeAttribute, mapper, isComponentProject, currentAssembly)) + { + return true; + } + + if (type is INamedTypeSymbol namedType && + namedType.AllInterfaces.Any(iface => IsWinRTType(iface, winrtRuntimeTypeAttribute, mapper, isComponentProject, currentAssembly))) + { + return true; + } + + return false; + } + + // Assuming a type is a WinRT type, this determines whether it is a WinRT type from custom type mappings. + // i.e Whether it is a built-in type that is also a WinRT type. + public static bool IsCustomMappedType(ISymbol type, TypeMapper mapper) + { + if (IsFundamentalType(type)) + { + return true; + } + + bool isCustomMappedType = false; + if (type.ContainingNamespace != null) + { + isCustomMappedType = mapper.HasMappingForType(string.Join(".", type.ContainingNamespace.ToDisplayString(), type.MetadataName)); + } + + // Ensure all generic parameters are WinRT types. + if (isCustomMappedType && + type is INamedTypeSymbol namedType && + namedType.IsGenericType && + !namedType.IsDefinition) + { + isCustomMappedType = namedType.TypeArguments.All(t => IsCustomMappedType(t, mapper)); + } + + return isCustomMappedType; + } + + // Checks if the interface references any internal types (either the interface itself or within its generic types). + public static bool IsInternalInterfaceFromReferences(INamedTypeSymbol iface, IAssemblySymbol currentAssembly) + { + if (iface.DeclaredAccessibility == Accessibility.Internal && + !SymbolEqualityComparer.Default.Equals(iface.ContainingAssembly, currentAssembly)) + { + return true; + } + + if (iface.IsGenericType) + { + // Making use of HashSet to avoid checking multiple times for same type and to avoid doing recursive calls. + HashSet genericArgumentsToProcess = new(iface.TypeArguments, SymbolEqualityComparer.Default); + HashSet visitedTypes = new(SymbolEqualityComparer.Default); + while (genericArgumentsToProcess.Count != 0) + { + var currentType = genericArgumentsToProcess.First(); + visitedTypes.Add(currentType); + genericArgumentsToProcess.Remove(currentType); + + if (currentType.DeclaredAccessibility == Accessibility.Internal && + !SymbolEqualityComparer.Default.Equals(currentType.ContainingAssembly, currentAssembly)) + { + return true; + } + + if (currentType is INamedTypeSymbol currentNamedTypeSymbol) + { + if (currentNamedTypeSymbol.IsGenericType) + { + foreach (var typeArgument in currentNamedTypeSymbol.TypeArguments) + { + if (!visitedTypes.Contains(typeArgument)) + { + genericArgumentsToProcess.Add(typeArgument); + } + } + } + } + } + } + + return false; + } + + // Checks whether the symbol references any generic that hasn't been instantiated + // 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, 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, mapper)))); + + static bool IsArgumentTypeParameter(ITypeSymbol argument) + { + return argument.TypeKind == TypeKind.TypeParameter; + } + } + + public static bool IsPartial(INamedTypeSymbol symbol) + { + bool isPartial = true; + for (ITypeSymbol parent = symbol; parent is not null; parent = parent.ContainingType) + { + isPartial &= parent.DeclaringSyntaxReferences.Any( + static syntax => syntax.GetSyntax() is BaseTypeDeclarationSyntax declaration && + declaration.Modifiers.Any(SyntaxKind.PartialKeyword)); + } + return isPartial; + } + + public static bool IsPartial(TypeDeclarationSyntax node) + { + bool isPartial = true; + for (TypeDeclarationSyntax parent = node; parent is not null; parent = parent.Parent as TypeDeclarationSyntax) + { + isPartial &= parent.Modifiers.Any(static m => m.IsKind(SyntaxKind.PartialKeyword)); + } + return isPartial; + } + + public static bool HasPrivateclass(ITypeSymbol symbol) + { + return symbol is INamedTypeSymbol namedType && + (namedType.DeclaredAccessibility == Accessibility.Private || + namedType.TypeArguments.Any(static argument => argument.DeclaredAccessibility == Accessibility.Private)); + } + + public static bool HasWinRTExposedTypeAttribute(ISymbol type) + { + return type.GetAttributes(). + Any(static attribute => string.CompareOrdinal(attribute.AttributeClass.Name, "WinRTExposedTypeAttribute") == 0); + } + + public static bool HasWinRTRuntimeClassNameAttribute(ISymbol type, Compilation compilation) + { + var winrtRuntimeClassNameAttribute = compilation.GetTypeByMetadataName("WinRT.WinRTRuntimeClassNameAttribute"); + if (winrtRuntimeClassNameAttribute is null) + { + return false; + } + + return HasAttributeWithType(type, winrtRuntimeClassNameAttribute); + } + + public static bool IsWinRTType(MemberDeclarationSyntax node) + { + bool isProjectedType = node.AttributeLists.SelectMany(static list => list.Attributes). + Any(static attribute => string.CompareOrdinal(attribute.Name.NormalizeWhitespace().ToFullString(), "global::WinRT.WindowsRuntimeType") == 0); + return isProjectedType; + } + + public static bool HasBindableCustomPropertyAttribute(MemberDeclarationSyntax node) + { + return node.AttributeLists.SelectMany(static list => list.Attributes).Any(IsBindableCustomPropertyAttribute); + + // Check based on identifier name if this is the GeneratedBindableCustomProperty attribute. + // Technically this can be a different namespace, but we will confirm later once + // we have access to the semantic model. + static bool IsBindableCustomPropertyAttribute(AttributeSyntax attribute) + { + var nameSyntax = attribute.Name; + if (nameSyntax is QualifiedNameSyntax qualifiedName) + { + // Right would have the attribute while left is the namespace. + nameSyntax = qualifiedName.Right; + } + + return nameSyntax is IdentifierNameSyntax name && + (name.Identifier.ValueText == "GeneratedBindableCustomProperty" || + name.Identifier.ValueText == "GeneratedBindableCustomPropertyAttribute"); + } + } + + /// + /// Checks whether or not a given symbol has an attribute with the specified type. + /// + /// The input instance to check. + /// The instance for the attribute type to look for. + /// Whether or not has an attribute with the specified type. + public static bool HasAttributeWithType(ISymbol symbol, ITypeSymbol attributeTypeSymbol) + { + foreach (AttributeData attribute in symbol.GetAttributes()) + { + if (SymbolEqualityComparer.Default.Equals(attribute.AttributeClass, attributeTypeSymbol)) + { + return true; + } + } + + return false; + } + + /// + /// Checks whether a symbol is annotated with [WinRTExposedType(typeof(WinRTManagedOnlyTypeDetails))]. + /// + public static bool IsManagedOnlyType(ISymbol symbol, ITypeSymbol winrtExposedTypeAttribute, ITypeSymbol winrtManagedOnlyTypeDetails) + { + foreach (AttributeData attribute in symbol.GetAttributes()) + { + if (SymbolEqualityComparer.Default.Equals(attribute.AttributeClass, winrtExposedTypeAttribute)) + { + if (attribute.ConstructorArguments is [{ Kind: TypedConstantKind.Type, Type: ITypeSymbol exposedTypeDetails }] && + SymbolEqualityComparer.Default.Equals(exposedTypeDetails, winrtManagedOnlyTypeDetails)) + { + return true; + } + + // A type can have just one [WinRTExposedType] attribute. If the details are not WinRTManagedOnlyTypeDetails, + // we can immediatley stop here and avoid checking all remaining attributes, as we couldn't possibly match. + return false; + } + } + + return false; + } + + public static Func IsWinRTType(Compilation compilation, bool isComponentProject) + { + var winrtTypeAttribute = compilation.GetTypeByMetadataName("WinRT.WindowsRuntimeTypeAttribute"); + return IsWinRTTypeHelper; + + bool IsWinRTTypeHelper(ISymbol type, TypeMapper typeMapper) + { + return IsWinRTType(type, winrtTypeAttribute, typeMapper, isComponentProject, compilation.Assembly); + } + } + + public static Func IsManagedOnlyType(Compilation compilation) + { + var winrtExposedTypeAttribute = compilation.GetTypeByMetadataName("WinRT.WinRTExposedTypeAttribute"); + var winrtManagedOnlyTypeDetails = compilation.GetTypeByMetadataName("WinRT.WinRTManagedOnlyTypeDetails"); + + return IsManagedOnlyTypeHelper; + + bool IsManagedOnlyTypeHelper(ISymbol type) + { + return IsManagedOnlyType(type, winrtExposedTypeAttribute, winrtManagedOnlyTypeDetails); + } + } + + private static string GetAbiTypeForFundamentalType(ISymbol type) + { + if (type is INamedTypeSymbol namedTypeSymbol) + { + switch (namedTypeSymbol.SpecialType) + { + case SpecialType.System_Boolean: + return "byte"; + case SpecialType.System_String: + return "IntPtr"; + case SpecialType.System_Char: + return "ushort"; + case SpecialType.System_Object: + return "IntPtr"; + case SpecialType.System_Single: + case SpecialType.System_Double: + case SpecialType.System_UInt16: + case SpecialType.System_UInt32: + case SpecialType.System_UInt64: + case SpecialType.System_Int16: + case SpecialType.System_Int32: + case SpecialType.System_Int64: + case SpecialType.System_Byte: + return type.ToDisplayString(); + } + } + + return type.ToDisplayString(); + } + + public static bool IsBlittableValueType(ITypeSymbol type, TypeMapper typeMapper) + { + if (!type.IsValueType) + { + return false; + } + + if (type.SpecialType != SpecialType.None) + { + switch (type.SpecialType) + { + case SpecialType.System_Single: + case SpecialType.System_Double: + case SpecialType.System_UInt16: + case SpecialType.System_UInt32: + case SpecialType.System_UInt64: + case SpecialType.System_Int16: + case SpecialType.System_Int32: + case SpecialType.System_Int64: + case SpecialType.System_Byte: + case SpecialType.System_SByte: + case SpecialType.System_IntPtr: + case SpecialType.System_UIntPtr: + return true; + default: + return false; + } + } + + if (type.ContainingNamespace != null) + { + string customTypeMapKey = string.Join(".", type.ContainingNamespace.ToDisplayString(), type.MetadataName); + if (typeMapper.HasMappingForType(customTypeMapKey)) + { + return typeMapper.GetMappedType(customTypeMapKey).IsBlittable(); + } + } + + if (type.TypeKind == TypeKind.Enum) + { + return true; + } + + if (type.TypeKind == TypeKind.Struct) + { + foreach (var typeMember in type.GetMembers()) + { + if (typeMember is IFieldSymbol field && + !field.IsStatic && + !IsBlittableValueType(field.Type, typeMapper)) + { + return false; + } + } + } + return true; + } + + public static string GetAbiType(ITypeSymbol type, TypeMapper mapper) + { + if (IsFundamentalType(type)) + { + return GetAbiTypeForFundamentalType(type); + } + + var typeStr = type.ToDisplayString(); + if (typeStr == "System.Type") + { + return "ABI.System.Type"; + } + else if (typeStr.StartsWith("System.Collections.Generic.KeyValuePair<")) + { + return "IntPtr"; + } + else if (typeStr == "System.Exception") + { + return "ABI.System.Exception"; + } + + if (type.IsValueType && !type.NullableAnnotation.HasFlag(NullableAnnotation.Annotated)) + { + string customTypeMapKey = string.Join(".", type.ContainingNamespace.ToDisplayString(), type.MetadataName); + if (mapper.HasMappingForType(customTypeMapKey)) + { + string prefix = mapper.GetMappedType(customTypeMapKey).IsBlittable() ? "" : "ABI."; + return prefix + typeStr; + } + + if (!IsBlittableValueType(type, mapper)) + { + var winrtHelperAttribute = type.GetAttributes(). + Where(static attribute => string.CompareOrdinal(attribute.AttributeClass.Name, "WindowsRuntimeHelperTypeAttribute") == 0). + FirstOrDefault(); + if (winrtHelperAttribute != null && + winrtHelperAttribute.ConstructorArguments.Any()) + { + return winrtHelperAttribute.ConstructorArguments[0].Value.ToString(); + } + // 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 + { + return "ABI." + typeStr; + } + } + else + { + return typeStr; + } + } + + return "IntPtr"; + } + + public static string GetMarshalerClass(string type, string abiType, TypeKind kind, bool isArray, bool useGenericMarshaler = false) + { + if (type == "System.String" || type == "string") + { + return "MarshalString"; + } + else if (type == "System.Type" || type == "Type") + { + if (isArray) + { + return "MarshalNonBlittable"; + } + else + { + return "global::ABI.System.Type"; + } + } + else if (type == "System.Exception" || type == "Exception") + { + if (isArray) + { + return "MarshalNonBlittable"; + } + else + { + return "global::ABI.System.Exception"; + } + } + else if (type == "System.Object" || type == "object") + { + return "MarshalInspectable"; + } + else if (type.StartsWith("System.Collections.Generic.KeyValuePair<")) + { + return $$"""MarshalInterface<{{type}}>"""; + } + else if (kind == TypeKind.Enum) + { + if (isArray) + { + return $$"""MarshalBlittable<{{type}}>"""; + } + else + { + return ""; + } + } + else if (kind == TypeKind.Struct) + { + if (type == abiType) + { + if (isArray) + { + return $$"""MarshalBlittable<{{type}}>"""; + } + else + { + return ""; + } + } + else + { + if (isArray) + { + return $$"""MarshalNonBlittable<{{type}}>"""; + } + else + { + return "global::ABI." + type; + } + } + } + else if (kind == TypeKind.Interface) + { + return $$"""MarshalInterface<{{type}}>"""; + } + else if (kind == TypeKind.Class || kind == TypeKind.Delegate) + { + return useGenericMarshaler ? "MarshalInspectable" : "global::ABI." + type; + } + + throw new ArgumentException(); + } + + public static string GetFromAbiMarshaler(GenericParameter genericParameter, string arg) + { + return GetFromAbiMarshaler( + genericParameter.ProjectedType, + genericParameter.AbiType, + genericParameter.TypeKind, + arg); + } + + public static string GetFromAbiMarshaler(string type, string abiType, TypeKind kind, string arg) + { + string marshalerType = GetMarshalerClass(type, abiType, kind, false); + if (kind == TypeKind.Enum || (kind == TypeKind.Struct && type == abiType)) + { + return arg; + } + else if (type == "bool") + { + return $$"""({{arg}} != 0)"""; + } + else if (type == "char") + { + return $$"""(char){{arg}}"""; + } + else + { + return $$"""{{marshalerType}}.FromAbi({{arg}})"""; + } + } + + public static string GetFromManagedMarshaler(GenericParameter genericParameter, string arg) + { + return GetFromManagedMarshaler( + genericParameter.ProjectedType, + genericParameter.AbiType, + genericParameter.TypeKind, + arg); + } + + public static string GetFromManagedMarshaler(string type, string abiType, TypeKind kind, string arg) + { + string marshalerType = GetMarshalerClass(type, abiType, kind, false); + if (kind == TypeKind.Enum || (kind == TypeKind.Struct && type == abiType)) + { + return arg; + } + else if (type == "bool") + { + return $$"""(byte)({{arg}} ? 1 : 0)"""; + } + else if (type == "char") + { + return $$"""(ushort){{arg}}"""; + } + else + { + return $$"""{{marshalerType}}.FromManaged({{arg}})"""; + } + } + + public static string GetCopyManagedArrayMarshaler(string type, string abiType, TypeKind kind, TypeFlags typeFlags) + { + if (kind == TypeKind.Class || kind == TypeKind.Delegate) + { + if (type is "System.String") return "global::WinRT.MarshalString"; + if (type is "System.Type") return "global::ABI.System.Type"; + if (type is "System.Object") return "global::WinRT.MarshalInspectable"; + + if (typeFlags.HasFlag(TypeFlags.Exception)) + { + return "global::WinRT.MarshalNonBlittable"; + } + + // Handles all other classes and delegate types + return $"global::WinRT.MarshalGenericHelper<{type}>"; + } + else + { + return GetMarshalerClass(type, abiType, kind, true); + } + } + + public static string GetCreateMarshaler(GenericParameter genericParameter, string arg) + { + return GetCreateMarshaler( + genericParameter.ProjectedType, + genericParameter.AbiType, + genericParameter.TypeKind, + arg); + } + + public static string GetCreateMarshaler(string type, string abiType, TypeKind kind, string arg) + { + if (kind == TypeKind.Enum || (kind == TypeKind.Struct && type == abiType) || + type == "bool" || + type == "char") + { + return ""; + } + else if (type == "System.String" || type == "string") + { + // TODO: Consider switching to pinning + return $$"""__{{arg}} = MarshalString.CreateMarshaler({{arg}});"""; + } + else if (kind == TypeKind.Struct) + { + string marshalerClass = GetMarshalerClass(type, abiType, kind, false); + return $$"""__{{arg}} = {{marshalerClass}}.CreateMarshaler({{arg}});"""; + } + else + { + string marshalerClass = GetMarshalerClass(type, abiType, kind, false); + return $$"""__{{arg}} = {{marshalerClass}}.CreateMarshaler2({{arg}});"""; + } + } + + public static string GetDisposeMarshaler(GenericParameter genericParameter, string arg) + { + return GetDisposeMarshaler( + genericParameter.ProjectedType, + genericParameter.AbiType, + genericParameter.TypeKind, + arg); + } + + public static string GetDisposeMarshaler(string type, string abiType, TypeKind kind, string arg) + { + if (kind == TypeKind.Enum || (kind == TypeKind.Struct && type == abiType) || + type == "bool" || + type == "char") + { + return ""; + } + else + { + string marshalerClass = GetMarshalerClass(type, abiType, kind, false, true); + return $$"""{{marshalerClass}}.DisposeMarshaler(__{{arg}});"""; + } + } + + public static string GetAbiFromMarshaler(GenericParameter genericParameter, string arg) + { + return GetAbiFromMarshaler( + genericParameter.ProjectedType, + genericParameter.AbiType, + genericParameter.TypeKind, + arg); + } + + public static string GetAbiFromMarshaler(string type, string abiType, TypeKind kind, string arg) + { + if (kind == TypeKind.Enum || (kind == TypeKind.Struct && type == abiType)) + { + return arg; + } + else if (type == "bool") + { + return $"(byte){arg}"; + } + else if (type == "char") + { + return $"(ushort){arg}"; + } + else + { + string marshalerClass = GetMarshalerClass(type, abiType, kind, false, true); + return $"{marshalerClass}.GetAbi(__{arg})"; + } + } + + public static string GetMarshalerDeclaration(GenericParameter genericParameter, string arg) + { + return GetMarshalerDeclaration( + genericParameter.ProjectedType, + genericParameter.AbiType, + genericParameter.TypeKind, + arg); + } + + public static string GetMarshalerDeclaration(string type, string abiType, TypeKind kind, string arg) + { + if (kind == TypeKind.Enum || (kind == TypeKind.Struct && type == abiType) || + type == "bool" || + type == "char") + { + return ""; + } + else if (kind == TypeKind.Struct) + { + return $"{GetAbiMarshalerType(type, abiType, kind, false)}.Marshaler __{arg} = default;"; + } + else + { + return $"{GetAbiMarshalerType(type, abiType, kind, false)} __{arg} = default;"; + } + } + + public static string GetAbiMarshalerType(string type, string abiType, TypeKind kind, bool isArray) + { + if (type == "System.String" || type == "string") + { + return isArray ? "MarshalString.MarshalerArray" : "MarshalString"; + } + else if (type == "System.Type" || type == "Type") + { + if (isArray) + { + return "MarshalNonBlittable.MarshalerArray"; + } + else + { + return "global::ABI.System.Type.Marshaler"; + } + } + else if (type.StartsWith("System.Collections.Generic.KeyValuePair<")) + { + return isArray ? $$"""MarshalInterfaceHelper<{{type}}>.MarshalerArray""" : "ObjectReferenceValue"; + } + else if (kind == TypeKind.Enum) + { + return isArray ? $$"""MarshalBlittable<{{type}}>.MarshalerArray""" : type; + } + else if (kind == TypeKind.Struct) + { + if (type == abiType) + { + return isArray ? $$"""MarshalBlittable<{{type}}>.MarshalerArray""" : type; + } + else + { + return isArray ? $$"""MarshalNonBlittable<{{type}}>.MarshalerArray""" : "ABI." + type; + } + } + else if (type == "System.Object" || type == "object" || kind == TypeKind.Class || kind == TypeKind.Interface || kind == TypeKind.Delegate) + { + return isArray ? $$"""MarshalInterfaceHelper<{{type}}>.MarshalerArray""" : "ObjectReferenceValue"; + } + + throw new ArgumentException(); + } + + public static string EscapeAssemblyNameForIdentifier(string typeName) + { + return Regex.Replace(typeName, """[^a-zA-Z0-9_]""", "_"); + } + + public static string EscapeTypeNameForIdentifier(string typeName) + { + return Regex.Replace(typeName, """[(\ |:<>,\.\-@;+'^!`)]""", "_"); + } + + public readonly struct MappedType + { + private readonly string @namespace; + private readonly string name; + private readonly string assembly; + private readonly bool isSystemType; + private readonly bool isValueType; + private readonly bool isBlittable; + private readonly Func multipleMappingFunc; + + public MappedType(string @namespace, string name, string assembly, bool isValueType = false, bool isBlittable = false) + { + this.@namespace = @namespace; + this.name = name; + this.assembly = assembly; + isSystemType = string.CompareOrdinal(this.assembly, "mscorlib") == 0; + this.isValueType = isValueType; + this.isBlittable = isBlittable; + multipleMappingFunc = null; + } + + public MappedType(Func multipleMappingFunc) + { + @namespace = null; + name = null; + assembly = null; + isSystemType = false; + isValueType = false; + this.multipleMappingFunc = multipleMappingFunc; + } + + public (string, string, string, bool, bool) GetMapping(ISymbol containingType = null) + { + return multipleMappingFunc != null ? + multipleMappingFunc(containingType) : (@namespace, name, assembly, isSystemType, isValueType); + } + + public bool IsBlittable() + { + return isValueType && isBlittable; + } + } + + private static readonly Dictionary AsyncMethodToTaskAdapter = new() + { + // AsAsyncOperation is an extension method, due to that using the format of ReducedFrom. + { "System.WindowsRuntimeSystemExtensions.AsAsyncOperation(System.Threading.Tasks.Task)", "System.Threading.Tasks.TaskToAsyncOperationAdapter`1" }, + { "System.Runtime.InteropServices.WindowsRuntime.AsyncInfo.Run(System.Func>)", "System.Threading.Tasks.TaskToAsyncOperationAdapter`1"}, + { "System.Runtime.InteropServices.WindowsRuntime.AsyncInfo.FromResult(TResult)", "System.Threading.Tasks.TaskToAsyncOperationAdapter`1" }, + { "System.Runtime.InteropServices.WindowsRuntime.AsyncInfo.FromException(System.Exception)", "System.Threading.Tasks.TaskToAsyncOperationAdapter`1" }, + { "System.Runtime.InteropServices.WindowsRuntime.AsyncInfo.CanceledOperation()", "System.Threading.Tasks.TaskToAsyncOperationAdapter`1" }, + { "System.Runtime.InteropServices.WindowsRuntime.AsyncInfo.Run(System.Func, System.Threading.Tasks.Task>)", "System.Threading.Tasks.TaskToAsyncOperationWithProgressAdapter`2" }, + { "System.Runtime.InteropServices.WindowsRuntime.AsyncInfo.FromResultWithProgress(TResult)", "System.Threading.Tasks.TaskToAsyncOperationWithProgressAdapter`2" }, + { "System.Runtime.InteropServices.WindowsRuntime.AsyncInfo.FromExceptionWithProgress(System.Exception)", "System.Threading.Tasks.TaskToAsyncOperationWithProgressAdapter`2" }, + { "System.Runtime.InteropServices.WindowsRuntime.AsyncInfo.CanceledOperationWithProgress()", "System.Threading.Tasks.TaskToAsyncOperationWithProgressAdapter`2" }, + { "System.Runtime.InteropServices.WindowsRuntime.AsyncInfo.Run(System.Func, System.Threading.Tasks.Task>)", "System.Threading.Tasks.TaskToAsyncActionWithProgressAdapter`1" }, + { "System.Runtime.InteropServices.WindowsRuntime.AsyncInfo.CompletedActionWithProgress()", "System.Threading.Tasks.TaskToAsyncActionWithProgressAdapter`1" }, + { "System.Runtime.InteropServices.WindowsRuntime.AsyncInfo.FromExceptionWithProgress(System.Exception)", "System.Threading.Tasks.TaskToAsyncActionWithProgressAdapter`1" }, + { "System.Runtime.InteropServices.WindowsRuntime.AsyncInfo.CanceledActionWithProgress()", "System.Threading.Tasks.TaskToAsyncActionWithProgressAdapter`1" } + }; + + public static string GetTaskAdapterIfAsyncMethod(IMethodSymbol symbol) + { + var symbolStr = symbol.IsExtensionMethod ? symbol.ReducedFrom?.ToDisplayString() : symbol.OriginalDefinition?.ToDisplayString(); + if (!string.IsNullOrEmpty(symbolStr)) + { + if (AsyncMethodToTaskAdapter.TryGetValue(symbolStr, out var adapterTypeStr)) + { + return adapterTypeStr; + } + } + + return null; + } + + public static string TrimGlobalFromTypeName(string typeName) + { + return typeName.StartsWith("global::") ? typeName[8..] : typeName; + } + } } \ No newline at end of file diff --git a/src/WinRT.Runtime/ApiCompatBaseline.net6.0.txt b/src/WinRT.Runtime/ApiCompatBaseline.net6.0.txt index 2416024d12..9167d10332 100644 --- a/src/WinRT.Runtime/ApiCompatBaseline.net6.0.txt +++ b/src/WinRT.Runtime/ApiCompatBaseline.net6.0.txt @@ -1,2 +1,3 @@ Compat issues with assembly WinRT.Runtime: -Total Issues: 0 +TypesMustExist : Type 'WinRT.MarshalGenericHelper' does not exist in the reference but it does exist in the implementation. +Total Issues: 1 diff --git a/src/WinRT.Runtime/ApiCompatBaseline.net8.0.txt b/src/WinRT.Runtime/ApiCompatBaseline.net8.0.txt index 381e90a629..5759f3650c 100644 --- a/src/WinRT.Runtime/ApiCompatBaseline.net8.0.txt +++ b/src/WinRT.Runtime/ApiCompatBaseline.net8.0.txt @@ -1,4 +1,5 @@ Compat issues with assembly WinRT.Runtime: CannotChangeAttribute : Attribute 'System.AttributeUsageAttribute' on 'WinRT.GeneratedBindableCustomPropertyAttribute' changed from '[AttributeUsageAttribute(AttributeTargets.Class, Inherited=false, AllowMultiple=false)]' in the contract to '[AttributeUsageAttribute(AttributeTargets.Class | AttributeTargets.Struct, Inherited=false, AllowMultiple=false)]' in the implementation. CannotRemoveAttribute : Attribute 'System.ComponentModel.EditorBrowsableAttribute' exists on 'WinRT.WinRTExposedTypeAttribute' in the contract but not the implementation. -Total Issues: 2 +TypesMustExist : Type 'WinRT.MarshalGenericHelper' does not exist in the reference but it does exist in the implementation. +Total Issues: 3 diff --git a/src/WinRT.Runtime/Marshalers.cs b/src/WinRT.Runtime/Marshalers.cs index c232a3cfa5..0513401cfb 100644 --- a/src/WinRT.Runtime/Marshalers.cs +++ b/src/WinRT.Runtime/Marshalers.cs @@ -2,6 +2,7 @@ // Licensed under the MIT License. using System; +using System.ComponentModel; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Reflection; @@ -990,7 +991,17 @@ public void DisposeAbiArray(object arg) } } - internal static class MarshalGenericHelper + /// + /// This type is only meant to be used by generated marshalling stubs. Its API surface might change in the future. + /// + /// The managed type to marshal. + [EditorBrowsable(EditorBrowsableState.Never)] +#if EMBED + internal +#else + public +#endif + static class MarshalGenericHelper { private static unsafe void CopyManagedFallback(T value, IntPtr dest) { @@ -1006,7 +1017,7 @@ private static unsafe void CopyManagedFallback(T value, IntPtr dest) } } - internal static unsafe void CopyManagedArray(T[] array, IntPtr data) => MarshalInterfaceHelper.CopyManagedArray(array, data, MarshalGeneric.CopyManaged ?? CopyManagedFallback); + public static unsafe void CopyManagedArray(T[] array, IntPtr data) => MarshalInterfaceHelper.CopyManagedArray(array, data, MarshalGeneric.CopyManaged ?? CopyManagedFallback); } #if EMBED diff --git a/src/WinRT.Runtime/MatchingRefApiCompatBaseline.net6.0.txt b/src/WinRT.Runtime/MatchingRefApiCompatBaseline.net6.0.txt index 2416024d12..9167d10332 100644 --- a/src/WinRT.Runtime/MatchingRefApiCompatBaseline.net6.0.txt +++ b/src/WinRT.Runtime/MatchingRefApiCompatBaseline.net6.0.txt @@ -1,2 +1,3 @@ Compat issues with assembly WinRT.Runtime: -Total Issues: 0 +TypesMustExist : Type 'WinRT.MarshalGenericHelper' does not exist in the reference but it does exist in the implementation. +Total Issues: 1 diff --git a/src/WinRT.Runtime/MatchingRefApiCompatBaseline.net8.0.txt b/src/WinRT.Runtime/MatchingRefApiCompatBaseline.net8.0.txt index 6ca5e66ce1..2fbfd660f1 100644 --- a/src/WinRT.Runtime/MatchingRefApiCompatBaseline.net8.0.txt +++ b/src/WinRT.Runtime/MatchingRefApiCompatBaseline.net8.0.txt @@ -3,4 +3,5 @@ TypesMustExist : Type 'WinRT.GeneratedWinRTExposedExternalTypeAttribute' does no TypesMustExist : Type 'WinRT.GeneratedWinRTExposedTypeAttribute' does not exist in the reference but it does exist in the implementation. CannotChangeAttribute : Attribute 'System.AttributeUsageAttribute' on 'WinRT.GeneratedBindableCustomPropertyAttribute' changed from '[AttributeUsageAttribute(AttributeTargets.Class | AttributeTargets.Struct, Inherited=false, AllowMultiple=false)]' in the implementation to '[AttributeUsageAttribute(AttributeTargets.Class, Inherited=false, AllowMultiple=false)]' in the reference. TypesMustExist : Type 'WinRT.WinRTManagedOnlyTypeDetails' does not exist in the reference but it does exist in the implementation. -Total Issues: 4 +TypesMustExist : Type 'WinRT.MarshalGenericHelper' does not exist in the reference but it does exist in the implementation. +Total Issues: 5