diff --git a/build/AzurePipelineTemplates/CsWinRT-BuildAndTest-Stage.yml b/build/AzurePipelineTemplates/CsWinRT-BuildAndTest-Stage.yml index 6017ac7c0..1c040cf2c 100644 --- a/build/AzurePipelineTemplates/CsWinRT-BuildAndTest-Stage.yml +++ b/build/AzurePipelineTemplates/CsWinRT-BuildAndTest-Stage.yml @@ -111,6 +111,18 @@ stages: script: | dir _build\$(BuildPlatform)\$(BuildConfiguration)\AuthoringConsumptionTest\bin _build\$(BuildPlatform)\$(BuildConfiguration)\AuthoringConsumptionTest\bin\AuthoringConsumptionTest.exe --gtest_output=xml:AUTHORINGTEST-$(Build.BuildNumber).xml + exit /b 0 + +# Run WUX Tests + - task: CmdLine@2 + displayName: Run WUX Tests + condition: and(succeeded(), or(eq(variables['BuildPlatform'], 'x86'), eq(variables['BuildPlatform'], 'x64'))) + continueOnError: True + inputs: + workingDirectory: $(Build.SourcesDirectory)\src + script: | + dir _build\$(BuildPlatform)\$(BuildConfiguration)\AuthoringWuxConsumptionTest\bin + _build\$(BuildPlatform)\$(BuildConfiguration)\AuthoringWuxConsumptionTest\bin\AuthoringWuxConsumptionTest.exe --gtest_output=xml:AUTHORINGWUXTEST-$(Build.BuildNumber).xml exit /b 0 # Run Functional Tests diff --git a/nuget/Microsoft.Windows.CsWinRT.Authoring.targets b/nuget/Microsoft.Windows.CsWinRT.Authoring.targets index 608746067..bb3ae3f19 100644 --- a/nuget/Microsoft.Windows.CsWinRT.Authoring.targets +++ b/nuget/Microsoft.Windows.CsWinRT.Authoring.targets @@ -31,6 +31,7 @@ Copyright (C) Microsoft Corporation. All rights reserved. + diff --git a/nuget/Microsoft.Windows.CsWinRT.targets b/nuget/Microsoft.Windows.CsWinRT.targets index f9b18979d..03c1d284a 100644 --- a/nuget/Microsoft.Windows.CsWinRT.targets +++ b/nuget/Microsoft.Windows.CsWinRT.targets @@ -230,6 +230,13 @@ $(CsWinRTInternalProjection) + + + $(CsWinRTUiXamlMode) + true + + + diff --git a/src/Authoring/WinRT.SourceGenerator/AotOptimizer.cs b/src/Authoring/WinRT.SourceGenerator/AotOptimizer.cs index 13501d1e1..f6996659d 100644 --- a/src/Authoring/WinRT.SourceGenerator/AotOptimizer.cs +++ b/src/Authoring/WinRT.SourceGenerator/AotOptimizer.cs @@ -20,17 +20,28 @@ public void Initialize(IncrementalGeneratorInitializationContext context) { var properties = context.AnalyzerConfigOptionsProvider.Select(static (provider, _) => (provider.IsCsWinRTAotOptimizerEnabled(), provider.IsCsWinRTComponent())); - var vtableAttributesToAdd = context.SyntaxProvider.CreateSyntaxProvider( + var typeMapper = context.AnalyzerConfigOptionsProvider.Select((options, ct) => options.GlobalOptions.GetUiXamlMode()).Select((mode, ct) => new TypeMapper(mode)); + + var possibleVtableAttributesToAdd = context.SyntaxProvider.CreateSyntaxProvider( static (n, _) => NeedVtableAttribute(n), - static (n, _) => GetVtableAttributeToAdd(n) - ).Where(vtableAttribute => vtableAttribute != null); + static (n, _) => n + ); + + var vtableAttributesToAdd = possibleVtableAttributesToAdd + .Combine(typeMapper) + .Select((data, ct) => GetVtableAttributeToAdd(data.Left, data.Right)) + .Where(n => n is not null); context.RegisterImplementationSourceOutput(vtableAttributesToAdd.Collect().Combine(properties), GenerateVtableAttributes); - var vtablesToAddOnLookupTable = context.SyntaxProvider.CreateSyntaxProvider( + var possibleVtablesToAddOnLookupTable = context.SyntaxProvider.CreateSyntaxProvider( static (n, _) => NeedVtableOnLookupTable(n), - static (n, _) => GetVtableAttributesToAddOnLookupTable(n) - ).Where(vtableAttribute => vtableAttribute != null); + static (n, _) => n); + + var vtablesToAddOnLookupTable = possibleVtablesToAddOnLookupTable + .Combine(typeMapper) + .Select((data, ct) => GetVtableAttributesToAddOnLookupTable(data.Left, data.Right)) + .Where(vtableAttribute => vtableAttribute != null); var genericInterfacesFromVtableAttribute = vtableAttributesToAdd.SelectMany(static (vtableAttribute, _) => vtableAttribute.GenericInterfaces).Collect(); var genericInterfacesFromVtableLookupTable = vtablesToAddOnLookupTable.SelectMany(static (vtable, _) => vtable.SelectMany(v => v.GenericInterfaces)).Collect(); @@ -52,10 +63,10 @@ private static bool NeedVtableAttribute(SyntaxNode node) !GeneratorHelper.IsWinRTType(declaration); // Making sure it isn't an RCW we are projecting. } - private static VtableAttribute GetVtableAttributeToAdd(GeneratorSyntaxContext context) + private static VtableAttribute GetVtableAttributeToAdd(GeneratorSyntaxContext context, TypeMapper typeMapper) { var symbol = context.SemanticModel.GetDeclaredSymbol(context.Node as ClassDeclarationSyntax); - return GetVtableAttributeToAdd(symbol, GeneratorHelper.IsWinRTType, context.SemanticModel.Compilation.Assembly, false); + return GetVtableAttributeToAdd(symbol, GeneratorHelper.IsWinRTType, typeMapper, context.SemanticModel.Compilation.Assembly, false); } private static string ToFullyQualifiedString(ISymbol symbol) @@ -88,7 +99,7 @@ private static string ToVtableLookupString(ISymbol symbol) } } - internal static VtableAttribute GetVtableAttributeToAdd(ITypeSymbol symbol, Func isWinRTType, IAssemblySymbol assemblySymbol, bool isAuthoring, string authoringDefaultInterface = "") + internal static VtableAttribute GetVtableAttributeToAdd(ITypeSymbol symbol, Func isWinRTType, TypeMapper mapper, IAssemblySymbol assemblySymbol, bool isAuthoring, string authoringDefaultInterface = "") { if (GeneratorHelper.HasNonInstantiatedWinRTGeneric(symbol) || GeneratorHelper.HasPrivateclass(symbol)) { @@ -105,13 +116,13 @@ internal static VtableAttribute GetVtableAttributeToAdd(ITypeSymbol symbol, Func foreach (var iface in symbol.AllInterfaces) { - if (isWinRTType(iface)) + if (isWinRTType(iface, mapper)) { interfacesToAddToVtable.Add(ToFullyQualifiedString(iface)); AddGenericInterfaceInstantiation(iface); } - if (iface.IsGenericType && TryGetCompatibleWindowsRuntimeTypesForVariantType(iface, null, isWinRTType, out var compatibleIfaces)) + if (iface.IsGenericType && TryGetCompatibleWindowsRuntimeTypesForVariantType(iface, mapper, null, isWinRTType, out var compatibleIfaces)) { foreach (var compatibleIface in compatibleIfaces) { @@ -189,7 +200,7 @@ void AddGenericInterfaceInstantiation(INamedTypeSymbol iface) genericParameters.Add(new GenericParameter( ToFullyQualifiedString(genericParameter), - GeneratorHelper.GetAbiType(genericParameter), + GeneratorHelper.GetAbiType(genericParameter, mapper), genericParameter.TypeKind)); } @@ -207,7 +218,7 @@ bool IsExternalInternalInterface(INamedTypeSymbol iface) } } - private static bool TryGetCompatibleWindowsRuntimeTypesForVariantType(INamedTypeSymbol type, Stack typeStack, Func isWinRTType, out IList compatibleTypes) + private static bool TryGetCompatibleWindowsRuntimeTypesForVariantType(INamedTypeSymbol type, TypeMapper mapper, Stack typeStack, Func isWinRTType, out IList compatibleTypes) { compatibleTypes = null; @@ -220,7 +231,7 @@ private static bool TryGetCompatibleWindowsRuntimeTypesForVariantType(INamedType } var definition = type.OriginalDefinition; - if (!isWinRTType(definition)) + if (!isWinRTType(definition, mapper)) { return false; } @@ -240,20 +251,20 @@ private static bool TryGetCompatibleWindowsRuntimeTypesForVariantType(INamedType HashSet compatibleTypesForGeneric = new(SymbolEqualityComparer.Default); - if (isWinRTType(type.TypeArguments[0])) + if (isWinRTType(type.TypeArguments[0], mapper)) { compatibleTypesForGeneric.Add(type.TypeArguments[0]); } foreach (var iface in type.TypeArguments[0].AllInterfaces) { - if (isWinRTType(iface)) + if (isWinRTType(iface, mapper)) { compatibleTypesForGeneric.Add(iface); } if (iface.IsGenericType - && TryGetCompatibleWindowsRuntimeTypesForVariantType(iface, typeStack, isWinRTType, out var compatibleIfaces)) + && TryGetCompatibleWindowsRuntimeTypesForVariantType(iface, mapper, typeStack, isWinRTType, out var compatibleIfaces)) { compatibleTypesForGeneric.UnionWith(compatibleIfaces); } @@ -262,7 +273,7 @@ private static bool TryGetCompatibleWindowsRuntimeTypesForVariantType(INamedType var baseType = type.TypeArguments[0].BaseType; while (baseType != null) { - if (isWinRTType(baseType)) + if (isWinRTType(baseType, mapper)) { compatibleTypesForGeneric.Add(baseType); } @@ -503,7 +514,7 @@ private static bool NeedVtableOnLookupTable(SyntaxNode node) node is AssignmentExpressionSyntax; } - private static List GetVtableAttributesToAddOnLookupTable(GeneratorSyntaxContext context) + private static List GetVtableAttributesToAddOnLookupTable(GeneratorSyntaxContext context, TypeMapper mapper) { HashSet vtableAttributes = new(); @@ -511,7 +522,7 @@ private static List GetVtableAttributesToAddOnLookupTable(Gener { var invocationSymbol = context.SemanticModel.GetSymbolInfo(invocation.Expression).Symbol; // Check if function is within a CsWinRT projected class or interface. - if (invocationSymbol is IMethodSymbol methodSymbol && GeneratorHelper.IsWinRTType(methodSymbol.ContainingSymbol)) + if (invocationSymbol is IMethodSymbol methodSymbol && GeneratorHelper.IsWinRTType(methodSymbol.ContainingSymbol, mapper)) { // Get the concrete types directly from the argument rather than // using what the method accepts, which might just be an interface, so @@ -530,14 +541,14 @@ private static List GetVtableAttributesToAddOnLookupTable(Gener { if (methodSymbol.Parameters[paramsIdx].Type is not IArrayTypeSymbol) { - var vtableAtribute = GetVtableAttributeToAdd(arrayType, GeneratorHelper.IsWinRTType, context.SemanticModel.Compilation.Assembly, false); + var vtableAtribute = GetVtableAttributeToAdd(arrayType, GeneratorHelper.IsWinRTType, mapper, context.SemanticModel.Compilation.Assembly, false); if (vtableAtribute != default) { vtableAttributes.Add(vtableAtribute); } // Also add the enumerator type to the lookup table as the native caller may call it. - AddEnumeratorAdapterForType(arrayType.ElementType, context.SemanticModel.Compilation, GeneratorHelper.IsWinRTType, vtableAttributes); + AddEnumeratorAdapterForType(arrayType.ElementType, mapper, context.SemanticModel.Compilation, GeneratorHelper.IsWinRTType, vtableAttributes); } } else if (argumentType.Type is not null) @@ -552,11 +563,11 @@ private static List GetVtableAttributesToAddOnLookupTable(Gener // information is available. if (argumentClassTypeSymbol.TypeKind == TypeKind.Delegate && argumentClassTypeSymbol.MetadataName.Contains("`") && - GeneratorHelper.IsWinRTType(argumentClassTypeSymbol) && + GeneratorHelper.IsWinRTType(argumentClassTypeSymbol, mapper) && methodSymbol.Parameters[paramsIdx].Type.SpecialType == SpecialType.System_Object) { var argumentClassNamedTypeSymbol = argumentClassTypeSymbol as INamedTypeSymbol; - vtableAttributes.Add(GetVtableAttributeToAdd(argumentClassTypeSymbol, GeneratorHelper.IsWinRTType, context.SemanticModel.Compilation.Assembly, false)); + vtableAttributes.Add(GetVtableAttributeToAdd(argumentClassTypeSymbol, GeneratorHelper.IsWinRTType, mapper, context.SemanticModel.Compilation.Assembly, false)); } // This handles the case where the source generator wasn't able to run @@ -569,19 +580,19 @@ private static List GetVtableAttributesToAddOnLookupTable(Gener // we handle it here. if (argumentClassTypeSymbol.TypeKind == TypeKind.Class && (argumentClassTypeSymbol.MetadataName.Contains("`") || - (!GeneratorHelper.IsWinRTType(argumentClassTypeSymbol) && + (!GeneratorHelper.IsWinRTType(argumentClassTypeSymbol, mapper) && !GeneratorHelper.HasWinRTExposedTypeAttribute(argumentClassTypeSymbol) && // If the type is defined in the same assembly as what the source generator is running on, // we let the WinRTExposedType attribute generator handle it. !SymbolEqualityComparer.Default.Equals(argumentClassTypeSymbol.ContainingAssembly, context.SemanticModel.Compilation.Assembly)))) { - var vtableAtribute = GetVtableAttributeToAdd(argumentClassTypeSymbol, GeneratorHelper.IsWinRTType, context.SemanticModel.Compilation.Assembly, false); + var vtableAtribute = GetVtableAttributeToAdd(argumentClassTypeSymbol, GeneratorHelper.IsWinRTType, mapper, context.SemanticModel.Compilation.Assembly, false); if (vtableAtribute != default) { vtableAttributes.Add(vtableAtribute); } - AddEnumeratorAdapterForEnumerableInterface(argumentClassTypeSymbol, context.SemanticModel.Compilation, GeneratorHelper.IsWinRTType, vtableAttributes); + AddEnumeratorAdapterForEnumerableInterface(argumentClassTypeSymbol, mapper, context.SemanticModel.Compilation, GeneratorHelper.IsWinRTType, vtableAttributes); } } } @@ -602,7 +613,7 @@ private static List GetVtableAttributesToAddOnLookupTable(Gener // Check if property being assigned to is within a CsWinRT projected class or interface. if (leftSymbol is IPropertySymbol propertySymbol && - GeneratorHelper.IsWinRTType(propertySymbol.ContainingSymbol)) + GeneratorHelper.IsWinRTType(propertySymbol.ContainingSymbol, mapper)) { var argumentType = context.SemanticModel.GetTypeInfo(assignment.Right); @@ -613,14 +624,14 @@ private static List GetVtableAttributesToAddOnLookupTable(Gener { if (propertySymbol.Type is not IArrayTypeSymbol) { - var vtableAtribute = GetVtableAttributeToAdd(arrayType, GeneratorHelper.IsWinRTType, context.SemanticModel.Compilation.Assembly, false); + var vtableAtribute = GetVtableAttributeToAdd(arrayType, GeneratorHelper.IsWinRTType, mapper, context.SemanticModel.Compilation.Assembly, false); if (vtableAtribute != default) { vtableAttributes.Add(vtableAtribute); } // Also add the enumerator type to the lookup table as the native caller can call it. - AddEnumeratorAdapterForType(arrayType.ElementType, context.SemanticModel.Compilation, GeneratorHelper.IsWinRTType, vtableAttributes); + AddEnumeratorAdapterForType(arrayType.ElementType, mapper, context.SemanticModel.Compilation, GeneratorHelper.IsWinRTType, vtableAttributes); } } else if (argumentType.Type is not null || argumentType.ConvertedType is not null) @@ -635,28 +646,28 @@ private static List GetVtableAttributesToAddOnLookupTable(Gener // assignment to object, it is not known, and that is handled here. if (argumentClassTypeSymbol.TypeKind == TypeKind.Delegate && argumentClassTypeSymbol.MetadataName.Contains("`") && - GeneratorHelper.IsWinRTType(argumentClassTypeSymbol) && + GeneratorHelper.IsWinRTType(argumentClassTypeSymbol, mapper) && propertySymbol.Type.SpecialType == SpecialType.System_Object) { var argumentClassNamedTypeSymbol = argumentClassTypeSymbol as INamedTypeSymbol; - vtableAttributes.Add(GetVtableAttributeToAdd(argumentClassTypeSymbol, GeneratorHelper.IsWinRTType, context.SemanticModel.Compilation.Assembly, false)); + vtableAttributes.Add(GetVtableAttributeToAdd(argumentClassTypeSymbol, GeneratorHelper.IsWinRTType, mapper, context.SemanticModel.Compilation.Assembly, false)); } if (argumentClassTypeSymbol.TypeKind == TypeKind.Class && (argumentClassTypeSymbol.MetadataName.Contains("`") || - (!GeneratorHelper.IsWinRTType(argumentClassTypeSymbol) && + (!GeneratorHelper.IsWinRTType(argumentClassTypeSymbol, mapper) && !GeneratorHelper.HasWinRTExposedTypeAttribute(argumentClassTypeSymbol) && // If the type is defined in the same assembly as what the source generator is running on, // we let the WinRTExposedType attribute generator handle it. !SymbolEqualityComparer.Default.Equals(argumentClassTypeSymbol.ContainingAssembly, context.SemanticModel.Compilation.Assembly)))) { - var vtableAtribute = GetVtableAttributeToAdd(argumentClassTypeSymbol, GeneratorHelper.IsWinRTType, context.SemanticModel.Compilation.Assembly, false); + var vtableAtribute = GetVtableAttributeToAdd(argumentClassTypeSymbol, GeneratorHelper.IsWinRTType, mapper, context.SemanticModel.Compilation.Assembly, false); if (vtableAtribute != default) { vtableAttributes.Add(vtableAtribute); } - AddEnumeratorAdapterForEnumerableInterface(argumentClassTypeSymbol, context.SemanticModel.Compilation, GeneratorHelper.IsWinRTType, vtableAttributes); + AddEnumeratorAdapterForEnumerableInterface(argumentClassTypeSymbol, mapper, context.SemanticModel.Compilation, GeneratorHelper.IsWinRTType, vtableAttributes); } } } @@ -668,11 +679,11 @@ private static List GetVtableAttributesToAddOnLookupTable(Gener // Any of the IEnumerable interfaces on the vtable can be used to get the enumerator. Given IEnumerable is // a covariant interface, it means that we can end up getting an instance of the enumerable adapter for any one // of those covariant interfaces and thereby need vtable lookup entries for all of them. - private static void AddEnumeratorAdapterForType(ITypeSymbol type, Compilation compilation, Func isWinRTType, HashSet vtableAttributes) + private static void AddEnumeratorAdapterForType(ITypeSymbol type, TypeMapper mapper, Compilation compilation, Func isWinRTType, HashSet vtableAttributes) { var enumerableType = compilation.GetTypeByMetadataName("System.Collections.Generic.IEnumerable`1"). Construct(type); - if (TryGetCompatibleWindowsRuntimeTypesForVariantType(enumerableType, null, isWinRTType, out var compatibleIfaces)) + if (TryGetCompatibleWindowsRuntimeTypesForVariantType(enumerableType, mapper, null, isWinRTType, out var compatibleIfaces)) { foreach (var compatibleIface in compatibleIfaces) { @@ -681,51 +692,51 @@ private static void AddEnumeratorAdapterForType(ITypeSymbol type, Compilation co { var enumeratorAdapterType = compilation.GetTypeByMetadataName("ABI.System.Collections.Generic.ToAbiEnumeratorAdapter`1"). Construct(compatibleIface.TypeArguments[0]); - vtableAttributes.Add(GetVtableAttributeToAdd(enumeratorAdapterType, isWinRTType, compilation.Assembly, false)); + vtableAttributes.Add(GetVtableAttributeToAdd(enumeratorAdapterType, isWinRTType, mapper, compilation.Assembly, false)); } } } } - internal static void AddEnumeratorAdapterForEnumerableInterface(ITypeSymbol classType, Compilation compilation, Func isWinRTType, HashSet vtableAttributes) + internal static void AddEnumeratorAdapterForEnumerableInterface(ITypeSymbol classType, TypeMapper mapper, Compilation compilation, Func isWinRTType, HashSet vtableAttributes) { // Type may implement multiple unique IEnumerable interfaces. foreach (var iface in classType.AllInterfaces) { if (iface.MetadataName == "IEnumerable`1") { - AddEnumeratorAdapterForType(iface.TypeArguments[0], compilation, isWinRTType, vtableAttributes); + AddEnumeratorAdapterForType(iface.TypeArguments[0], mapper, compilation, isWinRTType, vtableAttributes); } } } - internal static void AddVtableAdapterTypeForKnownInterface(ITypeSymbol classType, Compilation compilation, Func isWinRTType, HashSet vtableAttributes) + internal static void AddVtableAdapterTypeForKnownInterface(ITypeSymbol classType, Compilation compilation, Func isWinRTType, TypeMapper mapper, HashSet vtableAttributes) { foreach (var iface in classType.AllInterfaces) { if (iface.MetadataName == "IEnumerable`1") { - AddEnumeratorAdapterForType(iface.TypeArguments[0], compilation, isWinRTType, vtableAttributes); + AddEnumeratorAdapterForType(iface.TypeArguments[0], mapper, compilation, isWinRTType, vtableAttributes); } else if (iface.MetadataName == "IDictionary`2") { var readOnlyDictionaryType = compilation.GetTypeByMetadataName("System.Collections.ObjectModel.ReadOnlyDictionary`2"). Construct([.. iface.TypeArguments]); - vtableAttributes.Add(GetVtableAttributeToAdd(readOnlyDictionaryType, isWinRTType, compilation.Assembly, false)); + vtableAttributes.Add(GetVtableAttributeToAdd(readOnlyDictionaryType, isWinRTType, mapper, compilation.Assembly, false)); var keyValuePairType = compilation.GetTypeByMetadataName("System.Collections.Generic.KeyValuePair`2"). Construct([.. iface.TypeArguments]); - vtableAttributes.Add(GetVtableAttributeToAdd(keyValuePairType, isWinRTType, compilation.Assembly, false)); + vtableAttributes.Add(GetVtableAttributeToAdd(keyValuePairType, isWinRTType, mapper, compilation.Assembly, false)); var constantSplittableMapType = compilation.GetTypeByMetadataName("ABI.System.Collections.Generic.ConstantSplittableMap`2"). Construct([.. iface.TypeArguments]); - vtableAttributes.Add(GetVtableAttributeToAdd(constantSplittableMapType, isWinRTType, compilation.Assembly, false)); + vtableAttributes.Add(GetVtableAttributeToAdd(constantSplittableMapType, isWinRTType, mapper, compilation.Assembly, false)); } else if (iface.MetadataName == "IList`1") { var readOnlyCollectionType = compilation.GetTypeByMetadataName("System.Collections.ObjectModel.ReadOnlyCollection`1"). Construct([.. iface.TypeArguments]); - vtableAttributes.Add(GetVtableAttributeToAdd(readOnlyCollectionType, isWinRTType, compilation.Assembly, false)); + vtableAttributes.Add(GetVtableAttributeToAdd(readOnlyCollectionType, isWinRTType, mapper, compilation.Assembly, false)); } } } diff --git a/src/Authoring/WinRT.SourceGenerator/DiagnosticUtils.cs b/src/Authoring/WinRT.SourceGenerator/DiagnosticUtils.cs index 9c2215de1..528bd1598 100644 --- a/src/Authoring/WinRT.SourceGenerator/DiagnosticUtils.cs +++ b/src/Authoring/WinRT.SourceGenerator/DiagnosticUtils.cs @@ -16,11 +16,13 @@ public WinRTComponentScanner(GeneratorExecutionContext context, string assemblyN _assemblyName = assemblyName; _context = context; _flag = false; + _typeMapper = new TypeMapper(context.AnalyzerConfigOptions.GlobalOptions.GetUiXamlMode()); } private readonly string _assemblyName; private readonly GeneratorExecutionContext _context; private bool _flag; + private readonly TypeMapper _typeMapper; public bool Found() { return _flag; } @@ -105,7 +107,7 @@ private void CheckDeclarations() var props = @class.DescendantNodes().OfType().Where(IsPublic); // filter out methods and properties that will be replaced with our custom type mappings - IgnoreCustomTypeMappings(classSymbol, ref publicMethods, ref props); + IgnoreCustomTypeMappings(classSymbol, _typeMapper, ref publicMethods, ref props); if (!classSymbol.IsSealed && !classSymbol.IsStatic) { @@ -137,7 +139,7 @@ private void CheckDeclarations() var props = @interface.DescendantNodes().OfType().Where(IsPublic); // filter out methods and properties that will be replaced with our custom type mappings - IgnoreCustomTypeMappings(interfaceSym, ref methods, ref props); + IgnoreCustomTypeMappings(interfaceSym, _typeMapper, ref methods, ref props); if (interfaceSym.IsGenericType) { @@ -206,6 +208,7 @@ private bool IsMethodImpl(IMethodSymbol m, IMethodSymbol interfaceMethod) } private void IgnoreCustomTypeMappings(INamedTypeSymbol typeSymbol, + TypeMapper typeMapper, ref IEnumerable methods, ref IEnumerable properties) { @@ -217,7 +220,7 @@ string QualifiedName(INamedTypeSymbol sym) HashSet classMethods = new(); foreach (var @interface in typeSymbol.AllInterfaces. - Where(symbol => GeneratorHelper.MappedCSharpTypes.ContainsKey(QualifiedName(symbol)) || + Where(symbol => typeMapper.HasMappingForType(QualifiedName(symbol)) || WinRTTypeWriter.ImplementedInterfacesWithoutMapping.Contains(QualifiedName(symbol)))) { foreach (var interfaceMember in @interface.GetMembers()) diff --git a/src/Authoring/WinRT.SourceGenerator/Generator.cs b/src/Authoring/WinRT.SourceGenerator/Generator.cs index baf75519b..303051597 100644 --- a/src/Authoring/WinRT.SourceGenerator/Generator.cs +++ b/src/Authoring/WinRT.SourceGenerator/Generator.cs @@ -1,4 +1,4 @@ -using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Text; @@ -20,11 +20,14 @@ public class ComponentGenerator private Logger Logger { get; } private readonly GeneratorExecutionContext context; private string tempFolder; + private readonly TypeMapper mapper; public ComponentGenerator(GeneratorExecutionContext context) { this.context = context; Logger = new Logger(context); + mapper = new(context.AnalyzerConfigOptions.GlobalOptions.GetUiXamlMode()); + // TODO-WuxMux: output a module initializer that validates the MUX/WUX projection mode to ensure that things don't get out of sync. } private string GetTempFolder(bool clearSourceFilesFromFolder = false) @@ -152,7 +155,8 @@ public void Generate() assembly, version, metadataBuilder, - Logger); + Logger, + mapper); WinRTSyntaxReceiver syntaxReceiver = (WinRTSyntaxReceiver)context.SyntaxReceiver; Logger.Log("Found " + syntaxReceiver.Declarations.Count + " types"); diff --git a/src/Authoring/WinRT.SourceGenerator/Helper.cs b/src/Authoring/WinRT.SourceGenerator/Helper.cs index 1cd7f89ab..55c699c19 100644 --- a/src/Authoring/WinRT.SourceGenerator/Helper.cs +++ b/src/Authoring/WinRT.SourceGenerator/Helper.cs @@ -1,117 +1,117 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. - -using Microsoft.CodeAnalysis; + +using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Diagnostics; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; using System.Text.RegularExpressions; -namespace Generator -{ - public static class Helper - { - public static Guid EncodeGuid(byte[] data) - { - if (BitConverter.IsLittleEndian) - { - // swap bytes of int a - byte t = data[0]; - data[0] = data[3]; - data[3] = t; - t = data[1]; - data[1] = data[2]; - data[2] = t; - // swap bytes of short b - t = data[4]; - data[4] = data[5]; - data[5] = t; - // swap bytes of short c and encode rfc time/version field - t = data[6]; - data[6] = data[7]; - data[7] = (byte)((t & 0x0f) | (5 << 4)); - // encode rfc clock/reserved field - data[8] = (byte)((data[8] & 0x3f) | 0x80); - } - return new Guid(data.Take(16).ToArray()); - } - } - - class AttributeDataComparer : IEqualityComparer - { - public bool Equals(AttributeData x, AttributeData y) - { - return string.CompareOrdinal(x.ToString(), y.ToString()) == 0; - } - - public int GetHashCode(AttributeData obj) - { - return obj.ToString().GetHashCode(); - } - } - - static class GeneratorExecutionContextHelper - { - public static string GetAssemblyName(this GeneratorExecutionContext context) - { - context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.AssemblyName", out var assemblyName); - return assemblyName; - } - - public static string GetAssemblyVersion(this GeneratorExecutionContext context) - { - context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.AssemblyVersion", out var assemblyVersion); - return assemblyVersion; - } - - public static string GetGeneratedFilesDir(this GeneratorExecutionContext context) - { - context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.CsWinRTGeneratedFilesDir", out var generatedFilesDir); - Directory.CreateDirectory(generatedFilesDir); - return generatedFilesDir; - } - - public static bool IsCsWinRTComponent(this GeneratorExecutionContext context) - { - if (context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.CsWinRTComponent", out var isCsWinRTComponentStr)) - { - return bool.TryParse(isCsWinRTComponentStr, out var isCsWinRTComponent) && isCsWinRTComponent; - } - - return false; - } - - public static bool IsCsWinRTComponent(this AnalyzerConfigOptionsProvider provider) - { - if (provider.GlobalOptions.TryGetValue("build_property.CsWinRTComponent", out var isCsWinRTComponentStr)) - { - return bool.TryParse(isCsWinRTComponentStr, out var isCsWinRTComponent) && isCsWinRTComponent; - } - - return false; - } - - public static bool IsCsWinRTAotOptimizerEnabled(this AnalyzerConfigOptionsProvider provider) - { - if (provider.GlobalOptions.TryGetValue("build_property.CsWinRTAotOptimizerEnabled", out var isCsWinRTAotOptimizerEnabledStr)) - { - return bool.TryParse(isCsWinRTAotOptimizerEnabledStr, out var isCsWinRTAotOptimizerEnabled) && isCsWinRTAotOptimizerEnabled; - } - - return false; - } - - public static bool ShouldGenerateWinMDOnly(this GeneratorExecutionContext context) - { - if (context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.CsWinRTGenerateWinMDOnly", out var CsWinRTGenerateWinMDOnlyStr)) - { - return bool.TryParse(CsWinRTGenerateWinMDOnlyStr, out var CsWinRTGenerateWinMDOnly) && CsWinRTGenerateWinMDOnly; - } - - return false; +namespace Generator +{ + public static class Helper + { + public static Guid EncodeGuid(byte[] data) + { + if (BitConverter.IsLittleEndian) + { + // swap bytes of int a + byte t = data[0]; + data[0] = data[3]; + data[3] = t; + t = data[1]; + data[1] = data[2]; + data[2] = t; + // swap bytes of short b + t = data[4]; + data[4] = data[5]; + data[5] = t; + // swap bytes of short c and encode rfc time/version field + t = data[6]; + data[6] = data[7]; + data[7] = (byte)((t & 0x0f) | (5 << 4)); + // encode rfc clock/reserved field + data[8] = (byte)((data[8] & 0x3f) | 0x80); + } + return new Guid(data.Take(16).ToArray()); + } + } + + class AttributeDataComparer : IEqualityComparer + { + public bool Equals(AttributeData x, AttributeData y) + { + return string.CompareOrdinal(x.ToString(), y.ToString()) == 0; + } + + public int GetHashCode(AttributeData obj) + { + return obj.ToString().GetHashCode(); + } + } + + static class GeneratorExecutionContextHelper + { + public static string GetAssemblyName(this GeneratorExecutionContext context) + { + context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.AssemblyName", out var assemblyName); + return assemblyName; + } + + public static string GetAssemblyVersion(this GeneratorExecutionContext context) + { + context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.AssemblyVersion", out var assemblyVersion); + return assemblyVersion; + } + + public static string GetGeneratedFilesDir(this GeneratorExecutionContext context) + { + context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.CsWinRTGeneratedFilesDir", out var generatedFilesDir); + Directory.CreateDirectory(generatedFilesDir); + return generatedFilesDir; + } + + public static bool IsCsWinRTComponent(this GeneratorExecutionContext context) + { + if (context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.CsWinRTComponent", out var isCsWinRTComponentStr)) + { + return bool.TryParse(isCsWinRTComponentStr, out var isCsWinRTComponent) && isCsWinRTComponent; + } + + return false; + } + + public static bool IsCsWinRTComponent(this AnalyzerConfigOptionsProvider provider) + { + if (provider.GlobalOptions.TryGetValue("build_property.CsWinRTComponent", out var isCsWinRTComponentStr)) + { + return bool.TryParse(isCsWinRTComponentStr, out var isCsWinRTComponent) && isCsWinRTComponent; + } + + return false; + } + + public static bool IsCsWinRTAotOptimizerEnabled(this AnalyzerConfigOptionsProvider provider) + { + if (provider.GlobalOptions.TryGetValue("build_property.CsWinRTAotOptimizerEnabled", out var isCsWinRTAotOptimizerEnabledStr)) + { + return bool.TryParse(isCsWinRTAotOptimizerEnabledStr, out var isCsWinRTAotOptimizerEnabled) && isCsWinRTAotOptimizerEnabled; + } + + return false; + } + + public static bool ShouldGenerateWinMDOnly(this GeneratorExecutionContext context) + { + if (context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.CsWinRTGenerateWinMDOnly", out var CsWinRTGenerateWinMDOnlyStr)) + { + return bool.TryParse(CsWinRTGenerateWinMDOnlyStr, out var CsWinRTGenerateWinMDOnly) && CsWinRTGenerateWinMDOnly; + } + + return false; } /// @@ -119,51 +119,51 @@ public static bool ShouldGenerateWinMDOnly(this GeneratorExecutionContext contex /// /// The input value to use. /// Whether the "CsWinRTAotExportsEnabled" MSBuild property is defined. - public static bool ShouldGenerateWinRTNativeExports(this GeneratorExecutionContext context) - { - if (context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.CsWinRTAotExportsEnabled", out var isCsWinRTAotExportsEnabledStr)) - { - return bool.TryParse(isCsWinRTAotExportsEnabledStr, out var isCsWinRTAotExportsEnabled) && isCsWinRTAotExportsEnabled; - } - - return false; - } - - public static string GetCsWinRTExe(this GeneratorExecutionContext context) - { - context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.CsWinRTExe", out var cswinrtExe); - return cswinrtExe; - } - - public static bool GetKeepGeneratedSources(this GeneratorExecutionContext context) - { - context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.CsWinRTKeepGeneratedSources", out var keepGeneratedSourcesStr); - return keepGeneratedSourcesStr != null && bool.TryParse(keepGeneratedSourcesStr, out var keepGeneratedSources) && keepGeneratedSources; - } - - public static string GetCsWinRTWindowsMetadata(this GeneratorExecutionContext context) - { - context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.CsWinRTWindowsMetadata", out var cswinrtWindowsMetadata); - return cswinrtWindowsMetadata; - } - - public static string GetCsWinRTDependentMetadata(this GeneratorExecutionContext context) - { - context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.CsWinRTAuthoringInputs", out var winmds); - return winmds; - } - - public static string GetWinmdOutputFile(this GeneratorExecutionContext context) - { + public static bool ShouldGenerateWinRTNativeExports(this GeneratorExecutionContext context) + { + if (context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.CsWinRTAotExportsEnabled", out var isCsWinRTAotExportsEnabledStr)) + { + return bool.TryParse(isCsWinRTAotExportsEnabledStr, out var isCsWinRTAotExportsEnabled) && isCsWinRTAotExportsEnabled; + } + + return false; + } + + public static string GetCsWinRTExe(this GeneratorExecutionContext context) + { + context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.CsWinRTExe", out var cswinrtExe); + return cswinrtExe; + } + + public static bool GetKeepGeneratedSources(this GeneratorExecutionContext context) + { + context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.CsWinRTKeepGeneratedSources", out var keepGeneratedSourcesStr); + return keepGeneratedSourcesStr != null && bool.TryParse(keepGeneratedSourcesStr, out var keepGeneratedSources) && keepGeneratedSources; + } + + public static string GetCsWinRTWindowsMetadata(this GeneratorExecutionContext context) + { + context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.CsWinRTWindowsMetadata", out var cswinrtWindowsMetadata); + return cswinrtWindowsMetadata; + } + + public static string GetCsWinRTDependentMetadata(this GeneratorExecutionContext context) + { + context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.CsWinRTAuthoringInputs", out var winmds); + return winmds; + } + + public static string GetWinmdOutputFile(this GeneratorExecutionContext context) + { var fileName = context.GetAssemblyName(); if (context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.CsWinRTWinMDOutputFile", out var ret)) { fileName = ret!; - } - return Path.Combine(context.GetGeneratedFilesDir(), fileName + ".winmd"); - } - } - + } + return Path.Combine(context.GetGeneratedFilesDir(), fileName + ".winmd"); + } + } + static class GeneratorHelper { private static bool IsFundamentalType(ISymbol type) @@ -192,12 +192,12 @@ private static bool IsFundamentalType(ISymbol type) return type.ToDisplayString() == "System.Guid"; } - public static bool IsWinRTType(ISymbol type) + public static bool IsWinRTType(ISymbol type, TypeMapper mapper) { - return IsWinRTType(type, null); + return IsWinRTType(type, mapper, null); } - public static bool IsWinRTType(ISymbol type, Func isAuthoringWinRTType) + public static bool IsWinRTType(ISymbol type, TypeMapper mapper, Func isAuthoringWinRTType) { bool isProjectedType = type.GetAttributes(). Any(attribute => string.CompareOrdinal(attribute.AttributeClass.Name, "WindowsRuntimeTypeAttribute") == 0) || @@ -205,14 +205,14 @@ public static bool IsWinRTType(ISymbol type, Func isAuthoringWinR if (!isProjectedType & type.ContainingNamespace != null) { - isProjectedType = MappedCSharpTypes.ContainsKey(string.Join(".", type.ContainingNamespace.ToDisplayString(), type.MetadataName)); + isProjectedType = mapper.HasMappingForType(string.Join(".", type.ContainingNamespace.ToDisplayString(), type.MetadataName)); } // Ensure all generic parameters are WinRT types. if (isProjectedType && type is INamedTypeSymbol namedType && namedType.IsGenericType && !namedType.IsDefinition) { isProjectedType = namedType.TypeArguments.All(t => - IsWinRTType(t, isAuthoringWinRTType) || + IsWinRTType(t, mapper, isAuthoringWinRTType) || (isAuthoringWinRTType != null && isAuthoringWinRTType(t))); } @@ -295,7 +295,7 @@ private static string GetAbiTypeForFundamentalType(ISymbol type) return type.ToDisplayString(); } - public static bool IsBlittableValueType(ITypeSymbol type) + public static bool IsBlittableValueType(ITypeSymbol type, TypeMapper typeMapper) { if (!type.IsValueType) { @@ -325,9 +325,9 @@ public static bool IsBlittableValueType(ITypeSymbol type) } string customTypeMapKey = string.Join(".", type.ContainingNamespace.ToDisplayString(), type.MetadataName); - if (MappedCSharpTypes.ContainsKey(customTypeMapKey)) + if (typeMapper.HasMappingForType(customTypeMapKey)) { - return MappedCSharpTypes[customTypeMapKey].IsBlittable(); + return typeMapper.GetMappedType(customTypeMapKey).IsBlittable(); } if (type.TypeKind == TypeKind.Enum) @@ -339,7 +339,7 @@ public static bool IsBlittableValueType(ITypeSymbol type) { foreach (var typeMember in type.GetMembers()) { - if (typeMember is IFieldSymbol field && !IsBlittableValueType(field.Type)) + if (typeMember is IFieldSymbol field && !IsBlittableValueType(field.Type, typeMapper)) { return false; } @@ -348,7 +348,7 @@ public static bool IsBlittableValueType(ITypeSymbol type) return true; } - public static string GetAbiType(ITypeSymbol type) + public static string GetAbiType(ITypeSymbol type, TypeMapper mapper) { if (IsFundamentalType(type)) { @@ -368,9 +368,9 @@ public static string GetAbiType(ITypeSymbol type) if (type.IsValueType) { string customTypeMapKey = string.Join(".", type.ContainingNamespace.ToDisplayString(), type.MetadataName); - if (MappedCSharpTypes.ContainsKey(customTypeMapKey)) + if (mapper.HasMappingForType(customTypeMapKey)) { - string prefix = MappedCSharpTypes[customTypeMapKey].IsBlittable() ? "" : "ABI."; + string prefix = mapper.GetMappedType(customTypeMapKey).IsBlittable() ? "" : "ABI."; return prefix + typeStr; } @@ -385,7 +385,7 @@ public static string GetAbiType(ITypeSymbol type) // Handling authoring scenario where Impl type has the attributes and // if the current component is the one being authored, it may not be // generated yet to check given it is the same compilation. - else if (!IsBlittableValueType(type)) + else if (!IsBlittableValueType(type, mapper)) { return "ABI." + typeStr; } @@ -731,63 +731,5 @@ public bool IsBlittable() return isValueType && isBlittable; } } - - // Based on whether System.Type is used in an attribute declaration or elsewhere, we need to choose the correct custom mapping - // as attributes don't use the TypeName mapping. - internal static (string, string, string, bool, bool) GetSystemTypeCustomMapping(ISymbol containingSymbol) - { - bool isDefinedInAttribute = - containingSymbol != null && - string.CompareOrdinal((containingSymbol as INamedTypeSymbol).BaseType?.ToString(), "System.Attribute") == 0; - return isDefinedInAttribute ? - ("System", "Type", "mscorlib", true, false) : - ("Windows.UI.Xaml.Interop", "TypeName", "Windows.Foundation.UniversalApiContract", false, true); - } - - // This should be in sync with the reverse mapping from WinRT.Runtime/Projections.cs and cswinrt/helpers.h. - public static readonly Dictionary MappedCSharpTypes = new(StringComparer.Ordinal) - { - { "System.DateTimeOffset", new MappedType("Windows.Foundation", "DateTime", "Windows.Foundation.FoundationContract", true, false) }, - { "System.Exception", new MappedType("Windows.Foundation", "HResult", "Windows.Foundation.FoundationContract", true, false) }, - { "System.EventHandler`1", new MappedType("Windows.Foundation", "EventHandler`1", "Windows.Foundation.FoundationContract") }, - { "System.FlagsAttribute", new MappedType("System", "FlagsAttribute", "mscorlib" ) }, - { "System.IDisposable", new MappedType("Windows.Foundation", "IClosable", "Windows.Foundation.FoundationContract") }, - { "System.IServiceProvider", new MappedType("Microsoft.UI.Xaml", "IXamlServiceProvider", "Microsoft.UI") }, - { "System.Nullable`1", new MappedType("Windows.Foundation", "IReference`1", "Windows.Foundation.FoundationContract" ) }, - { "System.Object", new MappedType("System", "Object", "mscorlib" ) }, - { "System.TimeSpan", new MappedType("Windows.Foundation", "TimeSpan", "Windows.Foundation.FoundationContract", true, false) }, - { "System.Uri", new MappedType("Windows.Foundation", "Uri", "Windows.Foundation.FoundationContract") }, - { "System.ComponentModel.DataErrorsChangedEventArgs", new MappedType("Microsoft.UI.Xaml.Data", "DataErrorsChangedEventArgs", "Microsoft.UI") }, - { "System.ComponentModel.INotifyDataErrorInfo", new MappedType("Microsoft.UI.Xaml.Data", "INotifyDataErrorInfo", "Microsoft.UI") }, - { "System.ComponentModel.INotifyPropertyChanged", new MappedType("Microsoft.UI.Xaml.Data", "INotifyPropertyChanged", "Microsoft.UI") }, - { "System.ComponentModel.PropertyChangedEventArgs", new MappedType("Microsoft.UI.Xaml.Data", "PropertyChangedEventArgs", "Microsoft.UI") }, - { "System.ComponentModel.PropertyChangedEventHandler", new MappedType("Microsoft.UI.Xaml.Data", "PropertyChangedEventHandler", "Microsoft.UI") }, - { "System.Windows.Input.ICommand", new MappedType("Microsoft.UI.Xaml.Input", "ICommand", "Microsoft.UI") }, - { "System.Collections.IEnumerable", new MappedType("Microsoft.UI.Xaml.Interop", "IBindableIterable", "Microsoft.UI") }, - { "System.Collections.IList", new MappedType("Microsoft.UI.Xaml.Interop", "IBindableVector", "Microsoft.UI") }, - { "System.Collections.Specialized.INotifyCollectionChanged", new MappedType("Microsoft.UI.Xaml.Interop", "INotifyCollectionChanged", "Microsoft.UI") }, - { "System.Collections.Specialized.NotifyCollectionChangedAction", new MappedType("Microsoft.UI.Xaml.Interop", "NotifyCollectionChangedAction", "Microsoft.UI") }, - { "System.Collections.Specialized.NotifyCollectionChangedEventArgs", new MappedType("Microsoft.UI.Xaml.Interop", "NotifyCollectionChangedEventArgs", "Microsoft.UI") }, - { "System.Collections.Specialized.NotifyCollectionChangedEventHandler", new MappedType("Microsoft.UI.Xaml.Interop", "NotifyCollectionChangedEventHandler", "Microsoft.UI") }, - { "WinRT.EventRegistrationToken", new MappedType("Windows.Foundation", "EventRegistrationToken", "Windows.Foundation.FoundationContract", true, true) }, - { "System.AttributeTargets", new MappedType("Windows.Foundation.Metadata", "AttributeTargets", "Windows.Foundation.FoundationContract", true, true) }, - { "System.AttributeUsageAttribute", new MappedType("Windows.Foundation.Metadata", "AttributeUsageAttribute", "Windows.Foundation.FoundationContract") }, - { "System.Numerics.Matrix3x2", new MappedType("Windows.Foundation.Numerics", "Matrix3x2", "Windows.Foundation.FoundationContract", true, true) }, - { "System.Numerics.Matrix4x4", new MappedType("Windows.Foundation.Numerics", "Matrix4x4", "Windows.Foundation.FoundationContract", true, true) }, - { "System.Numerics.Plane", new MappedType("Windows.Foundation.Numerics", "Plane", "Windows.Foundation.FoundationContract", true, true) }, - { "System.Numerics.Quaternion", new MappedType("Windows.Foundation.Numerics", "Quaternion", "Windows.Foundation.FoundationContract", true, true) }, - { "System.Numerics.Vector2", new MappedType("Windows.Foundation.Numerics", "Vector2", "Windows.Foundation.FoundationContract", true, true) }, - { "System.Numerics.Vector3", new MappedType("Windows.Foundation.Numerics", "Vector3", "Windows.Foundation.FoundationContract", true, true) }, - { "System.Numerics.Vector4", new MappedType("Windows.Foundation.Numerics", "Vector4", "Windows.Foundation.FoundationContract", true, true) }, - { "System.Type", new MappedType(GetSystemTypeCustomMapping) }, - { "System.Collections.Generic.IEnumerable`1", new MappedType("Windows.Foundation.Collections", "IIterable`1", "Windows.Foundation.FoundationContract") }, - { "System.Collections.Generic.IEnumerator`1", new MappedType("Windows.Foundation.Collections", "IIterator`1", "Windows.Foundation.FoundationContract") }, - { "System.Collections.Generic.KeyValuePair`2", new MappedType("Windows.Foundation.Collections", "IKeyValuePair`2", "Windows.Foundation.FoundationContract") }, - { "System.Collections.Generic.IReadOnlyDictionary`2", new MappedType("Windows.Foundation.Collections", "IMapView`2", "Windows.Foundation.FoundationContract") }, - { "System.Collections.Generic.IDictionary`2", new MappedType("Windows.Foundation.Collections", "IMap`2", "Windows.Foundation.FoundationContract") }, - { "System.Collections.Generic.IReadOnlyList`1", new MappedType("Windows.Foundation.Collections", "IVectorView`1", "Windows.Foundation.FoundationContract") }, - { "System.Collections.Generic.IList`1", new MappedType("Windows.Foundation.Collections", "IVector`1", "Windows.Foundation.FoundationContract") }, - { "Windows.UI.Color", new MappedType("Windows.UI", "Color", "Windows.Foundation.UniversalApiContract", true, true) }, - }; - } -} + } +} diff --git a/src/Authoring/WinRT.SourceGenerator/TypeMapper.cs b/src/Authoring/WinRT.SourceGenerator/TypeMapper.cs new file mode 100644 index 000000000..e35ccc63e --- /dev/null +++ b/src/Authoring/WinRT.SourceGenerator/TypeMapper.cs @@ -0,0 +1,125 @@ +using Microsoft.CodeAnalysis; +using System; +using System.Collections.Generic; +using System.Text; +using static Generator.GeneratorHelper; + +namespace Generator +{ + internal sealed class TypeMapper + { + private readonly Dictionary typeMapping; + + // Based on whether System.Type is used in an attribute declaration or elsewhere, we need to choose the correct custom mapping + // as attributes don't use the TypeName mapping. + private static (string, string, string, bool, bool) GetSystemTypeCustomMapping(ISymbol containingSymbol) + { + bool isDefinedInAttribute = + containingSymbol != null && + string.CompareOrdinal((containingSymbol as INamedTypeSymbol).BaseType?.ToString(), "System.Attribute") == 0; + return isDefinedInAttribute ? + ("System", "Type", "mscorlib", true, false) : + ("Windows.UI.Xaml.Interop", "TypeName", "Windows.Foundation.UniversalApiContract", false, true); + } + + public TypeMapper(UiXamlMode xamlMode) + { + // This should be in sync with the reverse mapping from WinRT.Runtime/Projections.cs and cswinrt/helpers.h. + if (xamlMode == UiXamlMode.WindowsUiXaml) + { + typeMapping = new(StringComparer.Ordinal) + { + { "System.DateTimeOffset", new MappedType("Windows.Foundation", "DateTime", "Windows.Foundation.FoundationContract", true, false) }, + { "System.Exception", new MappedType("Windows.Foundation", "HResult", "Windows.Foundation.FoundationContract", true, false) }, + { "System.EventHandler`1", new MappedType("Windows.Foundation", "EventHandler`1", "Windows.Foundation.FoundationContract") }, + { "System.FlagsAttribute", new MappedType("System", "FlagsAttribute", "mscorlib" ) }, + { "System.IDisposable", new MappedType("Windows.Foundation", "IClosable", "Windows.Foundation.FoundationContract") }, + { "System.Nullable`1", new MappedType("Windows.Foundation", "IReference`1", "Windows.Foundation.FoundationContract" ) }, + { "System.Object", new MappedType("System", "Object", "mscorlib" ) }, + { "System.TimeSpan", new MappedType("Windows.Foundation", "TimeSpan", "Windows.Foundation.FoundationContract", true, false) }, + { "System.Uri", new MappedType("Windows.Foundation", "Uri", "Windows.Foundation.FoundationContract") }, + { "System.ComponentModel.INotifyPropertyChanged", new MappedType("Windows.UI.Xaml.Data", "INotifyPropertyChanged", "Windows.UI.Xaml") }, + { "System.ComponentModel.PropertyChangedEventArgs", new MappedType("Windows.UI.Xaml.Data", "PropertyChangedEventArgs", "Windows.UI.Xaml") }, + { "System.ComponentModel.PropertyChangedEventHandler", new MappedType("Windows.UI.Xaml.Data", "PropertyChangedEventHandler", "Windows.UI.Xaml") }, + { "System.Windows.Input.ICommand", new MappedType("Windows.UI.Xaml.Input", "ICommand", "Windows.UI.Xaml") }, + { "System.Collections.IEnumerable", new MappedType("Windows.UI.Xaml.Interop", "IBindableIterable", "Windows.UI.Xaml") }, + { "System.Collections.IList", new MappedType("Windows.UI.Xaml.Interop", "IBindableVector", "Windows.UI.Xaml") }, + { "System.Collections.Specialized.INotifyCollectionChanged", new MappedType("Windows.UI.Xaml.Interop", "INotifyCollectionChanged", "Windows.UI.Xaml") }, + { "System.Collections.Specialized.NotifyCollectionChangedAction", new MappedType("Windows.UI.Xaml.Interop", "NotifyCollectionChangedAction", "Windows.UI.Xaml") }, + { "System.Collections.Specialized.NotifyCollectionChangedEventArgs", new MappedType("Windows.UI.Xaml.Interop", "NotifyCollectionChangedEventArgs", "Windows.UI.Xaml") }, + { "System.Collections.Specialized.NotifyCollectionChangedEventHandler", new MappedType("Windows.UI.Xaml.Interop", "NotifyCollectionChangedEventHandler", "Windows.UI.Xaml") }, + { "WinRT.EventRegistrationToken", new MappedType("Windows.Foundation", "EventRegistrationToken", "Windows.Foundation.FoundationContract", true, true) }, + { "System.AttributeTargets", new MappedType("Windows.Foundation.Metadata", "AttributeTargets", "Windows.Foundation.FoundationContract", true, true) }, + { "System.AttributeUsageAttribute", new MappedType("Windows.Foundation.Metadata", "AttributeUsageAttribute", "Windows.Foundation.FoundationContract") }, + { "System.Numerics.Matrix3x2", new MappedType("Windows.Foundation.Numerics", "Matrix3x2", "Windows.Foundation.FoundationContract", true, true) }, + { "System.Numerics.Matrix4x4", new MappedType("Windows.Foundation.Numerics", "Matrix4x4", "Windows.Foundation.FoundationContract", true, true) }, + { "System.Numerics.Plane", new MappedType("Windows.Foundation.Numerics", "Plane", "Windows.Foundation.FoundationContract", true, true) }, + { "System.Numerics.Quaternion", new MappedType("Windows.Foundation.Numerics", "Quaternion", "Windows.Foundation.FoundationContract", true, true) }, + { "System.Numerics.Vector2", new MappedType("Windows.Foundation.Numerics", "Vector2", "Windows.Foundation.FoundationContract", true, true) }, + { "System.Numerics.Vector3", new MappedType("Windows.Foundation.Numerics", "Vector3", "Windows.Foundation.FoundationContract", true, true) }, + { "System.Numerics.Vector4", new MappedType("Windows.Foundation.Numerics", "Vector4", "Windows.Foundation.FoundationContract", true, true) }, + { "System.Type", new MappedType(GetSystemTypeCustomMapping) }, + { "System.Collections.Generic.IEnumerable`1", new MappedType("Windows.Foundation.Collections", "IIterable`1", "Windows.Foundation.FoundationContract") }, + { "System.Collections.Generic.IEnumerator`1", new MappedType("Windows.Foundation.Collections", "IIterator`1", "Windows.Foundation.FoundationContract") }, + { "System.Collections.Generic.KeyValuePair`2", new MappedType("Windows.Foundation.Collections", "IKeyValuePair`2", "Windows.Foundation.FoundationContract") }, + { "System.Collections.Generic.IReadOnlyDictionary`2", new MappedType("Windows.Foundation.Collections", "IMapView`2", "Windows.Foundation.FoundationContract") }, + { "System.Collections.Generic.IDictionary`2", new MappedType("Windows.Foundation.Collections", "IMap`2", "Windows.Foundation.FoundationContract") }, + { "System.Collections.Generic.IReadOnlyList`1", new MappedType("Windows.Foundation.Collections", "IVectorView`1", "Windows.Foundation.FoundationContract") }, + { "System.Collections.Generic.IList`1", new MappedType("Windows.Foundation.Collections", "IVector`1", "Windows.Foundation.FoundationContract") }, + { "Windows.UI.Color", new MappedType("Windows.UI", "Color", "Windows.Foundation.UniversalApiContract", true, true) }, + }; + } + else + { + typeMapping = new(StringComparer.Ordinal) + { + { "System.DateTimeOffset", new MappedType("Windows.Foundation", "DateTime", "Windows.Foundation.FoundationContract", true, false) }, + { "System.Exception", new MappedType("Windows.Foundation", "HResult", "Windows.Foundation.FoundationContract", true, false) }, + { "System.EventHandler`1", new MappedType("Windows.Foundation", "EventHandler`1", "Windows.Foundation.FoundationContract") }, + { "System.FlagsAttribute", new MappedType("System", "FlagsAttribute", "mscorlib" ) }, + { "System.IDisposable", new MappedType("Windows.Foundation", "IClosable", "Windows.Foundation.FoundationContract") }, + { "System.IServiceProvider", new MappedType("Microsoft.UI.Xaml", "IXamlServiceProvider", "Microsoft.UI") }, + { "System.Nullable`1", new MappedType("Windows.Foundation", "IReference`1", "Windows.Foundation.FoundationContract" ) }, + { "System.Object", new MappedType("System", "Object", "mscorlib" ) }, + { "System.TimeSpan", new MappedType("Windows.Foundation", "TimeSpan", "Windows.Foundation.FoundationContract", true, false) }, + { "System.Uri", new MappedType("Windows.Foundation", "Uri", "Windows.Foundation.FoundationContract") }, + { "System.ComponentModel.DataErrorsChangedEventArgs", new MappedType("Microsoft.UI.Xaml.Data", "DataErrorsChangedEventArgs", "Microsoft.UI") }, + { "System.ComponentModel.INotifyDataErrorInfo", new MappedType("Microsoft.UI.Xaml.Data", "INotifyDataErrorInfo", "Microsoft.UI") }, + { "System.ComponentModel.INotifyPropertyChanged", new MappedType("Microsoft.UI.Xaml.Data", "INotifyPropertyChanged", "Microsoft.UI") }, + { "System.ComponentModel.PropertyChangedEventArgs", new MappedType("Microsoft.UI.Xaml.Data", "PropertyChangedEventArgs", "Microsoft.UI") }, + { "System.ComponentModel.PropertyChangedEventHandler", new MappedType("Microsoft.UI.Xaml.Data", "PropertyChangedEventHandler", "Microsoft.UI") }, + { "System.Windows.Input.ICommand", new MappedType("Microsoft.UI.Xaml.Input", "ICommand", "Microsoft.UI") }, + { "System.Collections.IEnumerable", new MappedType("Microsoft.UI.Xaml.Interop", "IBindableIterable", "Microsoft.UI") }, + { "System.Collections.IList", new MappedType("Microsoft.UI.Xaml.Interop", "IBindableVector", "Microsoft.UI") }, + { "System.Collections.Specialized.INotifyCollectionChanged", new MappedType("Microsoft.UI.Xaml.Interop", "INotifyCollectionChanged", "Microsoft.UI") }, + { "System.Collections.Specialized.NotifyCollectionChangedAction", new MappedType("Microsoft.UI.Xaml.Interop", "NotifyCollectionChangedAction", "Microsoft.UI") }, + { "System.Collections.Specialized.NotifyCollectionChangedEventArgs", new MappedType("Microsoft.UI.Xaml.Interop", "NotifyCollectionChangedEventArgs", "Microsoft.UI") }, + { "System.Collections.Specialized.NotifyCollectionChangedEventHandler", new MappedType("Microsoft.UI.Xaml.Interop", "NotifyCollectionChangedEventHandler", "Microsoft.UI") }, + { "WinRT.EventRegistrationToken", new MappedType("Windows.Foundation", "EventRegistrationToken", "Windows.Foundation.FoundationContract", true, true) }, + { "System.AttributeTargets", new MappedType("Windows.Foundation.Metadata", "AttributeTargets", "Windows.Foundation.FoundationContract", true, true) }, + { "System.AttributeUsageAttribute", new MappedType("Windows.Foundation.Metadata", "AttributeUsageAttribute", "Windows.Foundation.FoundationContract") }, + { "System.Numerics.Matrix3x2", new MappedType("Windows.Foundation.Numerics", "Matrix3x2", "Windows.Foundation.FoundationContract", true, true) }, + { "System.Numerics.Matrix4x4", new MappedType("Windows.Foundation.Numerics", "Matrix4x4", "Windows.Foundation.FoundationContract", true, true) }, + { "System.Numerics.Plane", new MappedType("Windows.Foundation.Numerics", "Plane", "Windows.Foundation.FoundationContract", true, true) }, + { "System.Numerics.Quaternion", new MappedType("Windows.Foundation.Numerics", "Quaternion", "Windows.Foundation.FoundationContract", true, true) }, + { "System.Numerics.Vector2", new MappedType("Windows.Foundation.Numerics", "Vector2", "Windows.Foundation.FoundationContract", true, true) }, + { "System.Numerics.Vector3", new MappedType("Windows.Foundation.Numerics", "Vector3", "Windows.Foundation.FoundationContract", true, true) }, + { "System.Numerics.Vector4", new MappedType("Windows.Foundation.Numerics", "Vector4", "Windows.Foundation.FoundationContract", true, true) }, + { "System.Type", new MappedType(GetSystemTypeCustomMapping) }, + { "System.Collections.Generic.IEnumerable`1", new MappedType("Windows.Foundation.Collections", "IIterable`1", "Windows.Foundation.FoundationContract") }, + { "System.Collections.Generic.IEnumerator`1", new MappedType("Windows.Foundation.Collections", "IIterator`1", "Windows.Foundation.FoundationContract") }, + { "System.Collections.Generic.KeyValuePair`2", new MappedType("Windows.Foundation.Collections", "IKeyValuePair`2", "Windows.Foundation.FoundationContract") }, + { "System.Collections.Generic.IReadOnlyDictionary`2", new MappedType("Windows.Foundation.Collections", "IMapView`2", "Windows.Foundation.FoundationContract") }, + { "System.Collections.Generic.IDictionary`2", new MappedType("Windows.Foundation.Collections", "IMap`2", "Windows.Foundation.FoundationContract") }, + { "System.Collections.Generic.IReadOnlyList`1", new MappedType("Windows.Foundation.Collections", "IVectorView`1", "Windows.Foundation.FoundationContract") }, + { "System.Collections.Generic.IList`1", new MappedType("Windows.Foundation.Collections", "IVector`1", "Windows.Foundation.FoundationContract") }, + { "Windows.UI.Color", new MappedType("Windows.UI", "Color", "Windows.Foundation.UniversalApiContract", true, true) }, + }; + } + } + + public bool HasMappingForType(string typeName) => typeMapping.ContainsKey(typeName); + + public MappedType GetMappedType(string typeName) => typeMapping[typeName]; + } +} diff --git a/src/Authoring/WinRT.SourceGenerator/UiXamlMode.cs b/src/Authoring/WinRT.SourceGenerator/UiXamlMode.cs new file mode 100644 index 000000000..7432a1075 --- /dev/null +++ b/src/Authoring/WinRT.SourceGenerator/UiXamlMode.cs @@ -0,0 +1,26 @@ +using Microsoft.CodeAnalysis.Diagnostics; +using System; +using System.Collections.Generic; +using System.Text; + +namespace Generator +{ + internal enum UiXamlMode + { + MicrosoftUiXaml, + WindowsUiXaml, + } + + internal static class OptionsHelper + { + public static UiXamlMode GetUiXamlMode(this AnalyzerConfigOptions options) + { + if (options.TryGetValue("build_property.CsWinRTUiXamlMode", out var value) && Enum.TryParse(value, out UiXamlMode mode)) + { + return mode; + } + + return UiXamlMode.MicrosoftUiXaml; + } + } +} diff --git a/src/Authoring/WinRT.SourceGenerator/WinRTTypeWriter.cs b/src/Authoring/WinRT.SourceGenerator/WinRTTypeWriter.cs index 9e33c92c6..d2ef2cc11 100644 --- a/src/Authoring/WinRT.SourceGenerator/WinRTTypeWriter.cs +++ b/src/Authoring/WinRT.SourceGenerator/WinRTTypeWriter.cs @@ -265,7 +265,7 @@ class WinRTTypeWriter : CSharpSyntaxWalker private readonly Dictionary typeReferenceMapping; private readonly Dictionary assemblyReferenceMapping; private readonly MetadataBuilder metadataBuilder; - + private readonly TypeMapper mapper; private readonly Dictionary typeDefinitionMapping; private TypeDeclaration currentTypeDeclaration; @@ -275,12 +275,14 @@ public WinRTTypeWriter( string assembly, string version, MetadataBuilder metadataBuilder, - Logger logger) + Logger logger, + TypeMapper mapper) { this.assembly = assembly; this.version = version; this.metadataBuilder = metadataBuilder; Logger = logger; + this.mapper = mapper; typeReferenceMapping = new Dictionary(StringComparer.Ordinal); assemblyReferenceMapping = new Dictionary(StringComparer.Ordinal); typeDefinitionMapping = new Dictionary(StringComparer.Ordinal); @@ -435,9 +437,9 @@ private EntityHandle GetTypeReference(ISymbol symbol) var assembly = GetAssemblyForWinRTType(symbol); if (assembly == null) { - if (GeneratorHelper.MappedCSharpTypes.ContainsKey(fullType)) + if (mapper.HasMappingForType(fullType)) { - (@namespace, name, assembly, _, _) = GeneratorHelper.MappedCSharpTypes[fullType].GetMapping(currentTypeDeclaration.Node); + (@namespace, name, assembly, _, _) = mapper.GetMappedType(fullType).GetMapping(currentTypeDeclaration.Node); Logger.Log("custom mapping " + fullType + " to " + QualifiedName(@namespace, name) + " from " + assembly); } else @@ -520,9 +522,9 @@ private void EncodeSymbol(Symbol symbol, SignatureTypeEncoder typeEncoder) else { bool isValueType = symbol.Type.TypeKind == TypeKind.Enum || symbol.Type.TypeKind == TypeKind.Struct; - if (GeneratorHelper.MappedCSharpTypes.ContainsKey(QualifiedName(symbol.Type))) + if (mapper.HasMappingForType(QualifiedName(symbol.Type))) { - (_, _, _, _, isValueType) = GeneratorHelper.MappedCSharpTypes[QualifiedName(symbol.Type)].GetMapping(currentTypeDeclaration.Node); + (_, _, _, _, isValueType) = mapper.GetMappedType(QualifiedName(symbol.Type)).GetMapping(currentTypeDeclaration.Node); } typeEncoder.Type(GetTypeReference(symbol.Type), isValueType); } @@ -804,7 +806,7 @@ private void ProcessCustomMappedInterfaces(INamedTypeSymbol classSymbol) // Mark custom mapped interface members for removal later. // Note we want to also mark members from interfaces without mappings. foreach (var implementedInterface in GetInterfaces(classSymbol, true). - Where(symbol => GeneratorHelper.MappedCSharpTypes.ContainsKey(QualifiedName(symbol)) || + Where(symbol => mapper.HasMappingForType(QualifiedName(symbol)) || ImplementedInterfacesWithoutMapping.Contains(QualifiedName(symbol)))) { bool isPubliclyImplemented = false; @@ -825,7 +827,7 @@ private void ProcessCustomMappedInterfaces(INamedTypeSymbol classSymbol) } foreach (var implementedInterface in GetInterfaces(classSymbol) - .Where(symbol => GeneratorHelper.MappedCSharpTypes.ContainsKey(QualifiedName(symbol)))) + .Where(symbol => mapper.HasMappingForType(QualifiedName(symbol)))) { WriteCustomMappedTypeMembers(implementedInterface, true, isPublicImplementation[implementedInterface]); } @@ -853,9 +855,9 @@ INamedTypeSymbol GetTypeByMetadataName(string metadataName) private string GetMappedQualifiedTypeName(ITypeSymbol symbol) { string qualifiedName = QualifiedName(symbol); - if (GeneratorHelper.MappedCSharpTypes.ContainsKey(qualifiedName)) + if (mapper.HasMappingForType(qualifiedName)) { - var (@namespace, mappedTypeName, _, _, _) = GeneratorHelper.MappedCSharpTypes[qualifiedName].GetMapping(currentTypeDeclaration.Node); + var (@namespace, mappedTypeName, _, _, _) = mapper.GetMappedType(qualifiedName).GetMapping(currentTypeDeclaration.Node); qualifiedName = QualifiedName(@namespace, mappedTypeName); if (symbol is INamedTypeSymbol namedType && namedType.TypeArguments.Length > 0) { @@ -874,7 +876,7 @@ private string GetMappedQualifiedTypeName(ITypeSymbol symbol) private void WriteCustomMappedTypeMembers(INamedTypeSymbol symbol, bool isDefinition, bool isPublic = true) { - var (_, mappedTypeName, _, _, _) = GeneratorHelper.MappedCSharpTypes[QualifiedName(symbol)].GetMapping(currentTypeDeclaration.Node); + var (_, mappedTypeName, _, _, _) = mapper.GetMappedType(QualifiedName(symbol)).GetMapping(currentTypeDeclaration.Node); string qualifiedName = GetMappedQualifiedTypeName(symbol); Logger.Log("writing custom mapped type members for " + mappedTypeName + " public: " + isPublic + " qualified name: " + qualifiedName); @@ -1233,7 +1235,7 @@ void GatherPubliclyAccessibleInterfaces(ITypeSymbol symbol) GatherPubliclyAccessibleInterfaces(symbol); var baseType = symbol.BaseType; - while (baseType != null && !GeneratorHelper.IsWinRTType(baseType)) + while (baseType != null && !GeneratorHelper.IsWinRTType(baseType, mapper)) { GatherPubliclyAccessibleInterfaces(baseType); @@ -2438,9 +2440,9 @@ void AddType(INamedTypeSymbol type, bool treatAsProjectedType = false) { AddProjectedType(type); } - else if (GeneratorHelper.MappedCSharpTypes.ContainsKey(qualifiedName)) + else if (mapper.HasMappingForType(qualifiedName)) { - var (@namespace, name, assembly, isSystemType, _) = GeneratorHelper.MappedCSharpTypes[qualifiedName].GetMapping(); + var (@namespace, name, assembly, isSystemType, _) = mapper.GetMappedType(qualifiedName).GetMapping(); if (isSystemType) { var projectedType = Model.Compilation.GetTypeByMetadataName(QualifiedName(@namespace, name)); @@ -2532,7 +2534,7 @@ public void FinalizeGeneration() Logger.Log("finalizing interface " + implementedInterfaceQualifiedNameWithGenerics); var interfaceTypeDeclaration = typeDefinitionMapping[implementedInterfaceQualifiedNameWithGenerics]; - if (GeneratorHelper.MappedCSharpTypes.ContainsKey(QualifiedName(implementedInterface))) + if (mapper.HasMappingForType(QualifiedName(implementedInterface))) { Logger.Log("adding MethodImpls for custom mapped interface"); foreach (var interfaceMember in interfaceTypeDeclaration.MethodReferences) @@ -2663,11 +2665,11 @@ public void FinalizeGeneration() public void GenerateWinRTExposedClassAttributes(GeneratorExecutionContext context) { - bool IsWinRTType(ISymbol symbol) + bool IsWinRTType(ISymbol symbol, TypeMapper mapper) { if (!SymbolEqualityComparer.Default.Equals(symbol.ContainingAssembly, context.Compilation.Assembly)) { - return GeneratorHelper.IsWinRTType(symbol, IsWinRTType); + return GeneratorHelper.IsWinRTType(symbol, mapper, symbol => IsWinRTType(symbol, mapper)); } if (symbol is INamedTypeSymbol namedType) @@ -2701,8 +2703,8 @@ typeDeclaration.Node is INamedTypeSymbol symbol && symbol.TypeKind == TypeKind.Class && !symbol.IsStatic) { - vtableAttributesToAdd.Add(WinRTAotSourceGenerator.GetVtableAttributeToAdd(symbol, IsWinRTType, context.Compilation.Assembly, true, typeDeclaration.DefaultInterface)); - WinRTAotSourceGenerator.AddVtableAdapterTypeForKnownInterface(symbol, context.Compilation, IsWinRTType, vtableAttributesToAddOnLookupTable); + vtableAttributesToAdd.Add(WinRTAotSourceGenerator.GetVtableAttributeToAdd(symbol, IsWinRTType, mapper, context.Compilation.Assembly, true, typeDeclaration.DefaultInterface)); + WinRTAotSourceGenerator.AddVtableAdapterTypeForKnownInterface(symbol, context.Compilation, IsWinRTType, mapper, vtableAttributesToAddOnLookupTable); } } diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 5a1370dc5..caef79a59 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -30,6 +30,8 @@ netcoreapp3.1;net6.0;net8.0 netstandard2.0;net6.0;net8.0 netstandard2.0;net6.0;net8.0 + net6.0;net8.0 + net6.0;net8.0 net6.0-windows10.0.19041.0;net7.0-windows10.0.19041.0 net6.0-windows10.0.19041.0 net6.0;net8.0 diff --git a/src/Perf/IIDOptimizer/GuidPatcher.cs b/src/Perf/IIDOptimizer/GuidPatcher.cs index bd200dfd6..411b855fa 100644 --- a/src/Perf/IIDOptimizer/GuidPatcher.cs +++ b/src/Perf/IIDOptimizer/GuidPatcher.cs @@ -72,12 +72,14 @@ public GuidPatcher(AssemblyDefinition winRTRuntime, AssemblyDefinition targetAss guidGeneratorType = null; TypeDefinition? typeExtensionsType = null; + TypeDefinition? wuxMuxProjectedInterfaceAttributeType = null; // Use the type definition if we are patching WinRT.Runtime, otherwise lookup the types as references if (string.CompareOrdinal(assembly.Name.Name, "WinRT.Runtime") == 0) { - guidGeneratorType = winRTRuntimeAssembly.MainModule.Types.Where(typeDef => string.CompareOrdinal(typeDef.Name, "GuidGenerator") == 0).First(); - typeExtensionsType = winRTRuntimeAssembly.MainModule.Types.Where(typeDef => string.CompareOrdinal(typeDef.Name, "TypeExtensions") == 0).First(); + guidGeneratorType = winRTRuntimeAssembly.MainModule.Types.Where(typeDef => string.Equals(typeDef.Name, "GuidGenerator", StringComparison.Ordinal)).First(); + typeExtensionsType = winRTRuntimeAssembly.MainModule.Types.Where(typeDef => string.Equals(typeDef.Name, "TypeExtensions", StringComparison.Ordinal)).First(); + wuxMuxProjectedInterfaceAttributeType = winRTRuntimeAssembly.MainModule.Types.Where(typedef => string.Equals(typedef.Name, "WuxMuxProjectedInterfaceAttribute", StringComparison.Ordinal)).First(); } foreach (var asm in assembly.MainModule.AssemblyReferences) @@ -87,6 +89,7 @@ public GuidPatcher(AssemblyDefinition winRTRuntime, AssemblyDefinition targetAss guidGeneratorType = new TypeReference("WinRT", "GuidGenerator", assembly.MainModule, asm).Resolve(); typeExtensionsType = new TypeReference("WinRT", "TypeExtensions", assembly.MainModule, asm).Resolve(); + wuxMuxProjectedInterfaceAttributeType = new TypeReference("WinRT", "WuxMuxProjectedInterfaceAttribute", assembly.MainModule, asm).Resolve(); } else if (string.CompareOrdinal(asm.Name, "System.Runtime.InteropServices") == 0) { @@ -101,7 +104,7 @@ public GuidPatcher(AssemblyDefinition winRTRuntime, AssemblyDefinition targetAss getHelperTypeMethod = typeExtensionsType.Methods.First(m => String.CompareOrdinal(m.Name, "GetHelperType") == 0); } - signatureGenerator = new SignatureGenerator(assembly, guidAttributeType!, winRTRuntimeAssembly); + signatureGenerator = new SignatureGenerator(assembly, guidAttributeType!, wuxMuxProjectedInterfaceAttributeType!, winRTRuntimeAssembly); methodCache = new Dictionary(); } @@ -262,6 +265,11 @@ private void VisitSignature(SignaturePart rootSignaturePart, SignatureEmitter em emitter.PushCustomSignature(custom.Method); } break; + case GenericFallback fallback: + { + emitter.PushFallback(fallback.Type); + } + break; default: break; } diff --git a/src/Perf/IIDOptimizer/SignatureEmitter.cs b/src/Perf/IIDOptimizer/SignatureEmitter.cs index aa3d6a393..3483105d8 100644 --- a/src/Perf/IIDOptimizer/SignatureEmitter.cs +++ b/src/Perf/IIDOptimizer/SignatureEmitter.cs @@ -35,6 +35,8 @@ sealed record RuntimeGenericSignatureStep(GenericParameter OriginalTypeParameter sealed record RuntimeCustomSignatureStep(MethodReference method) : SignatureStep; + sealed record FallbackSignatureStep(TypeReference type) : SignatureStep; + public SignatureEmitter(TypeReference describedType, MethodDefinition guidDataGetterMethod) { this.describedType = describedType; @@ -76,6 +78,16 @@ public void PushCustomSignature(MethodReference customSignatureMethod) signatureSteps.Add(new RuntimeCustomSignatureStep(customSignatureMethod)); } + public void PushFallback(TypeReference type) + { + if (currentStringBuilder is not null) + { + signatureSteps.Add(new StringStep(currentStringBuilder.ToString())); + currentStringBuilder = null; + } + signatureSteps.Add(new FallbackSignatureStep(type)); + } + public void EmitGuidGetter( TypeDefinition guidDataBlockType, TypeDefinition implementationDetailsType, @@ -289,6 +301,25 @@ private void GenerateGuidFactoryFromComplexSignature(TypeDefinition implementati il.Emit(OpCodes.Stloc, fullSignatureLength); } break; + case FallbackSignatureStep(TypeReference type): + { + // byte[] bytes = Encoding.UTF8.GetBytes(GetSignature(typeof(type))) + il.Emit(OpCodes.Call, utf8EncodingGetter); + il.Emit(OpCodes.Ldtoken, type); + il.Emit(OpCodes.Call, getTypeFromHandleMethod); + il.Emit(OpCodes.Call, getSignatureMethod); + il.Emit(OpCodes.Callvirt, encodingGetBytes); + il.Emit(OpCodes.Dup); + // = new ReadOnlySpan(bytes); + il.Emit(OpCodes.Newobj, readOnlySpanOfByteArrayCtor); + il.Emit(OpCodes.Stloc, signatureParts[i]); + // signatureLength += bytes.Length + il.Emit(OpCodes.Ldlen); + il.Emit(OpCodes.Ldloc, fullSignatureLength); + il.Emit(OpCodes.Add_Ovf); + il.Emit(OpCodes.Stloc, fullSignatureLength); + } + break; default: il.Clear(); throw new InvalidOperationException(); diff --git a/src/Perf/IIDOptimizer/SignatureGenerator.cs b/src/Perf/IIDOptimizer/SignatureGenerator.cs index 7c6fd6282..67b2c2be3 100644 --- a/src/Perf/IIDOptimizer/SignatureGenerator.cs +++ b/src/Perf/IIDOptimizer/SignatureGenerator.cs @@ -37,6 +37,8 @@ sealed record NonGenericDelegateSignature(Guid DelegateIID) : SignaturePart; sealed record UninstantiatedGeneric(GenericParameter OriginalGenericParameter) : SignaturePart; + sealed record GenericFallback(TypeReference Type) : SignaturePart; + abstract record SignatureWithChildren(string GroupingName, string ThisEntitySignature, IEnumerable ChildrenSignatures) : SignaturePart; sealed record GenericSignature(Guid BaseGuid, IEnumerable GenericMemberSignatures) : @@ -55,12 +57,14 @@ sealed class SignatureGenerator { private readonly AssemblyDefinition assembly; private readonly TypeDefinition guidAttributeType; + private readonly TypeDefinition wuxMuxProjectedInterfaceAttributeType; private readonly AssemblyDefinition winRTRuntimeAssembly; - public SignatureGenerator(AssemblyDefinition assembly, TypeDefinition guidAttributeType, AssemblyDefinition runtimeAssembly) + public SignatureGenerator(AssemblyDefinition assembly, TypeDefinition guidAttributeType, TypeDefinition wuxMuxProjectedInterfaceAttributeType, AssemblyDefinition runtimeAssembly) { this.assembly = assembly; this.guidAttributeType = guidAttributeType; + this.wuxMuxProjectedInterfaceAttributeType = wuxMuxProjectedInterfaceAttributeType; this.winRTRuntimeAssembly = runtimeAssembly; } @@ -170,6 +174,13 @@ public SignaturePart GetSignatureParts(TypeReference type) return new RuntimeClassSignature(type, GetSignatureParts(iface)); } + // For types projected from WUX or MUX into .NET, we'll need to do a runtime lookup for the IID. + // TODO-WuxMux: We can instead take an option in the IID optimizer to hard-code the lookup for WUX or MUX when specified, which would be more efficient for scenarios where this is possible. + if (helperType?.Resolve().CustomAttributes.Any(attr => attr.AttributeType.Resolve() == wuxMuxProjectedInterfaceAttributeType) == true) + { + return new GenericFallback(type); + } + Guid? guidAttributeValue = type.ReadGuidFromAttribute(guidAttributeType, winRTRuntimeAssembly); if (guidAttributeValue == null) { diff --git a/src/Projections/Windows.UI.Xaml/Module.cs b/src/Projections/Windows.UI.Xaml/Module.cs new file mode 100644 index 000000000..636144eed --- /dev/null +++ b/src/Projections/Windows.UI.Xaml/Module.cs @@ -0,0 +1,3 @@ +#if NET +[assembly: global::System.Runtime.Versioning.SupportedOSPlatform("Windows")] +#endif diff --git a/src/Projections/Windows.UI.Xaml/Windows.UI.Xaml.csproj b/src/Projections/Windows.UI.Xaml/Windows.UI.Xaml.csproj new file mode 100644 index 000000000..d28f78380 --- /dev/null +++ b/src/Projections/Windows.UI.Xaml/Windows.UI.Xaml.csproj @@ -0,0 +1,28 @@ + + + + $(LibBuildTFMsNoNetStandard) + x64;x86 + Microsoft.Windows.UI.Xaml + true + + + + + + + + + + + + +-exclude Windows +-include Windows.UI.Xaml +-exclude Windows.UI.Xaml.Media.Animation.ConditionallyIndependentlyAnimatableAttribute +-exclude Windows.UI.Xaml.Media.Animation.KeyTime +-exclude Windows.UI.Xaml.Media.Animation.RepeatBehavior + + + + \ No newline at end of file diff --git a/src/Tests/AuthoringWuxConsumptionTest/AuthoringWuxConsumptionTest.exe.manifest b/src/Tests/AuthoringWuxConsumptionTest/AuthoringWuxConsumptionTest.exe.manifest new file mode 100644 index 000000000..3d69fa84a --- /dev/null +++ b/src/Tests/AuthoringWuxConsumptionTest/AuthoringWuxConsumptionTest.exe.manifest @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Tests/AuthoringWuxConsumptionTest/AuthoringWuxConsumptionTest.vcxproj b/src/Tests/AuthoringWuxConsumptionTest/AuthoringWuxConsumptionTest.vcxproj new file mode 100644 index 000000000..64c641b2f --- /dev/null +++ b/src/Tests/AuthoringWuxConsumptionTest/AuthoringWuxConsumptionTest.vcxproj @@ -0,0 +1,212 @@ + + + + + + + Debug + ARM64 + + + Debug + Win32 + + + Release + ARM64 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + {A04A0416-5E35-4DD0-8226-63D941B28467} + Win32Proj + AuthoringConsumptionTest + Application + v143 + v142 + Unicode + <_WinMDPlatform>$(Platform) + <_WinMDPlatform Condition="'$(Platform)' == 'Win32'">x86 + false + + + + + + + + + + + + + + Create + + + + + + + + true + true + true + true + + + + + {ffa9a78b-f53f-43ee-af87-24a80f4c330a} + TargetFramework=net6.0 + + + {0bb8f82d-874e-45aa-bca3-20ce0562164a} + TargetFramework=net6.0 + + + {7e33bcb7-19c5-4061-981d-ba695322708a} + + + {25244ced-966e-45f2-9711-1f51e951ff89} + TargetFramework=net6.0 + + + {d60cfcad-4a13-4047-91c8-9d7df4753493} + TargetFramework=net6.0 + + + + + ..\AuthoringWuxTest\bin\$(_WinMDPlatform)\$(Configuration)\net6.0\AuthoringWuxTest.winmd + true + + + + + + + + + + + + + + + Use + pch.h + Disabled + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + Level3 + + + true + Console + + + + + Use + pch.h + Disabled + X64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + Level3 + + + DebugFull + Console + + + + + Use + pch.h + Disabled + X64;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + Level3 + + + DebugFull + Console + + + + + Use + pch.h + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + MultiThreadedDLL + Level3 + ProgramDatabase + + + true + Console + true + true + + + + + Use + pch.h + X64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + MultiThreadedDLL + Level3 + ProgramDatabase + + + true + Console + true + true + + + + + Use + pch.h + X64;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + MultiThreadedDLL + Level3 + ProgramDatabase + + + true + Console + true + true + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + + + + + + \ No newline at end of file diff --git a/src/Tests/AuthoringWuxConsumptionTest/AuthoringWuxConsumptionTest.vcxproj.filters b/src/Tests/AuthoringWuxConsumptionTest/AuthoringWuxConsumptionTest.vcxproj.filters new file mode 100644 index 000000000..1332cff35 --- /dev/null +++ b/src/Tests/AuthoringWuxConsumptionTest/AuthoringWuxConsumptionTest.vcxproj.filters @@ -0,0 +1,39 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Header Files + + + + + Source Files + + + Source Files + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Tests/AuthoringWuxConsumptionTest/Directory.Build.targets b/src/Tests/AuthoringWuxConsumptionTest/Directory.Build.targets new file mode 100644 index 000000000..623267b30 --- /dev/null +++ b/src/Tests/AuthoringWuxConsumptionTest/Directory.Build.targets @@ -0,0 +1,16 @@ + + + + $(MSBuildProjectDirectory)/DoNotImport_MsAppxPackageTargets.targets + CopyTestAssets;$(PrepareForRunDependsOn) + + + + + + + + + diff --git a/src/Tests/AuthoringWuxConsumptionTest/DoNotImport_MsAppxPackageTargets.targets b/src/Tests/AuthoringWuxConsumptionTest/DoNotImport_MsAppxPackageTargets.targets new file mode 100644 index 000000000..bcb335b80 --- /dev/null +++ b/src/Tests/AuthoringWuxConsumptionTest/DoNotImport_MsAppxPackageTargets.targets @@ -0,0 +1,5 @@ + + + + + diff --git a/src/Tests/AuthoringWuxConsumptionTest/WinRT.Host.runtimeconfig.json b/src/Tests/AuthoringWuxConsumptionTest/WinRT.Host.runtimeconfig.json new file mode 100644 index 000000000..89437eff9 --- /dev/null +++ b/src/Tests/AuthoringWuxConsumptionTest/WinRT.Host.runtimeconfig.json @@ -0,0 +1,13 @@ +{ + "runtimeOptions": { + "tfm": "net6.0", + "rollForward": "LatestMinor", + "framework": { + "name": "Microsoft.NETCore.App", + "version": "6.0.0" + }, + "configProperties": { + "CsWinRT.UiXamlMode": "WindowsUiXaml" + } + } +} \ No newline at end of file diff --git a/src/Tests/AuthoringWuxConsumptionTest/packages.config b/src/Tests/AuthoringWuxConsumptionTest/packages.config new file mode 100644 index 000000000..98b40a750 --- /dev/null +++ b/src/Tests/AuthoringWuxConsumptionTest/packages.config @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/src/Tests/AuthoringWuxConsumptionTest/pch.cpp b/src/Tests/AuthoringWuxConsumptionTest/pch.cpp new file mode 100644 index 000000000..bcb5590be --- /dev/null +++ b/src/Tests/AuthoringWuxConsumptionTest/pch.cpp @@ -0,0 +1 @@ +#include "pch.h" diff --git a/src/Tests/AuthoringWuxConsumptionTest/pch.h b/src/Tests/AuthoringWuxConsumptionTest/pch.h new file mode 100644 index 000000000..db3c5d270 --- /dev/null +++ b/src/Tests/AuthoringWuxConsumptionTest/pch.h @@ -0,0 +1,26 @@ +#pragma once + +// Undefine GetCurrentTime macro to prevent +// conflict with Storyboard::GetCurrentTime +#undef GetCurrentTime + +#include +#include +#include + +#pragma push_macro("X86") +#pragma push_macro("X64") +#undef X86 +#undef X64 +#include "winrt/Windows.System.h" +#pragma pop_macro("X64") +#pragma pop_macro("X86") + +#include +#include +#include +#include + +#include + +#include "gtest/gtest.h" diff --git a/src/Tests/AuthoringWuxConsumptionTest/test.cpp b/src/Tests/AuthoringWuxConsumptionTest/test.cpp new file mode 100644 index 000000000..b182b935c --- /dev/null +++ b/src/Tests/AuthoringWuxConsumptionTest/test.cpp @@ -0,0 +1,75 @@ +#include "pch.h" + +using namespace winrt; +using namespace Windows::Foundation; +using namespace AuthoringWuxTest; + +TEST(AuthoringWuxTest, Collections) +{ + DisposableClass disposed; + disposed.Close(); + MultipleInterfaceMappingClass multipleInterfaces; + Windows::UI::Xaml::Interop::IBindableIterable bindable = multipleInterfaces; + Windows::Foundation::Collections::IVector vector = multipleInterfaces; + Windows::UI::Xaml::Interop::IBindableVector bindableVector = multipleInterfaces; + EXPECT_EQ(vector.Size(), 0); + EXPECT_EQ(bindableVector.Size(), 0); + vector.Append(DisposableClass()); + vector.Append(DisposableClass()); + vector.Append(disposed); + bindableVector.Append(DisposableClass()); + EXPECT_EQ(vector.Size(), 4); + EXPECT_EQ(bindableVector.Size(), 4); + + auto first = vector.First(); + EXPECT_TRUE(first.HasCurrent()); + EXPECT_FALSE(first.Current().IsDisposed()); + auto bindableFirst = bindable.First(); + EXPECT_TRUE(bindableFirst.HasCurrent()); + EXPECT_FALSE(bindableFirst.Current().as().IsDisposed()); + bindableFirst.Current().as().Close(); + EXPECT_TRUE(first.Current().IsDisposed()); + EXPECT_FALSE(vector.GetAt(1).IsDisposed()); + EXPECT_TRUE(vector.GetAt(2).IsDisposed()); + EXPECT_TRUE(bindableVector.First().Current().as().IsDisposed()); + EXPECT_FALSE(bindableVector.GetAt(3).as().IsDisposed()); + EXPECT_TRUE(bindableVector.GetAt(2).as().IsDisposed()); + for (auto obj : vector.GetView()) + { + obj.Close(); + } + + std::array view{}; + EXPECT_EQ(vector.GetMany(1, view), 2); + EXPECT_EQ(view.size(), 2); + for (auto& obj : view) + { + EXPECT_TRUE(obj.IsDisposed()); + } +} + +TEST(AuthoringWuxTest, PropertyChanged) +{ + CustomNotifyPropertyChanged customNotifyPropertyChanged; + Windows::UI::Xaml::Data::INotifyPropertyChanged propChanged = customNotifyPropertyChanged; + winrt::hstring propName = L"Number"; + bool eventTriggered = false; + auto token = propChanged.PropertyChanged(auto_revoke, [&eventTriggered, &propName](IInspectable sender, Windows::UI::Xaml::Data::PropertyChangedEventArgs args) + { + eventTriggered = (args.PropertyName() == propName); + }); + + customNotifyPropertyChanged.RaisePropertyChanged(propName); + + EXPECT_TRUE(eventTriggered); +} + +int main(int argc, char** argv) +{ + ::testing::InitGoogleTest(&argc, argv); + winrt::init_apartment(winrt::apartment_type::single_threaded); + auto manager = winrt::Windows::UI::Xaml::Hosting::WindowsXamlManager::InitializeForCurrentThread(); + int result = RUN_ALL_TESTS(); + manager.Close(); + return result; +} \ No newline at end of file diff --git a/src/Tests/AuthoringWuxTest/AuthoringWuxTest.csproj b/src/Tests/AuthoringWuxTest/AuthoringWuxTest.csproj new file mode 100644 index 000000000..a00cb2c58 --- /dev/null +++ b/src/Tests/AuthoringWuxTest/AuthoringWuxTest.csproj @@ -0,0 +1,22 @@ + + + + net6.0 + x64;x86 + true + true + WindowsUiXaml + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Tests/AuthoringWuxTest/Directory.Build.props b/src/Tests/AuthoringWuxTest/Directory.Build.props new file mode 100644 index 000000000..4cf186e3d --- /dev/null +++ b/src/Tests/AuthoringWuxTest/Directory.Build.props @@ -0,0 +1,9 @@ + + + + true + + + + + diff --git a/src/Tests/AuthoringWuxTest/Directory.Build.targets b/src/Tests/AuthoringWuxTest/Directory.Build.targets new file mode 100644 index 000000000..8dde12d1b --- /dev/null +++ b/src/Tests/AuthoringWuxTest/Directory.Build.targets @@ -0,0 +1,5 @@ + + + + + diff --git a/src/Tests/AuthoringWuxTest/Module.cs b/src/Tests/AuthoringWuxTest/Module.cs new file mode 100644 index 000000000..636144eed --- /dev/null +++ b/src/Tests/AuthoringWuxTest/Module.cs @@ -0,0 +1,3 @@ +#if NET +[assembly: global::System.Runtime.Versioning.SupportedOSPlatform("Windows")] +#endif diff --git a/src/Tests/AuthoringWuxTest/Program.cs b/src/Tests/AuthoringWuxTest/Program.cs new file mode 100644 index 000000000..004a3cb23 --- /dev/null +++ b/src/Tests/AuthoringWuxTest/Program.cs @@ -0,0 +1,171 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.ComponentModel; + +#pragma warning disable CA1416 + +namespace AuthoringWuxTest +{ + public sealed class DisposableClass : IDisposable + { + public bool IsDisposed { get; set; } + + public DisposableClass() + { + IsDisposed = false; + } + + public void Dispose() + { + IsDisposed = true; + } + } + public sealed class CustomNotifyPropertyChanged : INotifyPropertyChanged + { + public event PropertyChangedEventHandler PropertyChanged; + + public void RaisePropertyChanged(string propertyName) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + } + + public sealed class CustomNotifyCollectionChanged : INotifyCollectionChanged + { + public event NotifyCollectionChangedEventHandler CollectionChanged; + + public void RaiseCollectionChanged(NotifyCollectionChangedEventArgs args) + { + CollectionChanged?.Invoke(this, args); + } + } + + public sealed class CustomEnumerable : IEnumerable + { + private IEnumerable _enumerable; + + public CustomEnumerable(IEnumerable enumerable) + { + _enumerable = enumerable; + } + + public IEnumerator GetEnumerator() + { + return _enumerable.GetEnumerator(); + } + } + + public sealed class MultipleInterfaceMappingClass : IList, IList + { + private List _list = new List(); + + DisposableClass IList.this[int index] { get => _list[index]; set => _list[index] = value; } + object IList.this[int index] { get => _list[index]; set => ((IList)_list) [index] = value; } + + int ICollection.Count => _list.Count; + + int ICollection.Count => _list.Count; + + bool ICollection.IsReadOnly => true; + + bool IList.IsReadOnly => true; + + bool IList.IsFixedSize => false; + + bool ICollection.IsSynchronized => true; + + object ICollection.SyncRoot => ((ICollection) _list).SyncRoot; + + void ICollection.Add(DisposableClass item) + { + _list.Add(item); + } + + int IList.Add(object value) + { + return ((IList) _list).Add(value); + } + + void ICollection.Clear() + { + _list.Clear(); + } + + void IList.Clear() + { + _list.Clear(); + } + + bool ICollection.Contains(DisposableClass item) + { + return _list.Contains(item); + } + + bool IList.Contains(object value) + { + return ((IList) _list).Contains(value); + } + + void ICollection.CopyTo(DisposableClass[] array, int arrayIndex) + { + _list.CopyTo(array, arrayIndex); + } + + void ICollection.CopyTo(Array array, int index) + { + ((ICollection) _list).CopyTo(array, index); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return _list.GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return _list.GetEnumerator(); + } + + int IList.IndexOf(DisposableClass item) + { + return _list.IndexOf(item); + } + + int IList.IndexOf(object value) + { + return ((IList) _list).IndexOf(value); + } + + void IList.Insert(int index, DisposableClass item) + { + _list.Insert(index, item); + } + + void IList.Insert(int index, object value) + { + ((IList) _list).Insert(index, value); + } + + bool ICollection.Remove(DisposableClass item) + { + return _list.Remove(item); + } + + void IList.Remove(object value) + { + ((IList) _list).Remove(value); + } + + void IList.RemoveAt(int index) + { + _list.RemoveAt(index); + } + + void IList.RemoveAt(int index) + { + _list.RemoveAt(index); + } + } +} diff --git a/src/Tests/AuthoringWuxTest/Properties/launchSettings.json b/src/Tests/AuthoringWuxTest/Properties/launchSettings.json new file mode 100644 index 000000000..c05aeebf5 --- /dev/null +++ b/src/Tests/AuthoringWuxTest/Properties/launchSettings.json @@ -0,0 +1,8 @@ +{ + "profiles": { + "AuthoringSample": { + "commandName": "Project", + "nativeDebugging": true + } + } +} \ No newline at end of file diff --git a/src/WinRT.Runtime/GuidGenerator.cs b/src/WinRT.Runtime/GuidGenerator.cs index 8f028fa9e..0b8f71cb0 100644 --- a/src/WinRT.Runtime/GuidGenerator.cs +++ b/src/WinRT.Runtime/GuidGenerator.cs @@ -7,6 +7,7 @@ using System.Reflection; using System.Security.Cryptography; using System.Text; +using WinRT.Interop; namespace WinRT { @@ -19,16 +20,25 @@ static class GuidGenerator { public static Guid GetGUID(Type type) { - return type.GetGuidType().GUID; + type = type.GetGuidType(); + if (type.GetCustomAttribute() is {} wuxMuxAttribute) + { + return GetWuxMuxIID(wuxMuxAttribute); + } + return type.GUID; } - public static Guid GetIID( + public static Guid GetIID( #if NET [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] #endif Type type) { type = type.GetGuidType(); + if (type.GetCustomAttribute() is {} wuxMuxAttribute) + { + return GetWuxMuxIID(wuxMuxAttribute); + } if (!type.IsGenericType) { return type.GUID; @@ -36,21 +46,31 @@ public static Guid GetIID( return (Guid)type.GetField("PIID").GetValue(null); } - public static string GetSignature( + internal static Guid GetWuxMuxIID(WuxMuxProjectedTypeAttribute wuxMuxAttribute) + { + return Projections.UiXamlModeSetting switch + { + Projections.UiXamlMode.WindowsUiXaml => wuxMuxAttribute.WuxIID, + Projections.UiXamlMode.MicrosoftUiXaml => wuxMuxAttribute.MuxIID, + _ => throw new InvalidOperationException("Invalid UI XAML mode") + }; + } + + public static string GetSignature( #if NET [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] #endif Type type) - { + { if (type == typeof(object)) { return "cinterface(IInspectable)"; - } - + } + if (type == typeof(string)) { return "string"; - } + } var helperType = type.FindHelperType(); if (helperType != null) @@ -89,38 +109,38 @@ public static string GetSignature( if (!type.IsPrimitive) { var winrtTypeAttribute = type.GetCustomAttribute(); - if (winrtTypeAttribute != null && !string.IsNullOrEmpty(winrtTypeAttribute.GuidSignature)) - { - return winrtTypeAttribute.GuidSignature; + if (winrtTypeAttribute != null && !string.IsNullOrEmpty(winrtTypeAttribute.GuidSignature)) + { + return winrtTypeAttribute.GuidSignature; } - else if (winrtTypeAttribute == null && - (winrtTypeAttribute = type.GetAuthoringMetadataType()?.GetCustomAttribute()) != null && - !string.IsNullOrEmpty(winrtTypeAttribute.GuidSignature)) - { - return winrtTypeAttribute.GuidSignature; + else if (winrtTypeAttribute == null && + (winrtTypeAttribute = type.GetAuthoringMetadataType()?.GetCustomAttribute()) != null && + !string.IsNullOrEmpty(winrtTypeAttribute.GuidSignature)) + { + return winrtTypeAttribute.GuidSignature; } - else - { - var args = type.GetFields(BindingFlags.Instance | BindingFlags.Public).Select(fi => GetSignature(fi.FieldType)); - return "struct(" + type.FullName + ";" + String.Join(";", args) + ")"; + else + { + var args = type.GetFields(BindingFlags.Instance | BindingFlags.Public).Select(fi => GetSignature(fi.FieldType)); + return "struct(" + type.FullName + ";" + String.Join(";", args) + ")"; } } throw new InvalidOperationException("unsupported value type"); } } } - - // For authoring interfaces, we can use the metadata type or the helper type to get the guid. - // For built-in system interfaces that are custom type mapped, we use the helper type to get the guid. - // For others, either the type itself or the helper type has the same guid and can be used. + + // For authoring interfaces, we can use the metadata type or the helper type to get the guid. + // For built-in system interfaces that are custom type mapped, we use the helper type to get the guid. + // For others, either the type itself or the helper type has the same guid and can be used. type = type.IsInterface ? (helperType ?? type) : type; if (type.IsGenericType) { var args = type.GetGenericArguments().Select(t => GetSignature(t)); return "pinterface({" + GetGUID(type) + "};" + String.Join(";", args) + ")"; - } - + } + if (type.IsDelegate()) { return "delegate({" + GetGUID(type) + "})"; @@ -172,14 +192,14 @@ public static Guid CreateIID(Type type) { return new Guid(sig); } - else - { - return CreateIIDForGenericType(sig); + else + { + return CreateIIDForGenericType(sig); } } - internal static Guid CreateIIDForGenericType(string signature) - { + internal static Guid CreateIIDForGenericType(string signature) + { #if !NET var data = wrt_pinterface_namespace.ToByteArray().Concat(UTF8Encoding.UTF8.GetBytes(signature)).ToArray(); @@ -194,10 +214,10 @@ internal static Guid CreateIIDForGenericType(string signature) Span dataSpan = data; wrt_pinterface_namespace.TryWriteBytes(dataSpan); var numBytes = UTF8Encoding.UTF8.GetBytes(signature, dataSpan[16..]); - data = data[..(16 + numBytes)]; - - return encode_guid(SHA1.HashData(data)); -#endif + data = data[..(16 + numBytes)]; + + return encode_guid(SHA1.HashData(data)); +#endif } } } diff --git a/src/WinRT.Runtime/Interop/WuxMuxProjectedInterfaceAttribute.cs b/src/WinRT.Runtime/Interop/WuxMuxProjectedInterfaceAttribute.cs new file mode 100644 index 000000000..b30aa7dc4 --- /dev/null +++ b/src/WinRT.Runtime/Interop/WuxMuxProjectedInterfaceAttribute.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace WinRT.Interop +{ + /// + /// This type signals that the type it is applied to is projected into .NET from either a Windows.UI.Xaml type or a Microsoft.UI.Xaml type. + /// For this type, the GuidAttribute is not used and instead the GetGuidSignature method must be called to get the IID or generic IID signature part of the type. + /// + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] + internal sealed class WuxMuxProjectedTypeAttribute : Attribute + { + public Guid WuxIID { get; } + + public Guid MuxIID { get; } + + public WuxMuxProjectedTypeAttribute(string wuxIID, string muxIID) + { + WuxIID = Guid.Parse(wuxIID); + MuxIID = Guid.Parse(muxIID); + } + } +} diff --git a/src/WinRT.Runtime/MatchingRefApiCompatBaseline.txt b/src/WinRT.Runtime/MatchingRefApiCompatBaseline.txt index 212a3ac2d..8407ff19d 100644 --- a/src/WinRT.Runtime/MatchingRefApiCompatBaseline.txt +++ b/src/WinRT.Runtime/MatchingRefApiCompatBaseline.txt @@ -129,4 +129,9 @@ TypesMustExist : Type 'WinRT.StructTypeDetails' does not exist in the r MembersMustExist : Member 'public void WinRT.WindowsRuntimeTypeAttribute..ctor(System.String, System.String)' does not exist in the reference but it does exist in the implementation. MembersMustExist : Member 'public System.String WinRT.WindowsRuntimeTypeAttribute.GuidSignature.get()' does not exist in the reference but it does exist in the implementation. TypesMustExist : Type 'WinRT.WinRTExposedTypeAttribute' does not exist in the reference but it does exist in the implementation. -Total Issues: 130 +MembersMustExist : Member 'public System.Boolean WinRT.ComWrappersSupport.RegisterDelegateFactory(System.Type, System.Func)' does not exist in the reference but it does exist in the implementation. +MembersMustExist : Member 'public void WinRT.ComWrappersSupport.RegisterComInterfaceEntries(System.Type, System.Runtime.InteropServices.ComWrappers.ComInterfaceEntry[])' does not exist in the reference but it does exist in the implementation. +MembersMustExist : Member 'public System.ReadOnlySpan WinRT.MarshalString.FromAbiUnsafe(System.IntPtr)' does not exist in the reference but it does exist in the implementation. +CannotRemoveAttribute : Attribute 'WinRT.Interop.WuxMuxProjectedTypeAttribute' exists on 'ABI.System.Collections.Specialized.NotifyCollectionChangedEventHandler' in the implementation but not the reference. +CannotRemoveAttribute : Attribute 'WinRT.Interop.WuxMuxProjectedTypeAttribute' exists on 'ABI.System.ComponentModel.PropertyChangedEventHandler' in the implementation but not the reference. +Total Issues: 135 diff --git a/src/WinRT.Runtime/Projections.cs b/src/WinRT.Runtime/Projections.cs index 1f4d66d43..fab580b15 100644 --- a/src/WinRT.Runtime/Projections.cs +++ b/src/WinRT.Runtime/Projections.cs @@ -25,9 +25,33 @@ namespace WinRT #endif static class Projections { + internal enum UiXamlMode + { + MicrosoftUiXaml, + WindowsUiXaml + } + + private static UiXamlMode GetUIXamlModeSetting() + { + if (AppContext.GetData("CsWinRT.UiXamlMode") is string str && Enum.TryParse(str, out var mode)) + { +#if !NET5_0_OR_GREATER + if (mode == UiXamlMode.WindowsUiXaml) + { + throw new NotSupportedException("Windows.UI.Xaml is not supported before .NET 5. Please use built-in WinRT interop for Windows.UI.Xaml experiences"); + } +#endif + return mode; + } + return UiXamlMode.MicrosoftUiXaml; // We default to MUX for back-compat with existing projects. + } + + internal static UiXamlMode UiXamlModeSetting { get; } = GetUIXamlModeSetting(); + private static readonly ReaderWriterLockSlim rwlock = new ReaderWriterLockSlim(); private static readonly Dictionary CustomTypeToHelperTypeMappings = new Dictionary(); + private static readonly Dictionary CustomTypeToIIDMappings = new Dictionary(); private static readonly Dictionary CustomAbiTypeToTypeMappings = new Dictionary(); private static readonly Dictionary CustomAbiTypeNameToTypeMappings = new Dictionary(StringComparer.Ordinal); private static readonly Dictionary CustomTypeToAbiTypeNameMappings = new Dictionary(); @@ -36,7 +60,7 @@ static class Projections static Projections() { - // This should be in sync with cswinrt/helpers.h and the reverse mapping from WinRT.SourceGenerator/WinRTTypeWriter.cs. + // This should be in sync with cswinrt/helpers.h and the reverse mapping from WinRT.SourceGenerator/TypeMapper.cs. RegisterCustomAbiTypeMappingNoLock(typeof(bool), typeof(ABI.System.Boolean), "Boolean"); RegisterCustomAbiTypeMappingNoLock(typeof(char), typeof(ABI.System.Char), "Char"); RegisterCustomAbiTypeMappingNoLock(typeof(EventRegistrationToken), typeof(ABI.WinRT.EventRegistrationToken), "Windows.Foundation.EventRegistrationToken"); @@ -62,13 +86,41 @@ static Projections() RegisterCustomAbiTypeMappingNoLock(typeof(Exception), typeof(ABI.System.Exception), "Windows.Foundation.HResult"); RegisterCustomAbiTypeMappingNoLock(typeof(TimeSpan), typeof(ABI.System.TimeSpan), "Windows.Foundation.TimeSpan"); RegisterCustomAbiTypeMappingNoLock(typeof(Uri), typeof(ABI.System.Uri), "Windows.Foundation.Uri", isRuntimeClass: true); - RegisterCustomAbiTypeMappingNoLock(typeof(DataErrorsChangedEventArgs), typeof(ABI.System.ComponentModel.DataErrorsChangedEventArgs), "Microsoft.UI.Xaml.Data.DataErrorsChangedEventArgs", isRuntimeClass: true); - RegisterCustomAbiTypeMappingNoLock(typeof(PropertyChangedEventArgs), typeof(ABI.System.ComponentModel.PropertyChangedEventArgs), "Microsoft.UI.Xaml.Data.PropertyChangedEventArgs", isRuntimeClass: true); - RegisterCustomAbiTypeMappingNoLock(typeof(PropertyChangedEventHandler), typeof(ABI.System.ComponentModel.PropertyChangedEventHandler), "Microsoft.UI.Xaml.Data.PropertyChangedEventHandler"); - RegisterCustomAbiTypeMappingNoLock(typeof(INotifyDataErrorInfo), typeof(ABI.System.ComponentModel.INotifyDataErrorInfo), "Microsoft.UI.Xaml.Data.INotifyDataErrorInfo"); - RegisterCustomAbiTypeMappingNoLock(typeof(INotifyPropertyChanged), typeof(ABI.System.ComponentModel.INotifyPropertyChanged), "Microsoft.UI.Xaml.Data.INotifyPropertyChanged"); - RegisterCustomAbiTypeMappingNoLock(typeof(ICommand), typeof(ABI.System.Windows.Input.ICommand), "Microsoft.UI.Xaml.Interop.ICommand"); - RegisterCustomAbiTypeMappingNoLock(typeof(IServiceProvider), typeof(ABI.System.IServiceProvider), "Microsoft.UI.Xaml.IXamlServiceProvider"); + + if (UiXamlModeSetting == UiXamlMode.MicrosoftUiXaml) + { + RegisterCustomAbiTypeMappingNoLock(typeof(DataErrorsChangedEventArgs), typeof(ABI.System.ComponentModel.DataErrorsChangedEventArgs), "Microsoft.UI.Xaml.Data.DataErrorsChangedEventArgs", isRuntimeClass: true); + RegisterCustomAbiTypeMappingNoLock(typeof(PropertyChangedEventArgs), typeof(ABI.System.ComponentModel.PropertyChangedEventArgs), "Microsoft.UI.Xaml.Data.PropertyChangedEventArgs", isRuntimeClass: true); + RegisterCustomAbiTypeMappingNoLock(typeof(PropertyChangedEventHandler), typeof(ABI.System.ComponentModel.PropertyChangedEventHandler), "Microsoft.UI.Xaml.Data.PropertyChangedEventHandler"); + RegisterCustomAbiTypeMappingNoLock(typeof(INotifyDataErrorInfo), typeof(ABI.System.ComponentModel.INotifyDataErrorInfo), "Microsoft.UI.Xaml.Data.INotifyDataErrorInfo"); + RegisterCustomAbiTypeMappingNoLock(typeof(INotifyPropertyChanged), typeof(ABI.System.ComponentModel.INotifyPropertyChanged), "Microsoft.UI.Xaml.Data.INotifyPropertyChanged"); + RegisterCustomAbiTypeMappingNoLock(typeof(ICommand), typeof(ABI.System.Windows.Input.ICommand), "Microsoft.UI.Xaml.Interop.ICommand"); + RegisterCustomAbiTypeMappingNoLock(typeof(IServiceProvider), typeof(ABI.System.IServiceProvider), "Microsoft.UI.Xaml.IXamlServiceProvider"); + RegisterCustomAbiTypeMappingNoLock(typeof(IEnumerable), typeof(ABI.System.Collections.IEnumerable), "Microsoft.UI.Xaml.Interop.IBindableIterable"); + RegisterCustomAbiTypeMappingNoLock(typeof(IList), typeof(ABI.System.Collections.IList), "Microsoft.UI.Xaml.Interop.IBindableVector"); + RegisterCustomAbiTypeMappingNoLock(typeof(INotifyCollectionChanged), typeof(ABI.System.Collections.Specialized.INotifyCollectionChanged), "Microsoft.UI.Xaml.Interop.INotifyCollectionChanged"); + RegisterCustomAbiTypeMappingNoLock(typeof(NotifyCollectionChangedAction), typeof(ABI.System.Collections.Specialized.NotifyCollectionChangedAction), "Microsoft.UI.Xaml.Interop.NotifyCollectionChangedAction"); + RegisterCustomAbiTypeMappingNoLock(typeof(NotifyCollectionChangedEventArgs), typeof(ABI.System.Collections.Specialized.NotifyCollectionChangedEventArgs), "Microsoft.UI.Xaml.Interop.NotifyCollectionChangedEventArgs", isRuntimeClass: true); + RegisterCustomAbiTypeMappingNoLock(typeof(NotifyCollectionChangedEventHandler), typeof(ABI.System.Collections.Specialized.NotifyCollectionChangedEventHandler), "Microsoft.UI.Xaml.Interop.NotifyCollectionChangedEventHandler"); + CustomTypeToHelperTypeMappings.Add(typeof(Microsoft.UI.Xaml.Interop.IBindableVector), typeof(ABI.System.Collections.IList)); + } +#if NET5_0_OR_GREATER + else if (UiXamlModeSetting == UiXamlMode.WindowsUiXaml) + { + RegisterCustomAbiTypeMappingNoLock(typeof(PropertyChangedEventArgs), typeof(ABI.System.ComponentModel.PropertyChangedEventArgs), "Windows.UI.Xaml.Data.PropertyChangedEventArgs", isRuntimeClass: true); + RegisterCustomAbiTypeMappingNoLock(typeof(PropertyChangedEventHandler), typeof(ABI.System.ComponentModel.PropertyChangedEventHandler), "Windows.UI.Xaml.Data.PropertyChangedEventHandler"); + RegisterCustomAbiTypeMappingNoLock(typeof(INotifyPropertyChanged), typeof(ABI.System.ComponentModel.INotifyPropertyChanged), "Windows.UI.Xaml.Data.INotifyPropertyChanged"); + RegisterCustomAbiTypeMappingNoLock(typeof(ICommand), typeof(ABI.System.Windows.Input.ICommand), "Windows.UI.Xaml.Interop.ICommand"); + RegisterCustomAbiTypeMappingNoLock(typeof(IEnumerable), typeof(ABI.System.Collections.IEnumerable), "Windows.UI.Xaml.Interop.IBindableIterable"); + RegisterCustomAbiTypeMappingNoLock(typeof(IList), typeof(ABI.System.Collections.IList), "Windows.UI.Xaml.Interop.IBindableVector"); + RegisterCustomAbiTypeMappingNoLock(typeof(INotifyCollectionChanged), typeof(ABI.System.Collections.Specialized.INotifyCollectionChanged), "Windows.UI.Xaml.Interop.INotifyCollectionChanged"); + RegisterCustomAbiTypeMappingNoLock(typeof(NotifyCollectionChangedAction), typeof(ABI.System.Collections.Specialized.NotifyCollectionChangedAction), "Windows.UI.Xaml.Interop.NotifyCollectionChangedAction"); + RegisterCustomAbiTypeMappingNoLock(typeof(NotifyCollectionChangedEventArgs), typeof(ABI.System.Collections.Specialized.NotifyCollectionChangedEventArgs), "Windows.UI.Xaml.Interop.NotifyCollectionChangedEventArgs", isRuntimeClass: true); + RegisterCustomAbiTypeMappingNoLock(typeof(NotifyCollectionChangedEventHandler), typeof(ABI.System.Collections.Specialized.NotifyCollectionChangedEventHandler), "Windows.UI.Xaml.Interop.NotifyCollectionChangedEventHandler"); + CustomTypeToHelperTypeMappings.Add(typeof(Windows.UI.Xaml.Interop.IBindableVector), typeof(ABI.System.Collections.IList)); + } +#endif + RegisterCustomAbiTypeMappingNoLock(typeof(EventHandler<>), typeof(ABI.System.EventHandler<>), "Windows.Foundation.EventHandler`1"); RegisterCustomAbiTypeMappingNoLock(typeof(KeyValuePair<,>), typeof(ABI.System.Collections.Generic.KeyValuePair<,>), "Windows.Foundation.Collections.IKeyValuePair`2"); @@ -80,12 +132,6 @@ static Projections() RegisterCustomAbiTypeMappingNoLock(typeof(IReadOnlyDictionary<,>), typeof(ABI.System.Collections.Generic.IReadOnlyDictionary<,>), "Windows.Foundation.Collections.IMapView`2"); RegisterCustomAbiTypeMappingNoLock(typeof(IDisposable), typeof(ABI.System.IDisposable), "Windows.Foundation.IClosable"); - RegisterCustomAbiTypeMappingNoLock(typeof(IEnumerable), typeof(ABI.System.Collections.IEnumerable), "Microsoft.UI.Xaml.Interop.IBindableIterable"); - RegisterCustomAbiTypeMappingNoLock(typeof(IList), typeof(ABI.System.Collections.IList), "Microsoft.UI.Xaml.Interop.IBindableVector"); - RegisterCustomAbiTypeMappingNoLock(typeof(INotifyCollectionChanged), typeof(ABI.System.Collections.Specialized.INotifyCollectionChanged), "Microsoft.UI.Xaml.Interop.INotifyCollectionChanged"); - RegisterCustomAbiTypeMappingNoLock(typeof(NotifyCollectionChangedAction), typeof(ABI.System.Collections.Specialized.NotifyCollectionChangedAction), "Microsoft.UI.Xaml.Interop.NotifyCollectionChangedAction"); - RegisterCustomAbiTypeMappingNoLock(typeof(NotifyCollectionChangedEventArgs), typeof(ABI.System.Collections.Specialized.NotifyCollectionChangedEventArgs), "Microsoft.UI.Xaml.Interop.NotifyCollectionChangedEventArgs", isRuntimeClass: true); - RegisterCustomAbiTypeMappingNoLock(typeof(NotifyCollectionChangedEventHandler), typeof(ABI.System.Collections.Specialized.NotifyCollectionChangedEventHandler), "Microsoft.UI.Xaml.Interop.NotifyCollectionChangedEventHandler"); RegisterCustomAbiTypeMappingNoLock(typeof(Matrix3x2), typeof(ABI.System.Numerics.Matrix3x2), "Windows.Foundation.Numerics.Matrix3x2"); RegisterCustomAbiTypeMappingNoLock(typeof(Matrix4x4), typeof(ABI.System.Numerics.Matrix4x4), "Windows.Foundation.Numerics.Matrix4x4"); @@ -100,7 +146,6 @@ static Projections() CustomTypeToHelperTypeMappings.Add(typeof(IVector<>), typeof(ABI.System.Collections.Generic.IList<>)); CustomTypeToHelperTypeMappings.Add(typeof(IMapView<,>), typeof(ABI.System.Collections.Generic.IReadOnlyDictionary<,>)); CustomTypeToHelperTypeMappings.Add(typeof(IVectorView<>), typeof(ABI.System.Collections.Generic.IReadOnlyList<>)); - CustomTypeToHelperTypeMappings.Add(typeof(Microsoft.UI.Xaml.Interop.IBindableVector), typeof(ABI.System.Collections.IList)); #if NET CustomTypeToHelperTypeMappings.Add(typeof(ICollection<>), typeof(ABI.System.Collections.Generic.ICollection<>)); @@ -260,6 +305,11 @@ public static string FindCustomAbiTypeNameForType(Type type) } } + internal static Guid? FindCustomIIDForAbiType(Type type) + { + return CustomTypeToIIDMappings.TryGetValue(type, out Guid iid) ? iid : null; + } + private readonly static ConcurrentDictionary IsTypeWindowsRuntimeTypeCache = new(); public static bool IsTypeWindowsRuntimeType(Type type) { diff --git a/src/WinRT.Runtime/Projections/Bindable.net5.cs b/src/WinRT.Runtime/Projections/Bindable.net5.cs index 721c00255..f400c74d6 100644 --- a/src/WinRT.Runtime/Projections/Bindable.net5.cs +++ b/src/WinRT.Runtime/Projections/Bindable.net5.cs @@ -1,101 +1,162 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -using System; -using System.Collections; -using System.Collections.Generic; +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +using System; +using System.Collections; +using System.Collections.Generic; using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using WinRT; +using System.Runtime.InteropServices; +using WinRT; using WinRT.Interop; -#pragma warning disable 0169 // warning CS0169: The field '...' is never used -#pragma warning disable 0649 // warning CS0169: Field '...' is never assigned to - -namespace Microsoft.UI.Xaml.Interop -{ - [global::WinRT.WindowsRuntimeType] - [Guid("036D2C08-DF29-41AF-8AA2-D774BE62BA6F")] - [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Microsoft.UI.Xaml.Interop.IBindableIterable))] - internal interface IBindableIterable - { - IBindableIterator First(); - } - [global::WinRT.WindowsRuntimeType] - [Guid("6A1D6C07-076D-49F2-8314-F52C9C9A8331")] - [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Microsoft.UI.Xaml.Interop.IBindableIterator))] - internal interface IBindableIterator - { - bool MoveNext(); - // GetMany is not implemented by IBindableIterator, but it is here - // for compat purposes with WinUI where there are scenarios they do - // reinterpret_cast from IBindableIterator to IIterable. It is - // the last function in the vftable and shouldn't be called by anyone. - // If called, it will return NotImplementedException. - uint GetMany(ref object[] items); - object Current { get; } - bool HasCurrent { get; } - } - [global::WinRT.WindowsRuntimeType] - [Guid("393DE7DE-6FD0-4C0D-BB71-47244A113E93")] - internal interface IBindableVector : IEnumerable - { - object GetAt(uint index); - IBindableVectorView GetView(); - bool IndexOf(object value, out uint index); - void SetAt(uint index, object value); - void InsertAt(uint index, object value); - void RemoveAt(uint index); - void Append(object value); - void RemoveAtEnd(); - void Clear(); - uint Size { get; } - } - [global::WinRT.WindowsRuntimeType] - [Guid("346DD6E7-976E-4BC3-815D-ECE243BC0F33")] - [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Microsoft.UI.Xaml.Interop.IBindableVectorView))] - internal interface IBindableVectorView : IEnumerable - { - object GetAt(uint index); - bool IndexOf(object value, out uint index); - uint Size { get; } - } -} - -namespace ABI.Microsoft.UI.Xaml.Interop -{ - [DynamicInterfaceCastableImplementation] - [Guid("036D2C08-DF29-41AF-8AA2-D774BE62BA6F")] - internal unsafe interface IBindableIterable : global::Microsoft.UI.Xaml.Interop.IBindableIterable, ABI.System.Collections.IEnumerable - { - - } - - [DynamicInterfaceCastableImplementation] - [Guid("6A1D6C07-076D-49F2-8314-F52C9C9A8331")] - internal unsafe interface IBindableIterator : global::Microsoft.UI.Xaml.Interop.IBindableIterator +#pragma warning disable 0169 // warning CS0169: The field '...' is never used +#pragma warning disable 0649 // warning CS0169: Field '...' is never assigned to + +namespace ABI.System.Collections +{ + using WUX = global::Windows.UI.Xaml.Interop; + using MUX = global::Microsoft.UI.Xaml.Interop; + using global::System; + using global::System.Runtime.CompilerServices; + using global::System.Diagnostics.CodeAnalysis; + +#if EMBED + internal +#else + public +#endif + static class IEnumerableMethods + { + public static global::System.Guid IID { get; } = new Guid(new global::System.ReadOnlySpan(new byte[] { 0x08, 0x2C, 0x6D, 0x03, 0x29, 0xDF, 0xAF, 0x41, 0x8A, 0xA2, 0xD7, 0x74, 0xBE, 0x62, 0xBA, 0x6F })); + + public static IntPtr AbiToProjectionVftablePtr => IEnumerable.AbiToProjectionVftablePtr; + } + + [DynamicInterfaceCastableImplementation] + [Guid("036D2C08-DF29-41AF-8AA2-D774BE62BA6F")] + internal unsafe interface IEnumerable : global::System.Collections.IEnumerable, WUX.IBindableIterable, MUX.IBindableIterable { - public static readonly IntPtr AbiToProjectionVftablePtr; - static IBindableIterator() + public static string GetGuidSignature() => GuidGenerator.GetSignature(typeof(IEnumerable)); + + public sealed class AdaptiveFromAbiHelper : global::System.Collections.IEnumerable + { + private readonly Func _enumerator; + private readonly IWinRTObject _winRTObject; + + [DynamicDependency(DynamicallyAccessedMemberTypes.PublicMethods, typeof(IEnumerable<>))] + [SuppressMessage("Trimming", "IL2070:'this' argument does not satisfy 'DynamicallyAccessedMembersAttribute' in call to target method. The parameter of method does not have matching annotations.", Justification = "We explicitly preserve the type we're looking for with the DynamicDependency attribute.")] + [SuppressMessage("Trimming", "IL2075:'this' argument does not satisfy 'DynamicallyAccessedMembersAttribute' in call to target method. The return value of the source method does not have matching annotations.", Justification = "We can't annotate this case (GetMethod on a type returned from GetInterface), so we use DynamicDependency to keep alive the one type we care about's public methods.")] + public AdaptiveFromAbiHelper( + Type runtimeType, IWinRTObject winRTObject) + : this(winRTObject) + { + Type enumGenericType = (runtimeType.IsGenericType && runtimeType.GetGenericTypeDefinition() == typeof(IEnumerable<>)) ? + runtimeType : runtimeType.GetInterface("System.Collections.Generic.IEnumerable`1"); + if(enumGenericType != null) + { + var getEnumerator = enumGenericType.GetMethod("GetEnumerator"); + _enumerator = (IWinRTObject obj) => (IEnumerator)getEnumerator.Invoke(obj, null); + } + } + + public AdaptiveFromAbiHelper(IWinRTObject winRTObject) + { + _winRTObject = winRTObject; + if (winRTObject is WUX.IBindableIterable) + { + _enumerator = (IWinRTObject obj) => new Generic.FromAbiEnumerator(new NonGenericToGenericWuxIterator(((WUX.IBindableIterable)obj).First())); + } + else if (winRTObject is MUX.IBindableIterable) + { + _enumerator = (IWinRTObject obj) => new Generic.FromAbiEnumerator(new NonGenericToGenericMuxIterator(((MUX.IBindableIterable)obj).First())); + } + } + + public IEnumerator GetEnumerator() => _enumerator(_winRTObject); + + private sealed class NonGenericToGenericWuxIterator : global::Windows.Foundation.Collections.IIterator + { + private readonly WUX.IBindableIterator iterator; + + public NonGenericToGenericWuxIterator(WUX.IBindableIterator iterator) => this.iterator = iterator; + + public object _Current => iterator.Current; + public bool HasCurrent => iterator.HasCurrent; + public bool _MoveNext() { return iterator.MoveNext(); } + public uint GetMany(ref object[] items) => throw new NotSupportedException(); + } + + private sealed class NonGenericToGenericMuxIterator : global::Windows.Foundation.Collections.IIterator + { + private readonly MUX.IBindableIterator iterator; + + public NonGenericToGenericMuxIterator(MUX.IBindableIterator iterator) => this.iterator = iterator; + + public object _Current => iterator.Current; + public bool HasCurrent => iterator.HasCurrent; + public bool _MoveNext() { return iterator.MoveNext(); } + public uint GetMany(ref object[] items) => throw new NotSupportedException(); + } + } + + private sealed class ToWuxAbiHelper : WUX.IBindableIterable { - AbiToProjectionVftablePtr = ComWrappersSupport.AllocateVtableMemory(typeof(IBindableIterator), sizeof(IInspectable.Vftbl) + sizeof(IntPtr) * 4); - *(IInspectable.Vftbl*)AbiToProjectionVftablePtr = IInspectable.Vftbl.AbiToProjectionVftable; - ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[6] = &Do_Abi_get_Current_0; - ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[7] = &Do_Abi_get_HasCurrent_1; - ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[8] = &Do_Abi_MoveNext_2; - ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[9] = &Do_Abi_GetMany_3; + private readonly IEnumerable m_enumerable; + + internal ToWuxAbiHelper(IEnumerable enumerable) => m_enumerable = enumerable; + + WUX.IBindableIterator WUX.IBindableIterable.First() => MakeBindableIterator(m_enumerable.GetEnumerator()); + + internal static WUX.IBindableIterator MakeBindableIterator(IEnumerator enumerator) => + new Generic.IEnumerator.ToAbiHelper(new NonGenericToGenericEnumerator(enumerator)); + + private sealed class NonGenericToGenericEnumerator : IEnumerator + { + private readonly IEnumerator enumerator; + + public NonGenericToGenericEnumerator(IEnumerator enumerator) => this.enumerator = enumerator; + + public object Current => enumerator.Current; + public bool MoveNext() { return enumerator.MoveNext(); } + public void Reset() { enumerator.Reset(); } + public void Dispose() { } + } } - [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] - private static unsafe int Do_Abi_MoveNext_2(IntPtr thisPtr, byte* result) + private sealed class ToMuxAbiHelper(IEnumerable enumerable) : MUX.IBindableIterable + { + MUX.IBindableIterator MUX.IBindableIterable.First() => MakeBindableIterator(enumerable.GetEnumerator()); + + internal static MUX.IBindableIterator MakeBindableIterator(IEnumerator enumerator) => + new Generic.IEnumerator.ToAbiHelper(new NonGenericToGenericEnumerator(enumerator)); + + private sealed class NonGenericToGenericEnumerator(IEnumerator enumerator) : IEnumerator + { + public object Current => enumerator.Current; + public bool MoveNext() { return enumerator.MoveNext(); } + public void Reset() { enumerator.Reset(); } + public void Dispose() { } + } + } + + public static readonly IntPtr AbiToProjectionVftablePtr; + static IEnumerable() + { + AbiToProjectionVftablePtr = ComWrappersSupport.AllocateVtableMemory(typeof(IEnumerable), sizeof(IInspectable.Vftbl) + sizeof(IntPtr) * 1); + *(IInspectable.Vftbl*)AbiToProjectionVftablePtr = IInspectable.Vftbl.AbiToProjectionVftable; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[6] = Projections.UiXamlModeSetting is Projections.UiXamlMode.WindowsUiXaml ? &Do_Wux_Abi_First_0 : &Do_Mux_Abi_First_0; + } + + [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] + private static unsafe int Do_Wux_Abi_First_0(IntPtr thisPtr, IntPtr* result) { - bool __result = default; *result = default; try { - __result = global::WinRT.ComWrappersSupport.FindObject(thisPtr).MoveNext(); - *result = (byte)(__result ? 1 : 0); + var __this = global::WinRT.ComWrappersSupport.FindObject(thisPtr); + var iterator = ToWuxAbiHelper.MakeBindableIterator(__this.GetEnumerator()); + *result = MarshalInterface.FromManaged(iterator); } catch (Exception __exception__) { @@ -105,931 +166,620 @@ private static unsafe int Do_Abi_MoveNext_2(IntPtr thisPtr, byte* result) return 0; } - [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] - private static unsafe int Do_Abi_GetMany_3(IntPtr thisPtr, int __itemsSize, IntPtr items, uint* result) + [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] + private static unsafe int Do_Mux_Abi_First_0(IntPtr thisPtr, IntPtr* result) { *result = default; - try { - // Should never be called. - throw new NotImplementedException(); + var __this = global::WinRT.ComWrappersSupport.FindObject(thisPtr); + var iterator = ToMuxAbiHelper.MakeBindableIterator(__this.GetEnumerator()); + *result = MarshalInterface.FromManaged(iterator); } catch (Exception __exception__) { global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); } + return 0; } - [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] - private static unsafe int Do_Abi_get_Current_0(IntPtr thisPtr, IntPtr* value) + internal static ObjectReference ObjRefFromAbi(IntPtr thisPtr) { - object __value = default; - *value = default; + if (thisPtr == IntPtr.Zero) + { + return null; + } + return ObjectReference.FromAbi(thisPtr); + } + + private static AdaptiveFromAbiHelper _AbiHelper(IWinRTObject _this) + { + return (AdaptiveFromAbiHelper)_this.GetOrCreateTypeHelperData(typeof(global::System.Collections.IEnumerable).TypeHandle, + () => new AdaptiveFromAbiHelper(_this)); + } + + unsafe WUX.IBindableIterator WUX.IBindableIterable.First() + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IEnumerable).TypeHandle); + var ThisPtr = _obj.ThisPtr; + IntPtr __retval = default; try { - __value = global::WinRT.ComWrappersSupport.FindObject(thisPtr).Current; - *value = MarshalInspectable.FromManaged(__value); + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[6](ThisPtr, &__retval)); + return MarshalInterface.FromAbi(__retval); } - catch (Exception __exception__) + finally { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + MarshalInterface.DisposeAbi(__retval); } - return 0; } - [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] - private static unsafe int Do_Abi_get_HasCurrent_1(IntPtr thisPtr, byte* value) + unsafe MUX.IBindableIterator MUX.IBindableIterable.First() { - bool __value = default; - *value = default; + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IEnumerable).TypeHandle); + var ThisPtr = _obj.ThisPtr; + IntPtr __retval = default; try { - __value = global::WinRT.ComWrappersSupport.FindObject(thisPtr).HasCurrent; - *value = (byte)(__value ? 1 : 0); + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[6](ThisPtr, &__retval)); + return MarshalInterface.FromAbi(__retval); } - catch (Exception __exception__) + finally { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + MarshalInterface.DisposeAbi(__retval); } - return 0; - } - - internal static ObjectReference FromAbi(IntPtr thisPtr) => ObjectReference.FromAbi(thisPtr); - - unsafe bool global::Microsoft.UI.Xaml.Interop.IBindableIterator.MoveNext() - { - var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::Microsoft.UI.Xaml.Interop.IBindableIterator).TypeHandle); - var ThisPtr = _obj.ThisPtr; - byte __retval = default; - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[8](ThisPtr, &__retval)); - return __retval != 0; - } - - unsafe uint global::Microsoft.UI.Xaml.Interop.IBindableIterator.GetMany(ref object[] items) - { - // Should never be called. - throw new NotImplementedException(); - } - - unsafe object global::Microsoft.UI.Xaml.Interop.IBindableIterator.Current - { - get - { - var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::Microsoft.UI.Xaml.Interop.IBindableIterator).TypeHandle); - var ThisPtr = _obj.ThisPtr; - IntPtr __retval = default; - try - { - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[6](ThisPtr, &__retval)); - return MarshalInspectable.FromAbi(__retval); - } - finally - { - MarshalInspectable.DisposeAbi(__retval); - } - } - } - - unsafe bool global::Microsoft.UI.Xaml.Interop.IBindableIterator.HasCurrent - { - get - { - var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::Microsoft.UI.Xaml.Interop.IBindableIterator).TypeHandle); - var ThisPtr = _obj.ThisPtr; - byte __retval = default; - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[7](ThisPtr, &__retval)); - return __retval != 0; - } - } - - } - [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] - internal static class IBindableIterator_Delegates - { - public unsafe delegate int get_Current_0(IntPtr thisPtr, IntPtr* result); - public unsafe delegate int get_HasCurrent_1(IntPtr thisPtr, byte* result); - public unsafe delegate int MoveNext_2(IntPtr thisPtr, byte* result); - public unsafe delegate int GetMany_3(IntPtr thisPtr, int itemSize, IntPtr items, uint* result); - } - - [DynamicInterfaceCastableImplementation] - [Guid("346DD6E7-976E-4BC3-815D-ECE243BC0F33")] - internal unsafe interface IBindableVectorView : global::Microsoft.UI.Xaml.Interop.IBindableVectorView + } + + IEnumerator global::System.Collections.IEnumerable.GetEnumerator() + { + return _AbiHelper((IWinRTObject)this).GetEnumerator(); + } + } + + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] +#if EMBED + internal +#else + public +#endif + static class IEnumerable_Delegates { - public static readonly IntPtr AbiToProjectionVftablePtr; + public unsafe delegate int First_0(IntPtr thisPtr, IntPtr* result); + } - internal static readonly Guid IID = new(new ReadOnlySpan(new byte[] { 0xE7, 0xD6, 0x6D, 0x34, 0x6E, 0x97, 0xC3, 0x4B, 0x81, 0x5D, 0xEC, 0xE2, 0x43, 0xBC, 0x0F, 0x33 })); - - static IBindableVectorView() +#if EMBED + internal +#else + public +#endif + static class IListMethods + { + public static Guid IID { get; } = new Guid(new global::System.ReadOnlySpan(new byte[] { 0xDE, 0xE7, 0x3D, 0x39, 0xD0, 0x6F, 0x0D, 0x4C, 0xBB, 0x71, 0x47, 0x24, 0x4A, 0x11, 0x3E, 0x93 })); + + public static IntPtr AbiToProjectionVftablePtr => IList.AbiToProjectionVftablePtr; + } + + [DynamicInterfaceCastableImplementation] + [Guid("393DE7DE-6FD0-4C0D-BB71-47244A113E93")] + internal unsafe interface IList : global::System.Collections.IList, WUX.IBindableVector, MUX.IBindableVector + { + public static string GetGuidSignature() => GuidGenerator.GetSignature(typeof(IList)); + + public interface IBindableVectorAdapter { - AbiToProjectionVftablePtr = ComWrappersSupport.AllocateVtableMemory(typeof(IBindableVectorView), sizeof(IInspectable.Vftbl) + sizeof(IntPtr) * 3); - *(IInspectable.Vftbl*)AbiToProjectionVftablePtr = IInspectable.Vftbl.AbiToProjectionVftable; - ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[6] = &Do_Abi_GetAt_0; - ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[7] = &Do_Abi_get_Size_1; - ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[8] = &Do_Abi_IndexOf_2; + object GetAt(uint index); + IBindableVectorViewAdapter GetView(); + bool IndexOf(object value, out uint index); + void SetAt(uint index, object value); + void InsertAt(uint index, object value); + void RemoveAt(uint index); + void Append(object value); + void RemoveAtEnd(); + void Clear(); + uint Size { get; } } - [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] - private static unsafe int Do_Abi_GetAt_0(IntPtr thisPtr, uint index, IntPtr* result) + public interface IBindableVectorViewAdapter { - object __result = default; + object GetAt(uint index); + bool IndexOf(object value, out uint index); + uint Size { get; } + } - try - { - __result = global::WinRT.ComWrappersSupport.FindObject(thisPtr).GetAt(index); - *result = MarshalInspectable.FromManaged(__result); + private sealed class WuxBindableVectorAdapter(WUX.IBindableVector vector) : IBindableVectorAdapter + { + public object GetAt(uint index) => vector.GetAt(index); + public IBindableVectorViewAdapter GetView() => new WuxBindableVectorViewAdapter(vector.GetView()); + public bool IndexOf(object value, out uint index) => vector.IndexOf(value, out index); + public void SetAt(uint index, object value) => vector.SetAt(index, value); + public void InsertAt(uint index, object value) => vector.InsertAt(index, value); + public void RemoveAt(uint index) => vector.RemoveAt(index); + public void Append(object value) => vector.Append(value); + public void RemoveAtEnd() => vector.RemoveAtEnd(); + public void Clear() => vector.Clear(); + public uint Size => vector.Size; + private sealed class WuxBindableVectorViewAdapter(WUX.IBindableVectorView vectorView) : IBindableVectorViewAdapter + { + public object GetAt(uint index) => vectorView.GetAt(index); + public bool IndexOf(object value, out uint index) => vectorView.IndexOf(value, out index); + public uint Size => vectorView.Size; } - catch (Exception __exception__) + } + + private sealed class MuxBindableVectorAdapter(MUX.IBindableVector vector) : IBindableVectorAdapter + { + public object GetAt(uint index) => vector.GetAt(index); + public IBindableVectorViewAdapter GetView() => new WuxBindableVectorViewAdapter(vector.GetView()); + public bool IndexOf(object value, out uint index) => vector.IndexOf(value, out index); + public void SetAt(uint index, object value) => vector.SetAt(index, value); + public void InsertAt(uint index, object value) => vector.InsertAt(index, value); + public void RemoveAt(uint index) => vector.RemoveAt(index); + public void Append(object value) => vector.Append(value); + public void RemoveAtEnd() => vector.RemoveAtEnd(); + public void Clear() => vector.Clear(); + public uint Size => vector.Size; + + private sealed class WuxBindableVectorViewAdapter(MUX.IBindableVectorView vectorView) : IBindableVectorViewAdapter { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + public object GetAt(uint index) => vectorView.GetAt(index); + public bool IndexOf(object value, out uint index) => vectorView.IndexOf(value, out index); + public uint Size => vectorView.Size; } - return 0; } - [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] - private static unsafe int Do_Abi_IndexOf_2(IntPtr thisPtr, IntPtr value, uint* index, byte* returnValue) + public sealed class FromAbiHelper : global::System.Collections.IList { - bool __returnValue = default; + private readonly IBindableVectorAdapter _vector; - *index = default; - *returnValue = default; - uint __index = default; + public FromAbiHelper(IBindableVectorAdapter vector) + { + _vector = vector; + } - try + public bool IsSynchronized => false; + + public object SyncRoot { get => this; } + + public int Count { - __returnValue = global::WinRT.ComWrappersSupport.FindObject(thisPtr).IndexOf(MarshalInspectable.FromAbi(value), out __index); - *index = __index; - *returnValue = (byte)(__returnValue ? 1 : 0); + get + { + uint size = _vector.Size; + if (((uint)int.MaxValue) < size) + { + throw new InvalidOperationException(WinRTRuntimeErrorStrings.InvalidOperation_CollectionBackingListTooLarge); + } + return (int)size; + } } - catch (Exception __exception__) + + public void CopyTo(Array array, int arrayIndex) { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + if (array == null) + throw new ArgumentNullException(nameof(array)); + + // ICollection expects the destination array to be single-dimensional. + if (array.Rank != 1) + throw new ArgumentException(WinRTRuntimeErrorStrings.Arg_RankMultiDimNotSupported); + + int destLB = array.GetLowerBound(0); + int srcLen = Count; + int destLen = array.GetLength(0); + + if (arrayIndex < destLB) + throw new ArgumentOutOfRangeException(nameof(arrayIndex)); + + // Does the dimension in question have sufficient space to copy the expected number of entries? + // We perform this check before valid index check to ensure the exception message is in sync with + // the following snippet that uses regular framework code: + // + // ArrayList list = new ArrayList(); + // list.Add(1); + // Array items = Array.CreateInstance(typeof(object), new int[] { 1 }, new int[] { -1 }); + // list.CopyTo(items, 0); + + if (srcLen > (destLen - (arrayIndex - destLB))) + throw new ArgumentException(WinRTRuntimeErrorStrings.Argument_InsufficientSpaceToCopyCollection); + + if (arrayIndex - destLB > destLen) + throw new ArgumentException(WinRTRuntimeErrorStrings.Argument_IndexOutOfArrayBounds); + + // We need to verify the index as we; + for (uint i = 0; i < srcLen; i++) + { + array.SetValue(_vector.GetAt(i), i + arrayIndex); + } + } + + public object this[int index] + { + get => Indexer_Get(index); + set => Indexer_Set(index, value); + } + + internal object Indexer_Get(int index) + { + if (index < 0) + throw new ArgumentOutOfRangeException(nameof(index)); + + return GetAt(_vector, (uint)index); + } + + internal void Indexer_Set(int index, object value) + { + if (index < 0) + throw new ArgumentOutOfRangeException(nameof(index)); + + SetAt(_vector, (uint)index, value); + } + + public int Add(object value) + { + _vector.Append(value); + + uint size = _vector.Size; + if (((uint)int.MaxValue) < size) + { + throw new InvalidOperationException(WinRTRuntimeErrorStrings.InvalidOperation_CollectionBackingListTooLarge); + } + + return (int)(size - 1); + } + + public bool Contains(object item) + { + return _vector.IndexOf(item, out _); + } + + public void Clear() + { + _vector.Clear(); + } + + public bool IsFixedSize { get => false; } + + public bool IsReadOnly { get => false; } + + public int IndexOf(object item) + { + uint index; + bool exists = _vector.IndexOf(item, out index); + + if (!exists) + return -1; + + if (((uint)int.MaxValue) < index) + { + throw new InvalidOperationException(WinRTRuntimeErrorStrings.InvalidOperation_CollectionBackingListTooLarge); + } + + return (int)index; + } + + public void Insert(int index, object item) + { + if (index < 0) + throw new ArgumentOutOfRangeException(nameof(index)); + + InsertAtHelper(_vector, (uint)index, item); + } + + public void Remove(object item) + { + uint index; + bool exists = _vector.IndexOf(item, out index); + + if (exists) + { + if (((uint)int.MaxValue) < index) + { + throw new InvalidOperationException(WinRTRuntimeErrorStrings.InvalidOperation_CollectionBackingListTooLarge); + } + + RemoveAtHelper(_vector, index); + } + } + + public void RemoveAt(int index) + { + if (index < 0) + throw new ArgumentOutOfRangeException(nameof(index)); + + RemoveAtHelper(_vector, (uint)index); + } + + private static object GetAt(IBindableVectorAdapter _this, uint index) + { + try + { + return _this.GetAt(index); + + // We delegate bounds checking to the underlying collection and if it detected a fault, + // we translate it to the right exception: + } + catch (Exception ex) + { + if (ExceptionHelpers.E_BOUNDS == ex.HResult) + throw new ArgumentOutOfRangeException(nameof(index)); + throw; + } + } + + private static void SetAt(IBindableVectorAdapter _this, uint index, object value) + { + try + { + _this.SetAt(index, value); + + // We delegate bounds checking to the underlying collection and if it detected a fault, + // we translate it to the right exception: + } + catch (Exception ex) + { + if (ExceptionHelpers.E_BOUNDS == ex.HResult) + throw new ArgumentOutOfRangeException(nameof(index)); + throw; + } + } + + private static void InsertAtHelper(IBindableVectorAdapter _this, uint index, object item) + { + try + { + _this.InsertAt(index, item); + + // We delegate bounds checking to the underlying collection and if it detected a fault, + // we translate it to the right exception: + } + catch (Exception ex) + { + if (ExceptionHelpers.E_BOUNDS == ex.HResult) + throw new ArgumentOutOfRangeException(nameof(index)); + throw; + } + } + + private static void RemoveAtHelper(IBindableVectorAdapter _this, uint index) + { + try + { + _this.RemoveAt(index); + + // We delegate bounds checking to the underlying collection and if it detected a fault, + // we translate it to the right exception: + } + catch (Exception ex) + { + if (ExceptionHelpers.E_BOUNDS == ex.HResult) + throw new ArgumentOutOfRangeException(nameof(index)); + throw; + } + } + + public IEnumerator GetEnumerator() + { + return ((IEnumerable)(IWinRTObject)_vector).GetEnumerator(); } - return 0; } - [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] - private static unsafe int Do_Abi_get_Size_1(IntPtr thisPtr, uint* value) + public sealed class ToAbiHelper : WUX.IBindableVector, MUX.IBindableVector, IBindableVectorAdapter { - uint __value = default; + private global::System.Collections.IList _list; - *value = default; + public ToAbiHelper(global::System.Collections.IList list) => _list = list; - try + public object GetAt(uint index) { - __value = global::WinRT.ComWrappersSupport.FindObject(thisPtr).Size; - *value = __value; + EnsureIndexInt32(index, _list.Count); + + try + { + return _list[(int)index]; + } + catch (ArgumentOutOfRangeException ex) + { + throw ex.GetExceptionForHR(ExceptionHelpers.E_BOUNDS, WinRTRuntimeErrorStrings.ArgumentOutOfRange_Index); + } + } + + public uint Size { get => (uint)_list.Count; } + + IBindableVectorViewAdapter IBindableVectorAdapter.GetView() + { + return new ListToBindableVectorViewAdapter(_list); + } + + WUX.IBindableVectorView WUX.IBindableVector.GetView() + { + return new ListToBindableVectorViewAdapter(_list); + } + + MUX.IBindableVectorView MUX.IBindableVector.GetView() + { + return new ListToBindableVectorViewAdapter(_list); + } + + public bool IndexOf(object value, out uint index) + { + int ind = _list.IndexOf(value); + if (-1 == ind) + { + index = 0; + return false; + } + + index = (uint)ind; + return true; + } + + public void SetAt(uint index, object value) + { + EnsureIndexInt32(index, _list.Count); + + try + { + _list[(int)index] = value; + } + catch (ArgumentOutOfRangeException ex) + { + throw ex.GetExceptionForHR(ExceptionHelpers.E_BOUNDS, WinRTRuntimeErrorStrings.ArgumentOutOfRange_Index); + } + } + + public void InsertAt(uint index, object value) + { + // Inserting at an index one past the end of the list is equivalent to appending + // so we need to ensure that we're within (0, count + 1). + EnsureIndexInt32(index, _list.Count + 1); + + try + { + _list.Insert((int)index, value); + } + catch (ArgumentOutOfRangeException ex) + { + // Change error code to match what WinRT expects + ex.SetHResult(ExceptionHelpers.E_BOUNDS); + throw; + } + } + + public void RemoveAt(uint index) + { + EnsureIndexInt32(index, _list.Count); + + try + { + _list.RemoveAt((int)index); + } + catch (ArgumentOutOfRangeException ex) + { + // Change error code to match what WinRT expects + ex.SetHResult(ExceptionHelpers.E_BOUNDS); + throw; + } } - catch (Exception __exception__) + + public void Append(object value) { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + _list.Add(value); } - return 0; - } - - internal static ObjectReference FromAbi(IntPtr thisPtr) => ObjectReference.FromAbi(thisPtr); - - private static readonly global::System.Runtime.CompilerServices.ConditionalWeakTable _helperTable = new(); - - unsafe object global::Microsoft.UI.Xaml.Interop.IBindableVectorView.GetAt(uint index) - { - var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::Microsoft.UI.Xaml.Interop.IBindableIterator).TypeHandle); - var ThisPtr = _obj.ThisPtr; - IntPtr __retval = default; - try - { - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[6](ThisPtr, index, &__retval)); - return MarshalInspectable.FromAbi(__retval); - } - finally - { - MarshalInspectable.DisposeAbi(__retval); - } - } - - unsafe bool global::Microsoft.UI.Xaml.Interop.IBindableVectorView.IndexOf(object value, out uint index) - { - var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::Microsoft.UI.Xaml.Interop.IBindableIterator).TypeHandle); - var ThisPtr = _obj.ThisPtr; - ObjectReferenceValue __value = default; - uint __index = default; - byte __retval = default; - try - { - __value = MarshalInspectable.CreateMarshaler2(value); - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[8]( - ThisPtr, - MarshalInspectable.GetAbi(__value), - &__index, - &__retval)); - index = __index; - return __retval != 0; - } - finally - { - MarshalInspectable.DisposeMarshaler(__value); - } - } - - unsafe uint global::Microsoft.UI.Xaml.Interop.IBindableVectorView.Size - { - get - { - var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::Microsoft.UI.Xaml.Interop.IBindableIterator).TypeHandle); - var ThisPtr = _obj.ThisPtr; - uint __retval = default; - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[7](ThisPtr, &__retval)); - return __retval; - } - } - - IEnumerator IEnumerable.GetEnumerator() - { - return _helperTable.GetValue((IWinRTObject)this, - (enumerable) => new ABI.System.Collections.IEnumerable.FromAbiHelper((global::System.Collections.IEnumerable)(IWinRTObject)enumerable) - ).GetEnumerator(); - } - } - [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] - internal static class IBindableVectorView_Delegates - { - public unsafe delegate int GetAt_0(IntPtr thisPtr, uint index, IntPtr* result); - public unsafe delegate int get_Size_1(IntPtr thisPtr, uint* result); - public unsafe delegate int IndexOf_2(IntPtr thisPtr, IntPtr value, uint* index, byte* returnValue); - } -} - -namespace ABI.System.Collections -{ - using global::Microsoft.UI.Xaml.Interop; - using global::System; - using global::System.Runtime.CompilerServices; - -#if EMBED - internal -#else - public -#endif - static class IEnumerableMethods - { - public static global::System.Guid IID { get; } = new Guid(new global::System.ReadOnlySpan(new byte[] { 0x08, 0x2C, 0x6D, 0x03, 0x29, 0xDF, 0xAF, 0x41, 0x8A, 0xA2, 0xD7, 0x74, 0xBE, 0x62, 0xBA, 0x6F })); - public static IntPtr AbiToProjectionVftablePtr => IEnumerable.AbiToProjectionVftablePtr; - } - - [DynamicInterfaceCastableImplementation] - [Guid("036D2C08-DF29-41AF-8AA2-D774BE62BA6F")] - internal unsafe interface IEnumerable : global::System.Collections.IEnumerable, global::Microsoft.UI.Xaml.Interop.IBindableIterable - { - public static string GetGuidSignature() => GuidGenerator.GetSignature(typeof(IEnumerable)); - - public sealed class AdaptiveFromAbiHelper : FromAbiHelper, global::System.Collections.IEnumerable - { - private readonly Func _enumerator; - - public AdaptiveFromAbiHelper(Type runtimeType, IWinRTObject winRTObject) - :base(winRTObject) - { - Type enumGenericType = (runtimeType.IsGenericType && runtimeType.GetGenericTypeDefinition() == typeof(global::System.Collections.Generic.IEnumerable<>)) ? - runtimeType : runtimeType.GetInterface("System.Collections.Generic.IEnumerable`1"); - if(enumGenericType != null) - { - var getEnumerator = enumGenericType.GetMethod("GetEnumerator"); - _enumerator = (IWinRTObject obj) => (global::System.Collections.IEnumerator)getEnumerator.Invoke(obj, null); - } - } - - public override global::System.Collections.IEnumerator GetEnumerator() => _enumerator != null ? _enumerator(_winrtObject) : base.GetEnumerator(); - } - - public class FromAbiHelper : global::System.Collections.IEnumerable - { - private readonly global::System.Collections.IEnumerable _iterable; - protected readonly IWinRTObject _winrtObject; - - public FromAbiHelper(global::System.Collections.IEnumerable iterable) - { - _iterable = iterable; - } - - protected FromAbiHelper(IWinRTObject winrtObject) - { - _iterable = null; - _winrtObject = winrtObject; - } - - private IWinRTObject GetIterable() - { - return (IWinRTObject)_iterable ?? _winrtObject; - } - - public virtual global::System.Collections.IEnumerator GetEnumerator() => - new Generic.FromAbiEnumerator(new NonGenericToGenericIterator(((global::Microsoft.UI.Xaml.Interop.IBindableIterable) GetIterable()).First())); - - private sealed class NonGenericToGenericIterator : global::Windows.Foundation.Collections.IIterator - { - private readonly IBindableIterator iterator; - - public NonGenericToGenericIterator(IBindableIterator iterator) => this.iterator = iterator; - - public object _Current => iterator.Current; - public bool HasCurrent => iterator.HasCurrent; - public bool _MoveNext() { return iterator.MoveNext(); } - public uint GetMany(ref object[] items) => throw new NotSupportedException(); - } - } - - public sealed class ToAbiHelper : IBindableIterable - { - private readonly IEnumerable m_enumerable; - - internal ToAbiHelper(IEnumerable enumerable) => m_enumerable = enumerable; - - IBindableIterator IBindableIterable.First() => MakeBindableIterator(m_enumerable.GetEnumerator()); - - internal static IBindableIterator MakeBindableIterator(IEnumerator enumerator) => - new Generic.IEnumerator.ToAbiHelper(new NonGenericToGenericEnumerator(enumerator)); - - private sealed class NonGenericToGenericEnumerator : IEnumerator - { - private readonly IEnumerator enumerator; - - public NonGenericToGenericEnumerator(IEnumerator enumerator) => this.enumerator = enumerator; - - public object Current => enumerator.Current; - public bool MoveNext() { return enumerator.MoveNext(); } - public void Reset() { enumerator.Reset(); } - public void Dispose() { } - } - } + public void RemoveAtEnd() + { + if (_list.Count == 0) + { + Exception e = new InvalidOperationException(WinRTRuntimeErrorStrings.InvalidOperation_CannotRemoveLastFromEmptyCollection); + e.SetHResult(ExceptionHelpers.E_BOUNDS); + throw e; + } - public static readonly IntPtr AbiToProjectionVftablePtr; - static IEnumerable() - { - AbiToProjectionVftablePtr = ComWrappersSupport.AllocateVtableMemory(typeof(IEnumerable), sizeof(IInspectable.Vftbl) + sizeof(IntPtr) * 1); - *(IInspectable.Vftbl*)AbiToProjectionVftablePtr = IInspectable.Vftbl.AbiToProjectionVftable; - ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[6] = &Do_Abi_First_0; - } + uint size = (uint)_list.Count; + RemoveAt(size - 1); + } - [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] - private static unsafe int Do_Abi_First_0(IntPtr thisPtr, IntPtr* result) - { - *result = default; - try + public void Clear() { - var __this = global::WinRT.ComWrappersSupport.FindObject(thisPtr); - var iterator = ToAbiHelper.MakeBindableIterator(__this.GetEnumerator()); - *result = MarshalInterface.FromManaged(iterator); + _list.Clear(); } - catch (Exception __exception__) + + private static void EnsureIndexInt32(uint index, int listCapacity) { - global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); - return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + // We use '<=' and not '<' becasue int.MaxValue == index would imply + // that Size > int.MaxValue: + if (((uint)int.MaxValue) <= index || index >= (uint)listCapacity) + { + Exception e = new ArgumentOutOfRangeException(nameof(index), WinRTRuntimeErrorStrings.ArgumentOutOfRange_IndexLargerThanMaxValue); + e.SetHResult(ExceptionHelpers.E_BOUNDS); + throw e; + } } - return 0; - } - - internal static ObjectReference ObjRefFromAbi(IntPtr thisPtr) - { - if (thisPtr == IntPtr.Zero) - { - return null; - } - return ObjectReference.FromAbi(thisPtr); - } - - private static FromAbiHelper _AbiHelper(IWinRTObject _this) - { - return (FromAbiHelper)_this.GetOrCreateTypeHelperData(typeof(global::System.Collections.IEnumerable).TypeHandle, - () => new FromAbiHelper((global::System.Collections.IEnumerable)_this)); - } - - unsafe global::Microsoft.UI.Xaml.Interop.IBindableIterator global::Microsoft.UI.Xaml.Interop.IBindableIterable.First() - { - var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IEnumerable).TypeHandle); - var ThisPtr = _obj.ThisPtr; - IntPtr __retval = default; - try - { - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[6](ThisPtr, &__retval)); - return MarshalInterface.FromAbi(__retval); - } - finally - { - MarshalInterface.DisposeAbi(__retval); - } - } - - IEnumerator global::System.Collections.IEnumerable.GetEnumerator() - { - return _AbiHelper((IWinRTObject)this).GetEnumerator(); - } - } - - [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] -#if EMBED - internal -#else - public -#endif - static class IEnumerable_Delegates - { - public unsafe delegate int First_0(IntPtr thisPtr, IntPtr* result); - } - -#if EMBED - internal -#else - public -#endif - static class IListMethods - { - public static Guid IID { get; } = new Guid(new global::System.ReadOnlySpan(new byte[] { 0xDE, 0xE7, 0x3D, 0x39, 0xD0, 0x6F, 0x0D, 0x4C, 0xBB, 0x71, 0x47, 0x24, 0x4A, 0x11, 0x3E, 0x93 })); - - public static IntPtr AbiToProjectionVftablePtr => IList.AbiToProjectionVftablePtr; - } - [DynamicInterfaceCastableImplementation] - [Guid("393DE7DE-6FD0-4C0D-BB71-47244A113E93")] - internal unsafe interface IList : global::System.Collections.IList, global::Microsoft.UI.Xaml.Interop.IBindableVector - { - public static string GetGuidSignature() => GuidGenerator.GetSignature(typeof(IList)); - - public sealed class FromAbiHelper : global::System.Collections.IList - { - private readonly global::Microsoft.UI.Xaml.Interop.IBindableVector _vector; - - public FromAbiHelper(global::Microsoft.UI.Xaml.Interop.IBindableVector vector) - { - _vector = vector; - } - - public bool IsSynchronized => false; - - public object SyncRoot { get => this; } - - public int Count - { - get - { - uint size = _vector.Size; - if (((uint)int.MaxValue) < size) - { - throw new InvalidOperationException(WinRTRuntimeErrorStrings.InvalidOperation_CollectionBackingListTooLarge); - } - - return (int)size; - } - } - - public void CopyTo(Array array, int arrayIndex) - { - if (array == null) - throw new ArgumentNullException(nameof(array)); - - // ICollection expects the destination array to be single-dimensional. - if (array.Rank != 1) - throw new ArgumentException(WinRTRuntimeErrorStrings.Arg_RankMultiDimNotSupported); - - int destLB = array.GetLowerBound(0); - int srcLen = Count; - int destLen = array.GetLength(0); - - if (arrayIndex < destLB) - throw new ArgumentOutOfRangeException(nameof(arrayIndex)); - - // Does the dimension in question have sufficient space to copy the expected number of entries? - // We perform this check before valid index check to ensure the exception message is in sync with - // the following snippet that uses regular framework code: - // - // ArrayList list = new ArrayList(); - // list.Add(1); - // Array items = Array.CreateInstance(typeof(object), new int[] { 1 }, new int[] { -1 }); - // list.CopyTo(items, 0); - - if (srcLen > (destLen - (arrayIndex - destLB))) - throw new ArgumentException(WinRTRuntimeErrorStrings.Argument_InsufficientSpaceToCopyCollection); - - if (arrayIndex - destLB > destLen) - throw new ArgumentException(WinRTRuntimeErrorStrings.Argument_IndexOutOfArrayBounds); - - // We need to verify the index as we; - for (uint i = 0; i < srcLen; i++) - { - array.SetValue(_vector.GetAt(i), i + arrayIndex); - } - } - - public object this[int index] - { - get => Indexer_Get(index); - set => Indexer_Set(index, value); - } - - internal object Indexer_Get(int index) - { - if (index < 0) - throw new ArgumentOutOfRangeException(nameof(index)); - - return GetAt(_vector, (uint)index); - } - - internal void Indexer_Set(int index, object value) - { - if (index < 0) - throw new ArgumentOutOfRangeException(nameof(index)); - - SetAt(_vector, (uint)index, value); - } - - public int Add(object value) - { - _vector.Append(value); - - uint size = _vector.Size; - if (((uint)int.MaxValue) < size) - { - throw new InvalidOperationException(WinRTRuntimeErrorStrings.InvalidOperation_CollectionBackingListTooLarge); - } - - return (int)(size - 1); - } - - public bool Contains(object item) - { - return _vector.IndexOf(item, out _); - } - - public void Clear() - { - _vector.Clear(); - } - - public bool IsFixedSize { get => false; } - - public bool IsReadOnly { get => false; } - - public int IndexOf(object item) - { - uint index; - bool exists = _vector.IndexOf(item, out index); - - if (!exists) - return -1; - - if (((uint)int.MaxValue) < index) - { - throw new InvalidOperationException(WinRTRuntimeErrorStrings.InvalidOperation_CollectionBackingListTooLarge); - } - - return (int)index; - } - - public void Insert(int index, object item) - { - if (index < 0) - throw new ArgumentOutOfRangeException(nameof(index)); - - InsertAtHelper(_vector, (uint)index, item); - } - - public void Remove(object item) - { - uint index; - bool exists = _vector.IndexOf(item, out index); - - if (exists) - { - if (((uint)int.MaxValue) < index) - { - throw new InvalidOperationException(WinRTRuntimeErrorStrings.InvalidOperation_CollectionBackingListTooLarge); - } - - RemoveAtHelper(_vector, index); - } - } - - public void RemoveAt(int index) - { - if (index < 0) - throw new ArgumentOutOfRangeException(nameof(index)); - - RemoveAtHelper(_vector, (uint)index); - } - - private static object GetAt(global::Microsoft.UI.Xaml.Interop.IBindableVector _this, uint index) - { - try - { - return _this.GetAt(index); - - // We delegate bounds checking to the underlying collection and if it detected a fault, - // we translate it to the right exception: - } - catch (Exception ex) - { - if (ExceptionHelpers.E_BOUNDS == ex.HResult) - throw new ArgumentOutOfRangeException(nameof(index)); - throw; - } - } - - private static void SetAt(global::Microsoft.UI.Xaml.Interop.IBindableVector _this, uint index, object value) - { - try - { - _this.SetAt(index, value); - - // We delegate bounds checking to the underlying collection and if it detected a fault, - // we translate it to the right exception: - } - catch (Exception ex) - { - if (ExceptionHelpers.E_BOUNDS == ex.HResult) - throw new ArgumentOutOfRangeException(nameof(index)); - throw; - } - } - - private static void InsertAtHelper(global::Microsoft.UI.Xaml.Interop.IBindableVector _this, uint index, object item) - { - try - { - _this.InsertAt(index, item); - - // We delegate bounds checking to the underlying collection and if it detected a fault, - // we translate it to the right exception: - } - catch (Exception ex) - { - if (ExceptionHelpers.E_BOUNDS == ex.HResult) - throw new ArgumentOutOfRangeException(nameof(index)); - throw; - } - } - - private static void RemoveAtHelper(global::Microsoft.UI.Xaml.Interop.IBindableVector _this, uint index) - { - try - { - _this.RemoveAt(index); - - // We delegate bounds checking to the underlying collection and if it detected a fault, - // we translate it to the right exception: - } - catch (Exception ex) - { - if (ExceptionHelpers.E_BOUNDS == ex.HResult) - throw new ArgumentOutOfRangeException(nameof(index)); - throw; - } - } - - public IEnumerator GetEnumerator() - { - return ((IEnumerable)(IWinRTObject)_vector).GetEnumerator(); - } - } - - public sealed class ToAbiHelper : IBindableVector - { - private global::System.Collections.IList _list; - - public ToAbiHelper(global::System.Collections.IList list) => _list = list; - - public object GetAt(uint index) - { - EnsureIndexInt32(index, _list.Count); - - try - { - return _list[(int)index]; - } - catch (ArgumentOutOfRangeException ex) - { - throw ex.GetExceptionForHR(ExceptionHelpers.E_BOUNDS, WinRTRuntimeErrorStrings.ArgumentOutOfRange_Index); - } - } - - public uint Size { get => (uint)_list.Count; } - - IBindableVectorView IBindableVector.GetView() - { - return new ListToBindableVectorViewAdapter(_list); - } - - public bool IndexOf(object value, out uint index) - { - int ind = _list.IndexOf(value); - - if (-1 == ind) - { - index = 0; - return false; - } - - index = (uint)ind; - return true; - } - - public void SetAt(uint index, object value) - { - EnsureIndexInt32(index, _list.Count); - - try - { - _list[(int)index] = value; - } - catch (ArgumentOutOfRangeException ex) - { - throw ex.GetExceptionForHR(ExceptionHelpers.E_BOUNDS, WinRTRuntimeErrorStrings.ArgumentOutOfRange_Index); - } - } - - public void InsertAt(uint index, object value) - { - // Inserting at an index one past the end of the list is equivalent to appending - // so we need to ensure that we're within (0, count + 1). - EnsureIndexInt32(index, _list.Count + 1); - - try - { - _list.Insert((int)index, value); - } - catch (ArgumentOutOfRangeException ex) - { - // Change error code to match what WinRT expects - ex.SetHResult(ExceptionHelpers.E_BOUNDS); - throw; - } - } - - public void RemoveAt(uint index) - { - EnsureIndexInt32(index, _list.Count); - - try - { - _list.RemoveAt((int)index); - } - catch (ArgumentOutOfRangeException ex) - { - // Change error code to match what WinRT expects - ex.SetHResult(ExceptionHelpers.E_BOUNDS); - throw; - } - } - - public void Append(object value) - { - _list.Add(value); - } - - public void RemoveAtEnd() - { - if (_list.Count == 0) - { - Exception e = new InvalidOperationException(WinRTRuntimeErrorStrings.InvalidOperation_CannotRemoveLastFromEmptyCollection); - e.SetHResult(ExceptionHelpers.E_BOUNDS); - throw e; - } - - uint size = (uint)_list.Count; - RemoveAt(size - 1); - } - - public void Clear() - { - _list.Clear(); - } - - private static void EnsureIndexInt32(uint index, int listCapacity) - { - // We use '<=' and not '<' becasue int.MaxValue == index would imply - // that Size > int.MaxValue: - if (((uint)int.MaxValue) <= index || index >= (uint)listCapacity) - { - Exception e = new ArgumentOutOfRangeException(nameof(index), WinRTRuntimeErrorStrings.ArgumentOutOfRange_IndexLargerThanMaxValue); - e.SetHResult(ExceptionHelpers.E_BOUNDS); - throw e; - } - } - public IEnumerator GetEnumerator() => _list.GetEnumerator(); - internal sealed class ListToBindableVectorViewAdapterTypeDetails : IWinRTExposedTypeDetails + /// A Windows Runtime IBindableVectorView implementation that wraps around a managed IList exposing + /// it to Windows runtime interop. + internal sealed class ListToBindableVectorViewAdapter : WUX.IBindableVectorView, MUX.IBindableVectorView, IBindableVectorViewAdapter { - public ComWrappers.ComInterfaceEntry[] GetExposedInterfaces() + private readonly global::System.Collections.IList list; + + internal ListToBindableVectorViewAdapter(global::System.Collections.IList list) + { + if (list == null) + throw new ArgumentNullException(nameof(list)); + this.list = list; + } + + private static void EnsureIndexInt32(uint index, int listCapacity) { - return new ComWrappers.ComInterfaceEntry[] + // We use '<=' and not '<' becasue int.MaxValue == index would imply + // that Size > int.MaxValue: + if (((uint)int.MaxValue) <= index || index >= (uint)listCapacity) { - new ComWrappers.ComInterfaceEntry - { - IID = ABI.Microsoft.UI.Xaml.Interop.IBindableVectorView.IID, - Vtable = ABI.Microsoft.UI.Xaml.Interop.IBindableVectorView.AbiToProjectionVftablePtr - }, - new ComWrappers.ComInterfaceEntry - { - IID = ABI.System.Collections.IEnumerableMethods.IID, - Vtable = ABI.System.Collections.IEnumerableMethods.AbiToProjectionVftablePtr - } - }; + Exception e = new ArgumentOutOfRangeException(nameof(index), WinRTRuntimeErrorStrings.ArgumentOutOfRange_IndexLargerThanMaxValue); + e.SetHResult(ExceptionHelpers.E_BOUNDS); + throw e; + } } - } - /// A Windows Runtime IBindableVectorView implementation that wraps around a managed IList exposing - /// it to Windows runtime interop. - [global::WinRT.WinRTExposedType(typeof(ListToBindableVectorViewAdapterTypeDetails))] - internal sealed class ListToBindableVectorViewAdapter : IBindableVectorView - { - private readonly global::System.Collections.IList list; - - internal ListToBindableVectorViewAdapter(global::System.Collections.IList list) - { - if (list == null) - throw new ArgumentNullException(nameof(list)); - this.list = list; - } - - private static void EnsureIndexInt32(uint index, int listCapacity) - { - // We use '<=' and not '<' becasue int.MaxValue == index would imply - // that Size > int.MaxValue: - if (((uint)int.MaxValue) <= index || index >= (uint)listCapacity) - { - Exception e = new ArgumentOutOfRangeException(nameof(index), WinRTRuntimeErrorStrings.ArgumentOutOfRange_IndexLargerThanMaxValue); - e.SetHResult(ExceptionHelpers.E_BOUNDS); - throw e; - } - } - - public IBindableIterator First() => - IEnumerable.ToAbiHelper.MakeBindableIterator(list.GetEnumerator()); - - public object GetAt(uint index) - { - EnsureIndexInt32(index, list.Count); - - try - { - return list[(int)index]; - } - catch (ArgumentOutOfRangeException ex) - { - throw ex.GetExceptionForHR(ExceptionHelpers.E_BOUNDS, WinRTRuntimeErrorStrings.ArgumentOutOfRange_Index); - } - } - - public uint Size => (uint)list.Count; - - public bool IndexOf(object value, out uint index) - { - int ind = list.IndexOf(value); - - if (-1 == ind) - { - index = 0; - return false; - } - - index = (uint)ind; - return true; - } - - public IEnumerator GetEnumerator() => list.GetEnumerator(); - } + public object GetAt(uint index) + { + EnsureIndexInt32(index, list.Count); + + try + { + return list[(int)index]; + } + catch (ArgumentOutOfRangeException ex) + { + throw ex.GetExceptionForHR(ExceptionHelpers.E_BOUNDS, WinRTRuntimeErrorStrings.ArgumentOutOfRange_Index); + } + } + + public uint Size => (uint)list.Count; + + public bool IndexOf(object value, out uint index) + { + int ind = list.IndexOf(value); + + if (-1 == ind) + { + index = 0; + return false; + } + + index = (uint)ind; + return true; + } + + public IEnumerator GetEnumerator() => list.GetEnumerator(); + } } - public static readonly IntPtr AbiToProjectionVftablePtr; + public static readonly IntPtr AbiToProjectionVftablePtr; static IList() { - AbiToProjectionVftablePtr = ComWrappersSupport.AllocateVtableMemory(typeof(IList), sizeof(IInspectable.Vftbl) + sizeof(IntPtr) * 10); - *(IInspectable.Vftbl*)AbiToProjectionVftablePtr = IInspectable.Vftbl.AbiToProjectionVftable; + AbiToProjectionVftablePtr = ComWrappersSupport.AllocateVtableMemory(typeof(IList), sizeof(IInspectable.Vftbl) + sizeof(IntPtr) * 10); + *(IInspectable.Vftbl*)AbiToProjectionVftablePtr = IInspectable.Vftbl.AbiToProjectionVftable; ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[6] = &Do_Abi_GetAt_0; - ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[7] = &Do_Abi_get_Size_1; - ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[8] = &Do_Abi_GetView_2; - ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[9] = &Do_Abi_IndexOf_3; - ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[10] = &Do_Abi_SetAt_4; - ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[11] = &Do_Abi_InsertAt_5; - ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[12] = &Do_Abi_RemoveAt_6; - ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[13] = &Do_Abi_Append_7; - ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[14] = &Do_Abi_RemoveAtEnd_8; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[7] = &Do_Abi_get_Size_1; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[8] = Projections.UiXamlModeSetting is Projections.UiXamlMode.WindowsUiXaml ? &Do_Wux_Abi_GetView_2 : &Do_Mux_Abi_GetView_2; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[9] = &Do_Abi_IndexOf_3; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[10] = &Do_Abi_SetAt_4; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[11] = &Do_Abi_InsertAt_5; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[12] = &Do_Abi_RemoveAt_6; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[13] = &Do_Abi_Append_7; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[14] = &Do_Abi_RemoveAtEnd_8; ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[15] = &Do_Abi_Clear_9; } private static readonly ConditionalWeakTable _adapterTable = new(); - private static IBindableVector FindAdapter(IntPtr thisPtr) + private static IBindableVectorAdapter FindAdapter(IntPtr thisPtr) { var __this = global::WinRT.ComWrappersSupport.FindObject(thisPtr); return _adapterTable.GetValue(__this, (list) => new ToAbiHelper(list)); @@ -1055,14 +805,32 @@ private static unsafe int Do_Abi_GetAt_0(IntPtr thisPtr, uint index, IntPtr* res } [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] - private static unsafe int Do_Abi_GetView_2(IntPtr thisPtr, IntPtr* result) + private static unsafe int Do_Wux_Abi_GetView_2(IntPtr thisPtr, IntPtr* result) + { + IBindableVectorViewAdapter __result = default; + *result = default; + try + { + __result = FindAdapter(thisPtr).GetView(); + *result = MarshalInterface.FromManaged((WUX.IBindableVectorView)__result); + } + catch (Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + + [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] + private static unsafe int Do_Mux_Abi_GetView_2(IntPtr thisPtr, IntPtr* result) { - global::Microsoft.UI.Xaml.Interop.IBindableVectorView __result = default; + IBindableVectorViewAdapter __result = default; *result = default; try { __result = FindAdapter(thisPtr).GetView(); - *result = MarshalInterface.FromManaged(__result); + *result = MarshalInterface.FromManaged((MUX.IBindableVectorView)__result); } catch (Exception __exception__) { @@ -1201,202 +969,344 @@ private static unsafe int Do_Abi_get_Size_1(IntPtr thisPtr, uint* value) return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); } return 0; - } - - internal static ObjectReference ObjRefFromAbi(IntPtr thisPtr) - { - if (thisPtr == IntPtr.Zero) - { - return null; - } - return ObjectReference.FromAbi(thisPtr); - } - - internal static FromAbiHelper _VectorToList(IWinRTObject _this) - { - return (FromAbiHelper)_this.GetOrCreateTypeHelperData(typeof(global::System.Collections.IList).TypeHandle, - () => new FromAbiHelper((global::Microsoft.UI.Xaml.Interop.IBindableVector)_this)); - } - - unsafe object global::Microsoft.UI.Xaml.Interop.IBindableVector.GetAt(uint index) - { - var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); - var ThisPtr = _obj.ThisPtr; - IntPtr __retval = default; - try - { - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[6](ThisPtr, index, &__retval)); - return MarshalInspectable.FromAbi(__retval); - } - finally - { - MarshalInspectable.DisposeAbi(__retval); - } - } - - unsafe global::Microsoft.UI.Xaml.Interop.IBindableVectorView global::Microsoft.UI.Xaml.Interop.IBindableVector.GetView() - { - var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); - var ThisPtr = _obj.ThisPtr; - IntPtr __retval = default; - try - { - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[8](ThisPtr, &__retval)); - return MarshalInterface.FromAbi(__retval); - } - finally - { - MarshalInterface.DisposeAbi(__retval); - } - } - - unsafe bool global::Microsoft.UI.Xaml.Interop.IBindableVector.IndexOf(object value, out uint index) - { - var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); - var ThisPtr = _obj.ThisPtr; - ObjectReferenceValue __value = default; - uint __index = default; - byte __retval = default; - try - { + } + + internal static ObjectReference ObjRefFromAbi(IntPtr thisPtr) + { + if (thisPtr == IntPtr.Zero) + { + return null; + } + return ObjectReference.FromAbi(thisPtr); + } + + internal static FromAbiHelper _VectorToList(IWinRTObject _this) + { + IBindableVectorAdapter adapter = null; + if (Projections.UiXamlModeSetting is Projections.UiXamlMode.WindowsUiXaml) + { + adapter = new WuxBindableVectorAdapter((WUX.IBindableVector)_this); + } + else + { + adapter = new MuxBindableVectorAdapter((MUX.IBindableVector)_this); + } + return (FromAbiHelper)_this.GetOrCreateTypeHelperData(typeof(global::System.Collections.IList).TypeHandle, + () => new FromAbiHelper(adapter)); + } + + unsafe object WUX.IBindableVector.GetAt(uint index) + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); + var ThisPtr = _obj.ThisPtr; + IntPtr __retval = default; + try + { + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[6](ThisPtr, index, &__retval)); + return MarshalInspectable.FromAbi(__retval); + } + finally + { + MarshalInspectable.DisposeAbi(__retval); + } + } + + unsafe WUX.IBindableVectorView WUX.IBindableVector.GetView() + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); + var ThisPtr = _obj.ThisPtr; + IntPtr __retval = default; + try + { + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[8](ThisPtr, &__retval)); + return MarshalInterface.FromAbi(__retval); + } + finally + { + MarshalInterface.DisposeAbi(__retval); + } + } + + unsafe bool WUX.IBindableVector.IndexOf(object value, out uint index) + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); + var ThisPtr = _obj.ThisPtr; + ObjectReferenceValue __value = default; + uint __index = default; + byte __retval = default; + try + { + __value = MarshalInspectable.CreateMarshaler2(value); + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[9](ThisPtr, MarshalInspectable.GetAbi(__value), &__index, &__retval)); + index = __index; + return __retval != 0; + } + finally + { + MarshalInspectable.DisposeMarshaler(__value); + } + } + + unsafe void WUX.IBindableVector.SetAt(uint index, object value) + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); + var ThisPtr = _obj.ThisPtr; + ObjectReferenceValue __value = default; + try + { + __value = MarshalInspectable.CreateMarshaler2(value); + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[10](ThisPtr, index, MarshalInspectable.GetAbi(__value))); + } + finally + { + MarshalInspectable.DisposeMarshaler(__value); + } + } + + unsafe void WUX.IBindableVector.InsertAt(uint index, object value) + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); + var ThisPtr = _obj.ThisPtr; + ObjectReferenceValue __value = default; + try + { + __value = MarshalInspectable.CreateMarshaler2(value); + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[11](ThisPtr, index, MarshalInspectable.GetAbi(__value))); + } + finally + { + MarshalInspectable.DisposeMarshaler(__value); + } + } + + unsafe void WUX.IBindableVector.RemoveAt(uint index) + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); + var ThisPtr = _obj.ThisPtr; + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[12](ThisPtr, index)); + } + + unsafe void WUX.IBindableVector.Append(object value) + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); + var ThisPtr = _obj.ThisPtr; + ObjectReferenceValue __value = default; + try + { + __value = MarshalInspectable.CreateMarshaler2(value); + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[13](ThisPtr, MarshalInspectable.GetAbi(__value))); + } + finally + { + MarshalInspectable.DisposeMarshaler(__value); + } + } + + unsafe void WUX.IBindableVector.RemoveAtEnd() + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); + var ThisPtr = _obj.ThisPtr; + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[14](ThisPtr)); + } + + unsafe void WUX.IBindableVector.Clear() + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); + var ThisPtr = _obj.ThisPtr; + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[15](ThisPtr)); + } + + unsafe uint WUX.IBindableVector.Size + { + get + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); + var ThisPtr = _obj.ThisPtr; + uint __retval = default; + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[7](ThisPtr, &__retval)); + return __retval; + } + } + + unsafe object MUX.IBindableVector.GetAt(uint index) + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); + var ThisPtr = _obj.ThisPtr; + IntPtr __retval = default; + try + { + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[6](ThisPtr, index, &__retval)); + return MarshalInspectable.FromAbi(__retval); + } + finally + { + MarshalInspectable.DisposeAbi(__retval); + } + } + + unsafe MUX.IBindableVectorView MUX.IBindableVector.GetView() + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); + var ThisPtr = _obj.ThisPtr; + IntPtr __retval = default; + try + { + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[8](ThisPtr, &__retval)); + return MarshalInterface.FromAbi(__retval); + } + finally + { + MarshalInterface.DisposeAbi(__retval); + } + } + + unsafe bool MUX.IBindableVector.IndexOf(object value, out uint index) + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); + var ThisPtr = _obj.ThisPtr; + ObjectReferenceValue __value = default; + uint __index = default; + byte __retval = default; + try + { __value = MarshalInspectable.CreateMarshaler2(value); - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[9](ThisPtr, MarshalInspectable.GetAbi(__value), &__index, &__retval)); - index = __index; - return __retval != 0; - } - finally - { - MarshalInspectable.DisposeMarshaler(__value); - } - } - - unsafe void global::Microsoft.UI.Xaml.Interop.IBindableVector.SetAt(uint index, object value) - { - var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); - var ThisPtr = _obj.ThisPtr; - ObjectReferenceValue __value = default; - try - { + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[9](ThisPtr, MarshalInspectable.GetAbi(__value), &__index, &__retval)); + index = __index; + return __retval != 0; + } + finally + { + MarshalInspectable.DisposeMarshaler(__value); + } + } + + unsafe void MUX.IBindableVector.SetAt(uint index, object value) + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); + var ThisPtr = _obj.ThisPtr; + ObjectReferenceValue __value = default; + try + { __value = MarshalInspectable.CreateMarshaler2(value); - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[10](ThisPtr, index, MarshalInspectable.GetAbi(__value))); - } - finally - { - MarshalInspectable.DisposeMarshaler(__value); - } - } - - unsafe void global::Microsoft.UI.Xaml.Interop.IBindableVector.InsertAt(uint index, object value) - { - var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); - var ThisPtr = _obj.ThisPtr; - ObjectReferenceValue __value = default; - try - { + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[10](ThisPtr, index, MarshalInspectable.GetAbi(__value))); + } + finally + { + MarshalInspectable.DisposeMarshaler(__value); + } + } + + unsafe void MUX.IBindableVector.InsertAt(uint index, object value) + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); + var ThisPtr = _obj.ThisPtr; + ObjectReferenceValue __value = default; + try + { __value = MarshalInspectable.CreateMarshaler2(value); - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[11](ThisPtr, index, MarshalInspectable.GetAbi(__value))); - } - finally - { - MarshalInspectable.DisposeMarshaler(__value); - } - } - - unsafe void global::Microsoft.UI.Xaml.Interop.IBindableVector.RemoveAt(uint index) - { - var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[11](ThisPtr, index, MarshalInspectable.GetAbi(__value))); + } + finally + { + MarshalInspectable.DisposeMarshaler(__value); + } + } + + unsafe void MUX.IBindableVector.RemoveAt(uint index) + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); + var ThisPtr = _obj.ThisPtr; + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[12](ThisPtr, index)); + } + + unsafe void MUX.IBindableVector.Append(object value) + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); var ThisPtr = _obj.ThisPtr; - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[12](ThisPtr, index)); - } - - unsafe void global::Microsoft.UI.Xaml.Interop.IBindableVector.Append(object value) - { - var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); - var ThisPtr = _obj.ThisPtr; - ObjectReferenceValue __value = default; - try - { + ObjectReferenceValue __value = default; + try + { __value = MarshalInspectable.CreateMarshaler2(value); - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[13](ThisPtr, MarshalInspectable.GetAbi(__value))); - } - finally - { - MarshalInspectable.DisposeMarshaler(__value); - } - } - - unsafe void global::Microsoft.UI.Xaml.Interop.IBindableVector.RemoveAtEnd() - { - var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[13](ThisPtr, MarshalInspectable.GetAbi(__value))); + } + finally + { + MarshalInspectable.DisposeMarshaler(__value); + } + } + + unsafe void MUX.IBindableVector.RemoveAtEnd() + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); var ThisPtr = _obj.ThisPtr; - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[14](ThisPtr)); - } - - unsafe void global::Microsoft.UI.Xaml.Interop.IBindableVector.Clear() - { - var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[14](ThisPtr)); + } + + unsafe void MUX.IBindableVector.Clear() + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); var ThisPtr = _obj.ThisPtr; - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[15](ThisPtr)); - } - - unsafe uint global::Microsoft.UI.Xaml.Interop.IBindableVector.Size - { - get - { - var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); - var ThisPtr = _obj.ThisPtr; + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[15](ThisPtr)); + } + + unsafe uint MUX.IBindableVector.Size + { + get + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::System.Collections.IList).TypeHandle); + var ThisPtr = _obj.ThisPtr; uint __retval = default; - global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[7](ThisPtr, &__retval)); - return __retval; - } - } - - object global::System.Collections.IList.this[int index] - { - get => _VectorToList((IWinRTObject)this)[index]; - - set => _VectorToList((IWinRTObject)this)[index] = value; - } - - bool global::System.Collections.IList.IsFixedSize => _VectorToList((IWinRTObject)this).IsFixedSize; - - bool global::System.Collections.IList.IsReadOnly => _VectorToList((IWinRTObject)this).IsReadOnly; - - int global::System.Collections.ICollection.Count => _VectorToList((IWinRTObject)this).Count; - - bool global::System.Collections.ICollection.IsSynchronized => _VectorToList((IWinRTObject)this).IsSynchronized; - - object global::System.Collections.ICollection.SyncRoot => _VectorToList((IWinRTObject)this).SyncRoot; - - int global::System.Collections.IList.Add(object value) => _VectorToList((IWinRTObject)this).Add(value); - - void global::System.Collections.IList.Clear() => _VectorToList((IWinRTObject)this).Clear(); - - bool global::System.Collections.IList.Contains(object value) => _VectorToList((IWinRTObject)this).Contains(value); - - int global::System.Collections.IList.IndexOf(object value) => _VectorToList((IWinRTObject)this).IndexOf(value); - - void global::System.Collections.IList.Insert(int index, object value) => _VectorToList((IWinRTObject)this).Insert(index, value); - - void global::System.Collections.IList.Remove(object value) => _VectorToList((IWinRTObject)this).Remove(value); - - void global::System.Collections.IList.RemoveAt(int index) => _VectorToList((IWinRTObject)this).RemoveAt(index); - - void global::System.Collections.ICollection.CopyTo(Array array, int index) => _VectorToList((IWinRTObject)this).CopyTo(array, index); - - IEnumerator global::System.Collections.IEnumerable.GetEnumerator() => _VectorToList((IWinRTObject)this).GetEnumerator(); - } - internal static class IList_Delegates - { - public unsafe delegate int GetAt_0(IntPtr thisPtr, uint index, IntPtr* result); - public unsafe delegate int get_Size_1(IntPtr thisPtr, uint* result); - public unsafe delegate int GetView_2(IntPtr thisPtr, IntPtr* result); - public unsafe delegate int IndexOf_3(IntPtr thisPtr, IntPtr value, uint* index, byte* returnValue); - public unsafe delegate int SetAt_4(IntPtr thisPtr, uint index, IntPtr value); - public unsafe delegate int InsertAt_5(IntPtr thisPtr, uint index, IntPtr value); - public unsafe delegate int RemoveAt_6(IntPtr thisPtr, uint index); - public unsafe delegate int Append_7(IntPtr thisPtr, IntPtr value); - public unsafe delegate int RemoveAtEnd_8(IntPtr thisPtr); - public unsafe delegate int Clear_9(IntPtr thisPtr); - } -} + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[7](ThisPtr, &__retval)); + return __retval; + } + } + + object global::System.Collections.IList.this[int index] + { + get => _VectorToList((IWinRTObject)this)[index]; + + set => _VectorToList((IWinRTObject)this)[index] = value; + } + + bool global::System.Collections.IList.IsFixedSize => _VectorToList((IWinRTObject)this).IsFixedSize; + + bool global::System.Collections.IList.IsReadOnly => _VectorToList((IWinRTObject)this).IsReadOnly; + + int global::System.Collections.ICollection.Count => _VectorToList((IWinRTObject)this).Count; + + bool global::System.Collections.ICollection.IsSynchronized => _VectorToList((IWinRTObject)this).IsSynchronized; + + object global::System.Collections.ICollection.SyncRoot => _VectorToList((IWinRTObject)this).SyncRoot; + + int global::System.Collections.IList.Add(object value) => _VectorToList((IWinRTObject)this).Add(value); + + void global::System.Collections.IList.Clear() => _VectorToList((IWinRTObject)this).Clear(); + + bool global::System.Collections.IList.Contains(object value) => _VectorToList((IWinRTObject)this).Contains(value); + + int global::System.Collections.IList.IndexOf(object value) => _VectorToList((IWinRTObject)this).IndexOf(value); + + void global::System.Collections.IList.Insert(int index, object value) => _VectorToList((IWinRTObject)this).Insert(index, value); + + void global::System.Collections.IList.Remove(object value) => _VectorToList((IWinRTObject)this).Remove(value); + + void global::System.Collections.IList.RemoveAt(int index) => _VectorToList((IWinRTObject)this).RemoveAt(index); + + void global::System.Collections.ICollection.CopyTo(Array array, int index) => _VectorToList((IWinRTObject)this).CopyTo(array, index); + + IEnumerator global::System.Collections.IEnumerable.GetEnumerator() => _VectorToList((IWinRTObject)this).GetEnumerator(); + } + internal static class IList_Delegates + { + public unsafe delegate int GetAt_0(IntPtr thisPtr, uint index, IntPtr* result); + public unsafe delegate int get_Size_1(IntPtr thisPtr, uint* result); + public unsafe delegate int GetView_2(IntPtr thisPtr, IntPtr* result); + public unsafe delegate int IndexOf_3(IntPtr thisPtr, IntPtr value, uint* index, byte* returnValue); + public unsafe delegate int SetAt_4(IntPtr thisPtr, uint index, IntPtr value); + public unsafe delegate int InsertAt_5(IntPtr thisPtr, uint index, IntPtr value); + public unsafe delegate int RemoveAt_6(IntPtr thisPtr, uint index); + public unsafe delegate int Append_7(IntPtr thisPtr, IntPtr value); + public unsafe delegate int RemoveAtEnd_8(IntPtr thisPtr); + public unsafe delegate int Clear_9(IntPtr thisPtr); + } +} diff --git a/src/WinRT.Runtime/Projections/ICommand.net5.cs b/src/WinRT.Runtime/Projections/ICommand.net5.cs index 8f6ca008a..1f4c89b8c 100644 --- a/src/WinRT.Runtime/Projections/ICommand.net5.cs +++ b/src/WinRT.Runtime/Projections/ICommand.net5.cs @@ -20,6 +20,7 @@ static class ICommandMethods public static IntPtr AbiToProjectionVftablePtr => ICommand.Vftbl.AbiToProjectionVftablePtr; } + // ICommand has the same IID for both Windows.UI.Xaml.Input.ICommand and Microsoft.UI.Xaml.Input.ICommand, so we can use one interface definition for both without marking it as a WUX/MUX type. [EditorBrowsable(EditorBrowsableState.Never)] [Guid("E5AF3542-CA67-4081-995B-709DD13792DF")] [DynamicInterfaceCastableImplementation] diff --git a/src/WinRT.Runtime/Projections/ICustomPropertyProvider.net5.cs b/src/WinRT.Runtime/Projections/ICustomPropertyProvider.net5.cs index ca33a3457..0684e4cf5 100644 --- a/src/WinRT.Runtime/Projections/ICustomPropertyProvider.net5.cs +++ b/src/WinRT.Runtime/Projections/ICustomPropertyProvider.net5.cs @@ -6,6 +6,8 @@ using System.Runtime.InteropServices; using WinRT; +// These types have the same GUIDs in both Microsoft.UI.Xaml and Windows.UI.Xaml, +// so we don't need to duplicate them for the internal usage here as they can be transparently used by both WUX and MUX. namespace Microsoft.UI.Xaml.Data { [global::WinRT.WindowsRuntimeType] diff --git a/src/WinRT.Runtime/Projections/IEnumerable.net5.cs b/src/WinRT.Runtime/Projections/IEnumerable.net5.cs index e27a07dc4..334efee24 100644 --- a/src/WinRT.Runtime/Projections/IEnumerable.net5.cs +++ b/src/WinRT.Runtime/Projections/IEnumerable.net5.cs @@ -938,7 +938,7 @@ public static void DisposeAbi(IntPtr abi) => // In IEnumerator<> scenarios, we use this as a helper for the implementation and don't actually use it to // create a CCW. [global::WinRT.WinRTExposedType(typeof(IBindableIteratorTypeDetails))] - public sealed class ToAbiHelper : global::Windows.Foundation.Collections.IIterator, global::Microsoft.UI.Xaml.Interop.IBindableIterator + public sealed class ToAbiHelper : global::Windows.Foundation.Collections.IIterator, global::Microsoft.UI.Xaml.Interop.IBindableIterator, global::Windows.UI.Xaml.Interop.IBindableIterator { private readonly global::System.Collections.Generic.IEnumerator m_enumerator; private bool m_firstItem = true; @@ -1033,6 +1033,11 @@ public uint GetMany(ref T[] items) // Should not be called. throw new NotImplementedException(); } + uint global::Windows.UI.Xaml.Interop.IBindableIterator.GetMany(ref object[] items) + { + // Should not be called. + throw new NotImplementedException(); + } } public static readonly IntPtr AbiToProjectionVftablePtr; diff --git a/src/WinRT.Runtime/Projections/INotifyCollectionChanged.net5.cs b/src/WinRT.Runtime/Projections/INotifyCollectionChanged.net5.cs index 7c0d94350..161d7cf8e 100644 --- a/src/WinRT.Runtime/Projections/INotifyCollectionChanged.net5.cs +++ b/src/WinRT.Runtime/Projections/INotifyCollectionChanged.net5.cs @@ -1,20 +1,22 @@ -// Copyright (c) Microsoft Corporation. +// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. using System; using System.ComponentModel; +using System.Reflection; using System.Runtime.InteropServices; using WinRT; +using WinRT.Interop; namespace ABI.System.Collections.Specialized -{ +{ #if EMBED - internal + internal #else public #endif - static class INotifyCollectionChangedMethods - { + static class INotifyCollectionChangedMethods + { private volatile static global::System.Runtime.CompilerServices.ConditionalWeakTable _CollectionChanged; private static global::System.Runtime.CompilerServices.ConditionalWeakTable MakeCollectionChangedTable() { @@ -23,7 +25,7 @@ static class INotifyCollectionChangedMethods } private static global::System.Runtime.CompilerServices.ConditionalWeakTable CollectionChanged => _CollectionChanged ?? MakeCollectionChangedTable(); - + public static unsafe (Action, Action) Get_CollectionChanged(IObjectReference obj, object thisObj) { var eventSource = _CollectionChanged.GetValue(thisObj, (key) => @@ -35,19 +37,20 @@ public static unsafe (Action**)ThisPtr)[7]); }); return eventSource.EventActions; - } - - public static global::System.Guid IID { get; } = new Guid(new global::System.ReadOnlySpan(new byte[] { 0xE1, 0x55, 0x01, 0x53, 0xA5, 0x28, 0x93, 0x56, 0x87, 0xCE, 0x30, 0x72, 0x4D, 0x95, 0xA0, 0x6D })); - - public static IntPtr AbiToProjectionVftablePtr => INotifyCollectionChanged.Vftbl.AbiToProjectionVftablePtr; + } + + public static global::System.Guid IID { get; } = GuidGenerator.GetWuxMuxIID(typeof(INotifyCollectionChanged).GetCustomAttribute()); + public static IntPtr AbiToProjectionVftablePtr => INotifyCollectionChanged.Vftbl.AbiToProjectionVftablePtr; } [DynamicInterfaceCastableImplementation] [EditorBrowsable(EditorBrowsableState.Never)] - [Guid("530155E1-28A5-5693-87CE-30724D95A06D")] + [Guid("530155E1-28A5-5693-87CE-30724D95A06D")] + [WuxMuxProjectedType(wuxIID: "CF75D69C-F2F4-486B-B302-BB4C09BAEBFA", muxIID: "530155E1-28A5-5693-87CE-30724D95A06D")] internal unsafe interface INotifyCollectionChanged : global::System.Collections.Specialized.INotifyCollectionChanged { [Guid("530155E1-28A5-5693-87CE-30724D95A06D")] + [WuxMuxProjectedType(wuxIID: "CF75D69C-F2F4-486B-B302-BB4C09BAEBFA", muxIID: "530155E1-28A5-5693-87CE-30724D95A06D")] public struct Vftbl { internal IInspectable.Vftbl IInspectableVftbl; @@ -76,15 +79,15 @@ static unsafe Vftbl() } private volatile static global::System.Runtime.CompilerServices.ConditionalWeakTable> _collectionChanged_TokenTables; - - private static global::System.Runtime.CompilerServices.ConditionalWeakTable> MakeConditionalWeakTable() - { - global::System.Threading.Interlocked.CompareExchange(ref _collectionChanged_TokenTables, new(), null); - return _collectionChanged_TokenTables; + + private static global::System.Runtime.CompilerServices.ConditionalWeakTable> MakeConditionalWeakTable() + { + global::System.Threading.Interlocked.CompareExchange(ref _collectionChanged_TokenTables, new(), null); + return _collectionChanged_TokenTables; } - private static global::System.Runtime.CompilerServices.ConditionalWeakTable> _CollectionChanged_TokenTables => _collectionChanged_TokenTables ?? MakeConditionalWeakTable(); - + private static global::System.Runtime.CompilerServices.ConditionalWeakTable> _CollectionChanged_TokenTables => _collectionChanged_TokenTables ?? MakeConditionalWeakTable(); + [UnmanagedCallersOnly] private static unsafe int Do_Abi_add_CollectionChanged_0(IntPtr thisPtr, IntPtr handler, global::WinRT.EventRegistrationToken* token) { @@ -134,5 +137,5 @@ private static (Action _CollectionChanged((IWinRTObject)this).Item1(value); remove => _CollectionChanged((IWinRTObject)this).Item2(value); } - } + } } diff --git a/src/WinRT.Runtime/Projections/INotifyPropertyChanged.net5.cs b/src/WinRT.Runtime/Projections/INotifyPropertyChanged.net5.cs index 576c284f8..558e8e46c 100644 --- a/src/WinRT.Runtime/Projections/INotifyPropertyChanged.net5.cs +++ b/src/WinRT.Runtime/Projections/INotifyPropertyChanged.net5.cs @@ -2,31 +2,36 @@ // Licensed under the MIT License. using System; +using System.Reflection; using System.Runtime.InteropServices; using WinRT; +using WinRT.Interop; namespace ABI.System.ComponentModel -{ +{ #if EMBED internal #else public #endif static class INotifyPropertyChangedMethods - { - public static global::System.Guid IID { get; } = new Guid(new global::System.ReadOnlySpan(new byte[] { 0x01, 0x76, 0xB1, 0x90, 0x65, 0xB0, 0x6E, 0x58, 0x83, 0xD9, 0x9A, 0xDC, 0x3A, 0x69, 0x52, 0x84 })); + { + public static global::System.Guid IID { get; } = GuidGenerator.GetWuxMuxIID(typeof(INotifyPropertyChanged).GetCustomAttribute()); public static IntPtr AbiToProjectionVftablePtr => INotifyPropertyChanged.Vftbl.AbiToProjectionVftablePtr; } [DynamicInterfaceCastableImplementation] [Guid("90B17601-B065-586E-83D9-9ADC3A695284")] + [WuxMuxProjectedType(wuxIID: "CF75D69C-F2F4-486B-B302-BB4C09BAEBFA", muxIID: "90B17601-B065-586E-83D9-9ADC3A695284")] internal unsafe interface INotifyPropertyChanged : global::System.ComponentModel.INotifyPropertyChanged { [Guid("90B17601-B065-586E-83D9-9ADC3A695284")] [StructLayout(LayoutKind.Sequential)] + [WuxMuxProjectedType(wuxIID: "CF75D69C-F2F4-486B-B302-BB4C09BAEBFA", muxIID: "90B17601-B065-586E-83D9-9ADC3A695284")] public struct Vftbl { + internal IInspectable.Vftbl IInspectableVftbl; private delegate* unmanaged _add_PropertyChanged_0; @@ -67,6 +72,7 @@ private static unsafe int Do_Abi_add_PropertyChanged_0(IntPtr thisPtr, IntPtr ha *token = default; try { + global::System.Diagnostics.Debugger.Launch(); var __this = global::WinRT.ComWrappersSupport.FindObject(thisPtr); var __handler = global::ABI.System.ComponentModel.PropertyChangedEventHandler.FromAbi(handler); *token = _PropertyChanged_TokenTables.GetOrCreateValue(__this).AddEventHandler(__handler); diff --git a/src/WinRT.Runtime/Projections/Microsoft.UI.Xaml.Bindable.net5.cs b/src/WinRT.Runtime/Projections/Microsoft.UI.Xaml.Bindable.net5.cs new file mode 100644 index 000000000..95397bad6 --- /dev/null +++ b/src/WinRT.Runtime/Projections/Microsoft.UI.Xaml.Bindable.net5.cs @@ -0,0 +1,367 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using WinRT; +using WinRT.Interop; + + +#pragma warning disable 0169 // warning CS0169: The field '...' is never used +#pragma warning disable 0649 // warning CS0169: Field '...' is never assigned to + +namespace Microsoft.UI.Xaml.Interop +{ + [global::WinRT.WindowsRuntimeType] + [Guid("036D2C08-DF29-41AF-8AA2-D774BE62BA6F")] + [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Microsoft.UI.Xaml.Interop.IBindableIterable))] + internal interface IBindableIterable + { + IBindableIterator First(); + } + [global::WinRT.WindowsRuntimeType] + [Guid("6A1D6C07-076D-49F2-8314-F52C9C9A8331")] + [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Microsoft.UI.Xaml.Interop.IBindableIterator))] + internal interface IBindableIterator + { + bool MoveNext(); + // GetMany is not implemented by IBindableIterator, but it is here + // for compat purposes with WinUI where there are scenarios they do + // reinterpret_cast from IBindableIterator to IIterable. It is + // the last function in the vftable and shouldn't be called by anyone. + // If called, it will return NotImplementedException. + uint GetMany(ref object[] items); + object Current { get; } + bool HasCurrent { get; } + } + [global::WinRT.WindowsRuntimeType] + [Guid("393DE7DE-6FD0-4C0D-BB71-47244A113E93")] + internal interface IBindableVector : IEnumerable + { + object GetAt(uint index); + IBindableVectorView GetView(); + bool IndexOf(object value, out uint index); + void SetAt(uint index, object value); + void InsertAt(uint index, object value); + void RemoveAt(uint index); + void Append(object value); + void RemoveAtEnd(); + void Clear(); + uint Size { get; } + } + [global::WinRT.WindowsRuntimeType] + [Guid("346DD6E7-976E-4BC3-815D-ECE243BC0F33")] + [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Microsoft.UI.Xaml.Interop.IBindableVectorView))] + internal interface IBindableVectorView : IEnumerable + { + object GetAt(uint index); + bool IndexOf(object value, out uint index); + uint Size { get; } + } +} + +namespace ABI.Microsoft.UI.Xaml.Interop +{ + [DynamicInterfaceCastableImplementation] + [Guid("036D2C08-DF29-41AF-8AA2-D774BE62BA6F")] + internal unsafe interface IBindableIterable : global::Microsoft.UI.Xaml.Interop.IBindableIterable, ABI.System.Collections.IEnumerable + { + + } + + [DynamicInterfaceCastableImplementation] + [Guid("6A1D6C07-076D-49F2-8314-F52C9C9A8331")] + internal unsafe interface IBindableIterator : global::Microsoft.UI.Xaml.Interop.IBindableIterator + { + public static readonly IntPtr AbiToProjectionVftablePtr; + static IBindableIterator() + { + AbiToProjectionVftablePtr = ComWrappersSupport.AllocateVtableMemory(typeof(IBindableIterator), sizeof(IInspectable.Vftbl) + sizeof(IntPtr) * 4); + *(IInspectable.Vftbl*)AbiToProjectionVftablePtr = IInspectable.Vftbl.AbiToProjectionVftable; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[6] = &Do_Abi_get_Current_0; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[7] = &Do_Abi_get_HasCurrent_1; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[8] = &Do_Abi_MoveNext_2; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[9] = &Do_Abi_GetMany_3; + } + + [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] + private static unsafe int Do_Abi_MoveNext_2(IntPtr thisPtr, byte* result) + { + bool __result = default; + *result = default; + try + { + __result = global::WinRT.ComWrappersSupport.FindObject(thisPtr).MoveNext(); + *result = (byte)(__result ? 1 : 0); + } + catch (Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + + [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] + private static unsafe int Do_Abi_GetMany_3(IntPtr thisPtr, int __itemsSize, IntPtr items, uint* result) + { + *result = default; + + try + { + // Should never be called. + throw new NotImplementedException(); + } + catch (Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + } + + [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] + private static unsafe int Do_Abi_get_Current_0(IntPtr thisPtr, IntPtr* value) + { + object __value = default; + *value = default; + try + { + __value = global::WinRT.ComWrappersSupport.FindObject(thisPtr).Current; + *value = MarshalInspectable.FromManaged(__value); + } + catch (Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + + [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] + private static unsafe int Do_Abi_get_HasCurrent_1(IntPtr thisPtr, byte* value) + { + bool __value = default; + *value = default; + try + { + __value = global::WinRT.ComWrappersSupport.FindObject(thisPtr).HasCurrent; + *value = (byte)(__value ? 1 : 0); + } + catch (Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + + internal static ObjectReference FromAbi(IntPtr thisPtr) => ObjectReference.FromAbi(thisPtr); + + unsafe bool global::Microsoft.UI.Xaml.Interop.IBindableIterator.MoveNext() + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::Microsoft.UI.Xaml.Interop.IBindableIterator).TypeHandle); + var ThisPtr = _obj.ThisPtr; + byte __retval = default; + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[8](ThisPtr, &__retval)); + return __retval != 0; + } + + unsafe uint global::Microsoft.UI.Xaml.Interop.IBindableIterator.GetMany(ref object[] items) + { + // Should never be called. + throw new NotImplementedException(); + } + + unsafe object global::Microsoft.UI.Xaml.Interop.IBindableIterator.Current + { + get + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::Microsoft.UI.Xaml.Interop.IBindableIterator).TypeHandle); + var ThisPtr = _obj.ThisPtr; + IntPtr __retval = default; + try + { + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[6](ThisPtr, &__retval)); + return MarshalInspectable.FromAbi(__retval); + } + finally + { + MarshalInspectable.DisposeAbi(__retval); + } + } + } + + unsafe bool global::Microsoft.UI.Xaml.Interop.IBindableIterator.HasCurrent + { + get + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::Microsoft.UI.Xaml.Interop.IBindableIterator).TypeHandle); + var ThisPtr = _obj.ThisPtr; + byte __retval = default; + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[7](ThisPtr, &__retval)); + return __retval != 0; + } + } + + } + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + internal static class IBindableIterator_Delegates + { + public unsafe delegate int get_Current_0(IntPtr thisPtr, IntPtr* result); + public unsafe delegate int get_HasCurrent_1(IntPtr thisPtr, byte* result); + public unsafe delegate int MoveNext_2(IntPtr thisPtr, byte* result); + public unsafe delegate int GetMany_3(IntPtr thisPtr, int itemSize, IntPtr items, uint* result); + } + + [DynamicInterfaceCastableImplementation] + [Guid("346DD6E7-976E-4BC3-815D-ECE243BC0F33")] + internal unsafe interface IBindableVectorView : global::Microsoft.UI.Xaml.Interop.IBindableVectorView + { + public static readonly IntPtr AbiToProjectionVftablePtr; + static IBindableVectorView() + { + AbiToProjectionVftablePtr = ComWrappersSupport.AllocateVtableMemory(typeof(IBindableVectorView), sizeof(IInspectable.Vftbl) + sizeof(IntPtr) * 3); + *(IInspectable.Vftbl*)AbiToProjectionVftablePtr = IInspectable.Vftbl.AbiToProjectionVftable; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[6] = &Do_Abi_GetAt_0; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[7] = &Do_Abi_get_Size_1; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[8] = &Do_Abi_IndexOf_2; + } + + [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] + private static unsafe int Do_Abi_GetAt_0(IntPtr thisPtr, uint index, IntPtr* result) + { + object __result = default; + + try + { + __result = global::WinRT.ComWrappersSupport.FindObject(thisPtr).GetAt(index); + *result = MarshalInspectable.FromManaged(__result); + + } + catch (Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + + [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] + private static unsafe int Do_Abi_IndexOf_2(IntPtr thisPtr, IntPtr value, uint* index, byte* returnValue) + { + bool __returnValue = default; + + *index = default; + *returnValue = default; + uint __index = default; + + try + { + __returnValue = global::WinRT.ComWrappersSupport.FindObject(thisPtr).IndexOf(MarshalInspectable.FromAbi(value), out __index); + *index = __index; + *returnValue = (byte)(__returnValue ? 1 : 0); + + } + catch (Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + + [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] + private static unsafe int Do_Abi_get_Size_1(IntPtr thisPtr, uint* value) + { + uint __value = default; + + *value = default; + + try + { + __value = global::WinRT.ComWrappersSupport.FindObject(thisPtr).Size; + *value = __value; + + } + catch (Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + + internal static ObjectReference FromAbi(IntPtr thisPtr) => ObjectReference.FromAbi(thisPtr); + + private static readonly global::System.Runtime.CompilerServices.ConditionalWeakTable _helperTable = new(); + + unsafe object global::Microsoft.UI.Xaml.Interop.IBindableVectorView.GetAt(uint index) + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::Microsoft.UI.Xaml.Interop.IBindableIterator).TypeHandle); + var ThisPtr = _obj.ThisPtr; + IntPtr __retval = default; + try + { + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[6](ThisPtr, index, &__retval)); + return MarshalInspectable.FromAbi(__retval); + } + finally + { + MarshalInspectable.DisposeAbi(__retval); + } + } + + unsafe bool global::Microsoft.UI.Xaml.Interop.IBindableVectorView.IndexOf(object value, out uint index) + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::Microsoft.UI.Xaml.Interop.IBindableIterator).TypeHandle); + var ThisPtr = _obj.ThisPtr; + ObjectReferenceValue __value = default; + uint __index = default; + byte __retval = default; + try + { + __value = MarshalInspectable.CreateMarshaler2(value); + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[8]( + ThisPtr, + MarshalInspectable.GetAbi(__value), + &__index, + &__retval)); + index = __index; + return __retval != 0; + } + finally + { + MarshalInspectable.DisposeMarshaler(__value); + } + } + + unsafe uint global::Microsoft.UI.Xaml.Interop.IBindableVectorView.Size + { + get + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::Microsoft.UI.Xaml.Interop.IBindableIterator).TypeHandle); + var ThisPtr = _obj.ThisPtr; + uint __retval = default; + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[7](ThisPtr, &__retval)); + return __retval; + } + } + + IEnumerator IEnumerable.GetEnumerator() + { + return _helperTable.GetValue((IWinRTObject)this, + (enumerable) => new ABI.System.Collections.IEnumerable.AdaptiveFromAbiHelper(enumerable) + ).GetEnumerator(); + } + } + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + internal static class IBindableVectorView_Delegates + { + public unsafe delegate int GetAt_0(IntPtr thisPtr, uint index, IntPtr* result); + public unsafe delegate int get_Size_1(IntPtr thisPtr, uint* result); + public unsafe delegate int IndexOf_2(IntPtr thisPtr, IntPtr value, uint* index, byte* returnValue); + } +} diff --git a/src/WinRT.Runtime/Projections/Bindable.netstandard2.0.cs b/src/WinRT.Runtime/Projections/Microsoft.UI.Xaml.Bindable.netstandard2.0.cs similarity index 100% rename from src/WinRT.Runtime/Projections/Bindable.netstandard2.0.cs rename to src/WinRT.Runtime/Projections/Microsoft.UI.Xaml.Bindable.netstandard2.0.cs diff --git a/src/WinRT.Runtime/Projections/NotifyCollectionChangedAction.cs b/src/WinRT.Runtime/Projections/NotifyCollectionChangedAction.cs index b6ccf1bc7..62d5af9f4 100644 --- a/src/WinRT.Runtime/Projections/NotifyCollectionChangedAction.cs +++ b/src/WinRT.Runtime/Projections/NotifyCollectionChangedAction.cs @@ -1,10 +1,15 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. +using WinRT; + namespace ABI.System.Collections.Specialized { static class NotifyCollectionChangedAction { - public static string GetGuidSignature() => "enum(Microsoft.UI.Xaml.Interop.NotifyCollectionChangedAction;i4)"; + public static string GetGuidSignature() => + Projections.UiXamlModeSetting == Projections.UiXamlMode.WindowsUiXaml + ? "enum(Windows.UI.Xaml.Interop.NotifyCollectionChangedAction;i4)" + : "enum(Microsoft.UI.Xaml.Interop.NotifyCollectionChangedAction;i4)"; } } diff --git a/src/WinRT.Runtime/Projections/NotifyCollectionChangedEventArgs.cs b/src/WinRT.Runtime/Projections/NotifyCollectionChangedEventArgs.cs index 2cc04a771..75bb92ca3 100644 --- a/src/WinRT.Runtime/Projections/NotifyCollectionChangedEventArgs.cs +++ b/src/WinRT.Runtime/Projections/NotifyCollectionChangedEventArgs.cs @@ -1,279 +1,368 @@ // Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -using ABI.Microsoft.UI.Xaml.Interop; -using System; -using System.ComponentModel; -using System.Runtime.InteropServices; -using WinRT; -using WinRT.Interop; - -namespace ABI.Microsoft.UI.Xaml.Interop -{ - [global::WinRT.ObjectReferenceWrapper(nameof(_obj))] - [Guid("DA049FF2-D2E0-5FE8-8C7B-F87F26060B6F")] - internal sealed unsafe class INotifyCollectionChangedEventArgs - { - [Guid("DA049FF2-D2E0-5FE8-8C7B-F87F26060B6F")] - [StructLayout(LayoutKind.Sequential)] - public struct Vftbl - { - internal IInspectable.Vftbl IInspectableVftbl; - private void* _get_Action_0; - public delegate* unmanaged[Stdcall] get_Action_0 => (delegate* unmanaged[Stdcall])_get_Action_0; - private void* _get_NewItems_1; - public delegate* unmanaged[Stdcall] get_NewItems_1 => (delegate* unmanaged[Stdcall])_get_NewItems_1; - private void* _get_OldItems_2; - public delegate* unmanaged[Stdcall] get_OldItems_2 => (delegate* unmanaged[Stdcall])_get_OldItems_2; - private void* _get_NewStartingIndex_3; - public delegate* unmanaged[Stdcall] get_NewStartingIndex_3 => (delegate* unmanaged[Stdcall])_get_NewStartingIndex_3; - private void* _get_OldStartingIndex_4; - public delegate* unmanaged[Stdcall] get_OldStartingIndex_4 => (delegate* unmanaged[Stdcall])_get_OldStartingIndex_4; - } - internal static ObjectReference FromAbi(IntPtr thisPtr) => ObjectReference.FromAbi(thisPtr); - - public static implicit operator INotifyCollectionChangedEventArgs(IObjectReference obj) => (obj != null) ? new INotifyCollectionChangedEventArgs(obj) : null; - private readonly ObjectReference _obj; - public IObjectReference ObjRef { get => _obj; } - public IntPtr ThisPtr => _obj.ThisPtr; - public ObjectReference AsInterface() => _obj.As(); - public A As() => _obj.AsType(); - public INotifyCollectionChangedEventArgs(IObjectReference obj) : this(obj.As()) { } - internal INotifyCollectionChangedEventArgs(ObjectReference obj) - { - _obj = obj; - } - - public unsafe global::System.Collections.Specialized.NotifyCollectionChangedAction Action - { - get - { - global::System.Collections.Specialized.NotifyCollectionChangedAction __retval = default; - global::WinRT.ExceptionHelpers.ThrowExceptionForHR(_obj.Vftbl.get_Action_0(ThisPtr, &__retval)); - return __retval; - } - } - - public unsafe global::System.Collections.IList NewItems - { - get - { - IntPtr __retval = default; - try - { - global::WinRT.ExceptionHelpers.ThrowExceptionForHR(_obj.Vftbl.get_NewItems_1(ThisPtr, &__retval)); - return MarshalInterface.FromAbi(__retval); - } - finally - { - MarshalInterface.DisposeAbi(__retval); - } - } - } - - public unsafe int NewStartingIndex - { - get - { - int __retval = default; - global::WinRT.ExceptionHelpers.ThrowExceptionForHR(_obj.Vftbl.get_NewStartingIndex_3(ThisPtr, &__retval)); - return __retval; - } - } - - public unsafe global::System.Collections.IList OldItems - { - get - { - IntPtr __retval = default; - try - { - global::WinRT.ExceptionHelpers.ThrowExceptionForHR(_obj.Vftbl.get_OldItems_2(ThisPtr, &__retval)); - return MarshalInterface.FromAbi(__retval); - } - finally - { - MarshalInterface.DisposeAbi(__retval); - } - } - } - - public unsafe int OldStartingIndex - { - get - { - int __retval = default; - global::WinRT.ExceptionHelpers.ThrowExceptionForHR(_obj.Vftbl.get_OldStartingIndex_4(ThisPtr, &__retval)); - return __retval; - } - } - } - - [global::WinRT.ObjectReferenceWrapper(nameof(_obj))] - [Guid("5108EBA4-4892-5A20-8374-A96815E0FD27")] - internal sealed unsafe class WinRTNotifyCollectionChangedEventArgsRuntimeClassFactory - { - [Guid("5108EBA4-4892-5A20-8374-A96815E0FD27")] - [StructLayout(LayoutKind.Sequential)] - public struct Vftbl - { - internal IInspectable.Vftbl IInspectableVftbl; - private void* _CreateInstanceWithAllParameters_0; - public delegate* unmanaged[Stdcall] CreateInstanceWithAllParameters_0 => (delegate* unmanaged[Stdcall])_CreateInstanceWithAllParameters_0; - } - public static ObjectReference FromAbi(IntPtr thisPtr) => ObjectReference.FromAbi(thisPtr); - - public static implicit operator WinRTNotifyCollectionChangedEventArgsRuntimeClassFactory(IObjectReference obj) => (obj != null) ? new WinRTNotifyCollectionChangedEventArgsRuntimeClassFactory(obj) : null; - public static implicit operator WinRTNotifyCollectionChangedEventArgsRuntimeClassFactory(ObjectReference obj) => (obj != null) ? new WinRTNotifyCollectionChangedEventArgsRuntimeClassFactory(obj) : null; - private readonly ObjectReference _obj; - public IntPtr ThisPtr => _obj.ThisPtr; - public ObjectReference AsInterface() => _obj.As(); - public A As() => _obj.AsType(); - public WinRTNotifyCollectionChangedEventArgsRuntimeClassFactory(IObjectReference obj) : this(obj.As()) { } - public WinRTNotifyCollectionChangedEventArgsRuntimeClassFactory(ObjectReference obj) - { - _obj = obj; - } - - public unsafe IObjectReference CreateInstanceWithAllParameters(global::System.Collections.Specialized.NotifyCollectionChangedAction action, global::System.Collections.IList newItems, global::System.Collections.IList oldItems, int newIndex, int oldIndex, object baseInterface, out IObjectReference innerInterface) - { - ObjectReferenceValue __newItems = default; - ObjectReferenceValue __oldItems = default; - ObjectReferenceValue __baseInterface = default; - IntPtr __innerInterface = default; - IntPtr __retval = default; - try - { - __newItems = MarshalInterface.CreateMarshaler2(newItems); - __oldItems = MarshalInterface.CreateMarshaler2(oldItems); - __baseInterface = MarshalInspectable.CreateMarshaler2(baseInterface); - global::WinRT.ExceptionHelpers.ThrowExceptionForHR(_obj.Vftbl.CreateInstanceWithAllParameters_0(ThisPtr, action, MarshalInterface.GetAbi(__newItems), MarshalInterface.GetAbi(__oldItems), newIndex, oldIndex, MarshalInspectable.GetAbi(__baseInterface), &__innerInterface, &__retval)); - innerInterface = ObjectReference.FromAbi(__innerInterface); - return ObjectReference.FromAbi(__retval); - } - finally - { - MarshalInterface.DisposeMarshaler(__newItems); - MarshalInterface.DisposeMarshaler(__oldItems); - MarshalInspectable.DisposeMarshaler(__baseInterface); - MarshalInspectable.DisposeAbi(__innerInterface); - MarshalInspectable.DisposeAbi(__retval); - } +// Licensed under the MIT License. + +using ABI.Microsoft.UI.Xaml.Interop; +using System; +using System.ComponentModel; +using System.Runtime.InteropServices; +using WinRT; +using WinRT.Interop; + +namespace ABI.Microsoft.UI.Xaml.Interop +{ + [global::WinRT.ObjectReferenceWrapper(nameof(_obj))] + [Guid("DA049FF2-D2E0-5FE8-8C7B-F87F26060B6F")] + [WuxMuxProjectedType(wuxIID: "4CF68D33-E3F2-4964-B85E-945B4F7E2F21", muxIID: "DA049FF2-D2E0-5FE8-8C7B-F87F26060B6F")] + internal sealed unsafe class INotifyCollectionChangedEventArgs + { + [Guid("DA049FF2-D2E0-5FE8-8C7B-F87F26060B6F")] + [StructLayout(LayoutKind.Sequential)] + [WuxMuxProjectedType(wuxIID: "4CF68D33-E3F2-4964-B85E-945B4F7E2F21", muxIID: "DA049FF2-D2E0-5FE8-8C7B-F87F26060B6F")] + public struct Vftbl + { + internal IInspectable.Vftbl IInspectableVftbl; + private void* _get_Action_0; + public delegate* unmanaged[Stdcall] get_Action_0 => (delegate* unmanaged[Stdcall])_get_Action_0; + private void* _get_NewItems_1; + public delegate* unmanaged[Stdcall] get_NewItems_1 => (delegate* unmanaged[Stdcall])_get_NewItems_1; + private void* _get_OldItems_2; + public delegate* unmanaged[Stdcall] get_OldItems_2 => (delegate* unmanaged[Stdcall])_get_OldItems_2; + private void* _get_NewStartingIndex_3; + public delegate* unmanaged[Stdcall] get_NewStartingIndex_3 => (delegate* unmanaged[Stdcall])_get_NewStartingIndex_3; + private void* _get_OldStartingIndex_4; + public delegate* unmanaged[Stdcall] get_OldStartingIndex_4 => (delegate* unmanaged[Stdcall])_get_OldStartingIndex_4; + } + internal static ObjectReference FromAbi(IntPtr thisPtr) => ObjectReference.FromAbi(thisPtr); + + public static implicit operator INotifyCollectionChangedEventArgs(IObjectReference obj) => (obj != null) ? new INotifyCollectionChangedEventArgs(obj) : null; + private readonly ObjectReference _obj; + public IObjectReference ObjRef { get => _obj; } + public IntPtr ThisPtr => _obj.ThisPtr; + public ObjectReference AsInterface() => _obj.As(); + public A As() => _obj.AsType(); + public INotifyCollectionChangedEventArgs(IObjectReference obj) : this(obj.As()) { } + internal INotifyCollectionChangedEventArgs(ObjectReference obj) + { + _obj = obj; + } + + public unsafe global::System.Collections.Specialized.NotifyCollectionChangedAction Action + { + get + { + global::System.Collections.Specialized.NotifyCollectionChangedAction __retval = default; + global::WinRT.ExceptionHelpers.ThrowExceptionForHR(_obj.Vftbl.get_Action_0(ThisPtr, &__retval)); + return __retval; + } + } + + public unsafe global::System.Collections.IList NewItems + { + get + { + IntPtr __retval = default; + try + { + global::WinRT.ExceptionHelpers.ThrowExceptionForHR(_obj.Vftbl.get_NewItems_1(ThisPtr, &__retval)); + return MarshalInterface.FromAbi(__retval); + } + finally + { + MarshalInterface.DisposeAbi(__retval); + } + } + } + + public unsafe int NewStartingIndex + { + get + { + int __retval = default; + global::WinRT.ExceptionHelpers.ThrowExceptionForHR(_obj.Vftbl.get_NewStartingIndex_3(ThisPtr, &__retval)); + return __retval; + } + } + + public unsafe global::System.Collections.IList OldItems + { + get + { + IntPtr __retval = default; + try + { + global::WinRT.ExceptionHelpers.ThrowExceptionForHR(_obj.Vftbl.get_OldItems_2(ThisPtr, &__retval)); + return MarshalInterface.FromAbi(__retval); + } + finally + { + MarshalInterface.DisposeAbi(__retval); + } + } + } + + public unsafe int OldStartingIndex + { + get + { + int __retval = default; + global::WinRT.ExceptionHelpers.ThrowExceptionForHR(_obj.Vftbl.get_OldStartingIndex_4(ThisPtr, &__retval)); + return __retval; + } + } + } + + internal interface IWinRTNotifyCollectionChangedEventArgsRuntimeClassFactory + { + IObjectReference CreateInstanceWithAllParameters(global::System.Collections.Specialized.NotifyCollectionChangedAction action, global::System.Collections.IList newItems, global::System.Collections.IList oldItems, int newIndex, int oldIndex, object baseInterface, out IObjectReference innerInterface); + ObjectReferenceValue CreateInstanceWithAllParameters(global::System.Collections.Specialized.NotifyCollectionChangedAction action, global::System.Collections.IList newItems, global::System.Collections.IList oldItems, int newIndex, int oldIndex); + } + + [global::WinRT.ObjectReferenceWrapper(nameof(_obj))] + [Guid("5108EBA4-4892-5A20-8374-A96815E0FD27")] + internal sealed unsafe class MUXNotifyCollectionChangedEventArgsRuntimeClassFactory : IWinRTNotifyCollectionChangedEventArgsRuntimeClassFactory + { + [Guid("5108EBA4-4892-5A20-8374-A96815E0FD27")] + [StructLayout(LayoutKind.Sequential)] + public struct Vftbl + { + internal IInspectable.Vftbl IInspectableVftbl; + private void* _CreateInstanceWithAllParameters_0; + public delegate* unmanaged[Stdcall] CreateInstanceWithAllParameters_0 => (delegate* unmanaged[Stdcall])_CreateInstanceWithAllParameters_0; + } + public static ObjectReference FromAbi(IntPtr thisPtr) => ObjectReference.FromAbi(thisPtr); + + public static implicit operator MUXNotifyCollectionChangedEventArgsRuntimeClassFactory(IObjectReference obj) => (obj != null) ? new MUXNotifyCollectionChangedEventArgsRuntimeClassFactory(obj) : null; + public static implicit operator MUXNotifyCollectionChangedEventArgsRuntimeClassFactory(ObjectReference obj) => (obj != null) ? new MUXNotifyCollectionChangedEventArgsRuntimeClassFactory(obj) : null; + private readonly ObjectReference _obj; + public IntPtr ThisPtr => _obj.ThisPtr; + public ObjectReference AsInterface() => _obj.As(); + public A As() => _obj.AsType(); + public MUXNotifyCollectionChangedEventArgsRuntimeClassFactory(IObjectReference obj) : this(obj.As()) { } + public MUXNotifyCollectionChangedEventArgsRuntimeClassFactory(ObjectReference obj) + { + _obj = obj; + } + + public unsafe IObjectReference CreateInstanceWithAllParameters(global::System.Collections.Specialized.NotifyCollectionChangedAction action, global::System.Collections.IList newItems, global::System.Collections.IList oldItems, int newIndex, int oldIndex, object baseInterface, out IObjectReference innerInterface) + { + ObjectReferenceValue __newItems = default; + ObjectReferenceValue __oldItems = default; + ObjectReferenceValue __baseInterface = default; + IntPtr __innerInterface = default; + IntPtr __retval = default; + try + { + __newItems = MarshalInterface.CreateMarshaler2(newItems); + __oldItems = MarshalInterface.CreateMarshaler2(oldItems); + __baseInterface = MarshalInspectable.CreateMarshaler2(baseInterface); + global::WinRT.ExceptionHelpers.ThrowExceptionForHR(_obj.Vftbl.CreateInstanceWithAllParameters_0(ThisPtr, action, MarshalInterface.GetAbi(__newItems), MarshalInterface.GetAbi(__oldItems), newIndex, oldIndex, MarshalInspectable.GetAbi(__baseInterface), &__innerInterface, &__retval)); + innerInterface = ObjectReference.FromAbi(__innerInterface); + return ObjectReference.FromAbi(__retval); + } + finally + { + MarshalInterface.DisposeMarshaler(__newItems); + MarshalInterface.DisposeMarshaler(__oldItems); + MarshalInspectable.DisposeMarshaler(__baseInterface); + MarshalInspectable.DisposeAbi(__innerInterface); + MarshalInspectable.DisposeAbi(__retval); + } + } + + public unsafe ObjectReferenceValue CreateInstanceWithAllParameters(global::System.Collections.Specialized.NotifyCollectionChangedAction action, global::System.Collections.IList newItems, global::System.Collections.IList oldItems, int newIndex, int oldIndex) + { + ObjectReferenceValue __newItems = default; + ObjectReferenceValue __oldItems = default; + IntPtr __innerInterface = default; + IntPtr __retval = default; + try + { + __newItems = MarshalInterface.CreateMarshaler2(newItems); + __oldItems = MarshalInterface.CreateMarshaler2(oldItems); + global::WinRT.ExceptionHelpers.ThrowExceptionForHR(_obj.Vftbl.CreateInstanceWithAllParameters_0(ThisPtr, action, MarshalInterface.GetAbi(__newItems), MarshalInterface.GetAbi(__oldItems), newIndex, oldIndex, IntPtr.Zero, &__innerInterface, &__retval)); + return new ObjectReferenceValue(__retval); + } + finally + { + __newItems.Dispose(); + __oldItems.Dispose(); + MarshalInspectable.DisposeAbi(__innerInterface); + } } + } - public unsafe ObjectReferenceValue CreateInstanceWithAllParameters(global::System.Collections.Specialized.NotifyCollectionChangedAction action, global::System.Collections.IList newItems, global::System.Collections.IList oldItems, int newIndex, int oldIndex) - { - ObjectReferenceValue __newItems = default; - ObjectReferenceValue __oldItems = default; - IntPtr __innerInterface = default; - IntPtr __retval = default; - try - { - __newItems = MarshalInterface.CreateMarshaler2(newItems); - __oldItems = MarshalInterface.CreateMarshaler2(oldItems); - global::WinRT.ExceptionHelpers.ThrowExceptionForHR(_obj.Vftbl.CreateInstanceWithAllParameters_0(ThisPtr, action, MarshalInterface.GetAbi(__newItems), MarshalInterface.GetAbi(__oldItems), newIndex, oldIndex, IntPtr.Zero, &__innerInterface, &__retval)); - return new ObjectReferenceValue(__retval); - } - finally - { - __newItems.Dispose(); - __oldItems.Dispose(); - MarshalInspectable.DisposeAbi(__innerInterface); - } - } - } -} - -namespace ABI.System.Collections.Specialized -{ - [EditorBrowsable(EditorBrowsableState.Never)] - [StructLayout(LayoutKind.Sequential)] -#if EMBED - internal -#else - public -#endif - struct NotifyCollectionChangedEventArgs + [global::WinRT.ObjectReferenceWrapper(nameof(_obj))] + [Guid("B30C3E3A-DF8D-44A5-9A38-7AC0D08CE63D")] + internal sealed unsafe class WUXNotifyCollectionChangedEventArgsRuntimeClassFactory : IWinRTNotifyCollectionChangedEventArgsRuntimeClassFactory { - private static WinRTNotifyCollectionChangedEventArgsRuntimeClassFactory Instance = ActivationFactory.Get("Microsoft.UI.Xaml.Interop.NotifyCollectionChangedEventArgs"); - - public static IObjectReference CreateMarshaler(global::System.Collections.Specialized.NotifyCollectionChangedEventArgs value) - { - if (value is null) - { - return null; - } - - return Instance.CreateInstanceWithAllParameters(value.Action, value.NewItems, value.OldItems, value.NewStartingIndex, value.OldStartingIndex, null, out _); + [Guid("B30C3E3A-DF8D-44A5-9A38-7AC0D08CE63D")] + [StructLayout(LayoutKind.Sequential)] + public struct Vftbl + { + internal IInspectable.Vftbl IInspectableVftbl; + private void* _CreateInstanceWithAllParameters_0; + public delegate* unmanaged[Stdcall] CreateInstanceWithAllParameters_0 => (delegate* unmanaged[Stdcall])_CreateInstanceWithAllParameters_0; } + public static ObjectReference FromAbi(IntPtr thisPtr) => ObjectReference.FromAbi(thisPtr); - public static ObjectReferenceValue CreateMarshaler2(global::System.Collections.Specialized.NotifyCollectionChangedEventArgs value) - { - if (value is null) - { - return new ObjectReferenceValue(); - } - - return Instance.CreateInstanceWithAllParameters(value.Action, value.NewItems, value.OldItems, value.NewStartingIndex, value.OldStartingIndex); - } - - public static IntPtr GetAbi(IObjectReference m) => m?.ThisPtr ?? IntPtr.Zero; - - public static global::System.Collections.Specialized.NotifyCollectionChangedEventArgs FromAbi(IntPtr ptr) - { - if (ptr == IntPtr.Zero) - { - return null; - } - - INotifyCollectionChangedEventArgs args = INotifyCollectionChangedEventArgs.FromAbi(ptr); - return CreateNotifyCollectionChangedEventArgs(args.Action, args.NewItems, args.OldItems, args.NewStartingIndex, args.OldStartingIndex); - } - - private static global::System.Collections.Specialized.NotifyCollectionChangedEventArgs CreateNotifyCollectionChangedEventArgs( - global::System.Collections.Specialized.NotifyCollectionChangedAction action, - global::System.Collections.IList newItems, - global::System.Collections.IList oldItems, - int newStartingIndex, - int oldStartingIndex) => - action switch - { - global::System.Collections.Specialized.NotifyCollectionChangedAction.Add => new global::System.Collections.Specialized.NotifyCollectionChangedEventArgs(action, newItems, newStartingIndex), - global::System.Collections.Specialized.NotifyCollectionChangedAction.Remove => new global::System.Collections.Specialized.NotifyCollectionChangedEventArgs(action, oldItems, oldStartingIndex), - global::System.Collections.Specialized.NotifyCollectionChangedAction.Replace => new global::System.Collections.Specialized.NotifyCollectionChangedEventArgs(action, newItems, oldItems, newStartingIndex), - global::System.Collections.Specialized.NotifyCollectionChangedAction.Move => new global::System.Collections.Specialized.NotifyCollectionChangedEventArgs(action, newItems, newStartingIndex, oldStartingIndex), - global::System.Collections.Specialized.NotifyCollectionChangedAction.Reset => new global::System.Collections.Specialized.NotifyCollectionChangedEventArgs(global::System.Collections.Specialized.NotifyCollectionChangedAction.Reset), - _ => throw new ArgumentException(), - }; - - public static unsafe void CopyManaged(global::System.Collections.Specialized.NotifyCollectionChangedEventArgs o, IntPtr dest) - { - *(IntPtr*)dest.ToPointer() = CreateMarshaler2(o).Detach(); - } - - public static IntPtr FromManaged(global::System.Collections.Specialized.NotifyCollectionChangedEventArgs value) - { - if (value is null) - { - return IntPtr.Zero; - } - return CreateMarshaler2(value).Detach(); - } - - public static void DisposeMarshaler(IObjectReference m) { m?.Dispose(); } + public static implicit operator WUXNotifyCollectionChangedEventArgsRuntimeClassFactory(IObjectReference obj) => (obj != null) ? new WUXNotifyCollectionChangedEventArgsRuntimeClassFactory(obj) : null; + public static implicit operator WUXNotifyCollectionChangedEventArgsRuntimeClassFactory(ObjectReference obj) => (obj != null) ? new WUXNotifyCollectionChangedEventArgsRuntimeClassFactory(obj) : null; + private readonly ObjectReference _obj; + public IntPtr ThisPtr => _obj.ThisPtr; + public ObjectReference AsInterface() => _obj.As(); + public A As() => _obj.AsType(); + public WUXNotifyCollectionChangedEventArgsRuntimeClassFactory(IObjectReference obj) : this(obj.As()) { } + public WUXNotifyCollectionChangedEventArgsRuntimeClassFactory(ObjectReference obj) + { + _obj = obj; + } + + public unsafe IObjectReference CreateInstanceWithAllParameters(global::System.Collections.Specialized.NotifyCollectionChangedAction action, global::System.Collections.IList newItems, global::System.Collections.IList oldItems, int newIndex, int oldIndex, object baseInterface, out IObjectReference innerInterface) + { + ObjectReferenceValue __newItems = default; + ObjectReferenceValue __oldItems = default; + ObjectReferenceValue __baseInterface = default; + IntPtr __innerInterface = default; + IntPtr __retval = default; + try + { + __newItems = MarshalInterface.CreateMarshaler2(newItems); + __oldItems = MarshalInterface.CreateMarshaler2(oldItems); + __baseInterface = MarshalInspectable.CreateMarshaler2(baseInterface); + global::WinRT.ExceptionHelpers.ThrowExceptionForHR(_obj.Vftbl.CreateInstanceWithAllParameters_0(ThisPtr, action, MarshalInterface.GetAbi(__newItems), MarshalInterface.GetAbi(__oldItems), newIndex, oldIndex, MarshalInspectable.GetAbi(__baseInterface), &__innerInterface, &__retval)); + innerInterface = ObjectReference.FromAbi(__innerInterface); + return ObjectReference.FromAbi(__retval); + } + finally + { + MarshalInterface.DisposeMarshaler(__newItems); + MarshalInterface.DisposeMarshaler(__oldItems); + MarshalInspectable.DisposeMarshaler(__baseInterface); + MarshalInspectable.DisposeAbi(__innerInterface); + MarshalInspectable.DisposeAbi(__retval); + } + } + + public unsafe ObjectReferenceValue CreateInstanceWithAllParameters(global::System.Collections.Specialized.NotifyCollectionChangedAction action, global::System.Collections.IList newItems, global::System.Collections.IList oldItems, int newIndex, int oldIndex) + { + ObjectReferenceValue __newItems = default; + ObjectReferenceValue __oldItems = default; + IntPtr __innerInterface = default; + IntPtr __retval = default; + try + { + __newItems = MarshalInterface.CreateMarshaler2(newItems); + __oldItems = MarshalInterface.CreateMarshaler2(oldItems); + global::WinRT.ExceptionHelpers.ThrowExceptionForHR(_obj.Vftbl.CreateInstanceWithAllParameters_0(ThisPtr, action, MarshalInterface.GetAbi(__newItems), MarshalInterface.GetAbi(__oldItems), newIndex, oldIndex, IntPtr.Zero, &__innerInterface, &__retval)); + return new ObjectReferenceValue(__retval); + } + finally + { + __newItems.Dispose(); + __oldItems.Dispose(); + MarshalInspectable.DisposeAbi(__innerInterface); + } + } + } +} + +namespace ABI.System.Collections.Specialized +{ + [EditorBrowsable(EditorBrowsableState.Never)] + [StructLayout(LayoutKind.Sequential)] +#if EMBED + internal +#else + public +#endif + struct NotifyCollectionChangedEventArgs + { + private static IWinRTNotifyCollectionChangedEventArgsRuntimeClassFactory Instance = + Projections.UiXamlModeSetting == Projections.UiXamlMode.WindowsUiXaml + ? new WUXNotifyCollectionChangedEventArgsRuntimeClassFactory(ActivationFactory.Get("Windows.UI.Xaml.Interop.NotifyCollectionChangedEventArgs")) + : new MUXNotifyCollectionChangedEventArgsRuntimeClassFactory(ActivationFactory.Get("Microsoft.UI.Xaml.Interop.NotifyCollectionChangedEventArgs")); + + public static IObjectReference CreateMarshaler(global::System.Collections.Specialized.NotifyCollectionChangedEventArgs value) + { + if (value is null) + { + return null; + } + + return Instance.CreateInstanceWithAllParameters(value.Action, value.NewItems, value.OldItems, value.NewStartingIndex, value.OldStartingIndex, null, out _); + } + + public static ObjectReferenceValue CreateMarshaler2(global::System.Collections.Specialized.NotifyCollectionChangedEventArgs value) + { + if (value is null) + { + return new ObjectReferenceValue(); + } + + return Instance.CreateInstanceWithAllParameters(value.Action, value.NewItems, value.OldItems, value.NewStartingIndex, value.OldStartingIndex); + } + + public static IntPtr GetAbi(IObjectReference m) => m?.ThisPtr ?? IntPtr.Zero; + + public static global::System.Collections.Specialized.NotifyCollectionChangedEventArgs FromAbi(IntPtr ptr) + { + if (ptr == IntPtr.Zero) + { + return null; + } + + INotifyCollectionChangedEventArgs args = INotifyCollectionChangedEventArgs.FromAbi(ptr); + return CreateNotifyCollectionChangedEventArgs(args.Action, args.NewItems, args.OldItems, args.NewStartingIndex, args.OldStartingIndex); + } + + private static global::System.Collections.Specialized.NotifyCollectionChangedEventArgs CreateNotifyCollectionChangedEventArgs( + global::System.Collections.Specialized.NotifyCollectionChangedAction action, + global::System.Collections.IList newItems, + global::System.Collections.IList oldItems, + int newStartingIndex, + int oldStartingIndex) => + action switch + { + global::System.Collections.Specialized.NotifyCollectionChangedAction.Add => new global::System.Collections.Specialized.NotifyCollectionChangedEventArgs(action, newItems, newStartingIndex), + global::System.Collections.Specialized.NotifyCollectionChangedAction.Remove => new global::System.Collections.Specialized.NotifyCollectionChangedEventArgs(action, oldItems, oldStartingIndex), + global::System.Collections.Specialized.NotifyCollectionChangedAction.Replace => new global::System.Collections.Specialized.NotifyCollectionChangedEventArgs(action, newItems, oldItems, newStartingIndex), + global::System.Collections.Specialized.NotifyCollectionChangedAction.Move => new global::System.Collections.Specialized.NotifyCollectionChangedEventArgs(action, newItems, newStartingIndex, oldStartingIndex), + global::System.Collections.Specialized.NotifyCollectionChangedAction.Reset => new global::System.Collections.Specialized.NotifyCollectionChangedEventArgs(global::System.Collections.Specialized.NotifyCollectionChangedAction.Reset), + _ => throw new ArgumentException(), + }; + + public static unsafe void CopyManaged(global::System.Collections.Specialized.NotifyCollectionChangedEventArgs o, IntPtr dest) + { + *(IntPtr*)dest.ToPointer() = CreateMarshaler2(o).Detach(); + } + + public static IntPtr FromManaged(global::System.Collections.Specialized.NotifyCollectionChangedEventArgs value) + { + if (value is null) + { + return IntPtr.Zero; + } + return CreateMarshaler2(value).Detach(); + } + + public static void DisposeMarshaler(IObjectReference m) { m?.Dispose(); } public static void DisposeAbi(IntPtr abi) { MarshalInspectable.DisposeAbi(abi); } - public static unsafe MarshalInterfaceHelper.MarshalerArray CreateMarshalerArray(global::System.Collections.Specialized.NotifyCollectionChangedEventArgs[] array) => MarshalInterfaceHelper.CreateMarshalerArray2(array, CreateMarshaler2); - public static (int length, IntPtr data) GetAbiArray(object box) => MarshalInterfaceHelper.GetAbiArray(box); - public static unsafe global::System.Collections.Specialized.NotifyCollectionChangedEventArgs[] FromAbiArray(object box) => MarshalInterfaceHelper.FromAbiArray(box, FromAbi); - public static void CopyAbiArray(global::System.Collections.Specialized.NotifyCollectionChangedEventArgs[] array, object box) => MarshalInterfaceHelper.CopyAbiArray(array, box, FromAbi); - public static (int length, IntPtr data) FromManagedArray(global::System.Collections.Specialized.NotifyCollectionChangedEventArgs[] array) => MarshalInterfaceHelper.FromManagedArray(array, FromManaged); - public static void DisposeMarshalerArray(MarshalInterfaceHelper.MarshalerArray array) => MarshalInterfaceHelper.DisposeMarshalerArray(array); - public static unsafe void DisposeAbiArray(object box) => MarshalInspectable.DisposeAbiArray(box); - - public static string GetGuidSignature() - { - return "rc(Microsoft.UI.Xaml.Interop.NotifyCollectionChangedEventArgs;{4cf68d33-e3f2-4964-b85e-945b4f7e2f21})"; - } - } -} + public static unsafe MarshalInterfaceHelper.MarshalerArray CreateMarshalerArray(global::System.Collections.Specialized.NotifyCollectionChangedEventArgs[] array) => MarshalInterfaceHelper.CreateMarshalerArray2(array, CreateMarshaler2); + public static (int length, IntPtr data) GetAbiArray(object box) => MarshalInterfaceHelper.GetAbiArray(box); + public static unsafe global::System.Collections.Specialized.NotifyCollectionChangedEventArgs[] FromAbiArray(object box) => MarshalInterfaceHelper.FromAbiArray(box, FromAbi); + public static void CopyAbiArray(global::System.Collections.Specialized.NotifyCollectionChangedEventArgs[] array, object box) => MarshalInterfaceHelper.CopyAbiArray(array, box, FromAbi); + public static (int length, IntPtr data) FromManagedArray(global::System.Collections.Specialized.NotifyCollectionChangedEventArgs[] array) => MarshalInterfaceHelper.FromManagedArray(array, FromManaged); + public static void DisposeMarshalerArray(MarshalInterfaceHelper.MarshalerArray array) => MarshalInterfaceHelper.DisposeMarshalerArray(array); + public static unsafe void DisposeAbiArray(object box) => MarshalInspectable.DisposeAbiArray(box); + + public static string GetGuidSignature() + { + if (Projections.UiXamlModeSetting == Projections.UiXamlMode.WindowsUiXaml) + { + return "rc(Windows.UI.Xaml.Interop.NotifyCollectionChangedEventArgs;{4cf68d33-e3f2-4964-b85e-945b4f7e2f21})"; + } + return "rc(Microsoft.UI.Xaml.Interop.NotifyCollectionChangedEventArgs;{4cf68d33-e3f2-4964-b85e-945b4f7e2f21})"; + } + } +} diff --git a/src/WinRT.Runtime/Projections/NotifyCollectionChangedEventHandler.cs b/src/WinRT.Runtime/Projections/NotifyCollectionChangedEventHandler.cs index 1d39d310d..9305dc542 100644 --- a/src/WinRT.Runtime/Projections/NotifyCollectionChangedEventHandler.cs +++ b/src/WinRT.Runtime/Projections/NotifyCollectionChangedEventHandler.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. +// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. using System; @@ -13,6 +13,7 @@ namespace ABI.System.Collections.Specialized [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] [Guid("8B0909DC-2005-5D93-BF8A-725F017BAA8D")] + [WuxMuxProjectedType(wuxIID: "CA10B37C-F382-4591-8557-5E24965279B0", muxIID: "8B0909DC-2005-5D93-BF8A-725F017BAA8D")] #if EMBED internal #else @@ -41,28 +42,32 @@ static unsafe NotifyCollectionChangedEventHandler() var nativeVftbl = ComWrappersSupport.AllocateVtableMemory(typeof(NotifyCollectionChangedEventHandler), Marshal.SizeOf()); Marshal.StructureToPtr(AbiToProjectionVftable, nativeVftbl, false); AbiToProjectionVftablePtr = nativeVftbl; + + IID = Projections.UiXamlModeSetting == Projections.UiXamlMode.WindowsUiXaml + ? Guid.Parse("CA10B37C-F382-4591-8557-5E24965279B0") + : Guid.Parse("8B0909DC-2005-5D93-BF8A-725F017BAA8D"); } public static global::System.Delegate AbiInvokeDelegate { get; } - private static readonly Guid IID = new(0x8B0909DC, 0x2005, 0x5D93, 0xBF, 0x8A, 0x72, 0x5F, 0x01, 0x7B, 0xAA, 0x8D); + private static readonly Guid IID; public static unsafe IObjectReference CreateMarshaler(global::System.Collections.Specialized.NotifyCollectionChangedEventHandler managedDelegate) => - managedDelegate is null ? null : MarshalDelegate.CreateMarshaler(managedDelegate, IID); - + managedDelegate is null ? null : MarshalDelegate.CreateMarshaler(managedDelegate, IID); + public static unsafe ObjectReferenceValue CreateMarshaler2(global::System.Collections.Specialized.NotifyCollectionChangedEventHandler managedDelegate) => MarshalDelegate.CreateMarshaler2(managedDelegate, IID); public static IntPtr GetAbi(IObjectReference value) => MarshalInterfaceHelper.GetAbi(value); public static unsafe global::System.Collections.Specialized.NotifyCollectionChangedEventHandler FromAbi(IntPtr nativeDelegate) - { + { return MarshalDelegate.FromAbi(nativeDelegate); } - public static global::System.Collections.Specialized.NotifyCollectionChangedEventHandler CreateRcw(IntPtr ptr) - { - return new global::System.Collections.Specialized.NotifyCollectionChangedEventHandler(new NativeDelegateWrapper(ComWrappersSupport.GetObjectReferenceForInterface(ptr, IID)).Invoke); + public static global::System.Collections.Specialized.NotifyCollectionChangedEventHandler CreateRcw(IntPtr ptr) + { + return new global::System.Collections.Specialized.NotifyCollectionChangedEventHandler(new NativeDelegateWrapper(ComWrappersSupport.GetObjectReferenceForInterface(ptr, IID)).Invoke); } [global::WinRT.ObjectReferenceWrapper(nameof(_nativeDelegate))] @@ -129,8 +134,8 @@ public static IntPtr FromManaged(global::System.Collections.Specialized.NotifyCo public static void DisposeMarshaler(IObjectReference value) => MarshalInterfaceHelper.DisposeMarshaler(value); - public static void DisposeAbi(IntPtr abi) => MarshalInterfaceHelper.DisposeAbi(abi); - + public static void DisposeAbi(IntPtr abi) => MarshalInterfaceHelper.DisposeAbi(abi); + public static unsafe MarshalInterfaceHelper.MarshalerArray CreateMarshalerArray(global::System.Collections.Specialized.NotifyCollectionChangedEventHandler[] array) => MarshalInterfaceHelper.CreateMarshalerArray2(array, CreateMarshaler2); public static (int length, IntPtr data) GetAbiArray(object box) => MarshalInterfaceHelper.GetAbiArray(box); public static unsafe global::System.Collections.Specialized.NotifyCollectionChangedEventHandler[] FromAbiArray(object box) => MarshalInterfaceHelper.FromAbiArray(box, FromAbi); @@ -145,7 +150,7 @@ public static IntPtr FromManaged(global::System.Collections.Specialized.NotifyCo private static unsafe int Do_Abi_Invoke(IntPtr thisPtr, IntPtr sender, IntPtr e) { try - { + { #if NET var invoke = ComWrappersSupport.FindObject(thisPtr); invoke.Invoke(MarshalInspectable.FromAbi(sender), global::ABI.System.Collections.Specialized.NotifyCollectionChangedEventArgs.FromAbi(e)); @@ -167,9 +172,9 @@ private static unsafe int Do_Abi_Invoke(IntPtr thisPtr, IntPtr sender, IntPtr e) internal sealed unsafe class NotifyCollectionChangedEventSource : EventSource { - internal NotifyCollectionChangedEventSource(IObjectReference obj, + internal NotifyCollectionChangedEventSource(IObjectReference obj, #if NET - delegate* unmanaged[Stdcall] addHandler, + delegate* unmanaged[Stdcall] addHandler, #else delegate* unmanaged[Stdcall] addHandler, #endif diff --git a/src/WinRT.Runtime/Projections/PropertyChangedEventArgs.cs b/src/WinRT.Runtime/Projections/PropertyChangedEventArgs.cs index 4529aff6c..c81fb9afb 100644 --- a/src/WinRT.Runtime/Projections/PropertyChangedEventArgs.cs +++ b/src/WinRT.Runtime/Projections/PropertyChangedEventArgs.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. +// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. using System; @@ -18,10 +18,15 @@ internal unsafe struct IPropertyChangedEventArgsVftbl public delegate* unmanaged[Stdcall] get_PropertyName_0 => (delegate* unmanaged[Stdcall])_get_PropertyName_0; } + internal interface IWinRTPropertyChangedEventArgsRuntimeClassFactory + { + IObjectReference CreateInstance(string name, object baseInterface, out IObjectReference innerInterface); + ObjectReferenceValue CreateInstance(string name); + } [global::WinRT.ObjectReferenceWrapper(nameof(_obj))] [Guid("7C0C27A8-0B41-5070-B160-FC9AE960A36C")] - internal sealed unsafe class WinRTPropertyChangedEventArgsRuntimeClassFactory + internal sealed unsafe class MUXPropertyChangedEventArgsRuntimeClassFactory : IWinRTPropertyChangedEventArgsRuntimeClassFactory { [Guid("7C0C27A8-0B41-5070-B160-FC9AE960A36C")] [StructLayout(LayoutKind.Sequential)] @@ -33,14 +38,14 @@ public struct Vftbl } public static ObjectReference FromAbi(IntPtr thisPtr) => ObjectReference.FromAbi(thisPtr); - public static implicit operator WinRTPropertyChangedEventArgsRuntimeClassFactory(IObjectReference obj) => (obj != null) ? new WinRTPropertyChangedEventArgsRuntimeClassFactory(obj) : null; - public static implicit operator WinRTPropertyChangedEventArgsRuntimeClassFactory(ObjectReference obj) => (obj != null) ? new WinRTPropertyChangedEventArgsRuntimeClassFactory(obj) : null; + public static implicit operator MUXPropertyChangedEventArgsRuntimeClassFactory(IObjectReference obj) => (obj != null) ? new MUXPropertyChangedEventArgsRuntimeClassFactory(obj) : null; + public static implicit operator MUXPropertyChangedEventArgsRuntimeClassFactory(ObjectReference obj) => (obj != null) ? new MUXPropertyChangedEventArgsRuntimeClassFactory(obj) : null; private readonly ObjectReference _obj; public IntPtr ThisPtr => _obj.ThisPtr; public ObjectReference AsInterface() => _obj.As(); public A As() => _obj.AsType(); - public WinRTPropertyChangedEventArgsRuntimeClassFactory(IObjectReference obj) : this(obj.As()) { } - public WinRTPropertyChangedEventArgsRuntimeClassFactory(ObjectReference obj) + public MUXPropertyChangedEventArgsRuntimeClassFactory(IObjectReference obj) : this(obj.As()) { } + public MUXPropertyChangedEventArgsRuntimeClassFactory(ObjectReference obj) { _obj = obj; } @@ -54,11 +59,11 @@ public unsafe IObjectReference CreateInstance(string name, object baseInterface, { MarshalString.Pinnable __name = new(name); fixed (void* ___name = __name) - { + { __baseInterface = MarshalInspectable.CreateMarshaler(baseInterface); global::WinRT.ExceptionHelpers.ThrowExceptionForHR(_obj.Vftbl.CreateInstance_0(ThisPtr, MarshalString.GetAbi(ref __name), MarshalInspectable.GetAbi(__baseInterface), &__innerInterface, &__retval)); innerInterface = ObjectReference.FromAbi(__innerInterface); - return ObjectReference.Attach(ref __retval); + return ObjectReference.Attach(ref __retval); } } finally @@ -67,8 +72,8 @@ public unsafe IObjectReference CreateInstance(string name, object baseInterface, MarshalInspectable.DisposeAbi(__innerInterface); MarshalInspectable.DisposeAbi(__retval); } - } - + } + public unsafe ObjectReferenceValue CreateInstance(string name) { IntPtr __innerInterface = default; @@ -77,7 +82,7 @@ public unsafe ObjectReferenceValue CreateInstance(string name) { MarshalString.Pinnable __name = new(name); fixed (void* ___name = __name) - { + { global::WinRT.ExceptionHelpers.ThrowExceptionForHR(_obj.Vftbl.CreateInstance_0(ThisPtr, MarshalString.GetAbi(ref __name), IntPtr.Zero, &__innerInterface, &__retval)); return new ObjectReferenceValue(__retval); } @@ -87,7 +92,78 @@ public unsafe ObjectReferenceValue CreateInstance(string name) MarshalInspectable.DisposeAbi(__innerInterface); } } + } + + + + [global::WinRT.ObjectReferenceWrapper(nameof(_obj))] + [Guid("6DCC9C03-E0C7-4EEE-8EA9-37E3406EEB1C")] + internal sealed unsafe class WUXPropertyChangedEventArgsRuntimeClassFactory : IWinRTPropertyChangedEventArgsRuntimeClassFactory + { + [Guid("6DCC9C03-E0C7-4EEE-8EA9-37E3406EEB1C")] + [StructLayout(LayoutKind.Sequential)] + public struct Vftbl + { + internal IInspectable.Vftbl IInspectableVftbl; + private void* _CreateInstance_0; + public delegate* unmanaged[Stdcall] CreateInstance_0 => (delegate* unmanaged[Stdcall])_CreateInstance_0; + } + public static ObjectReference FromAbi(IntPtr thisPtr) => ObjectReference.FromAbi(thisPtr); + + public static implicit operator WUXPropertyChangedEventArgsRuntimeClassFactory(IObjectReference obj) => (obj != null) ? new WUXPropertyChangedEventArgsRuntimeClassFactory(obj) : null; + public static implicit operator WUXPropertyChangedEventArgsRuntimeClassFactory(ObjectReference obj) => (obj != null) ? new WUXPropertyChangedEventArgsRuntimeClassFactory(obj) : null; + private readonly ObjectReference _obj; + public IntPtr ThisPtr => _obj.ThisPtr; + public ObjectReference AsInterface() => _obj.As(); + public A As() => _obj.AsType(); + public WUXPropertyChangedEventArgsRuntimeClassFactory(IObjectReference obj) : this(obj.As()) { } + public WUXPropertyChangedEventArgsRuntimeClassFactory(ObjectReference obj) + { + _obj = obj; + } + public unsafe IObjectReference CreateInstance(string name, object baseInterface, out IObjectReference innerInterface) + { + IObjectReference __baseInterface = default; + IntPtr __innerInterface = default; + IntPtr __retval = default; + try + { + MarshalString.Pinnable __name = new(name); + fixed (void* ___name = __name) + { + __baseInterface = MarshalInspectable.CreateMarshaler(baseInterface); + global::WinRT.ExceptionHelpers.ThrowExceptionForHR(_obj.Vftbl.CreateInstance_0(ThisPtr, MarshalString.GetAbi(ref __name), MarshalInspectable.GetAbi(__baseInterface), &__innerInterface, &__retval)); + innerInterface = ObjectReference.FromAbi(__innerInterface); + return ObjectReference.Attach(ref __retval); + } + } + finally + { + MarshalInspectable.DisposeMarshaler(__baseInterface); + MarshalInspectable.DisposeAbi(__innerInterface); + MarshalInspectable.DisposeAbi(__retval); + } + } + + public unsafe ObjectReferenceValue CreateInstance(string name) + { + IntPtr __innerInterface = default; + IntPtr __retval = default; + try + { + MarshalString.Pinnable __name = new(name); + fixed (void* ___name = __name) + { + global::WinRT.ExceptionHelpers.ThrowExceptionForHR(_obj.Vftbl.CreateInstance_0(ThisPtr, MarshalString.GetAbi(ref __name), IntPtr.Zero, &__innerInterface, &__retval)); + return new ObjectReferenceValue(__retval); + } + } + finally + { + MarshalInspectable.DisposeAbi(__innerInterface); + } + } } } @@ -102,7 +178,10 @@ namespace ABI.System.ComponentModel #endif unsafe struct PropertyChangedEventArgs { - private static ABI.Microsoft.UI.Xaml.Data.WinRTPropertyChangedEventArgsRuntimeClassFactory Instance = ActivationFactory.Get("Microsoft.UI.Xaml.Data.PropertyChangedEventArgs"); + private static ABI.Microsoft.UI.Xaml.Data.IWinRTPropertyChangedEventArgsRuntimeClassFactory Instance = + Projections.UiXamlModeSetting == Projections.UiXamlMode.WindowsUiXaml + ? new ABI.Microsoft.UI.Xaml.Data.WUXPropertyChangedEventArgsRuntimeClassFactory(ActivationFactory.Get("Windows.UI.Xaml.Data.PropertyChangedEventArgs")) + : new ABI.Microsoft.UI.Xaml.Data.MUXPropertyChangedEventArgsRuntimeClassFactory(ActivationFactory.Get("Microsoft.UI.Xaml.Data.PropertyChangedEventArgs")); public static IObjectReference CreateMarshaler(global::System.ComponentModel.PropertyChangedEventArgs value) { @@ -112,8 +191,8 @@ public static IObjectReference CreateMarshaler(global::System.ComponentModel.Pro } return Instance.CreateInstance(value.PropertyName, null, out _); - } - + } + public static ObjectReferenceValue CreateMarshaler2(global::System.ComponentModel.PropertyChangedEventArgs value) { if (value is null) @@ -136,6 +215,8 @@ public static ObjectReferenceValue CreateMarshaler2(global::System.ComponentMode IntPtr propertyName = IntPtr.Zero; try { + // We can use the Microsoft.UI.Xaml.Data.IPropertyChangedEventArgsVftbl here in both WUX and MUX because the vtables are laid out the same and we know + // that we have either a MUX or WUX IPropertyChangedEventArgs pointer in ptr. ExceptionHelpers.ThrowExceptionForHR((**(ABI.Microsoft.UI.Xaml.Data.IPropertyChangedEventArgsVftbl**)ptr).get_PropertyName_0(ptr, &propertyName)); return new global::System.ComponentModel.PropertyChangedEventArgs(MarshalString.FromAbi(propertyName)); } @@ -160,8 +241,8 @@ public static IntPtr FromManaged(global::System.ComponentModel.PropertyChangedEv } public static void DisposeMarshaler(IObjectReference m) { m?.Dispose(); } - public static void DisposeAbi(IntPtr abi) { MarshalInspectable.DisposeAbi(abi); } - + public static void DisposeAbi(IntPtr abi) { MarshalInspectable.DisposeAbi(abi); } + public static unsafe MarshalInterfaceHelper.MarshalerArray CreateMarshalerArray(global::System.ComponentModel.PropertyChangedEventArgs[] array) => MarshalInterfaceHelper.CreateMarshalerArray2(array, CreateMarshaler2); public static (int length, IntPtr data) GetAbiArray(object box) => MarshalInterfaceHelper.GetAbiArray(box); public static unsafe global::System.ComponentModel.PropertyChangedEventArgs[] FromAbiArray(object box) => MarshalInterfaceHelper.FromAbiArray(box, FromAbi); @@ -172,6 +253,11 @@ public static IntPtr FromManaged(global::System.ComponentModel.PropertyChangedEv public static string GetGuidSignature() { + if (Projections.UiXamlModeSetting == Projections.UiXamlMode.WindowsUiXaml) + { + return "rc(Windows.UI.Xaml.Data.NotifyPropertyChangedEventArgs;{4f33a9a0-5cf4-47a4-b16f-d7faaf17457e})"; + } + return "rc(Microsoft.UI.Xaml.Data.NotifyPropertyChangedEventArgs;{4f33a9a0-5cf4-47a4-b16f-d7faaf17457e})"; } } diff --git a/src/WinRT.Runtime/Projections/PropertyChangedEventHandler.cs b/src/WinRT.Runtime/Projections/PropertyChangedEventHandler.cs index 28334aadd..3fc9f29ce 100644 --- a/src/WinRT.Runtime/Projections/PropertyChangedEventHandler.cs +++ b/src/WinRT.Runtime/Projections/PropertyChangedEventHandler.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. +// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. using System; @@ -12,6 +12,7 @@ namespace ABI.System.ComponentModel { [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] [Guid("E3DE52F6-1E32-5DA6-BB2D-B5B6096C962D")] + [WuxMuxProjectedType(wuxIID: "50F19C16-0A22-4D8E-A089-1EA9951657D2", muxIID: "E3DE52F6-1E32-5DA6-BB2D-B5B6096C962D")] #if EMBED internal #else @@ -40,28 +41,31 @@ static unsafe PropertyChangedEventHandler() var nativeVftbl = ComWrappersSupport.AllocateVtableMemory(typeof(PropertyChangedEventHandler), Marshal.SizeOf()); Marshal.StructureToPtr(AbiToProjectionVftable, nativeVftbl, false); AbiToProjectionVftablePtr = nativeVftbl; + IID = Projections.UiXamlModeSetting == Projections.UiXamlMode.WindowsUiXaml + ? Guid.Parse("50F19C16-0A22-4D8E-A089-1EA9951657D2") + : Guid.Parse("E3DE52F6-1E32-5DA6-BB2D-B5B6096C962D"); } - public static global::System.Delegate AbiInvokeDelegate { get; } - - private static readonly Guid IID = new(0xE3DE52F6, 0x1E32, 0x5DA6, 0xBB, 0x2D, 0xB5, 0xB6, 0x09, 0x6C, 0x96, 0x2D); + public static global::System.Delegate AbiInvokeDelegate { get; } + + private static readonly Guid IID; public static unsafe IObjectReference CreateMarshaler(global::System.ComponentModel.PropertyChangedEventHandler managedDelegate) => - managedDelegate is null ? null : MarshalDelegate.CreateMarshaler(managedDelegate, IID); - + managedDelegate is null ? null : MarshalDelegate.CreateMarshaler(managedDelegate, IID); + public static unsafe ObjectReferenceValue CreateMarshaler2(global::System.ComponentModel.PropertyChangedEventHandler managedDelegate) => MarshalDelegate.CreateMarshaler2(managedDelegate, IID); public static IntPtr GetAbi(IObjectReference value) => MarshalInterfaceHelper.GetAbi(value); public static unsafe global::System.ComponentModel.PropertyChangedEventHandler FromAbi(IntPtr nativeDelegate) - { + { return MarshalDelegate.FromAbi(nativeDelegate); - } - - public static global::System.ComponentModel.PropertyChangedEventHandler CreateRcw(IntPtr ptr) - { - return new global::System.ComponentModel.PropertyChangedEventHandler(new NativeDelegateWrapper(ComWrappersSupport.GetObjectReferenceForInterface(ptr, IID)).Invoke); + } + + public static global::System.ComponentModel.PropertyChangedEventHandler CreateRcw(IntPtr ptr) + { + return new global::System.ComponentModel.PropertyChangedEventHandler(new NativeDelegateWrapper(ComWrappersSupport.GetObjectReferenceForInterface(ptr, IID)).Invoke); } [global::WinRT.ObjectReferenceWrapper(nameof(_nativeDelegate))] @@ -127,8 +131,8 @@ public static IntPtr FromManaged(global::System.ComponentModel.PropertyChangedEv public static void DisposeMarshaler(IObjectReference value) => MarshalInterfaceHelper.DisposeMarshaler(value); - public static void DisposeAbi(IntPtr abi) => MarshalInterfaceHelper.DisposeAbi(abi); - + public static void DisposeAbi(IntPtr abi) => MarshalInterfaceHelper.DisposeAbi(abi); + public static unsafe MarshalInterfaceHelper.MarshalerArray CreateMarshalerArray(global::System.ComponentModel.PropertyChangedEventHandler[] array) => MarshalInterfaceHelper.CreateMarshalerArray2(array, CreateMarshaler2); public static (int length, IntPtr data) GetAbiArray(object box) => MarshalInterfaceHelper.GetAbiArray(box); public static unsafe global::System.ComponentModel.PropertyChangedEventHandler[] FromAbiArray(object box) => MarshalInterfaceHelper.FromAbiArray(box, FromAbi); @@ -143,7 +147,7 @@ public static IntPtr FromManaged(global::System.ComponentModel.PropertyChangedEv private static unsafe int Do_Abi_Invoke(IntPtr thisPtr, IntPtr sender, IntPtr e) { try - { + { #if NET var invoke = ComWrappersSupport.FindObject(thisPtr); invoke.Invoke(MarshalInspectable.FromAbi(sender), global::ABI.System.ComponentModel.PropertyChangedEventArgs.FromAbi(e)); @@ -167,7 +171,7 @@ internal sealed unsafe class PropertyChangedEventSource : EventSource addHandler, + delegate* unmanaged[Stdcall] addHandler, #else delegate* unmanaged[Stdcall] addHandler, #endif diff --git a/src/WinRT.Runtime/Projections/Windows.UI.Xaml.Bindable.net5.cs b/src/WinRT.Runtime/Projections/Windows.UI.Xaml.Bindable.net5.cs new file mode 100644 index 000000000..7f54e9b25 --- /dev/null +++ b/src/WinRT.Runtime/Projections/Windows.UI.Xaml.Bindable.net5.cs @@ -0,0 +1,367 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using WinRT; +using WinRT.Interop; + + +#pragma warning disable 0169 // warning CS0169: The field '...' is never used +#pragma warning disable 0649 // warning CS0169: Field '...' is never assigned to + +namespace Windows.UI.Xaml.Interop +{ + [global::WinRT.WindowsRuntimeType] + [Guid("036D2C08-DF29-41AF-8AA2-D774BE62BA6F")] + [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Windows.UI.Xaml.Interop.IBindableIterable))] + internal interface IBindableIterable + { + IBindableIterator First(); + } + [global::WinRT.WindowsRuntimeType] + [Guid("6A1D6C07-076D-49F2-8314-F52C9C9A8331")] + [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Windows.UI.Xaml.Interop.IBindableIterator))] + internal interface IBindableIterator + { + bool MoveNext(); + // GetMany is not implemented by IBindableIterator, but it is here + // for compat purposes with WinUI where there are scenarios they do + // reinterpret_cast from IBindableIterator to IIterable. It is + // the last function in the vftable and shouldn't be called by anyone. + // If called, it will return NotImplementedException. + uint GetMany(ref object[] items); + object Current { get; } + bool HasCurrent { get; } + } + [global::WinRT.WindowsRuntimeType] + [Guid("393DE7DE-6FD0-4C0D-BB71-47244A113E93")] + internal interface IBindableVector : IEnumerable + { + object GetAt(uint index); + IBindableVectorView GetView(); + bool IndexOf(object value, out uint index); + void SetAt(uint index, object value); + void InsertAt(uint index, object value); + void RemoveAt(uint index); + void Append(object value); + void RemoveAtEnd(); + void Clear(); + uint Size { get; } + } + [global::WinRT.WindowsRuntimeType] + [Guid("346DD6E7-976E-4BC3-815D-ECE243BC0F33")] + [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Windows.UI.Xaml.Interop.IBindableVectorView))] + internal interface IBindableVectorView : IEnumerable + { + object GetAt(uint index); + bool IndexOf(object value, out uint index); + uint Size { get; } + } +} + +namespace ABI.Windows.UI.Xaml.Interop +{ + [DynamicInterfaceCastableImplementation] + [Guid("036D2C08-DF29-41AF-8AA2-D774BE62BA6F")] + internal unsafe interface IBindableIterable : global::Windows.UI.Xaml.Interop.IBindableIterable, ABI.System.Collections.IEnumerable + { + + } + + [DynamicInterfaceCastableImplementation] + [Guid("6A1D6C07-076D-49F2-8314-F52C9C9A8331")] + internal unsafe interface IBindableIterator : global::Windows.UI.Xaml.Interop.IBindableIterator + { + public static readonly IntPtr AbiToProjectionVftablePtr; + static IBindableIterator() + { + AbiToProjectionVftablePtr = ComWrappersSupport.AllocateVtableMemory(typeof(IBindableIterator), sizeof(IInspectable.Vftbl) + sizeof(IntPtr) * 4); + *(IInspectable.Vftbl*)AbiToProjectionVftablePtr = IInspectable.Vftbl.AbiToProjectionVftable; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[6] = &Do_Abi_get_Current_0; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[7] = &Do_Abi_get_HasCurrent_1; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[8] = &Do_Abi_MoveNext_2; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[9] = &Do_Abi_GetMany_3; + } + + [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] + private static unsafe int Do_Abi_MoveNext_2(IntPtr thisPtr, byte* result) + { + bool __result = default; + *result = default; + try + { + __result = global::WinRT.ComWrappersSupport.FindObject(thisPtr).MoveNext(); + *result = (byte)(__result ? 1 : 0); + } + catch (Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + + [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] + private static unsafe int Do_Abi_GetMany_3(IntPtr thisPtr, int __itemsSize, IntPtr items, uint* result) + { + *result = default; + + try + { + // Should never be called. + throw new NotImplementedException(); + } + catch (Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + } + + [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] + private static unsafe int Do_Abi_get_Current_0(IntPtr thisPtr, IntPtr* value) + { + object __value = default; + *value = default; + try + { + __value = global::WinRT.ComWrappersSupport.FindObject(thisPtr).Current; + *value = MarshalInspectable.FromManaged(__value); + } + catch (Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + + [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] + private static unsafe int Do_Abi_get_HasCurrent_1(IntPtr thisPtr, byte* value) + { + bool __value = default; + *value = default; + try + { + __value = global::WinRT.ComWrappersSupport.FindObject(thisPtr).HasCurrent; + *value = (byte)(__value ? 1 : 0); + } + catch (Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + + internal static ObjectReference FromAbi(IntPtr thisPtr) => ObjectReference.FromAbi(thisPtr); + + unsafe bool global::Windows.UI.Xaml.Interop.IBindableIterator.MoveNext() + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::Windows.UI.Xaml.Interop.IBindableIterator).TypeHandle); + var ThisPtr = _obj.ThisPtr; + byte __retval = default; + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[8](ThisPtr, &__retval)); + return __retval != 0; + } + + unsafe uint global::Windows.UI.Xaml.Interop.IBindableIterator.GetMany(ref object[] items) + { + // Should never be called. + throw new NotImplementedException(); + } + + unsafe object global::Windows.UI.Xaml.Interop.IBindableIterator.Current + { + get + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::Windows.UI.Xaml.Interop.IBindableIterator).TypeHandle); + var ThisPtr = _obj.ThisPtr; + IntPtr __retval = default; + try + { + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[6](ThisPtr, &__retval)); + return MarshalInspectable.FromAbi(__retval); + } + finally + { + MarshalInspectable.DisposeAbi(__retval); + } + } + } + + unsafe bool global::Windows.UI.Xaml.Interop.IBindableIterator.HasCurrent + { + get + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::Windows.UI.Xaml.Interop.IBindableIterator).TypeHandle); + var ThisPtr = _obj.ThisPtr; + byte __retval = default; + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[7](ThisPtr, &__retval)); + return __retval != 0; + } + } + + } + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + internal static class IBindableIterator_Delegates + { + public unsafe delegate int get_Current_0(IntPtr thisPtr, IntPtr* result); + public unsafe delegate int get_HasCurrent_1(IntPtr thisPtr, byte* result); + public unsafe delegate int MoveNext_2(IntPtr thisPtr, byte* result); + public unsafe delegate int GetMany_3(IntPtr thisPtr, int itemSize, IntPtr items, uint* result); + } + + [DynamicInterfaceCastableImplementation] + [Guid("346DD6E7-976E-4BC3-815D-ECE243BC0F33")] + internal unsafe interface IBindableVectorView : global::Windows.UI.Xaml.Interop.IBindableVectorView + { + public static readonly IntPtr AbiToProjectionVftablePtr; + static IBindableVectorView() + { + AbiToProjectionVftablePtr = ComWrappersSupport.AllocateVtableMemory(typeof(IBindableVectorView), sizeof(IInspectable.Vftbl) + sizeof(IntPtr) * 3); + *(IInspectable.Vftbl*)AbiToProjectionVftablePtr = IInspectable.Vftbl.AbiToProjectionVftable; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[6] = &Do_Abi_GetAt_0; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[7] = &Do_Abi_get_Size_1; + ((delegate* unmanaged[Stdcall]*)AbiToProjectionVftablePtr)[8] = &Do_Abi_IndexOf_2; + } + + [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] + private static unsafe int Do_Abi_GetAt_0(IntPtr thisPtr, uint index, IntPtr* result) + { + object __result = default; + + try + { + __result = global::WinRT.ComWrappersSupport.FindObject(thisPtr).GetAt(index); + *result = MarshalInspectable.FromManaged(__result); + + } + catch (Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + + [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] + private static unsafe int Do_Abi_IndexOf_2(IntPtr thisPtr, IntPtr value, uint* index, byte* returnValue) + { + bool __returnValue = default; + + *index = default; + *returnValue = default; + uint __index = default; + + try + { + __returnValue = global::WinRT.ComWrappersSupport.FindObject(thisPtr).IndexOf(MarshalInspectable.FromAbi(value), out __index); + *index = __index; + *returnValue = (byte)(__returnValue ? 1 : 0); + + } + catch (Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + + [UnmanagedCallersOnly(CallConvs = new[] { typeof(CallConvStdcall) })] + private static unsafe int Do_Abi_get_Size_1(IntPtr thisPtr, uint* value) + { + uint __value = default; + + *value = default; + + try + { + __value = global::WinRT.ComWrappersSupport.FindObject(thisPtr).Size; + *value = __value; + + } + catch (Exception __exception__) + { + global::WinRT.ExceptionHelpers.SetErrorInfo(__exception__); + return global::WinRT.ExceptionHelpers.GetHRForException(__exception__); + } + return 0; + } + + internal static ObjectReference FromAbi(IntPtr thisPtr) => ObjectReference.FromAbi(thisPtr); + + private static readonly global::System.Runtime.CompilerServices.ConditionalWeakTable _helperTable = new(); + + unsafe object global::Windows.UI.Xaml.Interop.IBindableVectorView.GetAt(uint index) + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::Windows.UI.Xaml.Interop.IBindableIterator).TypeHandle); + var ThisPtr = _obj.ThisPtr; + IntPtr __retval = default; + try + { + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[6](ThisPtr, index, &__retval)); + return MarshalInspectable.FromAbi(__retval); + } + finally + { + MarshalInspectable.DisposeAbi(__retval); + } + } + + unsafe bool global::Windows.UI.Xaml.Interop.IBindableVectorView.IndexOf(object value, out uint index) + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::Windows.UI.Xaml.Interop.IBindableIterator).TypeHandle); + var ThisPtr = _obj.ThisPtr; + ObjectReferenceValue __value = default; + uint __index = default; + byte __retval = default; + try + { + __value = MarshalInspectable.CreateMarshaler2(value); + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[8]( + ThisPtr, + MarshalInspectable.GetAbi(__value), + &__index, + &__retval)); + index = __index; + return __retval != 0; + } + finally + { + MarshalInspectable.DisposeMarshaler(__value); + } + } + + unsafe uint global::Windows.UI.Xaml.Interop.IBindableVectorView.Size + { + get + { + var _obj = ((IWinRTObject)this).GetObjectReferenceForType(typeof(global::Windows.UI.Xaml.Interop.IBindableIterator).TypeHandle); + var ThisPtr = _obj.ThisPtr; + uint __retval = default; + global::WinRT.ExceptionHelpers.ThrowExceptionForHR((*(delegate* unmanaged[Stdcall]**)ThisPtr)[7](ThisPtr, &__retval)); + return __retval; + } + } + + IEnumerator IEnumerable.GetEnumerator() + { + return _helperTable.GetValue((IWinRTObject)this, + (enumerable) => new ABI.System.Collections.IEnumerable.AdaptiveFromAbiHelper(enumerable) + ).GetEnumerator(); + } + } + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + internal static class IBindableVectorView_Delegates + { + public unsafe delegate int GetAt_0(IntPtr thisPtr, uint index, IntPtr* result); + public unsafe delegate int get_Size_1(IntPtr thisPtr, uint* result); + public unsafe delegate int IndexOf_2(IntPtr thisPtr, IntPtr value, uint* index, byte* returnValue); + } +} diff --git a/src/cswinrt.sln b/src/cswinrt.sln index bdc0d86a0..e6bb53157 100644 --- a/src/cswinrt.sln +++ b/src/cswinrt.sln @@ -160,6 +160,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WinAppSDK", "Projections\Wi EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestLibrary", "Tests\FunctionalTests\TestLibrary\TestLibrary.csproj", "{335D51AC-1DCF-4487-A2BD-34CE2F17B3C4}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Windows.UI.Xaml", "Projections\Windows.UI.Xaml\Windows.UI.Xaml.csproj", "{E85F3614-79B6-4652-BDB0-64AF68874CE0}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AuthoringWuxTest", "Tests\AuthoringWuxTest\AuthoringWuxTest.csproj", "{D60CFCAD-4A13-4047-91C8-9D7DF4753493}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AuthoringWuxConsumptionTest", "Tests\AuthoringWuxConsumptionTest\AuthoringWuxConsumptionTest.vcxproj", "{A04A0416-5E35-4DD0-8226-63D941B28467}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|ARM = Debug|ARM @@ -732,6 +738,54 @@ Global {335D51AC-1DCF-4487-A2BD-34CE2F17B3C4}.Release|x64.Build.0 = Release|x64 {335D51AC-1DCF-4487-A2BD-34CE2F17B3C4}.Release|x86.ActiveCfg = Release|x86 {335D51AC-1DCF-4487-A2BD-34CE2F17B3C4}.Release|x86.Build.0 = Release|x86 + {E85F3614-79B6-4652-BDB0-64AF68874CE0}.Debug|ARM.ActiveCfg = Debug|x86 + {E85F3614-79B6-4652-BDB0-64AF68874CE0}.Debug|ARM.Build.0 = Debug|x86 + {E85F3614-79B6-4652-BDB0-64AF68874CE0}.Debug|ARM64.ActiveCfg = Debug|x86 + {E85F3614-79B6-4652-BDB0-64AF68874CE0}.Debug|ARM64.Build.0 = Debug|x86 + {E85F3614-79B6-4652-BDB0-64AF68874CE0}.Debug|x64.ActiveCfg = Debug|x64 + {E85F3614-79B6-4652-BDB0-64AF68874CE0}.Debug|x64.Build.0 = Debug|x64 + {E85F3614-79B6-4652-BDB0-64AF68874CE0}.Debug|x86.ActiveCfg = Debug|x86 + {E85F3614-79B6-4652-BDB0-64AF68874CE0}.Debug|x86.Build.0 = Debug|x86 + {E85F3614-79B6-4652-BDB0-64AF68874CE0}.Release|ARM.ActiveCfg = Release|x86 + {E85F3614-79B6-4652-BDB0-64AF68874CE0}.Release|ARM.Build.0 = Release|x86 + {E85F3614-79B6-4652-BDB0-64AF68874CE0}.Release|ARM64.ActiveCfg = Release|x86 + {E85F3614-79B6-4652-BDB0-64AF68874CE0}.Release|ARM64.Build.0 = Release|x86 + {E85F3614-79B6-4652-BDB0-64AF68874CE0}.Release|x64.ActiveCfg = Release|x64 + {E85F3614-79B6-4652-BDB0-64AF68874CE0}.Release|x64.Build.0 = Release|x64 + {E85F3614-79B6-4652-BDB0-64AF68874CE0}.Release|x86.ActiveCfg = Release|x86 + {E85F3614-79B6-4652-BDB0-64AF68874CE0}.Release|x86.Build.0 = Release|x86 + {D60CFCAD-4A13-4047-91C8-9D7DF4753493}.Debug|ARM.ActiveCfg = Debug|x86 + {D60CFCAD-4A13-4047-91C8-9D7DF4753493}.Debug|ARM.Build.0 = Debug|x86 + {D60CFCAD-4A13-4047-91C8-9D7DF4753493}.Debug|ARM64.ActiveCfg = Debug|x86 + {D60CFCAD-4A13-4047-91C8-9D7DF4753493}.Debug|ARM64.Build.0 = Debug|x86 + {D60CFCAD-4A13-4047-91C8-9D7DF4753493}.Debug|x64.ActiveCfg = Debug|x64 + {D60CFCAD-4A13-4047-91C8-9D7DF4753493}.Debug|x64.Build.0 = Debug|x64 + {D60CFCAD-4A13-4047-91C8-9D7DF4753493}.Debug|x86.ActiveCfg = Debug|x86 + {D60CFCAD-4A13-4047-91C8-9D7DF4753493}.Debug|x86.Build.0 = Debug|x86 + {D60CFCAD-4A13-4047-91C8-9D7DF4753493}.Release|ARM.ActiveCfg = Release|x86 + {D60CFCAD-4A13-4047-91C8-9D7DF4753493}.Release|ARM.Build.0 = Release|x86 + {D60CFCAD-4A13-4047-91C8-9D7DF4753493}.Release|ARM64.ActiveCfg = Release|x86 + {D60CFCAD-4A13-4047-91C8-9D7DF4753493}.Release|ARM64.Build.0 = Release|x86 + {D60CFCAD-4A13-4047-91C8-9D7DF4753493}.Release|x64.ActiveCfg = Release|x64 + {D60CFCAD-4A13-4047-91C8-9D7DF4753493}.Release|x64.Build.0 = Release|x64 + {D60CFCAD-4A13-4047-91C8-9D7DF4753493}.Release|x86.ActiveCfg = Release|x86 + {D60CFCAD-4A13-4047-91C8-9D7DF4753493}.Release|x86.Build.0 = Release|x86 + {A04A0416-5E35-4DD0-8226-63D941B28467}.Debug|ARM.ActiveCfg = Debug|Win32 + {A04A0416-5E35-4DD0-8226-63D941B28467}.Debug|ARM.Build.0 = Debug|Win32 + {A04A0416-5E35-4DD0-8226-63D941B28467}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {A04A0416-5E35-4DD0-8226-63D941B28467}.Debug|ARM64.Build.0 = Debug|ARM64 + {A04A0416-5E35-4DD0-8226-63D941B28467}.Debug|x64.ActiveCfg = Debug|x64 + {A04A0416-5E35-4DD0-8226-63D941B28467}.Debug|x64.Build.0 = Debug|x64 + {A04A0416-5E35-4DD0-8226-63D941B28467}.Debug|x86.ActiveCfg = Debug|Win32 + {A04A0416-5E35-4DD0-8226-63D941B28467}.Debug|x86.Build.0 = Debug|Win32 + {A04A0416-5E35-4DD0-8226-63D941B28467}.Release|ARM.ActiveCfg = Release|Win32 + {A04A0416-5E35-4DD0-8226-63D941B28467}.Release|ARM.Build.0 = Release|Win32 + {A04A0416-5E35-4DD0-8226-63D941B28467}.Release|ARM64.ActiveCfg = Release|ARM64 + {A04A0416-5E35-4DD0-8226-63D941B28467}.Release|ARM64.Build.0 = Release|ARM64 + {A04A0416-5E35-4DD0-8226-63D941B28467}.Release|x64.ActiveCfg = Release|x64 + {A04A0416-5E35-4DD0-8226-63D941B28467}.Release|x64.Build.0 = Release|x64 + {A04A0416-5E35-4DD0-8226-63D941B28467}.Release|x86.ActiveCfg = Release|Win32 + {A04A0416-5E35-4DD0-8226-63D941B28467}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -777,6 +831,9 @@ Global {C44DB047-5DF0-4732-98F4-A181D3AD8A7F} = {5ECC38F0-16FD-47E1-B8DC-8C474008AD55} {7B803846-91AE-4B98-AC93-D3FCFB2DE5AA} = {6D41796B-9904-40B8-BBCB-40B2D1BAE44B} {335D51AC-1DCF-4487-A2BD-34CE2F17B3C4} = {5ECC38F0-16FD-47E1-B8DC-8C474008AD55} + {E85F3614-79B6-4652-BDB0-64AF68874CE0} = {6D41796B-9904-40B8-BBCB-40B2D1BAE44B} + {D60CFCAD-4A13-4047-91C8-9D7DF4753493} = {CFB651EC-DAA4-4A11-ABCD-C77F90602EB5} + {A04A0416-5E35-4DD0-8226-63D941B28467} = {CFB651EC-DAA4-4A11-ABCD-C77F90602EB5} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {5AE8C9D7-2613-4E1A-A4F2-579BAC28D0A2} diff --git a/src/cswinrt/code_writers.h b/src/cswinrt/code_writers.h index 43bf8381b..db36d19ca 100644 --- a/src/cswinrt/code_writers.h +++ b/src/cswinrt/code_writers.h @@ -1440,7 +1440,7 @@ private % Make_%() if (event.Name() == "CanExecuteChanged" && event_type == "global::System.EventHandler") { auto parent_type = w.write_temp("%", bind(event.Parent(), typedef_name_type::NonProjected, true)); - if (parent_type == "Microsoft.UI.Xaml.Input.ICommand") + if (parent_type == "Microsoft.UI.Xaml.Input.ICommand" || parent_type == "Windows.UI.Xaml.Input.ICommand") { event_type = "global::System.EventHandler"; } diff --git a/src/cswinrt/cswinrt.vcxproj b/src/cswinrt/cswinrt.vcxproj index 674c12582..6980f4ebe 100644 --- a/src/cswinrt/cswinrt.vcxproj +++ b/src/cswinrt/cswinrt.vcxproj @@ -109,6 +109,12 @@ + + + + + + diff --git a/src/cswinrt/cswinrt.vcxproj.filters b/src/cswinrt/cswinrt.vcxproj.filters index 57e31721d..b06989e5d 100644 --- a/src/cswinrt/cswinrt.vcxproj.filters +++ b/src/cswinrt/cswinrt.vcxproj.filters @@ -51,6 +51,21 @@ {369a6d8a-43e6-48af-82c1-bb2e555909a4} + + {22aeef74-f4df-40f4-a18f-8053ac54f966} + + + {bb545b29-ba72-4949-b044-790f57ba17a5} + + + {8451fa83-9750-4aec-ae8c-a4149c4b98a6} + + + {98453be9-888b-4032-b5cd-4034b17197c9} + + + {03980bb6-f657-4c07-a456-5b4774de5773} + @@ -174,6 +189,24 @@ strings + + strings\additions\Windows.UI.Xaml.Controls.Primitives + + + strings\additions\Windows.UI.Xaml.Media.Animation + + + strings\additions\Windows.UI.Xaml.Media.Media3D + + + strings\additions\Windows.UI.Xaml.Media + + + strings\additions\Windows.UI.Xaml + + + strings\additions\Windows.UI.Xaml + diff --git a/src/cswinrt/helpers.h b/src/cswinrt/helpers.h index fcc3f7cc3..93b1ce916 100644 --- a/src/cswinrt/helpers.h +++ b/src/cswinrt/helpers.h @@ -670,7 +670,8 @@ namespace cswinrt } mapped_types[] = { // Make sure to keep this table consistent with the registrations in WinRT.Runtime/Projections.cs - // and the reverse mapping in WinRT.SourceGenerator/WinRTTypeWriter.cs. + // and the reverse mapping in WinRT.SourceGenerator/TypeMapper.cs. + // This table can include both the MUX and WUX types as only one will be selected at runtime. // NOTE: Must keep namespaces sorted (outer) and abi type names sorted (inner) { "Microsoft.UI.Xaml", { @@ -816,13 +817,92 @@ namespace cswinrt { "IColorHelperStatics2" }, } }, - // Temporary, until WinUI provides TypeName + { "Windows.UI.Xaml", + { + { "CornerRadius", "Windows.UI.Xaml", "CornerRadius" }, + { "CornerRadiusHelper" }, + { "Duration", "Windows.UI.Xaml", "Duration" }, + { "DurationHelper" }, + { "DurationType", "Windows.UI.Xaml", "DurationType" }, + { "GridLength", "Windows.UI.Xaml", "GridLength" }, + { "GridLengthHelper" }, + { "GridUnitType", "Windows.UI.Xaml", "GridUnitType" }, + { "ICornerRadiusHelper" }, + { "ICornerRadiusHelperStatics" }, + { "IDurationHelper" }, + { "IDurationHelperStatics" }, + { "IGridLengthHelper" }, + { "IGridLengthHelperStatics" }, + { "IThicknessHelper" }, + { "IThicknessHelperStatics" }, + { "Thickness", "Windows.UI.Xaml", "Thickness" }, + { "ThicknessHelper" }, + { "IXamlServiceProvider", "System", "IServiceProvider" }, + } + }, + { "Windows.UI.Xaml.Controls.Primitives", + { + { "GeneratorPosition", "Windows.UI.Xaml.Controls.Primitives", "GeneratorPosition" }, + { "GeneratorPositionHelper" }, + { "IGeneratorPositionHelper" }, + { "IGeneratorPositionHelperStatics" }, + } + }, + { "Windows.UI.Xaml.Data", + { + { "DataErrorsChangedEventArgs", "System.ComponentModel", "DataErrorsChangedEventArgs" }, + { "INotifyDataErrorInfo", "System.ComponentModel", "INotifyDataErrorInfo", true, true }, + { "INotifyPropertyChanged", "System.ComponentModel", "INotifyPropertyChanged" }, + { "PropertyChangedEventArgs", "System.ComponentModel", "PropertyChangedEventArgs" }, + { "PropertyChangedEventHandler", "System.ComponentModel", "PropertyChangedEventHandler" }, + } + }, + { "Windows.UI.Xaml.Input", + { + { "ICommand", "System.Windows.Input", "ICommand", true } + } + }, { "Windows.UI.Xaml.Interop", { + { "IBindableIterable", "System.Collections", "IEnumerable", true, true }, + { "IBindableVector", "System.Collections", "IList", true, true }, + { "INotifyCollectionChanged", "System.Collections.Specialized", "INotifyCollectionChanged", true }, + { "NotifyCollectionChangedAction", "System.Collections.Specialized", "NotifyCollectionChangedAction" }, + { "NotifyCollectionChangedEventArgs", "System.Collections.Specialized", "NotifyCollectionChangedEventArgs", true }, + { "NotifyCollectionChangedEventHandler", "System.Collections.Specialized", "NotifyCollectionChangedEventHandler", true }, { "TypeKind", "Windows.UI.Xaml.Interop", "TypeKind", true }, { "TypeName", "System", "Type", true } } }, + { "Windows.UI.Xaml.Media", + { + { "IMatrixHelper" }, + { "IMatrixHelperStatics" }, + { "Matrix", "Windows.UI.Xaml.Media", "Matrix" }, + { "MatrixHelper" }, + } + }, + { "Windows.UI.Xaml.Media.Animation", + { + { "IKeyTimeHelper" }, + { "IKeyTimeHelperStatics" }, + { "IRepeatBehaviorHelper" }, + { "IRepeatBehaviorHelperStatics" }, + { "KeyTime", "Windows.UI.Xaml.Media.Animation", "KeyTime" }, + { "KeyTimeHelper" }, + { "RepeatBehavior", "Windows.UI.Xaml.Media.Animation", "RepeatBehavior" }, + { "RepeatBehaviorHelper" }, + { "RepeatBehaviorType", "Windows.UI.Xaml.Media.Animation", "RepeatBehaviorType" } + } + }, + { "Windows.UI.Xaml.Media.Media3D", + { + { "IMatrix3DHelper" }, + { "IMatrix3DHelperStatics" }, + { "Matrix3D", "Windows.UI.Xaml.Media.Media3D", "Matrix3D" }, + { "Matrix3DHelper" }, + } + }, }; auto nsItr = std::lower_bound(std::begin(mapped_types), std::end(mapped_types), typeNamespace, [](auto&& v, std::string_view ns) diff --git a/src/cswinrt/strings/additions/Windows.UI.Xaml.Controls/Windows.UI.Xaml.Controls.Primitives.cs b/src/cswinrt/strings/additions/Windows.UI.Xaml.Controls/Windows.UI.Xaml.Controls.Primitives.cs new file mode 100644 index 000000000..ec28e9295 --- /dev/null +++ b/src/cswinrt/strings/additions/Windows.UI.Xaml.Controls/Windows.UI.Xaml.Controls.Primitives.cs @@ -0,0 +1,73 @@ + +namespace Windows.UI.Xaml.Controls.Primitives +{ + using global::Windows.Foundation; + + [global::WinRT.WindowsRuntimeType("Windows.UI.Xaml")] + [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Windows.UI.Xaml.Controls.Primitives.GeneratorPosition))] + [StructLayout(LayoutKind.Sequential)] +#if EMBED + internal +#else + public +#endif + struct GeneratorPosition + { + private int _index; + private int _offset; + + public int Index { get { return _index; } set { _index = value; } } + public int Offset { get { return _offset; } set { _offset = value; } } + + public GeneratorPosition(int index, int offset) + { + _index = index; + _offset = offset; + } + + public override int GetHashCode() + { + return _index.GetHashCode() + _offset.GetHashCode(); + } + + public override string ToString() + { + return string.Concat("GeneratorPosition (", _index.ToString(global::System.Globalization.CultureInfo.InvariantCulture), ",", _offset.ToString(global::System.Globalization.CultureInfo.InvariantCulture), ")"); + } + + public override bool Equals(object o) + { + if (o is GeneratorPosition) + { + GeneratorPosition that = (GeneratorPosition)o; + return _index == that._index && + _offset == that._offset; + } + return false; + } + + public static bool operator ==(GeneratorPosition gp1, GeneratorPosition gp2) + { + return gp1._index == gp2._index && + gp1._offset == gp2._offset; + } + + public static bool operator !=(GeneratorPosition gp1, GeneratorPosition gp2) + { + return !(gp1 == gp2); + } + } +} + +namespace ABI.Windows.UI.Xaml.Controls.Primitives +{ +#if EMBED + internal +#else + public +#endif + static class GeneratorPosition + { + public static string GetGuidSignature() => $"struct(Windows.UI.Xaml.Controls.Primitives.GeneratorPosition;i4;i4)"; + } +} diff --git a/src/cswinrt/strings/additions/Windows.UI.Xaml.Media.Animation/Windows.UI.Xaml.Media.Animation.cs b/src/cswinrt/strings/additions/Windows.UI.Xaml.Media.Animation/Windows.UI.Xaml.Media.Animation.cs new file mode 100644 index 000000000..259898959 --- /dev/null +++ b/src/cswinrt/strings/additions/Windows.UI.Xaml.Media.Animation/Windows.UI.Xaml.Media.Animation.cs @@ -0,0 +1,326 @@ + +namespace Windows.UI.Xaml.Media.Animation +{ + using global::Windows.Foundation; + + [global::WinRT.WindowsRuntimeType("Windows.UI.Xaml")] + [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Windows.UI.Xaml.Media.Animation.KeyTime))] + [StructLayout(LayoutKind.Sequential)] +#if EMBED + internal +#else + public +#endif + struct KeyTime + { + private TimeSpan _timeSpan; + + public static KeyTime FromTimeSpan(TimeSpan timeSpan) + { + if (timeSpan < TimeSpan.Zero) + { + throw new ArgumentOutOfRangeException(nameof(timeSpan)); + } + + KeyTime keyTime = default; + + keyTime._timeSpan = timeSpan; + + return keyTime; + } + + public static bool Equals(KeyTime keyTime1, KeyTime keyTime2) + { + return (keyTime1._timeSpan == keyTime2._timeSpan); + } + + public static bool operator ==(KeyTime keyTime1, KeyTime keyTime2) + { + return KeyTime.Equals(keyTime1, keyTime2); + } + + public static bool operator !=(KeyTime keyTime1, KeyTime keyTime2) + { + return !KeyTime.Equals(keyTime1, keyTime2); + } + + public bool Equals(KeyTime value) + { + return KeyTime.Equals(this, value); + } + + public override bool Equals(object value) + { + return value is KeyTime && this == (KeyTime)value; + } + + public override int GetHashCode() + { + return _timeSpan.GetHashCode(); + } + + public override string ToString() + { + return _timeSpan.ToString(); + } + + public static implicit operator KeyTime(TimeSpan timeSpan) + { + return KeyTime.FromTimeSpan(timeSpan); + } + + public TimeSpan TimeSpan + { + get + { + return _timeSpan; + } + } + } + + [global::WinRT.WindowsRuntimeType("Windows.UI.Xaml")] +#if EMBED + internal +#else + public +#endif + enum RepeatBehaviorType + { + Count, + Duration, + Forever + } + + [global::WinRT.WindowsRuntimeType("Windows.UI.Xaml")] + [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Windows.UI.Xaml.Media.Animation.RepeatBehavior))] + [StructLayout(LayoutKind.Sequential)] +#if EMBED + internal +#else + public +#endif + struct RepeatBehavior : IFormattable + { + private double _Count; + private TimeSpan _Duration; + private RepeatBehaviorType _Type; + + internal static bool IsFinite(double value) + { + return !(double.IsNaN(value) || double.IsInfinity(value)); + } + + public RepeatBehavior(double count) + { + if (!IsFinite(count) || count < 0.0) + { + throw new ArgumentOutOfRangeException(nameof(count)); + } + + _Duration = new TimeSpan(0); + _Count = count; + _Type = RepeatBehaviorType.Count; + } + + public RepeatBehavior(TimeSpan duration) + { + if (duration < new TimeSpan(0)) + { + throw new ArgumentOutOfRangeException(nameof(duration)); + } + + _Duration = duration; + _Count = 0.0; + _Type = RepeatBehaviorType.Duration; + } + + public static RepeatBehavior Forever + { + get + { + RepeatBehavior forever = default; + forever.Type = RepeatBehaviorType.Forever; + + return forever; + } + } + + public bool HasCount + { + get + { + return Type == RepeatBehaviorType.Count; + } + } + + public bool HasDuration + { + get + { + return Type == RepeatBehaviorType.Duration; + } + } + + public double Count + { + get { return _Count; } + set { _Count = value; } + } + + public TimeSpan Duration + { + get { return _Duration; } + set { _Duration = value; } + } + + public RepeatBehaviorType Type + { + get { return _Type; } + set { _Type = value; } + } + + public override string ToString() + { + return InternalToString(null, null); + } + + public string ToString(IFormatProvider formatProvider) + { + return InternalToString(null, formatProvider); + } + + string IFormattable.ToString(string format, IFormatProvider formatProvider) + { + return InternalToString(format, formatProvider); + } + + internal string InternalToString(string format, IFormatProvider formatProvider) + { + switch (_Type) + { + case RepeatBehaviorType.Forever: + + return "Forever"; + + case RepeatBehaviorType.Count: + + global::System.Text.StringBuilder sb = new global::System.Text.StringBuilder(); + + sb.AppendFormat( + formatProvider, + "{0:" + format + "}x", + _Count); + + return sb.ToString(); + + case RepeatBehaviorType.Duration: + + return _Duration.ToString(); + + default: + return string.Empty; + } + } + + public override bool Equals(object value) + { + if (value is RepeatBehavior) + { + return this.Equals((RepeatBehavior)value); + } + else + { + return false; + } + } + + public bool Equals(RepeatBehavior repeatBehavior) + { + if (_Type == repeatBehavior._Type) + { + return _Type switch + { + RepeatBehaviorType.Forever => true, + RepeatBehaviorType.Count => _Count == repeatBehavior._Count, + RepeatBehaviorType.Duration => _Duration == repeatBehavior._Duration, + _ => false, + }; + } + else + { + return false; + } + } + + public static bool Equals(RepeatBehavior repeatBehavior1, RepeatBehavior repeatBehavior2) + { + return repeatBehavior1.Equals(repeatBehavior2); + } + + public override int GetHashCode() + { + return _Type switch + { + RepeatBehaviorType.Count => _Count.GetHashCode(), + RepeatBehaviorType.Duration => _Duration.GetHashCode(), + + // We try to choose an unlikely hash code value for Forever. + // All Forevers need to return the same hash code value. + RepeatBehaviorType.Forever => int.MaxValue - 42, + + _ => base.GetHashCode(), + }; + } + + public static bool operator ==(RepeatBehavior repeatBehavior1, RepeatBehavior repeatBehavior2) + { + return repeatBehavior1.Equals(repeatBehavior2); + } + + public static bool operator !=(RepeatBehavior repeatBehavior1, RepeatBehavior repeatBehavior2) + { + return !repeatBehavior1.Equals(repeatBehavior2); + } + } +} + +namespace ABI.Windows.UI.Xaml.Media.Animation +{ +#if EMBED + internal +#else + public +#endif + static class KeyTime + { + public static string GetGuidSignature() + { + string timeSpanSignature = global::WinRT.GuidGenerator.GetSignature(typeof(global::System.TimeSpan)); + return $"struct(Windows.UI.Xaml.Media.Animation.KeyTime;{timeSpanSignature})"; + } + } + +#if EMBED + internal +#else + public +#endif + static class RepeatBehavior + { + public static string GetGuidSignature() + { + string timeSpanSignature = global::WinRT.GuidGenerator.GetSignature(typeof(global::System.TimeSpan)); + return $"struct(Windows.UI.Xaml.Media.Animation.RepeatBehavior;f8;{timeSpanSignature};{RepeatBehaviorType.GetGuidSignature()})"; + } + } + +#if EMBED + internal +#else + public +#endif + static class RepeatBehaviorType + { + public static string GetGuidSignature() => "enum(Windows.UI.Xaml.Media.Animation.RepeatBehaviorType;i4)"; + } +} diff --git a/src/cswinrt/strings/additions/Windows.UI.Xaml.Media.Media3D/Windows.UI.Xaml.Media.Media3D.cs b/src/cswinrt/strings/additions/Windows.UI.Xaml.Media.Media3D/Windows.UI.Xaml.Media.Media3D.cs new file mode 100644 index 000000000..98dfb069e --- /dev/null +++ b/src/cswinrt/strings/additions/Windows.UI.Xaml.Media.Media3D/Windows.UI.Xaml.Media.Media3D.cs @@ -0,0 +1,711 @@ + +namespace Windows.UI.Xaml.Media.Media3D +{ + using global::Windows.Foundation; + + [global::WinRT.WindowsRuntimeType("Windows.UI.Xaml")] + [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Windows.UI.Xaml.Media.Media3D.Matrix3D))] + [StructLayout(LayoutKind.Sequential)] +#if EMBED + internal +#else + public +#endif + struct Matrix3D : IFormattable + { + // Assuming this matrix has fourth column of 0,0,0,1 and isn't identity this function: + // Returns false if HasInverse is false, otherwise inverts the matrix. + private bool NormalizedAffineInvert() + { + double z20 = _m12 * _m23 - _m22 * _m13; + double z10 = _m32 * _m13 - _m12 * _m33; + double z00 = _m22 * _m33 - _m32 * _m23; + double det = _m31 * z20 + _m21 * z10 + _m11 * z00; + + if (IsZero(det)) + { + return false; + } + + // Compute 3x3 non-zero cofactors for the 2nd column + double z21 = _m21 * _m13 - _m11 * _m23; + double z11 = _m11 * _m33 - _m31 * _m13; + double z01 = _m31 * _m23 - _m21 * _m33; + + // Compute all six 2x2 determinants of 1st two columns + double y01 = _m11 * _m22 - _m21 * _m12; + double y02 = _m11 * _m32 - _m31 * _m12; + double y03 = _m11 * _offsetY - _offsetX * _m12; + double y12 = _m21 * _m32 - _m31 * _m22; + double y13 = _m21 * _offsetY - _offsetX * _m22; + double y23 = _m31 * _offsetY - _offsetX * _m32; + + // Compute all non-zero and non-one 3x3 cofactors for 2nd + // two columns + double z23 = _m23 * y03 - _offsetZ * y01 - _m13 * y13; + double z13 = _m13 * y23 - _m33 * y03 + _offsetZ * y02; + double z03 = _m33 * y13 - _offsetZ * y12 - _m23 * y23; + double z22 = y01; + double z12 = -y02; + double z02 = y12; + + double rcp = 1.0 / det; + + // Multiply all 3x3 cofactors by reciprocal & transpose + _m11 = (z00 * rcp); + _m12 = (z10 * rcp); + _m13 = (z20 * rcp); + + _m21 = (z01 * rcp); + _m22 = (z11 * rcp); + _m23 = (z21 * rcp); + + _m31 = (z02 * rcp); + _m32 = (z12 * rcp); + _m33 = (z22 * rcp); + + _offsetX = (z03 * rcp); + _offsetY = (z13 * rcp); + _offsetZ = (z23 * rcp); + + return true; + } + + // RETURNS true if has inverse & invert was done. Otherwise returns false & leaves matrix unchanged. + private bool InvertCore() + { + if (IsAffine) + { + return NormalizedAffineInvert(); + } + + // compute all six 2x2 determinants of 2nd two columns + double y01 = _m13 * _m24 - _m23 * _m14; + double y02 = _m13 * _m34 - _m33 * _m14; + double y03 = _m13 * _m44 - _offsetZ * _m14; + double y12 = _m23 * _m34 - _m33 * _m24; + double y13 = _m23 * _m44 - _offsetZ * _m24; + double y23 = _m33 * _m44 - _offsetZ * _m34; + + // Compute 3x3 cofactors for 1st the column + double z30 = _m22 * y02 - _m32 * y01 - _m12 * y12; + double z20 = _m12 * y13 - _m22 * y03 + _offsetY * y01; + double z10 = _m32 * y03 - _offsetY * y02 - _m12 * y23; + double z00 = _m22 * y23 - _m32 * y13 + _offsetY * y12; + + // Compute 4x4 determinant + double det = _offsetX * z30 + _m31 * z20 + _m21 * z10 + _m11 * z00; + + if (IsZero(det)) + { + return false; + } + + // Compute 3x3 cofactors for the 2nd column + double z31 = _m11 * y12 - _m21 * y02 + _m31 * y01; + double z21 = _m21 * y03 - _offsetX * y01 - _m11 * y13; + double z11 = _m11 * y23 - _m31 * y03 + _offsetX * y02; + double z01 = _m31 * y13 - _offsetX * y12 - _m21 * y23; + + // Compute all six 2x2 determinants of 1st two columns + y01 = _m11 * _m22 - _m21 * _m12; + y02 = _m11 * _m32 - _m31 * _m12; + y03 = _m11 * _offsetY - _offsetX * _m12; + y12 = _m21 * _m32 - _m31 * _m22; + y13 = _m21 * _offsetY - _offsetX * _m22; + y23 = _m31 * _offsetY - _offsetX * _m32; + + // Compute all 3x3 cofactors for 2nd two columns + double z33 = _m13 * y12 - _m23 * y02 + _m33 * y01; + double z23 = _m23 * y03 - _offsetZ * y01 - _m13 * y13; + double z13 = _m13 * y23 - _m33 * y03 + _offsetZ * y02; + double z03 = _m33 * y13 - _offsetZ * y12 - _m23 * y23; + double z32 = _m24 * y02 - _m34 * y01 - _m14 * y12; + double z22 = _m14 * y13 - _m24 * y03 + _m44 * y01; + double z12 = _m34 * y03 - _m44 * y02 - _m14 * y23; + double z02 = _m24 * y23 - _m34 * y13 + _m44 * y12; + + double rcp = 1.0 / det; + + // Multiply all 3x3 cofactors by reciprocal & transpose + _m11 = (z00 * rcp); + _m12 = (z10 * rcp); + _m13 = (z20 * rcp); + _m14 = (z30 * rcp); + + _m21 = (z01 * rcp); + _m22 = (z11 * rcp); + _m23 = (z21 * rcp); + _m24 = (z31 * rcp); + + _m31 = (z02 * rcp); + _m32 = (z12 * rcp); + _m33 = (z22 * rcp); + _m34 = (z32 * rcp); + + _offsetX = (z03 * rcp); + _offsetY = (z13 * rcp); + _offsetZ = (z23 * rcp); + _m44 = (z33 * rcp); + + return true; + } + + public Matrix3D(double m11, double m12, double m13, double m14, + double m21, double m22, double m23, double m24, + double m31, double m32, double m33, double m34, + double offsetX, double offsetY, double offsetZ, double m44) + { + _m11 = m11; + _m12 = m12; + _m13 = m13; + _m14 = m14; + _m21 = m21; + _m22 = m22; + _m23 = m23; + _m24 = m24; + _m31 = m31; + _m32 = m32; + _m33 = m33; + _m34 = m34; + _offsetX = offsetX; + _offsetY = offsetY; + _offsetZ = offsetZ; + _m44 = m44; + } + + // the transform is identity by default + // Actually fill in the fields - some (internal) code uses the fields directly for perf. + private static Matrix3D s_identity = CreateIdentity(); + + public double M11 + { + get + { + return _m11; + } + set + { + _m11 = value; + } + } + + public double M12 + { + get + { + return _m12; + } + set + { + _m12 = value; + } + } + + public double M13 + { + get + { + return _m13; + } + set + { + _m13 = value; + } + } + + public double M14 + { + get + { + return _m14; + } + set + { + _m14 = value; + } + } + + public double M21 + { + get + { + return _m21; + } + set + { + _m21 = value; + } + } + + public double M22 + { + get + { + return _m22; + } + set + { + _m22 = value; + } + } + + public double M23 + { + get + { + return _m23; + } + set + { + _m23 = value; + } + } + + public double M24 + { + get + { + return _m24; + } + set + { + _m24 = value; + } + } + + public double M31 + { + get + { + return _m31; + } + set + { + _m31 = value; + } + } + + public double M32 + { + get + { + return _m32; + } + set + { + _m32 = value; + } + } + + public double M33 + { + get + { + return _m33; + } + set + { + _m33 = value; + } + } + + public double M34 + { + get + { + return _m34; + } + set + { + _m34 = value; + } + } + + public double OffsetX + { + get + { + return _offsetX; + } + set + { + _offsetX = value; + } + } + + public double OffsetY + { + get + { + return _offsetY; + } + set + { + _offsetY = value; + } + } + + public double OffsetZ + { + get + { + return _offsetZ; + } + set + { + _offsetZ = value; + } + } + + public double M44 + { + get + { + return _m44; + } + set + { + _m44 = value; + } + } + + public static Matrix3D Identity + { + get + { + return s_identity; + } + } + + public bool IsIdentity + { + get + { + return (_m11 == 1 && _m12 == 0 && _m13 == 0 && _m14 == 0 && + _m21 == 0 && _m22 == 1 && _m23 == 0 && _m24 == 0 && + _m31 == 0 && _m32 == 0 && _m33 == 1 && _m34 == 0 && + _offsetX == 0 && _offsetY == 0 && _offsetZ == 0 && _m44 == 1); + } + } + + public override string ToString() + { + // Delegate to the internal method which implements all ToString calls. + return ConvertToString(null /* format string */, null /* format provider */); + } + + public string ToString(IFormatProvider provider) + { + // Delegate to the internal method which implements all ToString calls. + return ConvertToString(null /* format string */, provider); + } + + string IFormattable.ToString(string format, IFormatProvider provider) + { + // Delegate to the internal method which implements all ToString calls. + return ConvertToString(format, provider); + } + + private string ConvertToString(string format, IFormatProvider provider) + { + if (IsIdentity) + { + return "Identity"; + } + + // Helper to get the numeric list separator for a given culture. + char separator = TokenizerHelper.GetNumericListSeparator(provider); + return string.Format(provider, + "{1:" + format + "}{0}{2:" + format + "}{0}{3:" + format + "}{0}{4:" + format + "}{0}{5:" + format + + "}{0}{6:" + format + "}{0}{7:" + format + "}{0}{8:" + format + "}{0}{9:" + format + "}{0}{10:" + format + + "}{0}{11:" + format + "}{0}{12:" + format + "}{0}{13:" + format + "}{0}{14:" + format + "}{0}{15:" + format + "}{0}{16:" + format + "}", + separator, + _m11, _m12, _m13, _m14, + _m21, _m22, _m23, _m24, + _m31, _m32, _m33, _m34, + _offsetX, _offsetY, _offsetZ, _m44); + } + + public override int GetHashCode() + { + // Perform field-by-field XOR of HashCodes + return M11.GetHashCode() ^ + M12.GetHashCode() ^ + M13.GetHashCode() ^ + M14.GetHashCode() ^ + M21.GetHashCode() ^ + M22.GetHashCode() ^ + M23.GetHashCode() ^ + M24.GetHashCode() ^ + M31.GetHashCode() ^ + M32.GetHashCode() ^ + M33.GetHashCode() ^ + M34.GetHashCode() ^ + OffsetX.GetHashCode() ^ + OffsetY.GetHashCode() ^ + OffsetZ.GetHashCode() ^ + M44.GetHashCode(); + } + + public override bool Equals(object o) + { + return o is Matrix3D && Matrix3D.Equals(this, (Matrix3D)o); + } + + public bool Equals(Matrix3D value) + { + return Matrix3D.Equals(this, value); + } + + public static bool operator ==(Matrix3D matrix1, Matrix3D matrix2) + { + return matrix1.M11 == matrix2.M11 && + matrix1.M12 == matrix2.M12 && + matrix1.M13 == matrix2.M13 && + matrix1.M14 == matrix2.M14 && + matrix1.M21 == matrix2.M21 && + matrix1.M22 == matrix2.M22 && + matrix1.M23 == matrix2.M23 && + matrix1.M24 == matrix2.M24 && + matrix1.M31 == matrix2.M31 && + matrix1.M32 == matrix2.M32 && + matrix1.M33 == matrix2.M33 && + matrix1.M34 == matrix2.M34 && + matrix1.OffsetX == matrix2.OffsetX && + matrix1.OffsetY == matrix2.OffsetY && + matrix1.OffsetZ == matrix2.OffsetZ && + matrix1.M44 == matrix2.M44; + } + + public static bool operator !=(Matrix3D matrix1, Matrix3D matrix2) + { + return !(matrix1 == matrix2); + } + + public static Matrix3D operator *(Matrix3D matrix1, Matrix3D matrix2) + { + Matrix3D matrix3D = default; + + matrix3D.M11 = matrix1.M11 * matrix2.M11 + + matrix1.M12 * matrix2.M21 + + matrix1.M13 * matrix2.M31 + + matrix1.M14 * matrix2.OffsetX; + matrix3D.M12 = matrix1.M11 * matrix2.M12 + + matrix1.M12 * matrix2.M22 + + matrix1.M13 * matrix2.M32 + + matrix1.M14 * matrix2.OffsetY; + matrix3D.M13 = matrix1.M11 * matrix2.M13 + + matrix1.M12 * matrix2.M23 + + matrix1.M13 * matrix2.M33 + + matrix1.M14 * matrix2.OffsetZ; + matrix3D.M14 = matrix1.M11 * matrix2.M14 + + matrix1.M12 * matrix2.M24 + + matrix1.M13 * matrix2.M34 + + matrix1.M14 * matrix2.M44; + matrix3D.M21 = matrix1.M21 * matrix2.M11 + + matrix1.M22 * matrix2.M21 + + matrix1.M23 * matrix2.M31 + + matrix1.M24 * matrix2.OffsetX; + matrix3D.M22 = matrix1.M21 * matrix2.M12 + + matrix1.M22 * matrix2.M22 + + matrix1.M23 * matrix2.M32 + + matrix1.M24 * matrix2.OffsetY; + matrix3D.M23 = matrix1.M21 * matrix2.M13 + + matrix1.M22 * matrix2.M23 + + matrix1.M23 * matrix2.M33 + + matrix1.M24 * matrix2.OffsetZ; + matrix3D.M24 = matrix1.M21 * matrix2.M14 + + matrix1.M22 * matrix2.M24 + + matrix1.M23 * matrix2.M34 + + matrix1.M24 * matrix2.M44; + matrix3D.M31 = matrix1.M31 * matrix2.M11 + + matrix1.M32 * matrix2.M21 + + matrix1.M33 * matrix2.M31 + + matrix1.M34 * matrix2.OffsetX; + matrix3D.M32 = matrix1.M31 * matrix2.M12 + + matrix1.M32 * matrix2.M22 + + matrix1.M33 * matrix2.M32 + + matrix1.M34 * matrix2.OffsetY; + matrix3D.M33 = matrix1.M31 * matrix2.M13 + + matrix1.M32 * matrix2.M23 + + matrix1.M33 * matrix2.M33 + + matrix1.M34 * matrix2.OffsetZ; + matrix3D.M34 = matrix1.M31 * matrix2.M14 + + matrix1.M32 * matrix2.M24 + + matrix1.M33 * matrix2.M34 + + matrix1.M34 * matrix2.M44; + matrix3D.OffsetX = matrix1.OffsetX * matrix2.M11 + + matrix1.OffsetY * matrix2.M21 + + matrix1.OffsetZ * matrix2.M31 + + matrix1.M44 * matrix2.OffsetX; + matrix3D.OffsetY = matrix1.OffsetX * matrix2.M12 + + matrix1.OffsetY * matrix2.M22 + + matrix1.OffsetZ * matrix2.M32 + + matrix1.M44 * matrix2.OffsetY; + matrix3D.OffsetZ = matrix1.OffsetX * matrix2.M13 + + matrix1.OffsetY * matrix2.M23 + + matrix1.OffsetZ * matrix2.M33 + + matrix1.M44 * matrix2.OffsetZ; + matrix3D.M44 = matrix1.OffsetX * matrix2.M14 + + matrix1.OffsetY * matrix2.M24 + + matrix1.OffsetZ * matrix2.M34 + + matrix1.M44 * matrix2.M44; + + // matrix3D._type is not set. + + return matrix3D; + } + + public bool HasInverse + { + get + { + return !IsZero(Determinant); + } + } + + public void Invert() + { + if (!InvertCore()) + { + throw new InvalidOperationException(); + } + } + + private static Matrix3D CreateIdentity() + { + Matrix3D matrix3D = default; + matrix3D.SetMatrix(1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1); + return matrix3D; + } + + private void SetMatrix(double m11, double m12, double m13, double m14, + double m21, double m22, double m23, double m24, + double m31, double m32, double m33, double m34, + double offsetX, double offsetY, double offsetZ, double m44) + { + _m11 = m11; + _m12 = m12; + _m13 = m13; + _m14 = m14; + _m21 = m21; + _m22 = m22; + _m23 = m23; + _m24 = m24; + _m31 = m31; + _m32 = m32; + _m33 = m33; + _m34 = m34; + _offsetX = offsetX; + _offsetY = offsetY; + _offsetZ = offsetZ; + _m44 = m44; + } + + private static bool Equals(Matrix3D matrix1, Matrix3D matrix2) + { + return matrix1.M11.Equals(matrix2.M11) && + matrix1.M12.Equals(matrix2.M12) && + matrix1.M13.Equals(matrix2.M13) && + matrix1.M14.Equals(matrix2.M14) && + matrix1.M21.Equals(matrix2.M21) && + matrix1.M22.Equals(matrix2.M22) && + matrix1.M23.Equals(matrix2.M23) && + matrix1.M24.Equals(matrix2.M24) && + matrix1.M31.Equals(matrix2.M31) && + matrix1.M32.Equals(matrix2.M32) && + matrix1.M33.Equals(matrix2.M33) && + matrix1.M34.Equals(matrix2.M34) && + matrix1.OffsetX.Equals(matrix2.OffsetX) && + matrix1.OffsetY.Equals(matrix2.OffsetY) && + matrix1.OffsetZ.Equals(matrix2.OffsetZ) && + matrix1.M44.Equals(matrix2.M44); + } + + private double GetNormalizedAffineDeterminant() + { + double z20 = _m12 * _m23 - _m22 * _m13; + double z10 = _m32 * _m13 - _m12 * _m33; + double z00 = _m22 * _m33 - _m32 * _m23; + + return _m31 * z20 + _m21 * z10 + _m11 * z00; + } + + private bool IsAffine + { + get + { + return (_m14 == 0.0 && _m24 == 0.0 && _m34 == 0.0 && _m44 == 1.0); + } + } + + private double Determinant + { + get + { + if (IsAffine) + { + return GetNormalizedAffineDeterminant(); + } + + // compute all six 2x2 determinants of 2nd two columns + double y01 = _m13 * _m24 - _m23 * _m14; + double y02 = _m13 * _m34 - _m33 * _m14; + double y03 = _m13 * _m44 - _offsetZ * _m14; + double y12 = _m23 * _m34 - _m33 * _m24; + double y13 = _m23 * _m44 - _offsetZ * _m24; + double y23 = _m33 * _m44 - _offsetZ * _m34; + + // Compute 3x3 cofactors for 1st the column + double z30 = _m22 * y02 - _m32 * y01 - _m12 * y12; + double z20 = _m12 * y13 - _m22 * y03 + _offsetY * y01; + double z10 = _m32 * y03 - _offsetY * y02 - _m12 * y23; + double z00 = _m22 * y23 - _m32 * y13 + _offsetY * y12; + + return _offsetX * z30 + _m31 * z20 + _m21 * z10 + _m11 * z00; + } + } + + private static bool IsZero(double value) + { + return Math.Abs(value) < 10.0 * DBL_EPSILON_RELATIVE_1; + } + + private const double DBL_EPSILON_RELATIVE_1 = 1.1102230246251567e-016; /* smallest such that 1.0+DBL_EPSILON != 1.0 */ + + private double _m11; + private double _m12; + private double _m13; + private double _m14; + private double _m21; + private double _m22; + private double _m23; + private double _m24; + private double _m31; + private double _m32; + private double _m33; + private double _m34; + private double _offsetX; + private double _offsetY; + private double _offsetZ; + private double _m44; + } +} + +namespace ABI.Windows.UI.Xaml.Media.Media3D +{ +#if EMBED + internal +#else + public +#endif + static class Matrix3D + { + public static string GetGuidSignature() => + $"struct(Windows.UI.Xaml.Media.Media3D.Matrix3D;f8;f8;f8;f8;f8;f8;f8;f8;f8;f8;f8;f8;f8;f8;f8;f8)"; + } +} diff --git a/src/cswinrt/strings/additions/Windows.UI.Xaml.Media/Windows.UI.Xaml.Media.cs b/src/cswinrt/strings/additions/Windows.UI.Xaml.Media/Windows.UI.Xaml.Media.cs new file mode 100644 index 000000000..b156e5104 --- /dev/null +++ b/src/cswinrt/strings/additions/Windows.UI.Xaml.Media/Windows.UI.Xaml.Media.cs @@ -0,0 +1,263 @@ + +namespace Windows.UI.Xaml.Media +{ + using global::Windows.Foundation; + + [global::WinRT.WindowsRuntimeType("Windows.UI.Xaml")] + [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Windows.UI.Xaml.Media.Matrix))] + [StructLayout(LayoutKind.Sequential)] +#if EMBED + internal +#else + public +#endif + struct Matrix : IFormattable + { + public Matrix(double m11, double m12, + double m21, double m22, + double offsetX, double offsetY) + { + _m11 = m11; + _m12 = m12; + _m21 = m21; + _m22 = m22; + _offsetX = offsetX; + _offsetY = offsetY; + } + + // the transform is identity by default + private static Matrix s_identity = CreateIdentity(); + + public double M11 + { + get + { + return _m11; + } + set + { + _m11 = value; + } + } + + public double M12 + { + get + { + return _m12; + } + set + { + _m12 = value; + } + } + + public double M21 + { + get + { + return _m21; + } + set + { + _m21 = value; + } + } + + public double M22 + { + get + { + return _m22; + } + set + { + _m22 = value; + } + } + + public double OffsetX + { + get + { + return _offsetX; + } + set + { + _offsetX = value; + } + } + + public double OffsetY + { + get + { + return _offsetY; + } + set + { + _offsetY = value; + } + } + + public static Matrix Identity + { + get + { + return s_identity; + } + } + + public bool IsIdentity + { + get + { + return (_m11 == 1 && _m12 == 0 && _m21 == 0 && _m22 == 1 && _offsetX == 0 && _offsetY == 0); + } + } + + public override string ToString() + { + // Delegate to the internal method which implements all ToString calls. + return ConvertToString(null /* format string */, null /* format provider */); + } + + public string ToString(IFormatProvider provider) + { + // Delegate to the internal method which implements all ToString calls. + return ConvertToString(null /* format string */, provider); + } + + string IFormattable.ToString(string format, IFormatProvider provider) + { + // Delegate to the internal method which implements all ToString calls. + return ConvertToString(format, provider); + } + + private string ConvertToString(string format, IFormatProvider provider) + { + if (IsIdentity) + { + return "Identity"; + } + + // Helper to get the numeric list separator for a given culture. + char separator = TokenizerHelper.GetNumericListSeparator(provider); + return string.Format(provider, + "{1:" + format + "}{0}{2:" + format + "}{0}{3:" + format + "}{0}{4:" + format + "}{0}{5:" + format + "}{0}{6:" + format + "}", + separator, + _m11, + _m12, + _m21, + _m22, + _offsetX, + _offsetY); + } + + public Point Transform(Point point) + { + float x = (float)point.X; + float y = (float)point.Y; + this.MultiplyPoint(ref x, ref y); + Point point2 = new Point(x, y); + return point2; + } + + public override int GetHashCode() + { + // Perform field-by-field XOR of HashCodes + return M11.GetHashCode() ^ + M12.GetHashCode() ^ + M21.GetHashCode() ^ + M22.GetHashCode() ^ + OffsetX.GetHashCode() ^ + OffsetY.GetHashCode(); + } + + public override bool Equals(object o) + { + return o is Matrix && Matrix.Equals(this, (Matrix)o); + } + + public bool Equals(Matrix value) + { + return Matrix.Equals(this, value); + } + + public static bool operator ==(Matrix matrix1, Matrix matrix2) + { + return matrix1.M11 == matrix2.M11 && + matrix1.M12 == matrix2.M12 && + matrix1.M21 == matrix2.M21 && + matrix1.M22 == matrix2.M22 && + matrix1.OffsetX == matrix2.OffsetX && + matrix1.OffsetY == matrix2.OffsetY; + } + + public static bool operator !=(Matrix matrix1, Matrix matrix2) + { + return !(matrix1 == matrix2); + } + + private static Matrix CreateIdentity() + { + Matrix matrix = default; + matrix.SetMatrix(1, 0, + 0, 1, + 0, 0); + return matrix; + } + + private void SetMatrix(double m11, double m12, + double m21, double m22, + double offsetX, double offsetY) + { + _m11 = m11; + _m12 = m12; + _m21 = m21; + _m22 = m22; + _offsetX = offsetX; + _offsetY = offsetY; + } + + private void MultiplyPoint(ref float x, ref float y) + { + double num = (y * _m21) + _offsetX; + double num2 = (x * _m12) + _offsetY; + x *= (float)_m11; + x += (float)num; + y *= (float)_m22; + y += (float)num2; + } + + private static bool Equals(Matrix matrix1, Matrix matrix2) + { + return matrix1.M11.Equals(matrix2.M11) && + matrix1.M12.Equals(matrix2.M12) && + matrix1.M21.Equals(matrix2.M21) && + matrix1.M22.Equals(matrix2.M22) && + matrix1.OffsetX.Equals(matrix2.OffsetX) && + matrix1.OffsetY.Equals(matrix2.OffsetY); + } + + private double _m11; + private double _m12; + private double _m21; + private double _m22; + private double _offsetX; + private double _offsetY; + } +} + +namespace ABI.Windows.UI.Xaml.Media +{ +#if EMBED + internal +#else + public +#endif + static class Matrix + { + public static string GetGuidSignature() => $"struct(Windows.UI.Xaml.Media.Matrix;f8;f8;f8;f8;f8;f8)"; + } +} diff --git a/src/cswinrt/strings/additions/Windows.UI.Xaml/Windows.UI.Xaml.SR.cs b/src/cswinrt/strings/additions/Windows.UI.Xaml/Windows.UI.Xaml.SR.cs new file mode 100644 index 000000000..cbb4596bb --- /dev/null +++ b/src/cswinrt/strings/additions/Windows.UI.Xaml/Windows.UI.Xaml.SR.cs @@ -0,0 +1,17 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace Windows.UI.Xaml +{ + static class SR + { + public static string DirectUI_CornerRadius_InvalidMember = "Invalid value for {0} property on CornerRadius."; + public static string DirectUI_InvalidArgument = "Invalid argument."; + public static string ElementNotAvailable_Default = "The element is not available."; + public static string ElementNotEnabled_Default = "The element is not enabled."; + public static string XamlParse_Default = "XAML parsing failed."; + public static string LayoutCycle_Default = "A cycle occurred while laying out the GUI."; + public static string PlatformNotSupported_WindowsRuntime = "Windows Runtime (WinRT) is not supported on this platform."; + } +} diff --git a/src/cswinrt/strings/additions/Windows.UI.Xaml/Windows.UI.Xaml.cs b/src/cswinrt/strings/additions/Windows.UI.Xaml/Windows.UI.Xaml.cs new file mode 100644 index 000000000..341d016d6 --- /dev/null +++ b/src/cswinrt/strings/additions/Windows.UI.Xaml/Windows.UI.Xaml.cs @@ -0,0 +1,774 @@ + +namespace Windows.UI.Xaml +{ + using global::Windows.Foundation; + + [global::WinRT.WindowsRuntimeType("Windows.UI.Xaml")] + [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Windows.UI.Xaml.CornerRadius))] + [StructLayout(LayoutKind.Sequential)] +#if EMBED + internal +#else + public +#endif + struct CornerRadius + { + private double _TopLeft; + private double _TopRight; + private double _BottomRight; + private double _BottomLeft; + + public CornerRadius(double uniformRadius) + { + Validate(uniformRadius, uniformRadius, uniformRadius, uniformRadius); + _TopLeft = _TopRight = _BottomRight = _BottomLeft = uniformRadius; + } + + public CornerRadius(double topLeft, double topRight, double bottomRight, double bottomLeft) + { + Validate(topLeft, topRight, bottomRight, bottomLeft); + + _TopLeft = topLeft; + _TopRight = topRight; + _BottomRight = bottomRight; + _BottomLeft = bottomLeft; + } + + private static void Validate(double topLeft, double topRight, double bottomRight, double bottomLeft) + { + if (topLeft < 0.0 || double.IsNaN(topLeft)) + throw new ArgumentException(string.Format(SR.DirectUI_CornerRadius_InvalidMember, "TopLeft")); + + if (topRight < 0.0 || double.IsNaN(topRight)) + throw new ArgumentException(string.Format(SR.DirectUI_CornerRadius_InvalidMember, "TopRight")); + + if (bottomRight < 0.0 || double.IsNaN(bottomRight)) + throw new ArgumentException(string.Format(SR.DirectUI_CornerRadius_InvalidMember, "BottomRight")); + + if (bottomLeft < 0.0 || double.IsNaN(bottomLeft)) + throw new ArgumentException(string.Format(SR.DirectUI_CornerRadius_InvalidMember, "BottomLeft")); + } + + public override string ToString() + { + return ToString(global::System.Globalization.CultureInfo.InvariantCulture); + } + + internal string ToString(global::System.Globalization.CultureInfo cultureInfo) + { + char listSeparator = TokenizerHelper.GetNumericListSeparator(cultureInfo); + + // Initial capacity [64] is an estimate based on a sum of: + // 48 = 4x double (twelve digits is generous for the range of values likely) + // 8 = 4x Unit Type string (approx two characters) + // 4 = 4x separator characters + global::System.Text.StringBuilder sb = new global::System.Text.StringBuilder(64); + + sb.Append(InternalToString(_TopLeft, cultureInfo)); + sb.Append(listSeparator); + sb.Append(InternalToString(_TopRight, cultureInfo)); + sb.Append(listSeparator); + sb.Append(InternalToString(_BottomRight, cultureInfo)); + sb.Append(listSeparator); + sb.Append(InternalToString(_BottomLeft, cultureInfo)); + return sb.ToString(); + } + + internal string InternalToString(double l, global::System.Globalization.CultureInfo cultureInfo) + { + if (double.IsNaN(l)) return "Auto"; + return Convert.ToString(l, cultureInfo); + } + + public override bool Equals(object obj) + { + if (obj is CornerRadius) + { + CornerRadius otherObj = (CornerRadius)obj; + return (this == otherObj); + } + return (false); + } + + public bool Equals(CornerRadius cornerRadius) + { + return (this == cornerRadius); + } + + public override int GetHashCode() + { + return _TopLeft.GetHashCode() ^ _TopRight.GetHashCode() ^ _BottomLeft.GetHashCode() ^ _BottomRight.GetHashCode(); + } + + public static bool operator ==(CornerRadius cr1, CornerRadius cr2) + { + return cr1._TopLeft == cr2._TopLeft && cr1._TopRight == cr2._TopRight && cr1._BottomRight == cr2._BottomRight && cr1._BottomLeft == cr2._BottomLeft; + } + + public static bool operator !=(CornerRadius cr1, CornerRadius cr2) + { + return (!(cr1 == cr2)); + } + + public double TopLeft + { + get { return _TopLeft; } + set + { + Validate(value, 0, 0, 0); + _TopLeft = value; + } + } + + public double TopRight + { + get { return _TopRight; } + set + { + Validate(0, value, 0, 0); + _TopRight = value; + } + } + + public double BottomRight + { + get { return _BottomRight; } + set + { + Validate(0, 0, value, 0); + _BottomRight = value; + } + } + + public double BottomLeft + { + get { return _BottomLeft; } + set + { + Validate(0, 0, 0, value); + _BottomLeft = value; + } + } + } + + [global::WinRT.WindowsRuntimeType("Windows.UI.Xaml")] +#if EMBED + internal +#else + public +#endif + enum GridUnitType + { + Auto = 0, + Pixel, + Star, + } + + [global::WinRT.WindowsRuntimeType("Windows.UI.Xaml")] + [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Windows.UI.Xaml.GridLength))] + [StructLayout(LayoutKind.Sequential)] +#if EMBED + internal +#else + public +#endif + struct GridLength + { + private readonly double _unitValue; + private readonly GridUnitType _unitType; + + private const double Default = 1.0; + private static readonly GridLength s_auto = new GridLength(Default, GridUnitType.Auto); + + public GridLength(double pixels) + : this(pixels, GridUnitType.Pixel) + { + } + + internal static bool IsFinite(double value) + { + return !(double.IsNaN(value) || double.IsInfinity(value)); + } + + public GridLength(double value, GridUnitType type) + { + if (!IsFinite(value) || value < 0.0) + { + throw new ArgumentException(SR.DirectUI_InvalidArgument, nameof(value)); + } + if (type != GridUnitType.Auto && type != GridUnitType.Pixel && type != GridUnitType.Star) + { + throw new ArgumentException(SR.DirectUI_InvalidArgument, nameof(type)); + } + + _unitValue = (type == GridUnitType.Auto) ? Default : value; + _unitType = type; + } + + + public double Value { get { return ((_unitType == GridUnitType.Auto) ? s_auto._unitValue : _unitValue); } } + public GridUnitType GridUnitType { get { return (_unitType); } } + + + public bool IsAbsolute { get { return (_unitType == GridUnitType.Pixel); } } + public bool IsAuto { get { return (_unitType == GridUnitType.Auto); } } + public bool IsStar { get { return (_unitType == GridUnitType.Star); } } + + public static GridLength Auto + { + get { return (s_auto); } + } + + + public static bool operator ==(GridLength gl1, GridLength gl2) + { + return (gl1.GridUnitType == gl2.GridUnitType + && gl1.Value == gl2.Value); + } + + public static bool operator !=(GridLength gl1, GridLength gl2) + { + return (gl1.GridUnitType != gl2.GridUnitType + || gl1.Value != gl2.Value); + } + + public override bool Equals(object oCompare) + { + if (oCompare is GridLength) + { + GridLength l = (GridLength)oCompare; + return (this == l); + } + else + return false; + } + + public bool Equals(GridLength gridLength) + { + return (this == gridLength); + } + + public override int GetHashCode() + { + return ((int)_unitValue + (int)_unitType); + } + + public override string ToString() + { + return this.ToString(global::System.Globalization.CultureInfo.InvariantCulture); + } + + internal string ToString(global::System.Globalization.CultureInfo cultureInfo) + { + char listSeparator = TokenizerHelper.GetNumericListSeparator(cultureInfo); + + // Initial capacity [64] is an estimate based on a sum of: + // 12 = 1x double (twelve digits is generous for the range of values likely) + // 8 = 4x Unit Type string (approx two characters) + // 2 = 2x separator characters + + if (_unitType == GridUnitType.Auto) + { + return "Auto"; + } + else if (_unitType == GridUnitType.Pixel) + { + return Convert.ToString(_unitValue, cultureInfo); + } + else + { + return Convert.ToString(_unitValue, cultureInfo) + "*"; + } + } + } + + [global::WinRT.WindowsRuntimeType("Windows.UI.Xaml")] + [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Windows.UI.Xaml.Thickness))] + [StructLayout(LayoutKind.Sequential)] +#if EMBED + internal +#else + public +#endif + struct Thickness + { + private double _Left; + private double _Top; + private double _Right; + private double _Bottom; + + public Thickness(double uniformLength) + { + _Left = _Top = _Right = _Bottom = uniformLength; + } + + public Thickness(double left, double top, double right, double bottom) + { + _Left = left; + _Top = top; + _Right = right; + _Bottom = bottom; + } + + public double Left + { + get { return _Left; } + set { _Left = value; } + } + + public double Top + { + get { return _Top; } + set { _Top = value; } + } + + public double Right + { + get { return _Right; } + set { _Right = value; } + } + + public double Bottom + { + get { return _Bottom; } + set { _Bottom = value; } + } + + public override string ToString() + { + return ToString(global::System.Globalization.CultureInfo.InvariantCulture); + } + + internal string ToString(global::System.Globalization.CultureInfo cultureInfo) + { + char listSeparator = TokenizerHelper.GetNumericListSeparator(cultureInfo); + + // Initial capacity [64] is an estimate based on a sum of: + // 48 = 4x double (twelve digits is generous for the range of values likely) + // 8 = 4x Unit Type string (approx two characters) + // 4 = 4x separator characters + global::System.Text.StringBuilder sb = new global::System.Text.StringBuilder(64); + + sb.Append(InternalToString(_Left, cultureInfo)); + sb.Append(listSeparator); + sb.Append(InternalToString(_Top, cultureInfo)); + sb.Append(listSeparator); + sb.Append(InternalToString(_Right, cultureInfo)); + sb.Append(listSeparator); + sb.Append(InternalToString(_Bottom, cultureInfo)); + return sb.ToString(); + } + + internal string InternalToString(double l, global::System.Globalization.CultureInfo cultureInfo) + { + if (double.IsNaN(l)) return "Auto"; + return Convert.ToString(l, cultureInfo); + } + + public override bool Equals(object obj) + { + if (obj is Thickness) + { + Thickness otherObj = (Thickness)obj; + return (this == otherObj); + } + return (false); + } + + public bool Equals(Thickness thickness) + { + return (this == thickness); + } + + public override int GetHashCode() + { + return _Left.GetHashCode() ^ _Top.GetHashCode() ^ _Right.GetHashCode() ^ _Bottom.GetHashCode(); + } + + public static bool operator ==(Thickness t1, Thickness t2) + { + return t1._Left == t2._Left && t1._Top == t2._Top && t1._Right == t2._Right && t1._Bottom == t2._Bottom; + } + + public static bool operator !=(Thickness t1, Thickness t2) + { + return (!(t1 == t2)); + } + } + + [global::WinRT.WindowsRuntimeType("Windows.UI.Xaml")] +#if EMBED + internal +#else + public +#endif + enum DurationType + { + Automatic, + TimeSpan, + Forever + } + + [global::WinRT.WindowsRuntimeType("Windows.UI.Xaml")] + [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Windows.UI.Xaml.Duration))] + [StructLayout(LayoutKind.Sequential)] +#if EMBED + internal +#else + public +#endif + struct Duration + { + private readonly TimeSpan _timeSpan; + private DurationType _durationType; + + public Duration(TimeSpan timeSpan) + { + _durationType = DurationType.TimeSpan; + _timeSpan = timeSpan; + } + + public static implicit operator Duration(TimeSpan timeSpan) + { + return new Duration(timeSpan); + } + + public static Duration operator +(Duration t1, Duration t2) + { + if (t1.HasTimeSpan && t2.HasTimeSpan) + { + return new Duration(t1._timeSpan + t2._timeSpan); + } + else if (t1._durationType != DurationType.Automatic && t2._durationType != DurationType.Automatic) + { + return Duration.Forever; + } + else + { + // Automatic + anything is Automatic + return Duration.Automatic; + } + } + + public static Duration operator -(Duration t1, Duration t2) + { + if (t1.HasTimeSpan && t2.HasTimeSpan) + { + return new Duration(t1._timeSpan - t2._timeSpan); + } + else if (t1._durationType == DurationType.Forever && t2.HasTimeSpan) + { + return Duration.Forever; + } + else + { + return Duration.Automatic; + } + } + + public static bool operator ==(Duration t1, Duration t2) + { + return t1.Equals(t2); + } + + public static bool operator !=(Duration t1, Duration t2) + { + return !(t1.Equals(t2)); + } + + public static bool operator >(Duration t1, Duration t2) + { + if (t1.HasTimeSpan && t2.HasTimeSpan) + { + return t1._timeSpan > t2._timeSpan; + } + else if (t1.HasTimeSpan && t2._durationType == DurationType.Forever) + { + return false; + } + else if (t1._durationType == DurationType.Forever && t2.HasTimeSpan) + { + return true; + } + else + { + return false; + } + } + + public static bool operator >=(Duration t1, Duration t2) + { + if (t1._durationType == DurationType.Automatic && t2._durationType == DurationType.Automatic) + { + return true; + } + else if (t1._durationType == DurationType.Automatic || t2._durationType == DurationType.Automatic) + { + return false; + } + else + { + return !(t1 < t2); + } + } + + public static bool operator <(Duration t1, Duration t2) + { + if (t1.HasTimeSpan && t2.HasTimeSpan) + { + return t1._timeSpan < t2._timeSpan; + } + else if (t1.HasTimeSpan && t2._durationType == DurationType.Forever) + { + return true; + } + else if (t1._durationType == DurationType.Forever && t2.HasTimeSpan) + { + return false; + } + else + { + return false; + } + } + + public static bool operator <=(Duration t1, Duration t2) + { + if (t1._durationType == DurationType.Automatic && t2._durationType == DurationType.Automatic) + { + return true; + } + else if (t1._durationType == DurationType.Automatic || t2._durationType == DurationType.Automatic) + { + return false; + } + else + { + return !(t1 > t2); + } + } + + public static int Compare(Duration t1, Duration t2) + { + if (t1._durationType == DurationType.Automatic) + { + if (t2._durationType == DurationType.Automatic) + { + return 0; + } + else + { + return -1; + } + } + else if (t2._durationType == DurationType.Automatic) + { + return 1; + } + else + { + if (t1 < t2) + { + return -1; + } + else if (t1 > t2) + { + return 1; + } + else + { + return 0; + } + } + } + + public static Duration operator +(Duration duration) + { + return duration; + } + + public bool HasTimeSpan + { + get + { + return _durationType == DurationType.TimeSpan; + } + } + + public static Duration Automatic + { + get + { + Duration duration = default; + duration._durationType = DurationType.Automatic; + + return duration; + } + } + + public static Duration Forever + { + get + { + Duration duration = default; + duration._durationType = DurationType.Forever; + + return duration; + } + } + + public TimeSpan TimeSpan + { + get + { + if (HasTimeSpan) + { + return _timeSpan; + } + else + { + throw new InvalidOperationException(); + } + } + } + + public Duration Add(Duration duration) + { + return this + duration; + } + + public override bool Equals(object value) + { + return value is Duration && Equals((Duration)value); + } + + public bool Equals(Duration duration) + { + if (HasTimeSpan) + { + if (duration.HasTimeSpan) + { + return _timeSpan == duration._timeSpan; + } + else + { + return false; + } + } + else + { + return _durationType == duration._durationType; + } + } + + public static bool Equals(Duration t1, Duration t2) + { + return t1.Equals(t2); + } + + public override int GetHashCode() + { + if (HasTimeSpan) + { + return _timeSpan.GetHashCode(); + } + else + { + return _durationType.GetHashCode() + 17; + } + } + + public Duration Subtract(Duration duration) + { + return this - duration; + } + + public override string ToString() + { + if (HasTimeSpan) + { + return _timeSpan.ToString(); // "00"; //TypeDescriptor.GetConverter(_timeSpan).ConvertToString(_timeSpan); + } + else if (_durationType == DurationType.Forever) + { + return "Forever"; + } + else // IsAutomatic + { + return "Automatic"; + } + } + } +} + +namespace ABI.Windows.UI.Xaml +{ +#if EMBED + internal +#else + public +#endif + static class CornerRadius + { + public static string GetGuidSignature() => $"struct(Windows.UI.Xaml.CornerRadius;f8;f8;f8;f8)"; + } + +#if EMBED + internal +#else + public +#endif + static class Duration + { + public static string GetGuidSignature() + { + string timeSpanSignature = global::WinRT.GuidGenerator.GetSignature(typeof(global::System.TimeSpan)); + string durationTypeSignature = global::WinRT.GuidGenerator.GetSignature(typeof(global::Windows.UI.Xaml.DurationType)); + return $"struct(Windows.UI.Xaml.Duration;{timeSpanSignature};{durationTypeSignature})"; + } + } + +#if EMBED + internal +#else + public +#endif + static class DurationType + { + public static string GetGuidSignature() => "enum(Windows.UI.Xaml.DurationType;i4)"; + } + +#if EMBED + internal +#else + public +#endif + static class GridLength + { + public static string GetGuidSignature() + { + string unitTypeSignature = global::WinRT.GuidGenerator.GetSignature(typeof(global::Windows.UI.Xaml.GridUnitType)); + return $"struct(Windows.UI.Xaml.GridLength;f8;{unitTypeSignature})"; + } + } + +#if EMBED + internal +#else + public +#endif + static class GridUnitType + { + public static string GetGuidSignature() => "enum(Windows.UI.Xaml.GridUnitType;i4)"; + } + +#if EMBED + internal +#else + public +#endif + static class Thickness + { + public static string GetGuidSignature() => $"struct(Windows.UI.Xaml.Thickness;f8;f8;f8;f8)"; + } +}