diff --git a/build/AzurePipelineTemplates/CsWinRT-BuildAndTest-Stage.yml b/build/AzurePipelineTemplates/CsWinRT-BuildAndTest-Stage.yml
index f18022997..892d6d680 100644
--- a/build/AzurePipelineTemplates/CsWinRT-BuildAndTest-Stage.yml
+++ b/build/AzurePipelineTemplates/CsWinRT-BuildAndTest-Stage.yml
@@ -5,7 +5,7 @@ stages:
- job: BuildAndTest
pool:
vmImage: windows-latest
- timeoutInMinutes: 90
+ timeoutInMinutes: 120
# https://docs.microsoft.com/en-us/azure/devops/pipelines/process/phases?view=azure-devops&tabs=yaml#multi-job-configuration
strategy:
maxParallel: 10
@@ -113,6 +113,16 @@ stages:
_build\$(BuildPlatform)\$(BuildConfiguration)\AuthoringConsumptionTest\bin\AuthoringConsumptionTest.exe --gtest_output=xml:AUTHORINGTEST-$(Build.BuildNumber).xml
exit /b 0
+# Run Functional Tests
+ - task: CmdLine@2
+ displayName: Run Functional Tests
+ condition: and(succeeded(), or(eq(variables['BuildPlatform'], 'x86'), eq(variables['BuildPlatform'], 'x64')))
+ inputs:
+ workingDirectory: $(Build.SourcesDirectory)\src
+ script: |
+ set cswinrt_label=functionaltest
+ build.cmd $(BuildPlatform) $(BuildConfiguration) $(VersionNumber) $(Build.BuildNumber) $(WinRT.Runtime.AssemblyVersion)
+
- job: Benchmarks
displayName: Run Benchmarks
condition: or(eq(variables['_RunBenchmarks'],'true'), eq(variables['Build.Reason'],'Schedule'))
diff --git a/src/Perf/IIDOptimizer/SignatureGenerator.cs b/src/Perf/IIDOptimizer/SignatureGenerator.cs
index d184c6215..7c9271254 100644
--- a/src/Perf/IIDOptimizer/SignatureGenerator.cs
+++ b/src/Perf/IIDOptimizer/SignatureGenerator.cs
@@ -201,6 +201,12 @@ bool TryGetDefaultInterfaceTypeForRuntimeClassType(TypeReference runtimeClassTyp
return false;
}
+ if (runtimeClassAttribute.ConstructorArguments[0].Value is TypeReference typeReference)
+ {
+ defaultInterface = typeReference;
+ return true;
+ }
+
string defaultInterfacePropertyName = (string)runtimeClassAttribute.ConstructorArguments[0].Value;
var defaultInterfaceProperty = rcDef.Properties.FirstOrDefault(prop => prop.Name == defaultInterfacePropertyName);
diff --git a/src/Projections/Reunion/Reunion.csproj b/src/Projections/Reunion/Reunion.csproj
index 0cff1b9ef..aedc6b79a 100644
--- a/src/Projections/Reunion/Reunion.csproj
+++ b/src/Projections/Reunion/Reunion.csproj
@@ -5,6 +5,8 @@
x64;x86
Microsoft.WinUI
9.9.9.9
+ true
+ true
diff --git a/src/Projections/Test/Test.csproj b/src/Projections/Test/Test.csproj
index 4ae22502c..b72f2d496 100644
--- a/src/Projections/Test/Test.csproj
+++ b/src/Projections/Test/Test.csproj
@@ -3,6 +3,8 @@
netstandard2.0;net5.0;net6.0
x64;x86
+ true
+ true
diff --git a/src/Projections/Test/TestHost.ProbeByHost.cs b/src/Projections/Test/TestHost.ProbeByHost.cs
index f8b6d8a0d..ba95df96e 100644
--- a/src/Projections/Test/TestHost.ProbeByHost.cs
+++ b/src/Projections/Test/TestHost.ProbeByHost.cs
@@ -12,7 +12,8 @@
namespace Windows.Foundation
{
[global::WinRT.WindowsRuntimeType]
- [Guid("00000035-0000-0000-c000-000000000046")]
+ [Guid("00000035-0000-0000-c000-000000000046")]
+ [WindowsRuntimeHelperType(typeof(global::ABI.Windows.Foundation.IActivationFactory))]
internal interface IActivationFactory
{
Object ActivateInstance();
diff --git a/src/Projections/TestHost.ProbeByClass/TestHost.ProbeByClass.cs b/src/Projections/TestHost.ProbeByClass/TestHost.ProbeByClass.cs
index f2eebbb6b..c6078c042 100644
--- a/src/Projections/TestHost.ProbeByClass/TestHost.ProbeByClass.cs
+++ b/src/Projections/TestHost.ProbeByClass/TestHost.ProbeByClass.cs
@@ -12,7 +12,8 @@
namespace Windows.Foundation
{
[global::WinRT.WindowsRuntimeType]
- [Guid("00000035-0000-0000-c000-000000000046")]
+ [Guid("00000035-0000-0000-c000-000000000046")]
+ [WindowsRuntimeHelperType(typeof(global::ABI.Windows.Foundation.IActivationFactory))]
internal interface IActivationFactory
{
Object ActivateInstance();
diff --git a/src/Projections/WinUI/WinUI.csproj b/src/Projections/WinUI/WinUI.csproj
index bdadc3a37..a018f36ed 100644
--- a/src/Projections/WinUI/WinUI.csproj
+++ b/src/Projections/WinUI/WinUI.csproj
@@ -3,6 +3,8 @@
netstandard2.0;net5.0;net6.0
x64;x86
+ true
+ true
diff --git a/src/Projections/Windows/Windows.csproj b/src/Projections/Windows/Windows.csproj
index 7311ac284..825ddc72e 100644
--- a/src/Projections/Windows/Windows.csproj
+++ b/src/Projections/Windows/Windows.csproj
@@ -4,6 +4,8 @@
netstandard2.0;net5.0;net6.0
x64;x86
Microsoft.Windows.SDK.NET
+ true
+ true
diff --git a/src/Tests/FunctionalTests/Async/Async.csproj b/src/Tests/FunctionalTests/Async/Async.csproj
new file mode 100644
index 000000000..43370b531
--- /dev/null
+++ b/src/Tests/FunctionalTests/Async/Async.csproj
@@ -0,0 +1,18 @@
+
+
+
+ Exe
+ net6.0
+ x86;x64
+ win10-x86;win10-x64
+ $(MSBuildProjectDirectory)\..\PublishProfiles\win10-$(Platform).pubxml
+ true
+ false
+
+
+
+
+
+
+
+
diff --git a/src/Tests/FunctionalTests/Async/Program.cs b/src/Tests/FunctionalTests/Async/Program.cs
new file mode 100644
index 000000000..b43cc2c89
--- /dev/null
+++ b/src/Tests/FunctionalTests/Async/Program.cs
@@ -0,0 +1,65 @@
+using System;
+using System.Threading.Tasks;
+using TestComponentCSharp;
+
+var instance = new Class();
+
+instance.IntProperty = 12;
+var async_get_int = instance.GetIntAsync();
+int async_int = 0;
+async_get_int.Completed = (info, status) => async_int = info.GetResults();
+async_get_int.GetResults();
+
+if (async_int != 12)
+{
+ return 101;
+}
+
+instance.StringProperty = "foo";
+var async_get_string = instance.GetStringAsync();
+string async_string = "";
+async_get_string.Completed = (info, status) => async_string = info.GetResults();
+int async_progress;
+async_get_string.Progress = (info, progress) => async_progress = progress;
+async_get_string.GetResults();
+
+if (async_string != "foo")
+{
+ return 102;
+}
+
+var task = InvokeAddAsync(instance, 20, 10);
+if (task.Wait(25))
+{
+ return 103;
+}
+
+instance.CompleteAsync();
+if (!task.Wait(1000))
+{
+ return 104;
+}
+
+if (task.Status != TaskStatus.RanToCompletion || task.Result != 30)
+{
+ return 105;
+}
+
+var ports = await Windows.Devices.Enumeration.DeviceInformation.FindAllAsync(
+ Windows.Devices.SerialCommunication.SerialDevice.GetDeviceSelector(),
+ new string[] { "System.ItemNameDisplay" });
+foreach (var port in ports)
+{
+ object o = port.Properties["System.ItemNameDisplay"];
+ if (o is null)
+ {
+ return 106;
+ }
+}
+
+return 100;
+
+static async Task InvokeAddAsync(Class instance, int lhs, int rhs)
+{
+ return await instance.AddAsync(lhs, rhs);
+}
\ No newline at end of file
diff --git a/src/Tests/FunctionalTests/CCW/CCW.csproj b/src/Tests/FunctionalTests/CCW/CCW.csproj
new file mode 100644
index 000000000..481703f07
--- /dev/null
+++ b/src/Tests/FunctionalTests/CCW/CCW.csproj
@@ -0,0 +1,18 @@
+
+
+
+ Exe
+ net6.0
+ x86;x64
+ win10-x86;win10-x64
+ $(MSBuildProjectDirectory)\..\PublishProfiles\win10-$(Platform).pubxml
+ true
+ false
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Tests/FunctionalTests/CCW/Program.cs b/src/Tests/FunctionalTests/CCW/Program.cs
new file mode 100644
index 000000000..f436a2da1
--- /dev/null
+++ b/src/Tests/FunctionalTests/CCW/Program.cs
@@ -0,0 +1,80 @@
+using System;
+using TestComponentCSharp;
+using WinRT.Interop;
+using WinRT;
+
+var managedProperties = new ManagedProperties(42);
+var instance = new Class();
+
+// Ensure we can use the IProperties interface from the native side.
+instance.CopyProperties(managedProperties);
+if (managedProperties.ReadWriteProperty != instance.ReadWriteProperty)
+{
+ return 101;
+}
+
+// Check for the default interfaces provided by WinRT.Runtime
+Guid IID_IMarshal = new Guid("00000003-0000-0000-c000-000000000046");
+IObjectReference ccw = MarshalInterface.CreateMarshaler(managedProperties);
+ccw.TryAs(IID_IMarshal, out var marshalCCW);
+if (marshalCCW == null)
+{
+ return 102;
+}
+
+// Check for managed implemented interface to ensure not trimmed.
+Guid IID_IUriHandler = new Guid("FF4B4334-2104-537D-812E-67E3856AC7A2");
+ccw.TryAs(IID_IUriHandler, out var uriHandlerCCW);
+if (uriHandlerCCW == null)
+{
+ return 103;
+}
+
+// Ensure that interfaces on the vtable / object don't get trimmed even if unused.
+Guid IID_IWarning1 = new Guid("4DB3FA26-4BB1-50EA-8362-98F49651E516");
+Guid IID_IWarningClassOverrides = new Guid("E5635CE4-D483-55AA-86D5-080DC07F0A09");
+
+var managedWarningClass = new ManagedWarningClass();
+ccw = MarshalInterface.CreateMarshaler(managedWarningClass);
+ccw.TryAs(IID_IWarning1, out var warningCCW);
+if (warningCCW == null)
+{
+ return 104;
+}
+
+ccw.TryAs(IID_IWarningClassOverrides, out var warningOverrideCCW);
+if (warningOverrideCCW == null)
+{
+ return 105;
+}
+
+return 100;
+
+sealed class ManagedProperties : IProperties1, IUriHandler
+{
+ private readonly int _value;
+
+ public ManagedProperties(int value)
+ {
+ _value = value;
+ }
+
+ public int ReadWriteProperty => _value;
+
+ public void AddUriHandler(ProvideUri provideUri)
+ {
+ _ = provideUri();
+ }
+
+ void IUriHandler.AddUriHandler(ProvideUri provideUri) => AddUriHandler(provideUri);
+}
+
+sealed class ManagedWarningClass : WarningClass, IUriHandler
+{
+ public void AddUriHandler(ProvideUri provideUri)
+ {
+ _ = provideUri();
+ }
+
+ void IUriHandler.AddUriHandler(ProvideUri provideUri) => AddUriHandler(provideUri);
+}
\ No newline at end of file
diff --git a/src/Tests/FunctionalTests/ClassActivation/ClassActivation.csproj b/src/Tests/FunctionalTests/ClassActivation/ClassActivation.csproj
new file mode 100644
index 000000000..43370b531
--- /dev/null
+++ b/src/Tests/FunctionalTests/ClassActivation/ClassActivation.csproj
@@ -0,0 +1,18 @@
+
+
+
+ Exe
+ net6.0
+ x86;x64
+ win10-x86;win10-x64
+ $(MSBuildProjectDirectory)\..\PublishProfiles\win10-$(Platform).pubxml
+ true
+ false
+
+
+
+
+
+
+
+
diff --git a/src/Tests/FunctionalTests/ClassActivation/Program.cs b/src/Tests/FunctionalTests/ClassActivation/Program.cs
new file mode 100644
index 000000000..efa64e53f
--- /dev/null
+++ b/src/Tests/FunctionalTests/ClassActivation/Program.cs
@@ -0,0 +1,18 @@
+using System;
+using TestComponentCSharp;
+
+// new RCW / Factory activation
+var instance = new Class();
+
+var expectedEnum = EnumValue.Two;
+instance.EnumProperty = expectedEnum;
+
+// Custom type marshaling
+var expectedUri = new Uri("http://expected");
+instance.UriProperty = expectedUri;
+
+var instance2 = new Class(32);
+
+return instance.EnumProperty == expectedEnum &&
+ instance.UriProperty == expectedUri &&
+ instance2.IntProperty == 32 ? 100 : 101;
diff --git a/src/Tests/FunctionalTests/Collections/Collections.csproj b/src/Tests/FunctionalTests/Collections/Collections.csproj
new file mode 100644
index 000000000..43370b531
--- /dev/null
+++ b/src/Tests/FunctionalTests/Collections/Collections.csproj
@@ -0,0 +1,18 @@
+
+
+
+ Exe
+ net6.0
+ x86;x64
+ win10-x86;win10-x64
+ $(MSBuildProjectDirectory)\..\PublishProfiles\win10-$(Platform).pubxml
+ true
+ false
+
+
+
+
+
+
+
+
diff --git a/src/Tests/FunctionalTests/Collections/Program.cs b/src/Tests/FunctionalTests/Collections/Program.cs
new file mode 100644
index 000000000..cba570661
--- /dev/null
+++ b/src/Tests/FunctionalTests/Collections/Program.cs
@@ -0,0 +1,64 @@
+using System.Collections.Generic;
+using System.Linq;
+using test_component_derived.Nested;
+using TestComponentCSharp;
+
+var instance = new Class();
+
+var expected = new int[] { 0, 1, 2 };
+
+instance.BindableIterableProperty = expected;
+if (expected != instance.BindableIterableProperty)
+{
+ return 101;
+}
+
+var instance2 = TestComponent.TestRunner.MakeTests();
+var dict = new Dictionary()
+{
+ ["apples"] = "1",
+ ["oranges"] = "2",
+ ["pears"] = "3"
+};
+IDictionary outDict = null;
+var retDict = instance2.Collection3(dict, out outDict);
+if (!SequencesEqual(dict, outDict, retDict))
+{
+ return 101;
+}
+
+float[] floatArr = new float[] { 1.0f, 2.0f, 3.0f };
+float[] floatArr2 = new float[floatArr.Length];
+float[] outFloatArr;
+float[] retFloatArr = instance2.Array9(floatArr, floatArr2, out outFloatArr);
+if (!AllEqual(floatArr, floatArr2, outFloatArr, retFloatArr))
+{
+ return 101;
+}
+
+var hierarchyDAsObjectList = HierarchyC.CreateDerivedHierarchyDAsObjectList();
+foreach (var hierarchyDAsObject in hierarchyDAsObjectList)
+{
+ var hierarchyDAsHierarchyCCast = (HierarchyC)hierarchyDAsObject;
+ if (hierarchyDAsHierarchyCCast.HierarchyB_Method() != "HierarchyC.HierarchyB_Method" ||
+ hierarchyDAsHierarchyCCast.HierarchyA_Method() != "HierarchyB.HierarchyA_Method")
+ {
+ return 101;
+ }
+}
+
+var hierarchyDAsHierarchyCList = HierarchyC.CreateDerivedHierarchyDList();
+foreach (var hierarchyDAsHierarchyC in hierarchyDAsHierarchyCList)
+{
+ if (hierarchyDAsHierarchyC.HierarchyB_Method() != "HierarchyC.HierarchyB_Method" ||
+ hierarchyDAsHierarchyC.HierarchyA_Method() != "HierarchyB.HierarchyA_Method")
+ {
+ return 101;
+ }
+}
+
+return 100;
+
+static bool SequencesEqual(IEnumerable x, params IEnumerable[] list) => list.All((y) => x.SequenceEqual(y));
+
+static bool AllEqual(T[] x, params T[][] list) => list.All((y) => x.SequenceEqual(y));
diff --git a/src/Tests/FunctionalTests/DerivedClassActivation/DerivedClassActivation.csproj b/src/Tests/FunctionalTests/DerivedClassActivation/DerivedClassActivation.csproj
new file mode 100644
index 000000000..43370b531
--- /dev/null
+++ b/src/Tests/FunctionalTests/DerivedClassActivation/DerivedClassActivation.csproj
@@ -0,0 +1,18 @@
+
+
+
+ Exe
+ net6.0
+ x86;x64
+ win10-x86;win10-x64
+ $(MSBuildProjectDirectory)\..\PublishProfiles\win10-$(Platform).pubxml
+ true
+ false
+
+
+
+
+
+
+
+
diff --git a/src/Tests/FunctionalTests/DerivedClassActivation/Program.cs b/src/Tests/FunctionalTests/DerivedClassActivation/Program.cs
new file mode 100644
index 000000000..9e49d265b
--- /dev/null
+++ b/src/Tests/FunctionalTests/DerivedClassActivation/Program.cs
@@ -0,0 +1,6 @@
+using test_component_base;
+using test_component_derived.Nested;
+
+HierarchyB hierarchyCAsHierarchyB = new HierarchyC();
+return hierarchyCAsHierarchyB.HierarchyB_Method() == "HierarchyC.HierarchyB_Method" &&
+ hierarchyCAsHierarchyB.HierarchyA_Method() == "HierarchyB.HierarchyA_Method" ? 100 : 101;
diff --git a/src/Tests/FunctionalTests/DerivedClassAsBaseClass/DerivedClassAsBaseClass.csproj b/src/Tests/FunctionalTests/DerivedClassAsBaseClass/DerivedClassAsBaseClass.csproj
new file mode 100644
index 000000000..43370b531
--- /dev/null
+++ b/src/Tests/FunctionalTests/DerivedClassAsBaseClass/DerivedClassAsBaseClass.csproj
@@ -0,0 +1,18 @@
+
+
+
+ Exe
+ net6.0
+ x86;x64
+ win10-x86;win10-x64
+ $(MSBuildProjectDirectory)\..\PublishProfiles\win10-$(Platform).pubxml
+ true
+ false
+
+
+
+
+
+
+
+
diff --git a/src/Tests/FunctionalTests/DerivedClassAsBaseClass/Program.cs b/src/Tests/FunctionalTests/DerivedClassAsBaseClass/Program.cs
new file mode 100644
index 000000000..af9dfdd3c
--- /dev/null
+++ b/src/Tests/FunctionalTests/DerivedClassAsBaseClass/Program.cs
@@ -0,0 +1,18 @@
+using test_component_base;
+using test_component_derived.Nested;
+
+var hierarchyDAsHierarchyC = HierarchyC.CreateDerivedHierarchyD();
+if (hierarchyDAsHierarchyC.HierarchyB_Method() != "HierarchyC.HierarchyB_Method" ||
+ hierarchyDAsHierarchyC.HierarchyA_Method() != "HierarchyB.HierarchyA_Method")
+{
+ return 101;
+}
+
+var hierarchyDAsHierarchyCCast = (HierarchyC) HierarchyC.CreateDerivedHierarchyDAsObject();
+if (hierarchyDAsHierarchyCCast.HierarchyB_Method() != "HierarchyC.HierarchyB_Method" ||
+ hierarchyDAsHierarchyCCast.HierarchyA_Method() != "HierarchyB.HierarchyA_Method")
+{
+ return 101;
+}
+
+return 100;
\ No newline at end of file
diff --git a/src/Tests/FunctionalTests/DynamicInterfaceCasting/DynamicInterfaceCasting.csproj b/src/Tests/FunctionalTests/DynamicInterfaceCasting/DynamicInterfaceCasting.csproj
new file mode 100644
index 000000000..43370b531
--- /dev/null
+++ b/src/Tests/FunctionalTests/DynamicInterfaceCasting/DynamicInterfaceCasting.csproj
@@ -0,0 +1,18 @@
+
+
+
+ Exe
+ net6.0
+ x86;x64
+ win10-x86;win10-x64
+ $(MSBuildProjectDirectory)\..\PublishProfiles\win10-$(Platform).pubxml
+ true
+ false
+
+
+
+
+
+
+
+
diff --git a/src/Tests/FunctionalTests/DynamicInterfaceCasting/Program.cs b/src/Tests/FunctionalTests/DynamicInterfaceCasting/Program.cs
new file mode 100644
index 000000000..dcbb8323f
--- /dev/null
+++ b/src/Tests/FunctionalTests/DynamicInterfaceCasting/Program.cs
@@ -0,0 +1,7 @@
+using TestComponent;
+using WinRT;
+using WinRT.Interop;
+
+var instance = new Class();
+var agileObject = (IAgileObject)(IWinRTObject)instance;
+return agileObject != null ? 100 : 101;
\ No newline at end of file
diff --git a/src/Tests/FunctionalTests/Events/Events.csproj b/src/Tests/FunctionalTests/Events/Events.csproj
new file mode 100644
index 000000000..43370b531
--- /dev/null
+++ b/src/Tests/FunctionalTests/Events/Events.csproj
@@ -0,0 +1,18 @@
+
+
+
+ Exe
+ net6.0
+ x86;x64
+ win10-x86;win10-x64
+ $(MSBuildProjectDirectory)\..\PublishProfiles\win10-$(Platform).pubxml
+ true
+ false
+
+
+
+
+
+
+
+
diff --git a/src/Tests/FunctionalTests/Events/Program.cs b/src/Tests/FunctionalTests/Events/Program.cs
new file mode 100644
index 000000000..f798035a8
--- /dev/null
+++ b/src/Tests/FunctionalTests/Events/Program.cs
@@ -0,0 +1,59 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using TestComponentCSharp;
+
+int events_expected = 0;
+int events_received = 0;
+
+var instance = new Class();
+
+instance.Event0 += () => events_received++;
+instance.InvokeEvent0();
+events_expected++;
+
+instance.Event1 += (Class sender) =>
+{
+ events_received++;
+};
+instance.InvokeEvent1(instance);
+events_expected++;
+
+int int0 = 42;
+instance.Event2 += (Class sender, int arg0) =>
+{
+ if (arg0 == int0)
+ {
+ events_received++;
+ }
+};
+instance.InvokeEvent2(instance, int0);
+events_expected++;
+
+var collection0 = new int[] { 42, 1729 };
+var collection1 = new Dictionary { [1] = "foo", [2] = "bar" };
+instance.CollectionEvent += (Class sender, IList arg0, IDictionary arg1) =>
+{
+ if (arg0.SequenceEqual(collection0) && arg1.SequenceEqual(collection1))
+ {
+ events_received++;
+ }
+};
+instance.InvokeCollectionEvent(instance, collection0, collection1);
+events_expected++;
+
+var managedUriHandler = new ManagedUriHandler();
+instance.AddUriHandler(managedUriHandler);
+bool uriMatches = managedUriHandler.Uri == new Uri("http://github.com");
+
+return events_received == events_expected && uriMatches ? 100 : 101;
+
+class ManagedUriHandler : IUriHandler
+{
+ public Uri Uri { get; private set; }
+
+ public void AddUriHandler(ProvideUri provideUri)
+ {
+ Uri = provideUri();
+ }
+}
\ No newline at end of file
diff --git a/src/Tests/FunctionalTests/JsonValueFunctionCalls/JsonValueFunctionCalls.csproj b/src/Tests/FunctionalTests/JsonValueFunctionCalls/JsonValueFunctionCalls.csproj
new file mode 100644
index 000000000..ddd828fa9
--- /dev/null
+++ b/src/Tests/FunctionalTests/JsonValueFunctionCalls/JsonValueFunctionCalls.csproj
@@ -0,0 +1,18 @@
+
+
+
+ Exe
+ net6.0
+ x86;x64
+ win10-x86;win10-x64
+ $(MSBuildProjectDirectory)\..\PublishProfiles\win10-$(Platform).pubxml
+ true
+ false
+
+
+
+
+
+
+
+
diff --git a/src/Tests/FunctionalTests/JsonValueFunctionCalls/Program.cs b/src/Tests/FunctionalTests/JsonValueFunctionCalls/Program.cs
new file mode 100644
index 000000000..1800a57ea
--- /dev/null
+++ b/src/Tests/FunctionalTests/JsonValueFunctionCalls/Program.cs
@@ -0,0 +1,21 @@
+using Windows.Foundation;
+
+// Static function calls and create RCW for existing object.
+IStringable[] a = new IStringable[] {
+ Windows.Data.Json.JsonValue.CreateNumberValue(3),
+ Windows.Data.Json.JsonValue.CreateNumberValue(4),
+ Windows.Data.Json.JsonValue.CreateNumberValue(5.0)
+ };
+
+int result = 0;
+
+// Interface function call
+foreach (var str in a)
+{
+ result += int.Parse(str.ToString());
+}
+
+// Class function call
+result += (int)(a[1] as Windows.Data.Json.JsonValue).GetNumber();
+
+return result == 16 ? 100 : 101;
\ No newline at end of file
diff --git a/src/Tests/FunctionalTests/PublishProfiles/win10-arm64.pubxml b/src/Tests/FunctionalTests/PublishProfiles/win10-arm64.pubxml
new file mode 100644
index 000000000..5957dcb09
--- /dev/null
+++ b/src/Tests/FunctionalTests/PublishProfiles/win10-arm64.pubxml
@@ -0,0 +1,14 @@
+
+
+
+ FileSystem
+ arm64
+ win10-arm64
+ bin\$(Configuration)\$(TargetFramework)\$(RuntimeIdentifier)\publish\
+ True
+ False
+ False
+ True
+ true
+
+
diff --git a/src/Tests/FunctionalTests/PublishProfiles/win10-x64.pubxml b/src/Tests/FunctionalTests/PublishProfiles/win10-x64.pubxml
new file mode 100644
index 000000000..0e6acfc89
--- /dev/null
+++ b/src/Tests/FunctionalTests/PublishProfiles/win10-x64.pubxml
@@ -0,0 +1,14 @@
+
+
+
+ FileSystem
+ x64
+ win10-x64
+ bin\$(Configuration)\$(TargetFramework)\$(RuntimeIdentifier)\publish\
+ True
+ False
+ False
+ True
+ true
+
+
diff --git a/src/Tests/FunctionalTests/PublishProfiles/win10-x86.pubxml b/src/Tests/FunctionalTests/PublishProfiles/win10-x86.pubxml
new file mode 100644
index 000000000..ab39fc15f
--- /dev/null
+++ b/src/Tests/FunctionalTests/PublishProfiles/win10-x86.pubxml
@@ -0,0 +1,14 @@
+
+
+
+ FileSystem
+ x86
+ win10-x86
+ bin\$(Configuration)\$(TargetFramework)\$(RuntimeIdentifier)\publish\
+ True
+ False
+ False
+ True
+ true
+
+
diff --git a/src/Tests/FunctionalTests/Structs/Program.cs b/src/Tests/FunctionalTests/Structs/Program.cs
new file mode 100644
index 000000000..1988ec481
--- /dev/null
+++ b/src/Tests/FunctionalTests/Structs/Program.cs
@@ -0,0 +1,22 @@
+using TestComponentCSharp;
+
+var instance = new Class();
+var blittable = instance.GetBlittableStructVector();
+
+int sum = 0;
+int expected_sum = 0;
+for (int i = 0; i < blittable.Count; i++)
+{
+ sum += blittable[i].blittable.i32;
+ expected_sum += i;
+}
+
+var nonblittable = instance.GetNonBlittableStructVector();
+for (int i = 0; i < nonblittable.Count; i++)
+{
+ sum += nonblittable[i].blittable.i32;
+ expected_sum += i;
+}
+
+return sum == expected_sum ? 100 : 101;
+
diff --git a/src/Tests/FunctionalTests/Structs/Structs.csproj b/src/Tests/FunctionalTests/Structs/Structs.csproj
new file mode 100644
index 000000000..43370b531
--- /dev/null
+++ b/src/Tests/FunctionalTests/Structs/Structs.csproj
@@ -0,0 +1,18 @@
+
+
+
+ Exe
+ net6.0
+ x86;x64
+ win10-x86;win10-x64
+ $(MSBuildProjectDirectory)\..\PublishProfiles\win10-$(Platform).pubxml
+ true
+ false
+
+
+
+
+
+
+
+
diff --git a/src/Tests/TestComponentCSharp/TestComponentCSharp.vcxproj b/src/Tests/TestComponentCSharp/TestComponentCSharp.vcxproj
index b4d5d8a52..d014d2c83 100644
--- a/src/Tests/TestComponentCSharp/TestComponentCSharp.vcxproj
+++ b/src/Tests/TestComponentCSharp/TestComponentCSharp.vcxproj
@@ -47,6 +47,9 @@
Unicode
false
+
+ true
+
diff --git a/src/WinRT.Runtime/Attributes.cs b/src/WinRT.Runtime/Attributes.cs
index 2a842db78..4599de3f3 100644
--- a/src/WinRT.Runtime/Attributes.cs
+++ b/src/WinRT.Runtime/Attributes.cs
@@ -3,6 +3,7 @@
using System;
using System.ComponentModel;
+using System.Diagnostics.CodeAnalysis;
namespace WinRT
{
@@ -64,5 +65,37 @@ public WindowsRuntimeTypeAttribute(string sourceMetadata = null)
}
public string SourceMetadata { get; }
+ }
+
+ ///
+ /// When applied to a type, it specifies the provided type, if one is provided, is the ABI helper type for this type.
+ ///
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.Delegate | AttributeTargets.Struct | AttributeTargets.Enum, Inherited = false, AllowMultiple = false)]
+#if EMBED
+ internal
+#else
+ public
+#endif
+ sealed class WindowsRuntimeHelperTypeAttribute : Attribute
+ {
+ // Indicates no associated helper types (i.e. blittable types).
+ public WindowsRuntimeHelperTypeAttribute()
+ {
+ }
+
+ public WindowsRuntimeHelperTypeAttribute(
+#if NET
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.PublicFields)]
+#endif
+ Type helperType)
+ {
+ HelperType = helperType;
+ }
+
+#if NET
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.PublicFields)]
+#endif
+ public Type HelperType { get; }
}
}
diff --git a/src/WinRT.Runtime/ComWrappersSupport.cs b/src/WinRT.Runtime/ComWrappersSupport.cs
index bb9a3ece7..1ab7f18b4 100644
--- a/src/WinRT.Runtime/ComWrappersSupport.cs
+++ b/src/WinRT.Runtime/ComWrappersSupport.cs
@@ -6,6 +6,7 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
@@ -149,7 +150,9 @@ public static ObjectReference GetObjectReferenceForInterface(IntPtr extern
}
}
- public static void RegisterProjectionAssembly(Assembly assembly) => TypeNameSupport.RegisterProjectionAssembly(assembly);
+ public static void RegisterProjectionAssembly(Assembly assembly) => TypeNameSupport.RegisterProjectionAssembly(assembly);
+
+ public static void RegisterProjectionTypeBaseTypeMapping(IDictionary typeNameToBaseTypeNameMapping) => TypeNameSupport.RegisterProjectionTypeBaseTypeMapping(typeNameToBaseTypeNameMapping);
internal static object GetRuntimeClassCCWTypeIfAny(object obj)
{
@@ -166,7 +169,13 @@ internal static object GetRuntimeClassCCWTypeIfAny(object obj)
return obj;
}
- internal static List GetInterfaceTableEntries(Type type)
+ internal static List GetInterfaceTableEntries(
+#if NET6_0_OR_GREATER
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.Interfaces)]
+#elif NET
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]
+#endif
+ Type type)
{
var entries = new List();
bool hasCustomIMarshalInterface = false;
@@ -374,7 +383,11 @@ private static Func CreateNullableTFactory(Type implementa
return (IInspectable obj) => getValueMethod.Invoke(null, new[] { obj });
}
- private static Func CreateAbiNullableTFactory(Type implementationType)
+ private static Func CreateAbiNullableTFactory(
+#if NET
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicMethods)]
+#endif
+ Type implementationType)
{
var getValueMethod = implementationType.GetMethod("GetValue", BindingFlags.Static | BindingFlags.NonPublic);
return (IInspectable obj) => getValueMethod.Invoke(null, new[] { obj });
@@ -413,7 +426,12 @@ private static Func CreateCustomTypeMappingFactory(Type cu
return (IInspectable obj) => fromAbiMethodFunc(obj.ThisPtr);
}
- internal static Func CreateTypedRcwFactory(Type implementationType, string runtimeClassName = null)
+ internal static Func CreateTypedRcwFactory(
+#if NET
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicConstructors)]
+#endif
+ Type implementationType,
+ string runtimeClassName = null)
{
// If runtime class name is empty or "Object", then just use IInspectable.
if (implementationType == null || implementationType == typeof(object))
@@ -464,15 +482,18 @@ internal static Func CreateTypedRcwFactory(Type implementa
}
return CreateFactoryForImplementationType(runtimeClassName, implementationType);
- }
-
+ }
+
+#if NET
+ [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicConstructors)]
+#endif
internal static Type GetRuntimeClassForTypeCreation(IInspectable inspectable, Type staticallyDeterminedType)
{
string runtimeClassName = inspectable.GetRuntimeClassName(noThrow: true);
Type implementationType = null;
if (!string.IsNullOrEmpty(runtimeClassName))
{
- implementationType = TypeNameSupport.FindTypeByNameCached(runtimeClassName);
+ implementationType = TypeNameSupport.FindRcwTypeByNameCached(runtimeClassName);
}
if (staticallyDeterminedType != null && staticallyDeterminedType != typeof(object))
diff --git a/src/WinRT.Runtime/ComWrappersSupport.net5.cs b/src/WinRT.Runtime/ComWrappersSupport.net5.cs
index 46dba7941..09e91df18 100644
--- a/src/WinRT.Runtime/ComWrappersSupport.net5.cs
+++ b/src/WinRT.Runtime/ComWrappersSupport.net5.cs
@@ -4,6 +4,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
using System.Linq.Expressions;
using System.Reflection;
using System.Runtime.CompilerServices;
@@ -35,7 +36,10 @@ private static DefaultComWrappers DefaultComWrappersInstance
}
internal static readonly ConditionalWeakTable InspectableInfoTable = new ConditionalWeakTable();
- [ThreadStatic] internal static Type CreateRCWType;
+
+ [ThreadStatic]
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicConstructors)]
+ internal static Type CreateRCWType;
private static ComWrappers _comWrappers;
private static object _comWrappersLock = new object();
@@ -82,12 +86,12 @@ internal static unsafe InspectableInfo GetInspectableInfo(IntPtr pThis)
return InspectableInfoTable.GetValue(_this.GetType(), o => PregenerateNativeTypeInformation(o).inspectableInfo);
}
- public static T CreateRcwForComObject(IntPtr ptr)
+ public static T CreateRcwForComObject<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicConstructors)] T>(IntPtr ptr)
{
return CreateRcwForComObject(ptr, true);
}
- private static T CreateRcwForComObject(IntPtr ptr, bool tryUseCache)
+ private static T CreateRcwForComObject<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicConstructors)] T>(IntPtr ptr, bool tryUseCache)
{
if (ptr == IntPtr.Zero)
{
@@ -211,11 +215,30 @@ public static void InitializeComWrappers(ComWrappers wrappers = null)
ComWrappers = wrappers;
}
- internal static Func GetTypedRcwFactory(Type implementationType) => TypedObjectFactoryCacheForType.GetOrAdd(implementationType, classType => CreateTypedRcwFactory(classType));
+ internal static Func GetTypedRcwFactory([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicConstructors)] Type implementationType) => TypedObjectFactoryCacheForType.GetOrAdd(implementationType, classType => CreateTypedRcwFactory(classType));
- private static Func CreateFactoryForImplementationType(string runtimeClassName, Type implementationType)
+ private static Func CreateFactoryForImplementationType(string runtimeClassName, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicConstructors)] Type implementationType)
{
if (implementationType.IsGenericType)
+ {
+ Type genericImplType = GetGenericImplType(implementationType);
+ if (genericImplType != null)
+ {
+ var createRcw = genericImplType.GetMethod("CreateRcw", BindingFlags.Public | BindingFlags.Static, null, new[] { typeof(IInspectable) }, null);
+ return (Func)createRcw.CreateDelegate(typeof(Func));
+ }
+ }
+
+ if (implementationType.IsInterface)
+ {
+ return obj => obj;
+ }
+
+ var constructor = implementationType.GetConstructor(BindingFlags.NonPublic | BindingFlags.CreateInstance | BindingFlags.Instance, null, new[] { typeof(IObjectReference) }, null);
+ return (IInspectable obj) => constructor.Invoke(new[] { obj.ObjRef });
+
+ [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)]
+ static Type GetGenericImplType(Type implementationType)
{
var genericType = implementationType.GetGenericTypeDefinition();
@@ -240,21 +263,13 @@ private static Func CreateFactoryForImplementationType(str
{
genericImplType = typeof(IEnumerableImpl<>);
}
-
- if (genericImplType != null)
+ else
{
- var createRcw = genericImplType.MakeGenericType(implementationType.GetGenericArguments()).GetMethod("CreateRcw", BindingFlags.Public | BindingFlags.Static, null, new[] { typeof(IInspectable) }, null);
- return (Func)createRcw.CreateDelegate(typeof(Func));
+ return null;
}
- }
-
- if (implementationType.IsInterface)
- {
- return obj => obj;
- }
- var constructor = implementationType.GetConstructor(BindingFlags.NonPublic | BindingFlags.CreateInstance | BindingFlags.Instance, null, new[] { typeof(IObjectReference) }, null);
- return (IInspectable obj) => constructor.Invoke(new[] { obj.ObjRef });
+ return genericImplType.MakeGenericType(implementationType.GetGenericArguments());
+ }
}
}
@@ -439,7 +454,13 @@ static unsafe DefaultComWrappers()
protected override unsafe ComInterfaceEntry* ComputeVtables(object obj, CreateComInterfaceFlags flags, out int count)
{
- var vtableEntries = TypeVtableEntryTable.GetValue(obj.GetType(), (type) =>
+ var vtableEntries = TypeVtableEntryTable.GetValue(obj.GetType(), (
+#if NET6_0_OR_GREATER
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.Interfaces)]
+#elif NET
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]
+#endif
+ type) =>
{
if (IsRuntimeImplementedRCW(type))
{
diff --git a/src/WinRT.Runtime/GuidGenerator.cs b/src/WinRT.Runtime/GuidGenerator.cs
index f87bd7f05..2028abe82 100644
--- a/src/WinRT.Runtime/GuidGenerator.cs
+++ b/src/WinRT.Runtime/GuidGenerator.cs
@@ -2,6 +2,7 @@
// Licensed under the MIT License.
using System;
+using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Reflection;
using System.Security.Cryptography;
@@ -21,7 +22,11 @@ public static Guid GetGUID(Type type)
return type.GetGuidType().GUID;
}
- public static Guid GetIID(Type type)
+ public static Guid GetIID(
+#if NET
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)]
+#endif
+ Type type)
{
type = type.GetGuidType();
if (!type.IsGenericType)
@@ -31,7 +36,11 @@ public static Guid GetIID(Type type)
return (Guid)type.GetField("PIID").GetValue(null);
}
- public static string GetSignature(Type type)
+ public static string GetSignature(
+#if NET
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)]
+#endif
+ Type type)
{
if (type == typeof(object))
{
diff --git a/src/WinRT.Runtime/Interop/IActivationFactory.cs b/src/WinRT.Runtime/Interop/IActivationFactory.cs
index 0acc53c69..1ba4f4614 100644
--- a/src/WinRT.Runtime/Interop/IActivationFactory.cs
+++ b/src/WinRT.Runtime/Interop/IActivationFactory.cs
@@ -9,7 +9,8 @@
namespace WinRT.Interop
{
[WindowsRuntimeType]
- [Guid("00000035-0000-0000-C000-000000000046")]
+ [Guid("00000035-0000-0000-C000-000000000046")]
+ [WindowsRuntimeHelperType(typeof(global::ABI.WinRT.Interop.IActivationFactory))]
#if EMBED
internal
#else
diff --git a/src/WinRT.Runtime/Interop/IAgileReference.net5.cs b/src/WinRT.Runtime/Interop/IAgileReference.net5.cs
index b0bc9b85e..78ff5392b 100644
--- a/src/WinRT.Runtime/Interop/IAgileReference.net5.cs
+++ b/src/WinRT.Runtime/Interop/IAgileReference.net5.cs
@@ -7,14 +7,16 @@
namespace WinRT.Interop
{
[WindowsRuntimeType]
- [Guid("C03F6A43-65A4-9818-987E-E0B810D2A6F2")]
+ [Guid("C03F6A43-65A4-9818-987E-E0B810D2A6F2")]
+ [WindowsRuntimeHelperType(typeof(global::ABI.WinRT.Interop.IAgileReference))]
internal interface IAgileReference
{
IObjectReference Resolve(Guid riid);
}
[WindowsRuntimeType]
- [Guid("94ea2b94-e9cc-49e0-c0ff-ee64ca8f5b90")]
+ [Guid("94ea2b94-e9cc-49e0-c0ff-ee64ca8f5b90")]
+ [WindowsRuntimeHelperType(typeof(global::ABI.WinRT.Interop.IAgileObject))]
#if EMBED
internal
#else
@@ -26,7 +28,8 @@ interface IAgileObject
}
[WindowsRuntimeType]
- [Guid("00000146-0000-0000-C000-000000000046")]
+ [Guid("00000146-0000-0000-C000-000000000046")]
+ [WindowsRuntimeHelperType(typeof(global::ABI.WinRT.Interop.IGlobalInterfaceTable))]
internal interface IGlobalInterfaceTable
{
IntPtr RegisterInterfaceInGlobal(IntPtr ptr, Guid riid);
diff --git a/src/WinRT.Runtime/Interop/IAgileReference.netstandard2.0.cs b/src/WinRT.Runtime/Interop/IAgileReference.netstandard2.0.cs
index 65f984eda..edbb4f13c 100644
--- a/src/WinRT.Runtime/Interop/IAgileReference.netstandard2.0.cs
+++ b/src/WinRT.Runtime/Interop/IAgileReference.netstandard2.0.cs
@@ -7,14 +7,16 @@
namespace WinRT.Interop
{
[WindowsRuntimeType]
- [Guid("C03F6A43-65A4-9818-987E-E0B810D2A6F2")]
+ [Guid("C03F6A43-65A4-9818-987E-E0B810D2A6F2")]
+ [WindowsRuntimeHelperType(typeof(global::ABI.WinRT.Interop.IAgileReference))]
internal interface IAgileReference
{
IObjectReference Resolve(Guid riid);
}
[WindowsRuntimeType]
- [Guid("94ea2b94-e9cc-49e0-c0ff-ee64ca8f5b90")]
+ [Guid("94ea2b94-e9cc-49e0-c0ff-ee64ca8f5b90")]
+ [WindowsRuntimeHelperType(typeof(global::ABI.WinRT.Interop.IAgileObject))]
#if EMBED
internal
#else
@@ -25,7 +27,8 @@ interface IAgileObject
}
[WindowsRuntimeType]
- [Guid("00000146-0000-0000-C000-000000000046")]
+ [Guid("00000146-0000-0000-C000-000000000046")]
+ [WindowsRuntimeHelperType(typeof(global::ABI.WinRT.Interop.IGlobalInterfaceTable))]
internal interface IGlobalInterfaceTable
{
IntPtr RegisterInterfaceInGlobal(IntPtr ptr, Guid riid);
diff --git a/src/WinRT.Runtime/Interop/IMarshal.cs b/src/WinRT.Runtime/Interop/IMarshal.cs
index 32a519d15..dbd421014 100644
--- a/src/WinRT.Runtime/Interop/IMarshal.cs
+++ b/src/WinRT.Runtime/Interop/IMarshal.cs
@@ -13,7 +13,8 @@ internal enum MSHCTX : int { Local = 0, NoSharedMem = 1, DifferentMachine = 2, I
internal enum MSHLFLAGS : int { Normal = 0, TableStrong = 1, TableWeak = 2, NoPing = 4 }
[global::WinRT.WindowsRuntimeType("Windows.Foundation.UniversalApiContract")]
- [Guid("00000003-0000-0000-c000-000000000046")]
+ [Guid("00000003-0000-0000-c000-000000000046")]
+ [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.WinRT.Interop.IMarshal))]
internal interface IMarshal
{
unsafe void GetUnmarshalClass(Guid* riid, IntPtr pv, MSHCTX dwDestContext, IntPtr pvDestContext, MSHLFLAGS mshlFlags, Guid* pCid);
diff --git a/src/WinRT.Runtime/Interop/IWeakReferenceSource.net5.cs b/src/WinRT.Runtime/Interop/IWeakReferenceSource.net5.cs
index d0597618c..1e09d0f78 100644
--- a/src/WinRT.Runtime/Interop/IWeakReferenceSource.net5.cs
+++ b/src/WinRT.Runtime/Interop/IWeakReferenceSource.net5.cs
@@ -10,6 +10,7 @@ namespace WinRT.Interop
{
[WindowsRuntimeType]
[Guid("00000038-0000-0000-C000-000000000046")]
+ [WindowsRuntimeHelperType(typeof(global::ABI.WinRT.Interop.IWeakReferenceSource))]
#if EMBED
internal
#else
@@ -22,6 +23,7 @@ interface IWeakReferenceSource
[WindowsRuntimeType]
[Guid("00000037-0000-0000-C000-000000000046")]
+ [WindowsRuntimeHelperType(typeof(global::ABI.WinRT.Interop.IWeakReference))]
#if EMBED
internal
#else
diff --git a/src/WinRT.Runtime/Interop/IWeakReferenceSource.netstandard2.0.cs b/src/WinRT.Runtime/Interop/IWeakReferenceSource.netstandard2.0.cs
index 24b447089..15cb04999 100644
--- a/src/WinRT.Runtime/Interop/IWeakReferenceSource.netstandard2.0.cs
+++ b/src/WinRT.Runtime/Interop/IWeakReferenceSource.netstandard2.0.cs
@@ -7,7 +7,8 @@
namespace WinRT.Interop
{
[WindowsRuntimeType]
- [Guid("00000038-0000-0000-C000-000000000046")]
+ [Guid("00000038-0000-0000-C000-000000000046")]
+ [WindowsRuntimeHelperType(typeof(global::ABI.WinRT.Interop.IWeakReferenceSource))]
#if EMBED
internal
#else
@@ -19,7 +20,8 @@ interface IWeakReferenceSource
}
[WindowsRuntimeType]
- [Guid("00000037-0000-0000-C000-000000000046")]
+ [Guid("00000037-0000-0000-C000-000000000046")]
+ [WindowsRuntimeHelperType(typeof(global::ABI.WinRT.Interop.IWeakReference))]
#if EMBED
internal
#else
diff --git a/src/WinRT.Runtime/Marshalers.cs b/src/WinRT.Runtime/Marshalers.cs
index dcb61f881..f03556e72 100644
--- a/src/WinRT.Runtime/Marshalers.cs
+++ b/src/WinRT.Runtime/Marshalers.cs
@@ -3,6 +3,7 @@
using System;
using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
using System.Linq.Expressions;
using System.Reflection;
using System.Runtime.CompilerServices;
@@ -447,7 +448,11 @@ public static void DisposeAbiArray(object box)
#endif
class MarshalGeneric
{
+#if NET
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)]
+#endif
protected static readonly Type HelperType = typeof(T).GetHelperType();
+
protected static readonly Type AbiType = typeof(T).GetAbiType();
protected static readonly Type MarshalerType = typeof(T).GetMarshalerType();
private static readonly bool MarshalByObjectReferenceValueSupported = typeof(T).GetMarshaler2Type() == typeof(ObjectReferenceValue);
@@ -1038,6 +1043,14 @@ public static void DisposeAbi(IntPtr ptr)
#endif
struct MarshalInterface
{
+#if NET
+ [DynamicallyAccessedMembers(
+ DynamicallyAccessedMemberTypes.PublicFields |
+ DynamicallyAccessedMemberTypes.NonPublicFields |
+ DynamicallyAccessedMemberTypes.PublicNestedTypes |
+ DynamicallyAccessedMemberTypes.PublicMethods |
+ DynamicallyAccessedMemberTypes.NonPublicMethods)]
+#endif
private static readonly Type HelperType = typeof(T).GetHelperType();
private static Func _ToAbi;
private static Func _CreateMarshaler;
@@ -1181,9 +1194,23 @@ private static Func BindCreateMarshaler()
#else
public
#endif
- static class MarshalInspectable
+ static class MarshalInspectable<
+#if NET6_0_OR_GREATER
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.Interfaces | DynamicallyAccessedMemberTypes.NonPublicConstructors)]
+#elif NET
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]
+#endif
+ T>
{
- public static IObjectReference CreateMarshaler(T o, Guid iid, bool unwrapObject = true)
+ public static IObjectReference CreateMarshaler(
+#if NET6_0_OR_GREATER
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.Interfaces)]
+#elif NET
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]
+#endif
+ T o,
+ Guid iid,
+ bool unwrapObject = true)
{
if (o is null)
{
@@ -1205,12 +1232,27 @@ public static IObjectReference CreateMarshaler(T o, Guid iid, bool unwrapObje
return ComWrappersSupport.CreateCCWForObject(o, iid);
}
- public static IObjectReference CreateMarshaler(T o, bool unwrapObject = true)
+ public static IObjectReference CreateMarshaler(
+#if NET6_0_OR_GREATER
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.Interfaces)]
+#elif NET
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]
+#endif
+ T o,
+ bool unwrapObject = true)
{
return CreateMarshaler(o, InterfaceIIDs.IInspectable_IID, unwrapObject);
}
- public static ObjectReferenceValue CreateMarshaler2(T o, Guid iid, bool unwrapObject = true)
+ public static ObjectReferenceValue CreateMarshaler2(
+#if NET6_0_OR_GREATER
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.Interfaces)]
+#elif NET
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]
+#endif
+ T o,
+ Guid iid,
+ bool unwrapObject = true)
{
if (o is null)
{
@@ -1232,8 +1274,13 @@ public static ObjectReferenceValue CreateMarshaler2(T o, Guid iid, bool unwrapOb
return ComWrappersSupport.CreateCCWForObjectForMarshaling(o, iid);
}
- public static ObjectReferenceValue CreateMarshaler2(T o, bool unwrapObject = true) =>
- CreateMarshaler2(o, InterfaceIIDs.IInspectable_IID, unwrapObject);
+ public static ObjectReferenceValue CreateMarshaler2(
+#if NET6_0_OR_GREATER
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.Interfaces)]
+#elif NET
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)]
+#endif
+ T o, bool unwrapObject = true) => CreateMarshaler2(o, InterfaceIIDs.IInspectable_IID, unwrapObject);
public static IntPtr GetAbi(IObjectReference objRef) =>
objRef is null ? IntPtr.Zero : MarshalInterfaceHelper.GetAbi(objRef);
@@ -1397,7 +1444,7 @@ internal static class Marshaler
#if EMBED
internal
-#else
+#else
public
#endif
class Marshaler
@@ -1599,6 +1646,9 @@ static Marshaler()
RefAbiType = AbiType.MakeByRefType();
}
+#if NET
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)]
+#endif
public static readonly Type AbiType;
public static readonly Type RefAbiType;
public static readonly Func CreateMarshaler;
diff --git a/src/WinRT.Runtime/MatchingRefApiCompatBaseline.net5.0.txt b/src/WinRT.Runtime/MatchingRefApiCompatBaseline.net5.0.txt
index 59248b033..b48d884cf 100644
--- a/src/WinRT.Runtime/MatchingRefApiCompatBaseline.net5.0.txt
+++ b/src/WinRT.Runtime/MatchingRefApiCompatBaseline.net5.0.txt
@@ -2,6 +2,7 @@ Compat issues with assembly WinRT.Runtime:
MembersMustExist : Member 'public WinRT.ObjectReferenceValue ABI.System.EventHandler.CreateMarshaler2(System.EventHandler)' does not exist in the reference but it does exist in the implementation.
MembersMustExist : Member 'public System.EventHandler ABI.System.EventHandler.CreateRcw(System.IntPtr)' does not exist in the reference but it does exist in the implementation.
MembersMustExist : Member 'public WinRT.ObjectReferenceValue ABI.System.Nullable.CreateMarshaler2(System.Object)' does not exist in the reference but it does exist in the implementation.
+CannotRemoveAttribute : Attribute 'System.Diagnostics.CodeAnalysis.UnconditionalSuppressMessageAttribute' exists on 'ABI.System.Type.FromAbi(ABI.System.Type)' in the implementation but not the reference.
MembersMustExist : Member 'public ABI.System.Type ABI.System.Type.GetAbi(ABI.System.Type.Pinnable)' does not exist in the reference but it does exist in the implementation.
TypesMustExist : Type 'ABI.System.Type.Pinnable' does not exist in the reference but it does exist in the implementation.
MembersMustExist : Member 'public WinRT.ObjectReferenceValue ABI.System.Uri.CreateMarshaler2(System.Uri)' does not exist in the reference but it does exist in the implementation.
@@ -21,10 +22,14 @@ MembersMustExist : Member 'public WinRT.ObjectReferenceValue ABI.System.Componen
MembersMustExist : Member 'public System.ComponentModel.PropertyChangedEventHandler ABI.System.ComponentModel.PropertyChangedEventHandler.CreateRcw(System.IntPtr)' does not exist in the reference but it does exist in the implementation.
TypesMustExist : Type 'ABI.WinRT.Interop.IWeakReferenceSourceMethods' does not exist in the reference but it does exist in the implementation.
TypesMustExist : Type 'System.Numerics.VectorExtensions' does not exist in the reference but it does exist in the implementation.
+CannotRemoveAttribute : Attribute 'WinRT.WindowsRuntimeHelperTypeAttribute' exists on 'Windows.Foundation.Point' in the implementation but not the reference.
+CannotRemoveAttribute : Attribute 'WinRT.WindowsRuntimeHelperTypeAttribute' exists on 'Windows.Foundation.Rect' in the implementation but not the reference.
+CannotRemoveAttribute : Attribute 'WinRT.WindowsRuntimeHelperTypeAttribute' exists on 'Windows.Foundation.Size' in the implementation but not the reference.
TypesMustExist : Type 'WinRT.ComWrappersHelper' does not exist in the reference but it does exist in the implementation.
MembersMustExist : Member 'public WinRT.ObjectReference WinRT.ComWrappersSupport.GetObjectReferenceForInterface(System.IntPtr)' does not exist in the reference but it does exist in the implementation.
MembersMustExist : Member 'public WinRT.ObjectReference WinRT.ComWrappersSupport.GetObjectReferenceForInterface(System.IntPtr, System.Guid)' does not exist in the reference but it does exist in the implementation.
MembersMustExist : Member 'public void WinRT.ComWrappersSupport.RegisterObjectForInterface(System.Object, System.IntPtr, System.Runtime.InteropServices.CreateObjectFlags)' does not exist in the reference but it does exist in the implementation.
+MembersMustExist : Member 'public void WinRT.ComWrappersSupport.RegisterProjectionTypeBaseTypeMapping(System.Collections.Generic.IDictionary)' does not exist in the reference but it does exist in the implementation.
MembersMustExist : Member 'protected void WinRT.IObjectReference.AddRef(System.Boolean)' does not exist in the reference but it does exist in the implementation.
MembersMustExist : Member 'public WinRT.ObjectReference WinRT.IObjectReference.AsKnownPtr(System.IntPtr)' does not exist in the reference but it does exist in the implementation.
MembersMustExist : Member 'public WinRT.ObjectReferenceValue WinRT.IObjectReference.AsValue()' does not exist in the reference but it does exist in the implementation.
@@ -32,6 +37,8 @@ MembersMustExist : Member 'public WinRT.ObjectReferenceValue WinRT.IObjectRefere
MembersMustExist : Member 'public System.Int32 WinRT.IObjectReference.TryAs(System.Guid, System.IntPtr)' does not exist in the reference but it does exist in the implementation.
MembersMustExist : Member 'public WinRT.ObjectReferenceValue WinRT.MarshalDelegate.CreateMarshaler2(System.Object, System.Guid, System.Boolean)' does not exist in the reference but it does exist in the implementation.
MembersMustExist : Member 'public T WinRT.MarshalDelegate.FromAbi(System.IntPtr)' does not exist in the reference but it does exist in the implementation.
+CannotRemoveAttribute : Attribute 'System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute' exists on 'System.Type WinRT.Marshaler.AbiType' in the implementation but not the reference.
+CannotRemoveAttribute : Attribute 'System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute' exists on 'System.Type WinRT.MarshalGeneric.HelperType' in the implementation but not the reference.
MembersMustExist : Member 'public WinRT.ObjectReferenceValue WinRT.MarshalInspectable.CreateMarshaler2(T, System.Boolean)' does not exist in the reference but it does exist in the implementation.
MembersMustExist : Member 'public WinRT.ObjectReferenceValue WinRT.MarshalInspectable.CreateMarshaler2(T, System.Guid, System.Boolean)' does not exist in the reference but it does exist in the implementation.
MembersMustExist : Member 'public WinRT.IObjectReference WinRT.MarshalInspectable.CreateMarshaler(T, System.Guid, System.Boolean)' does not exist in the reference but it does exist in the implementation.
@@ -49,6 +56,9 @@ MembersMustExist : Member 'public System.IntPtr WinRT.MarshalString.GetAbi()' do
MembersMustExist : Member 'public System.IntPtr WinRT.MarshalString.GetAbi(WinRT.MarshalString.Pinnable)' does not exist in the reference but it does exist in the implementation.
TypesMustExist : Type 'WinRT.MarshalString.Pinnable' does not exist in the reference but it does exist in the implementation.
TypesMustExist : Type 'WinRT.ObjectReferenceValue' does not exist in the reference but it does exist in the implementation.
+TypesMustExist : Type 'WinRT.WindowsRuntimeHelperTypeAttribute' does not exist in the reference but it does exist in the implementation.
+CannotRemoveAttribute : Attribute 'WinRT.WindowsRuntimeHelperTypeAttribute' exists on 'WinRT.Interop.IActivationFactory' in the implementation but not the reference.
+CannotRemoveAttribute : Attribute 'WinRT.WindowsRuntimeHelperTypeAttribute' exists on 'WinRT.Interop.IAgileObject' in the implementation but not the reference.
TypesMustExist : Type 'WinRT.Interop.IWeakReference' does not exist in the reference but it does exist in the implementation.
TypesMustExist : Type 'WinRT.Interop.IWeakReferenceSource' does not exist in the reference but it does exist in the implementation.
-Total Issues: 52
+Total Issues: 62
diff --git a/src/WinRT.Runtime/ObjectReference.cs b/src/WinRT.Runtime/ObjectReference.cs
index 3fbd74c63..2ad8d65ce 100644
--- a/src/WinRT.Runtime/ObjectReference.cs
+++ b/src/WinRT.Runtime/ObjectReference.cs
@@ -3,6 +3,7 @@
using System;
using System.Collections.Concurrent;
+using System.Diagnostics.CodeAnalysis;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
@@ -122,8 +123,17 @@ protected IObjectReference(IntPtr thisPtr)
Dispose(false);
}
- public ObjectReference As() => As(GuidGenerator.GetIID(typeof(T)));
- public unsafe ObjectReference As(Guid iid)
+ public ObjectReference As<
+#if NET
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicFields)]
+#endif
+ T>() => As(GuidGenerator.GetIID(typeof(T)));
+
+ public unsafe ObjectReference As<
+#if NET
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicFields)]
+#endif
+ T>(Guid iid)
{
Marshal.ThrowExceptionForHR(TryAs(iid, out var objRef));
return objRef;
@@ -154,9 +164,17 @@ public unsafe TInterface AsInterface()
#endif
}
- public int TryAs(out ObjectReference objRef) => TryAs(GuidGenerator.GetIID(typeof(T)), out objRef);
+ public int TryAs<
+#if NET
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicFields)]
+#endif
+ T>(out ObjectReference objRef) => TryAs(GuidGenerator.GetIID(typeof(T)), out objRef);
- public virtual unsafe int TryAs(Guid iid, out ObjectReference objRef)
+ public virtual unsafe int TryAs<
+#if NET
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicFields)]
+#endif
+ T>(Guid iid, out ObjectReference objRef)
{
objRef = null;
ThrowIfDisposed();
@@ -385,7 +403,11 @@ public unsafe ObjectReferenceValue AsValue(Guid iid)
#else
public
#endif
- class ObjectReference : IObjectReference
+ class ObjectReference<
+#if NET
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicConstructors)]
+#endif
+ T> : IObjectReference
{
private readonly T _vftbl;
public T Vftbl
@@ -472,7 +494,11 @@ private protected virtual T GetVftblForCurrentContext()
}
}
- internal sealed class ObjectReferenceWithContext : ObjectReference
+ internal sealed class ObjectReferenceWithContext<
+#if NET
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicConstructors)]
+#endif
+ T> : ObjectReference
{
private readonly IntPtr _contextCallbackPtr;
private readonly IntPtr _contextToken;
@@ -607,7 +633,11 @@ public override ObjectReference AsKnownPtr(IntPtr ptr)
return objRef;
}
- public override unsafe int TryAs(Guid iid, out ObjectReference objRef)
+ public override unsafe int TryAs<
+#if NET
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicConstructors)]
+#endif
+ U>(Guid iid, out ObjectReference objRef)
{
objRef = null;
diff --git a/src/WinRT.Runtime/Projections.cs b/src/WinRT.Runtime/Projections.cs
index 31eae71f3..82e2f7696 100644
--- a/src/WinRT.Runtime/Projections.cs
+++ b/src/WinRT.Runtime/Projections.cs
@@ -7,6 +7,7 @@
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
+using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Numerics;
using System.Reflection;
@@ -24,6 +25,7 @@ namespace WinRT
static class Projections
{
private static readonly ReaderWriterLockSlim rwlock = new ReaderWriterLockSlim();
+
private static readonly Dictionary CustomTypeToHelperTypeMappings = new Dictionary();
private static readonly Dictionary CustomAbiTypeToTypeMappings = new Dictionary();
private static readonly Dictionary CustomAbiTypeNameToTypeMappings = new Dictionary(StringComparer.Ordinal);
@@ -97,12 +99,28 @@ 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(global::Microsoft.UI.Xaml.Interop.IBindableVector), typeof(ABI.System.Collections.IList));
+ 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<>));
+ CustomTypeToHelperTypeMappings.Add(typeof(IReadOnlyCollection<>), typeof(ABI.System.Collections.Generic.IReadOnlyCollection<>));
+#endif
+ RegisterCustomAbiTypeMappingNoLock(typeof(EventHandler), typeof(ABI.System.EventHandler));
CustomTypeToAbiTypeNameMappings.Add(typeof(System.Type), "Windows.UI.Xaml.Interop.TypeName");
}
- public static void RegisterCustomAbiTypeMapping(Type publicType, Type abiType, string winrtTypeName, bool isRuntimeClass = false)
+ public static void RegisterCustomAbiTypeMapping(
+ Type publicType,
+#if NET
+ [DynamicallyAccessedMembers(
+ DynamicallyAccessedMemberTypes.PublicMethods |
+ DynamicallyAccessedMemberTypes.NonPublicMethods |
+ DynamicallyAccessedMemberTypes.PublicNestedTypes)]
+#endif
+ Type abiType,
+ string winrtTypeName,
+ bool isRuntimeClass = false)
{
rwlock.EnterWriteLock();
try
@@ -115,7 +133,17 @@ public static void RegisterCustomAbiTypeMapping(Type publicType, Type abiType, s
}
}
- private static void RegisterCustomAbiTypeMappingNoLock(Type publicType, Type abiType, string winrtTypeName, bool isRuntimeClass = false)
+ private static void RegisterCustomAbiTypeMappingNoLock(
+ Type publicType,
+#if NET
+ [DynamicallyAccessedMembers(
+ DynamicallyAccessedMemberTypes.PublicMethods |
+ DynamicallyAccessedMemberTypes.NonPublicMethods |
+ DynamicallyAccessedMemberTypes.PublicNestedTypes)]
+#endif
+ Type abiType,
+ string winrtTypeName,
+ bool isRuntimeClass = false)
{
CustomTypeToHelperTypeMappings.Add(publicType, abiType);
CustomAbiTypeToTypeMappings.Add(abiType, publicType);
@@ -128,6 +156,26 @@ private static void RegisterCustomAbiTypeMappingNoLock(Type publicType, Type abi
}
}
+ private static void RegisterCustomAbiTypeMappingNoLock(
+ Type publicType,
+#if NET
+ [DynamicallyAccessedMembers(
+ DynamicallyAccessedMemberTypes.PublicMethods |
+ DynamicallyAccessedMemberTypes.NonPublicMethods |
+ DynamicallyAccessedMemberTypes.PublicNestedTypes)]
+#endif
+ Type abiType)
+ {
+ CustomTypeToHelperTypeMappings.Add(publicType, abiType);
+ CustomAbiTypeToTypeMappings.Add(abiType, publicType);
+ }
+
+#if NET
+ [return: DynamicallyAccessedMembers(
+ DynamicallyAccessedMemberTypes.PublicMethods |
+ DynamicallyAccessedMemberTypes.NonPublicMethods |
+ DynamicallyAccessedMemberTypes.PublicNestedTypes)]
+#endif
public static Type FindCustomHelperTypeMapping(Type publicType, bool filterToRuntimeClass = false)
{
rwlock.EnterReadLock();
diff --git a/src/WinRT.Runtime/Projections/Bindable.net5.cs b/src/WinRT.Runtime/Projections/Bindable.net5.cs
index 5b1a58d52..6f4d943ac 100644
--- a/src/WinRT.Runtime/Projections/Bindable.net5.cs
+++ b/src/WinRT.Runtime/Projections/Bindable.net5.cs
@@ -16,12 +16,14 @@ 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();
@@ -51,6 +53,7 @@ internal interface IBindableVector : IEnumerable
}
[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);
diff --git a/src/WinRT.Runtime/Projections/Bindable.netstandard2.0.cs b/src/WinRT.Runtime/Projections/Bindable.netstandard2.0.cs
index 66031b2c0..01b715ffb 100644
--- a/src/WinRT.Runtime/Projections/Bindable.netstandard2.0.cs
+++ b/src/WinRT.Runtime/Projections/Bindable.netstandard2.0.cs
@@ -15,12 +15,14 @@ namespace Microsoft.UI.Xaml.Interop
{
[global::WinRT.WindowsRuntimeType]
[Guid("036D2C08-DF29-41AF-8AA2-D774BE62BA6F")]
+ [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.System.Collections.IEnumerable))]
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();
@@ -50,6 +52,7 @@ internal interface IBindableVector : IEnumerable
}
[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);
diff --git a/src/WinRT.Runtime/Projections/Geometry.cs b/src/WinRT.Runtime/Projections/Geometry.cs
index e7ace5436..a7227556d 100644
--- a/src/WinRT.Runtime/Projections/Geometry.cs
+++ b/src/WinRT.Runtime/Projections/Geometry.cs
@@ -12,7 +12,8 @@ internal static class GSR
public static string ArgumentOutOfRange_NeedNonNegNum = "Non-negative number required.";
}
- [global::WinRT.WindowsRuntimeType("Windows.Foundation.FoundationContract")]
+ [global::WinRT.WindowsRuntimeType("Windows.Foundation.FoundationContract")]
+ [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Windows.Foundation.Point))]
[StructLayout(LayoutKind.Sequential)]
#if EMBED
internal
@@ -104,7 +105,8 @@ public override int GetHashCode()
}
}
- [global::WinRT.WindowsRuntimeType("Windows.Foundation.FoundationContract")]
+ [global::WinRT.WindowsRuntimeType("Windows.Foundation.FoundationContract")]
+ [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Windows.Foundation.Rect))]
[StructLayout(LayoutKind.Sequential)]
#if EMBED
internal
@@ -428,7 +430,8 @@ public override int GetHashCode()
}
}
- [global::WinRT.WindowsRuntimeType("Windows.Foundation.FoundationContract")]
+ [global::WinRT.WindowsRuntimeType("Windows.Foundation.FoundationContract")]
+ [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Windows.Foundation.Size))]
[StructLayout(LayoutKind.Sequential)]
#if EMBED
internal
diff --git a/src/WinRT.Runtime/Projections/ICustomPropertyProvider.net5.cs b/src/WinRT.Runtime/Projections/ICustomPropertyProvider.net5.cs
index 3a1d6e2d4..ca33a3457 100644
--- a/src/WinRT.Runtime/Projections/ICustomPropertyProvider.net5.cs
+++ b/src/WinRT.Runtime/Projections/ICustomPropertyProvider.net5.cs
@@ -8,7 +8,8 @@
namespace Microsoft.UI.Xaml.Data
{
- [global::WinRT.WindowsRuntimeType]
+ [global::WinRT.WindowsRuntimeType]
+ [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Microsoft.UI.Xaml.Data.ICustomProperty))]
[Guid("30DA92C0-23E8-42A0-AE7C-734A0E5D2782")]
interface ICustomProperty
{
diff --git a/src/WinRT.Runtime/Projections/ICustomPropertyProvider.netstandard2.0.cs b/src/WinRT.Runtime/Projections/ICustomPropertyProvider.netstandard2.0.cs
index fcb55584a..889e1ab48 100644
--- a/src/WinRT.Runtime/Projections/ICustomPropertyProvider.netstandard2.0.cs
+++ b/src/WinRT.Runtime/Projections/ICustomPropertyProvider.netstandard2.0.cs
@@ -9,7 +9,8 @@
namespace Microsoft.UI.Xaml.Data
{
[global::WinRT.WindowsRuntimeType]
- [Guid("30DA92C0-23E8-42A0-AE7C-734A0E5D2782")]
+ [Guid("30DA92C0-23E8-42A0-AE7C-734A0E5D2782")]
+ [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Microsoft.UI.Xaml.Data.ICustomProperty))]
interface ICustomProperty
{
object GetValue(object target);
diff --git a/src/WinRT.Runtime/Projections/IReferenceArray.net5.cs b/src/WinRT.Runtime/Projections/IReferenceArray.net5.cs
index a55a2cc08..08d3fd949 100644
--- a/src/WinRT.Runtime/Projections/IReferenceArray.net5.cs
+++ b/src/WinRT.Runtime/Projections/IReferenceArray.net5.cs
@@ -12,6 +12,7 @@ namespace Windows.Foundation
// a "public" type for the type mapping definition.
// IReferenceArray cannot appear in signatures, so it doesn't need to actually be public.
[Guid("61C17707-2D65-11E0-9AE8-D48564015472")]
+ [WindowsRuntimeHelperType(typeof(global::ABI.Windows.Foundation.IReferenceArray<>))]
internal interface IReferenceArray
{
T[] Value { get; }
diff --git a/src/WinRT.Runtime/Projections/IReferenceArray.netstandard2.0.cs b/src/WinRT.Runtime/Projections/IReferenceArray.netstandard2.0.cs
index 370881905..89047f7e6 100644
--- a/src/WinRT.Runtime/Projections/IReferenceArray.netstandard2.0.cs
+++ b/src/WinRT.Runtime/Projections/IReferenceArray.netstandard2.0.cs
@@ -11,7 +11,8 @@ namespace Windows.Foundation
// Provide a stub definition of IReferenceArray so we have
// a "public" type for the type mapping definition.
// IReferenceArray cannot appear in signatures, so it doesn't need to actually be public.
- [Guid("61C17707-2D65-11E0-9AE8-D48564015472")]
+ [Guid("61C17707-2D65-11E0-9AE8-D48564015472")]
+ [WindowsRuntimeHelperType(typeof(global::ABI.Windows.Foundation.IReferenceArray<>))]
internal interface IReferenceArray
{
T[] Value { get; }
diff --git a/src/WinRT.Runtime/Projections/Nullable.cs b/src/WinRT.Runtime/Projections/Nullable.cs
index 4c44373d2..6bddb5b33 100644
--- a/src/WinRT.Runtime/Projections/Nullable.cs
+++ b/src/WinRT.Runtime/Projections/Nullable.cs
@@ -2,6 +2,7 @@
// Licensed under the MIT License.
using System;
+using System.Diagnostics.CodeAnalysis;
using System.Linq.Expressions;
using System.Reflection;
using System.Runtime.InteropServices;
@@ -9,14 +10,17 @@
using WinRT.Interop;
namespace ABI.Windows.Foundation
-{
+{
using System;
internal static class BoxedValueIReferenceImpl
{
private static global::ABI.System.Nullable.Vftbl AbiToProjectionVftable;
- public static IntPtr AbiToProjectionVftablePtr;
-
+ public static IntPtr AbiToProjectionVftablePtr;
+
+#if NET
+ [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode", Justification = "ABI types used with MakeGenericType are not reflected on.")]
+#endif
static unsafe BoxedValueIReferenceImpl()
{
AbiToProjectionVftable = new global::ABI.System.Nullable.Vftbl
diff --git a/src/WinRT.Runtime/Projections/Type.cs b/src/WinRT.Runtime/Projections/Type.cs
index a5b2281b0..80bcd751d 100644
--- a/src/WinRT.Runtime/Projections/Type.cs
+++ b/src/WinRT.Runtime/Projections/Type.cs
@@ -3,6 +3,9 @@
using System;
using System.Collections.Concurrent;
+using System.Diagnostics.CodeAnalysis;
+using System.Globalization;
+using System.Reflection;
using WinRT;
namespace ABI.System
@@ -56,9 +59,15 @@ public ref readonly char GetPinnableReference()
private static (String Name, TypeKind Kind) ToAbi(global::System.Type value)
{
- TypeKind kind = TypeKind.Custom;
-
- if (value is object)
+#if NET
+ if (value is FakeMetadataType fakeMetadataType)
+ {
+ return (fakeMetadataType.FullName, TypeKind.Metadata);
+ }
+#endif
+
+ TypeKind kind = TypeKind.Custom;
+ if (value is not null)
{
if (value.IsPrimitive)
{
@@ -116,8 +125,12 @@ public static Type GetAbi(Marshaler m)
Name = MarshalString.GetAbi(m.Name),
Kind = m.Kind
};
- }
-
+ }
+
+#if NET
+ [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode",
+ Justification = "Any types which are trimmed are not used by managed user code and there is fallback logic to handle that.")]
+#endif
public static global::System.Type FromAbi(Type value)
{
string name = MarshalString.FromAbi(value.Name);
@@ -126,12 +139,24 @@ public static Type GetAbi(Marshaler m)
return null;
}
- if(value.Kind == TypeKind.Custom)
+ if (value.Kind == TypeKind.Custom)
{
return global::System.Type.GetType(name);
}
- return TypeNameSupport.FindTypeByNameCached(name);
+ var type = TypeNameSupport.FindTypeByNameCached(name);
+
+#if NET
+ // The type might have been trimmed, represent it with a fake type if requested
+ // by the the Xaml metadata provider. Given there are no C# references to it, it shouldn't
+ // be used, but if it is, an exception will be thrown.
+ if (type == null && value.Kind == TypeKind.Metadata)
+ {
+ type = FakeMetadataType.GetFakeMetadataType(name);
+ }
+#endif
+
+ return type;
}
public static unsafe void CopyAbi(Marshaler arg, IntPtr dest) =>
@@ -157,5 +182,202 @@ public static string GetGuidSignature()
{
return "struct(Windows.UI.Xaml.Interop.TypeName;string;enum(Windows.UI.Xaml.Interop.TypeKind;i4))";
}
+ }
+
+ // Restricting to NET5 or greater as TypeInfo doesn't expose a constructor on .NET Standard 2.0 and we only need this
+ // for WinUI scenarios.
+#if NET
+ internal sealed class FakeMetadataType : global::System.Reflection.TypeInfo
+ {
+ private static readonly ConcurrentDictionary fakeMetadataTypeCache = new(StringComparer.Ordinal);
+
+ private readonly string fullName;
+
+ private FakeMetadataType(string fullName)
+ {
+ this.fullName = fullName;
+ }
+
+ internal static FakeMetadataType GetFakeMetadataType(string name)
+ {
+ return fakeMetadataTypeCache.GetOrAdd(name, (name) => new FakeMetadataType(name));
+ }
+
+ public override Assembly Assembly => throw new InvalidOperationException();
+
+ public override string AssemblyQualifiedName => throw new InvalidOperationException();
+
+ public override global::System.Type BaseType => throw new InvalidOperationException();
+
+ public override string FullName => fullName;
+
+ public override Guid GUID => throw new InvalidOperationException();
+
+ public override Module Module => throw new InvalidOperationException();
+
+ public override string Namespace => throw new InvalidOperationException();
+
+ public override global::System.Type UnderlyingSystemType => throw new InvalidOperationException();
+
+ public override string Name => throw new InvalidOperationException();
+
+ public override ConstructorInfo[] GetConstructors(BindingFlags bindingAttr)
+ {
+ throw new InvalidOperationException();
+ }
+
+ public override object[] GetCustomAttributes(bool inherit)
+ {
+ throw new InvalidOperationException();
+ }
+
+ public override object[] GetCustomAttributes(global::System.Type attributeType, bool inherit)
+ {
+ throw new InvalidOperationException();
+ }
+
+ public override global::System.Type GetElementType()
+ {
+ throw new InvalidOperationException();
+ }
+
+ public override EventInfo GetEvent(string name, BindingFlags bindingAttr)
+ {
+ throw new InvalidOperationException();
+ }
+
+ public override EventInfo[] GetEvents(BindingFlags bindingAttr)
+ {
+ throw new InvalidOperationException();
+ }
+
+ public override FieldInfo GetField(string name, BindingFlags bindingAttr)
+ {
+ throw new InvalidOperationException();
+ }
+
+ public override FieldInfo[] GetFields(BindingFlags bindingAttr)
+ {
+ throw new InvalidOperationException();
+ }
+
+#if NET6_0_OR_GREATER
+ [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.Interfaces)]
+#endif
+ public override global::System.Type GetInterface(string name, bool ignoreCase)
+ {
+ throw new InvalidOperationException();
+ }
+
+ public override global::System.Type[] GetInterfaces()
+ {
+ throw new InvalidOperationException();
+ }
+
+ public override MemberInfo[] GetMembers(BindingFlags bindingAttr)
+ {
+ throw new InvalidOperationException();
+ }
+
+ public override MethodInfo[] GetMethods(BindingFlags bindingAttr)
+ {
+ throw new InvalidOperationException();
+ }
+
+ public override global::System.Type GetNestedType(string name, BindingFlags bindingAttr)
+ {
+ throw new InvalidOperationException();
+ }
+
+ public override global::System.Type[] GetNestedTypes(BindingFlags bindingAttr)
+ {
+ throw new InvalidOperationException();
+ }
+
+ public override PropertyInfo[] GetProperties(BindingFlags bindingAttr)
+ {
+ throw new InvalidOperationException();
+ }
+
+ public override object InvokeMember(string name, BindingFlags invokeAttr, Binder binder, object target, object[] args, ParameterModifier[] modifiers, CultureInfo culture, string[] namedParameters)
+ {
+ throw new InvalidOperationException();
+ }
+
+ public override bool IsDefined(global::System.Type attributeType, bool inherit)
+ {
+ throw new InvalidOperationException();
+ }
+
+ protected override TypeAttributes GetAttributeFlagsImpl()
+ {
+ throw new InvalidOperationException();
+ }
+
+ protected override ConstructorInfo GetConstructorImpl(BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, global::System.Type[] types, ParameterModifier[] modifiers)
+ {
+ throw new InvalidOperationException();
+ }
+
+ protected override MethodInfo GetMethodImpl(string name, BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, global::System.Type[] types, ParameterModifier[] modifiers)
+ {
+ throw new InvalidOperationException();
+ }
+
+ protected override PropertyInfo GetPropertyImpl(string name, BindingFlags bindingAttr, Binder binder, global::System.Type returnType, global::System.Type[] types, ParameterModifier[] modifiers)
+ {
+ throw new InvalidOperationException();
+ }
+
+ protected override bool HasElementTypeImpl()
+ {
+ throw new InvalidOperationException();
+ }
+
+ protected override bool IsArrayImpl()
+ {
+ throw new InvalidOperationException();
+ }
+
+ protected override bool IsByRefImpl()
+ {
+ throw new InvalidOperationException();
+ }
+
+ protected override bool IsCOMObjectImpl()
+ {
+ throw new InvalidOperationException();
+ }
+
+ protected override bool IsPointerImpl()
+ {
+ throw new InvalidOperationException();
+ }
+
+ protected override bool IsPrimitiveImpl()
+ {
+ throw new InvalidOperationException();
+ }
+
+ public override string ToString()
+ {
+ return fullName;
+ }
+
+ public override bool Equals(object o)
+ {
+ return ReferenceEquals(this, o);
+ }
+
+ public override bool Equals(global::System.Type o)
+ {
+ return ReferenceEquals(this, o);
+ }
+
+ public override int GetHashCode()
+ {
+ return fullName.GetHashCode();
+ }
}
+#endif
}
diff --git a/src/WinRT.Runtime/TypeExtensions.cs b/src/WinRT.Runtime/TypeExtensions.cs
index 14a25154e..02683ad55 100644
--- a/src/WinRT.Runtime/TypeExtensions.cs
+++ b/src/WinRT.Runtime/TypeExtensions.cs
@@ -3,6 +3,7 @@
using System;
using System.Collections.Concurrent;
+using System.Diagnostics.CodeAnalysis;
using System.Reflection;
namespace WinRT
@@ -14,48 +15,109 @@ namespace WinRT
#endif
static class TypeExtensions
{
- private readonly static ConcurrentDictionary HelperTypeCache = new ConcurrentDictionary();
-
+ private readonly static ConcurrentDictionary HelperTypeCache = new ConcurrentDictionary();
+
+#if NET
+ [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods |
+ DynamicallyAccessedMemberTypes.NonPublicMethods |
+ DynamicallyAccessedMemberTypes.PublicNestedTypes |
+ DynamicallyAccessedMemberTypes.PublicFields)]
+#endif
public static Type FindHelperType(this Type type)
{
- return HelperTypeCache.GetOrAdd(type, (type) =>
+ return HelperTypeCache.GetOrAdd(type,
+#if NET
+ [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods |
+ DynamicallyAccessedMemberTypes.NonPublicMethods |
+ DynamicallyAccessedMemberTypes.PublicNestedTypes |
+ DynamicallyAccessedMemberTypes.PublicFields)]
+#endif
+ (type) =>
{
if (typeof(Exception).IsAssignableFrom(type))
{
type = typeof(Exception);
}
Type customMapping = Projections.FindCustomHelperTypeMapping(type);
- if (customMapping is object)
+ if (customMapping is not null)
{
return customMapping;
}
- string fullTypeName = type.FullName;
- string ccwTypePrefix = "ABI.Impl.";
- if (fullTypeName.StartsWith(ccwTypePrefix, StringComparison.Ordinal))
- {
- fullTypeName = fullTypeName.Substring(ccwTypePrefix.Length);
+ var helperTypeAtribute = type.GetCustomAttribute();
+ if (helperTypeAtribute is not null)
+ {
+ return GetHelperTypeFromAttribute(helperTypeAtribute, type);
}
- var helper = $"ABI.{fullTypeName}";
- return type.Assembly.GetType(helper) ?? Type.GetType(helper);
- });
- }
-
+ return FindHelperTypeFallback(type);
+ });
+
+#if NET
+ [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode",
+ Justification = "No members of the generic type are dynamically accessed other than for the attributes on it.")]
+ [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.PublicNestedTypes | DynamicallyAccessedMemberTypes.PublicFields)]
+#endif
+ static Type GetHelperTypeFromAttribute(WindowsRuntimeHelperTypeAttribute helperTypeAtribute, Type type)
+ {
+ if (type.IsGenericType)
+ {
+ return helperTypeAtribute.HelperType.MakeGenericType(type.GetGenericArguments());
+ }
+ else
+ {
+ return helperTypeAtribute.HelperType;
+ }
+ }
+
+#if NET
+ [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode",
+ Justification = "This is a fallback for compat purposes with existing projections. " +
+ "Applications which make use of trimming will make use of updated projections that won't hit this code path.")]
+#endif
+ static Type FindHelperTypeFallback(Type type)
+ {
+ string fullTypeName = type.FullName;
+ string ccwTypePrefix = "ABI.Impl.";
+ if (fullTypeName.StartsWith(ccwTypePrefix, StringComparison.Ordinal))
+ {
+ fullTypeName = fullTypeName.Substring(ccwTypePrefix.Length);
+ }
+
+ var helper = $"ABI.{fullTypeName}";
+ return type.Assembly.GetType(helper) ?? Type.GetType(helper);
+ }
+ }
+
+#if NET
+ [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods |
+ DynamicallyAccessedMemberTypes.NonPublicMethods |
+ DynamicallyAccessedMemberTypes.PublicNestedTypes)]
+#endif
public static Type GetHelperType(this Type type)
{
var helperType = type.FindHelperType();
if (helperType is object)
return helperType;
throw new InvalidOperationException($"Target type is not a projected type: {type.FullName}.");
- }
-
+ }
+
+#if NET
+ [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)]
+#endif
public static Type GetGuidType(this Type type)
{
return type.IsDelegate() ? type.GetHelperType() : type;
- }
-
- public static Type FindVftblType(this Type helperType)
+ }
+
+#if NET
+ [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicFields)]
+#endif
+ public static Type FindVftblType(
+#if NET
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicNestedTypes)]
+#endif
+ this Type helperType)
{
Type vftblType = helperType.GetNestedType("Vftbl");
if (vftblType is null)
@@ -69,7 +131,11 @@ public static Type FindVftblType(this Type helperType)
return vftblType;
}
- internal static IntPtr GetAbiToProjectionVftblPtr(this Type helperType)
+ internal static IntPtr GetAbiToProjectionVftblPtr(
+#if NET
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)]
+#endif
+ this Type helperType)
{
return (IntPtr)(helperType.FindVftblType() ?? helperType).GetField("AbiToProjectionVftablePtr", BindingFlags.Public | BindingFlags.Static).GetValue(null);
}
@@ -118,7 +184,7 @@ internal static Type GetAuthoringMetadataType(this Type type)
return AuthoringMetadataTypeCache.GetOrAdd(type, (type) =>
{
var ccwTypeName = $"ABI.Impl.{type.FullName}";
- return type.Assembly.GetType(ccwTypeName, false) ?? Type.GetType(ccwTypeName, false);
+ return type.Assembly.GetType(ccwTypeName, false);
});
}
}
diff --git a/src/WinRT.Runtime/TypeNameSupport.cs b/src/WinRT.Runtime/TypeNameSupport.cs
index 889d7009a..7814f85bd 100644
--- a/src/WinRT.Runtime/TypeNameSupport.cs
+++ b/src/WinRT.Runtime/TypeNameSupport.cs
@@ -5,6 +5,7 @@
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Reflection;
using System.Text;
@@ -34,33 +35,71 @@ enum TypeNameGenerationFlags
#endif
static class TypeNameSupport
{
- private static readonly List projectionAssemblies = new List();
+ private static readonly List projectionAssemblies = new List();
+ private static readonly List> projectionTypeNameToBaseTypeNameMappings = new List>();
private static readonly ConcurrentDictionary typeNameCache = new ConcurrentDictionary(StringComparer.Ordinal) { ["TrackerCollection"] = null };
+ private static readonly ConcurrentDictionary baseRcwTypeCache = new ConcurrentDictionary(StringComparer.Ordinal) { ["TrackerCollection"] = null };
public static void RegisterProjectionAssembly(Assembly assembly)
{
projectionAssemblies.Add(assembly);
- }
-
+ }
+
+ internal static void RegisterProjectionTypeBaseTypeMapping(IDictionary typeNameToBaseTypeNameMapping)
+ {
+ projectionTypeNameToBaseTypeNameMappings.Add(typeNameToBaseTypeNameMapping);
+ }
+
+#if NET
+ [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicConstructors)]
+#endif
+ public static Type FindRcwTypeByNameCached(string runtimeClassName)
+ {
+ // Try to get the given type name. If it is not found, the type might have been trimmed.
+ // Due to that, check if one of the base types exists and if so use that instead for the RCW type.
+ var rcwType = FindTypeByNameCached(runtimeClassName);
+ if (rcwType is null)
+ {
+ rcwType = baseRcwTypeCache.GetOrAdd(runtimeClassName,
+#if NET
+ [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicConstructors)]
+#endif
+ (runtimeClassName) =>
+ {
+ var resolvedBaseType = projectionTypeNameToBaseTypeNameMappings.Find((dict) => dict.ContainsKey(runtimeClassName))?[runtimeClassName];
+ return resolvedBaseType is not null ? FindRcwTypeByNameCached(resolvedBaseType) : null;
+ });
+ }
+
+ return rcwType;
+ }
+
///
/// Parses and loads the given type name, if not found in the cache.
///
/// The runtime class name to attempt to parse.
/// The type, if found. Null otherwise
+#if NET
+ [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicConstructors)]
+#endif
public static Type FindTypeByNameCached(string runtimeClassName)
{
- return typeNameCache.GetOrAdd(runtimeClassName, (runtimeClassName) =>
- {
- Type implementationType = null;
- try
- {
- implementationType = FindTypeByName(runtimeClassName.AsSpan()).type;
- }
- catch (Exception)
+ return typeNameCache.GetOrAdd(runtimeClassName,
+#if NET
+ [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicConstructors)]
+#endif
+ (runtimeClassName) =>
{
- }
- return implementationType;
- });
+ Type implementationType = null;
+ try
+ {
+ implementationType = FindTypeByName(runtimeClassName.AsSpan()).type;
+ }
+ catch (Exception)
+ {
+ }
+ return implementationType;
+ });
}
///
@@ -90,8 +129,8 @@ public static (Type type, int remaining) FindTypeByName(ReadOnlySpan runti
var (genericTypeName, genericTypes, remaining) = ParseGenericTypeName(runtimeClassName);
return (FindTypeByNameCore(genericTypeName, genericTypes), remaining);
}
- }
-
+ }
+
///
/// Resolve a type from the given simple type name and the provided generic parameters.
///
@@ -102,6 +141,11 @@ public static (Type type, int remaining) FindTypeByName(ReadOnlySpan runti
/// We look up the type dynamically because at this point in the stack we can't know
/// the full type closure of the application.
///
+#if NET
+ [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode",
+ Justification = "Any types which are trimmed are not used by user code and there is fallback logic to handle that.")]
+ [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicConstructors)]
+#endif
private static Type FindTypeByNameCore(string runtimeClassName, Type[] genericTypes)
{
Type resolvedType = Projections.FindCustomTypeForAbiTypeName(runtimeClassName);
@@ -111,7 +155,7 @@ private static Type FindTypeByNameCore(string runtimeClassName, Type[] genericTy
if (genericTypes is null)
{
Type primitiveType = ResolvePrimitiveType(runtimeClassName);
- if (primitiveType is object)
+ if (primitiveType is not null)
{
return primitiveType;
}
@@ -120,7 +164,7 @@ private static Type FindTypeByNameCore(string runtimeClassName, Type[] genericTy
foreach (var assembly in projectionAssemblies)
{
Type type = assembly.GetType(runtimeClassName);
- if (type is object)
+ if (type is not null)
{
resolvedType = type;
break;
@@ -133,15 +177,15 @@ private static Type FindTypeByNameCore(string runtimeClassName, Type[] genericTy
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
{
Type type = assembly.GetType(runtimeClassName);
- if (type is object)
+ if (type is not null)
{
resolvedType = type;
break;
}
}
- }
+ }
- if (resolvedType is object)
+ if (resolvedType is not null)
{
if (genericTypes != null)
{
diff --git a/src/WinRT.Runtime/WinRT.Runtime.csproj b/src/WinRT.Runtime/WinRT.Runtime.csproj
index a473b85dd..317f18f1b 100644
--- a/src/WinRT.Runtime/WinRT.Runtime.csproj
+++ b/src/WinRT.Runtime/WinRT.Runtime.csproj
@@ -21,6 +21,8 @@
Copyright (c) Microsoft Corporation. All rights reserved.
true
key.snk
+ true
+ true
diff --git a/src/build.cmd b/src/build.cmd
index 9c55ec243..90dcea672 100644
--- a/src/build.cmd
+++ b/src/build.cmd
@@ -75,6 +75,8 @@ if "%cswinrt_assembly_version%"=="" set cswinrt_assembly_version=0.0.0.0
if "%cswinrt_baseline_breaking_compat_errors%"=="" set cswinrt_baseline_breaking_compat_errors=false
if "%cswinrt_baseline_assembly_version_compat_errors%"=="" set cswinrt_baseline_assembly_version_compat_errors=false
+set cswinrt_functional_tests=JsonValueFunctionCalls, ClassActivation, Structs, Events, DynamicInterfaceCasting, Collections, Async, DerivedClassActivation, DerivedClassAsBaseClass, CCW
+
rem Generate prerelease targets file to exercise build warnings
set prerelease_targets=%this_dir%..\nuget\Microsoft.Windows.CsWinRT.Prerelease.targets
rem Create default %prerelease_targets%
@@ -137,6 +139,17 @@ if ErrorLevel 1 (
echo ERROR: Build failed
exit /b !ErrorLevel!
)
+
+if "%cswinrt_platform%" NEQ "arm" (
+ if "%cswinrt_platform%" NEQ "arm64" (
+ echo Publishing functional tests for %cswinrt_platform% %cswinrt_configuration%
+ for %%a in (%cswinrt_functional_tests%) do (
+ echo Publishing %%a
+ call :exec %msbuild_path%msbuild.exe /t:restore /t:publish %cswinrt_build_params% /p:platform=%cswinrt_platform%;configuration=%cswinrt_configuration%;VersionNumber=%cswinrt_version_number%;VersionString=%cswinrt_version_string%;AssemblyVersionNumber=%cswinrt_assembly_version%;GenerateTestProjection=true;BaselineAllAPICompatError=%cswinrt_baseline_breaking_compat_errors%;BaselineAllMatchingRefApiCompatError=%cswinrt_baseline_assembly_version_compat_errors% /p:solutiondir=%this_dir% %this_dir%Tests\FunctionalTests\%%a\%%a.csproj
+ )
+ )
+)
+
if "%cswinrt_build_only%"=="true" goto :eof
:buildembedded
@@ -222,6 +235,23 @@ if ErrorLevel 1 (
exit /b !ErrorLevel!
)
+:functionaltest
+rem Run functional tests
+echo Running cswinrt functional tests for %cswinrt_platform% %cswinrt_configuration%
+
+for %%a in (%cswinrt_functional_tests%) do (
+ echo Running %%a
+
+ call :exec %this_dir%Tests\FunctionalTests\%%a\bin\%cswinrt_configuration%\net6.0\win10-%cswinrt_platform%\publish\%%a.exe
+ if !errorlevel! NEQ 100 (
+ echo.
+ echo ERROR: Functional test '%%a' failed with !errorlevel!, skipping NuGet pack
+ exit /b !ErrorLevel!
+ )
+)
+
+if "%cswinrt_label%"=="functionaltest" exit /b 0
+
:package
rem We set the properties of the CsWinRT.nuspec here, and pass them as the -Properties option when we call `nuget pack`
set cswinrt_bin_dir=%this_dir%_build\%cswinrt_platform%\%cswinrt_configuration%\cswinrt\bin\
@@ -247,5 +277,4 @@ echo.
) else (
%*
)
-goto :eof
-
+goto :eof
\ No newline at end of file
diff --git a/src/cswinrt.sln b/src/cswinrt.sln
index cb5140050..4786d8219 100644
--- a/src/cswinrt.sln
+++ b/src/cswinrt.sln
@@ -125,6 +125,35 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_component_fast", "Test
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OOPExe", "Tests\OOPExe\OOPExe.csproj", "{8DB50E24-9599-4890-939D-C87C1EC5DDAD}"
EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JsonValueFunctionCalls", "Tests\FunctionalTests\JsonValueFunctionCalls\JsonValueFunctionCalls.csproj", "{EE5B4B23-5D4B-4DFB-8DC9-4DBB1B735CC8}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "FunctionalTests", "FunctionalTests", "{5ECC38F0-16FD-47E1-B8DC-8C474008AD55}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "PublishProfiles", "PublishProfiles", "{6FBE79A9-9D6D-4436-9F84-797ED1C9F676}"
+ ProjectSection(SolutionItems) = preProject
+ Tests\FunctionalTests\PublishProfiles\win10-arm64.pubxml = Tests\FunctionalTests\PublishProfiles\win10-arm64.pubxml
+ Tests\FunctionalTests\PublishProfiles\win10-x64.pubxml = Tests\FunctionalTests\PublishProfiles\win10-x64.pubxml
+ Tests\FunctionalTests\PublishProfiles\win10-x86.pubxml = Tests\FunctionalTests\PublishProfiles\win10-x86.pubxml
+ EndProjectSection
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ClassActivation", "Tests\FunctionalTests\ClassActivation\ClassActivation.csproj", "{F0D6034B-5368-4B13-BBB9-4ABBC535AA0E}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DerivedClassActivation", "Tests\FunctionalTests\DerivedClassActivation\DerivedClassActivation.csproj", "{1AB3E799-A573-4704-9AC3-FF7D6BBA8D6D}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Events", "Tests\FunctionalTests\Events\Events.csproj", "{2059A2D5-6E35-4CCF-A385-8A442FC6AD95}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Structs", "Tests\FunctionalTests\Structs\Structs.csproj", "{5EC7393C-CEBA-42F2-9105-D39315C602EC}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Collections", "Tests\FunctionalTests\Collections\Collections.csproj", "{EA892842-E3C6-45B3-9D3F-3C1FE41D5239}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Async", "Tests\FunctionalTests\Async\Async.csproj", "{94E1D7EA-F932-4C7F-8EE8-5DEFD8474D05}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DynamicInterfaceCasting", "Tests\FunctionalTests\DynamicInterfaceCasting\DynamicInterfaceCasting.csproj", "{756947F1-26D7-49ED-A4E8-8C4F126182C8}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DerivedClassAsBaseClass", "Tests\FunctionalTests\DerivedClassAsBaseClass\DerivedClassAsBaseClass.csproj", "{E3AEC9A4-D1A3-448D-B980-F82894792AF1}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CCW", "Tests\FunctionalTests\CCW\CCW.csproj", "{C44DB047-5DF0-4732-98F4-A181D3AD8A7F}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|ARM = Debug|ARM
@@ -516,18 +545,138 @@ Global
{0E0ACA62-A92F-44CF-BD41-AEB541946DF8}.Release|x64.Build.0 = Release|x64
{0E0ACA62-A92F-44CF-BD41-AEB541946DF8}.Release|x86.ActiveCfg = Release|Win32
{0E0ACA62-A92F-44CF-BD41-AEB541946DF8}.Release|x86.Build.0 = Release|Win32
- {8DB50E24-9599-4890-939D-C87C1EC5DDAD}.Debug|ARM.ActiveCfg = Debug|x86
- {8DB50E24-9599-4890-939D-C87C1EC5DDAD}.Debug|ARM64.ActiveCfg = Debug|x86
+ {8DB50E24-9599-4890-939D-C87C1EC5DDAD}.Debug|ARM.ActiveCfg = Debug|ARM
+ {8DB50E24-9599-4890-939D-C87C1EC5DDAD}.Debug|ARM64.ActiveCfg = Debug|ARM64
{8DB50E24-9599-4890-939D-C87C1EC5DDAD}.Debug|x64.ActiveCfg = Debug|x64
{8DB50E24-9599-4890-939D-C87C1EC5DDAD}.Debug|x64.Build.0 = Debug|x64
{8DB50E24-9599-4890-939D-C87C1EC5DDAD}.Debug|x86.ActiveCfg = Debug|x86
{8DB50E24-9599-4890-939D-C87C1EC5DDAD}.Debug|x86.Build.0 = Debug|x86
- {8DB50E24-9599-4890-939D-C87C1EC5DDAD}.Release|ARM.ActiveCfg = Release|x86
- {8DB50E24-9599-4890-939D-C87C1EC5DDAD}.Release|ARM64.ActiveCfg = Release|x86
+ {8DB50E24-9599-4890-939D-C87C1EC5DDAD}.Release|ARM.ActiveCfg = Release|ARM
+ {8DB50E24-9599-4890-939D-C87C1EC5DDAD}.Release|ARM64.ActiveCfg = Release|ARM64
{8DB50E24-9599-4890-939D-C87C1EC5DDAD}.Release|x64.ActiveCfg = Release|x64
{8DB50E24-9599-4890-939D-C87C1EC5DDAD}.Release|x64.Build.0 = Release|x64
{8DB50E24-9599-4890-939D-C87C1EC5DDAD}.Release|x86.ActiveCfg = Release|x86
{8DB50E24-9599-4890-939D-C87C1EC5DDAD}.Release|x86.Build.0 = Release|x86
+ {EE5B4B23-5D4B-4DFB-8DC9-4DBB1B735CC8}.Debug|ARM.ActiveCfg = Debug|ARM
+ {EE5B4B23-5D4B-4DFB-8DC9-4DBB1B735CC8}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {EE5B4B23-5D4B-4DFB-8DC9-4DBB1B735CC8}.Debug|x64.ActiveCfg = Debug|x64
+ {EE5B4B23-5D4B-4DFB-8DC9-4DBB1B735CC8}.Debug|x64.Build.0 = Debug|x64
+ {EE5B4B23-5D4B-4DFB-8DC9-4DBB1B735CC8}.Debug|x86.ActiveCfg = Debug|x86
+ {EE5B4B23-5D4B-4DFB-8DC9-4DBB1B735CC8}.Debug|x86.Build.0 = Debug|x86
+ {EE5B4B23-5D4B-4DFB-8DC9-4DBB1B735CC8}.Release|ARM.ActiveCfg = Release|ARM
+ {EE5B4B23-5D4B-4DFB-8DC9-4DBB1B735CC8}.Release|ARM64.ActiveCfg = Release|ARM64
+ {EE5B4B23-5D4B-4DFB-8DC9-4DBB1B735CC8}.Release|x64.ActiveCfg = Release|x64
+ {EE5B4B23-5D4B-4DFB-8DC9-4DBB1B735CC8}.Release|x64.Build.0 = Release|x64
+ {EE5B4B23-5D4B-4DFB-8DC9-4DBB1B735CC8}.Release|x86.ActiveCfg = Release|x86
+ {EE5B4B23-5D4B-4DFB-8DC9-4DBB1B735CC8}.Release|x86.Build.0 = Release|x86
+ {F0D6034B-5368-4B13-BBB9-4ABBC535AA0E}.Debug|ARM.ActiveCfg = Debug|ARM
+ {F0D6034B-5368-4B13-BBB9-4ABBC535AA0E}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {F0D6034B-5368-4B13-BBB9-4ABBC535AA0E}.Debug|x64.ActiveCfg = Debug|x64
+ {F0D6034B-5368-4B13-BBB9-4ABBC535AA0E}.Debug|x64.Build.0 = Debug|x64
+ {F0D6034B-5368-4B13-BBB9-4ABBC535AA0E}.Debug|x86.ActiveCfg = Debug|x86
+ {F0D6034B-5368-4B13-BBB9-4ABBC535AA0E}.Debug|x86.Build.0 = Debug|x86
+ {F0D6034B-5368-4B13-BBB9-4ABBC535AA0E}.Release|ARM.ActiveCfg = Release|ARM
+ {F0D6034B-5368-4B13-BBB9-4ABBC535AA0E}.Release|ARM64.ActiveCfg = Release|ARM64
+ {F0D6034B-5368-4B13-BBB9-4ABBC535AA0E}.Release|x64.ActiveCfg = Release|x64
+ {F0D6034B-5368-4B13-BBB9-4ABBC535AA0E}.Release|x64.Build.0 = Release|x64
+ {F0D6034B-5368-4B13-BBB9-4ABBC535AA0E}.Release|x86.ActiveCfg = Release|x86
+ {F0D6034B-5368-4B13-BBB9-4ABBC535AA0E}.Release|x86.Build.0 = Release|x86
+ {1AB3E799-A573-4704-9AC3-FF7D6BBA8D6D}.Debug|ARM.ActiveCfg = Debug|ARM
+ {1AB3E799-A573-4704-9AC3-FF7D6BBA8D6D}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {1AB3E799-A573-4704-9AC3-FF7D6BBA8D6D}.Debug|x64.ActiveCfg = Debug|x64
+ {1AB3E799-A573-4704-9AC3-FF7D6BBA8D6D}.Debug|x64.Build.0 = Debug|x64
+ {1AB3E799-A573-4704-9AC3-FF7D6BBA8D6D}.Debug|x86.ActiveCfg = Debug|x86
+ {1AB3E799-A573-4704-9AC3-FF7D6BBA8D6D}.Debug|x86.Build.0 = Debug|x86
+ {1AB3E799-A573-4704-9AC3-FF7D6BBA8D6D}.Release|ARM.ActiveCfg = Release|ARM
+ {1AB3E799-A573-4704-9AC3-FF7D6BBA8D6D}.Release|ARM64.ActiveCfg = Release|ARM64
+ {1AB3E799-A573-4704-9AC3-FF7D6BBA8D6D}.Release|x64.ActiveCfg = Release|x64
+ {1AB3E799-A573-4704-9AC3-FF7D6BBA8D6D}.Release|x64.Build.0 = Release|x64
+ {1AB3E799-A573-4704-9AC3-FF7D6BBA8D6D}.Release|x86.ActiveCfg = Release|x86
+ {1AB3E799-A573-4704-9AC3-FF7D6BBA8D6D}.Release|x86.Build.0 = Release|x86
+ {2059A2D5-6E35-4CCF-A385-8A442FC6AD95}.Debug|ARM.ActiveCfg = Debug|ARM
+ {2059A2D5-6E35-4CCF-A385-8A442FC6AD95}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {2059A2D5-6E35-4CCF-A385-8A442FC6AD95}.Debug|x64.ActiveCfg = Debug|x64
+ {2059A2D5-6E35-4CCF-A385-8A442FC6AD95}.Debug|x64.Build.0 = Debug|x64
+ {2059A2D5-6E35-4CCF-A385-8A442FC6AD95}.Debug|x86.ActiveCfg = Debug|x86
+ {2059A2D5-6E35-4CCF-A385-8A442FC6AD95}.Debug|x86.Build.0 = Debug|x86
+ {2059A2D5-6E35-4CCF-A385-8A442FC6AD95}.Release|ARM.ActiveCfg = Release|ARM
+ {2059A2D5-6E35-4CCF-A385-8A442FC6AD95}.Release|ARM64.ActiveCfg = Release|ARM64
+ {2059A2D5-6E35-4CCF-A385-8A442FC6AD95}.Release|x64.ActiveCfg = Release|x64
+ {2059A2D5-6E35-4CCF-A385-8A442FC6AD95}.Release|x64.Build.0 = Release|x64
+ {2059A2D5-6E35-4CCF-A385-8A442FC6AD95}.Release|x86.ActiveCfg = Release|x86
+ {2059A2D5-6E35-4CCF-A385-8A442FC6AD95}.Release|x86.Build.0 = Release|x86
+ {5EC7393C-CEBA-42F2-9105-D39315C602EC}.Debug|ARM.ActiveCfg = Debug|ARM
+ {5EC7393C-CEBA-42F2-9105-D39315C602EC}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {5EC7393C-CEBA-42F2-9105-D39315C602EC}.Debug|x64.ActiveCfg = Debug|x64
+ {5EC7393C-CEBA-42F2-9105-D39315C602EC}.Debug|x64.Build.0 = Debug|x64
+ {5EC7393C-CEBA-42F2-9105-D39315C602EC}.Debug|x86.ActiveCfg = Debug|x86
+ {5EC7393C-CEBA-42F2-9105-D39315C602EC}.Debug|x86.Build.0 = Debug|x86
+ {5EC7393C-CEBA-42F2-9105-D39315C602EC}.Release|ARM.ActiveCfg = Release|ARM
+ {5EC7393C-CEBA-42F2-9105-D39315C602EC}.Release|ARM64.ActiveCfg = Release|ARM64
+ {5EC7393C-CEBA-42F2-9105-D39315C602EC}.Release|x64.ActiveCfg = Release|x64
+ {5EC7393C-CEBA-42F2-9105-D39315C602EC}.Release|x64.Build.0 = Release|x64
+ {5EC7393C-CEBA-42F2-9105-D39315C602EC}.Release|x86.ActiveCfg = Release|x86
+ {5EC7393C-CEBA-42F2-9105-D39315C602EC}.Release|x86.Build.0 = Release|x86
+ {EA892842-E3C6-45B3-9D3F-3C1FE41D5239}.Debug|ARM.ActiveCfg = Debug|ARM
+ {EA892842-E3C6-45B3-9D3F-3C1FE41D5239}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {EA892842-E3C6-45B3-9D3F-3C1FE41D5239}.Debug|x64.ActiveCfg = Debug|x64
+ {EA892842-E3C6-45B3-9D3F-3C1FE41D5239}.Debug|x64.Build.0 = Debug|x64
+ {EA892842-E3C6-45B3-9D3F-3C1FE41D5239}.Debug|x86.ActiveCfg = Debug|x86
+ {EA892842-E3C6-45B3-9D3F-3C1FE41D5239}.Debug|x86.Build.0 = Debug|x86
+ {EA892842-E3C6-45B3-9D3F-3C1FE41D5239}.Release|ARM.ActiveCfg = Release|ARM
+ {EA892842-E3C6-45B3-9D3F-3C1FE41D5239}.Release|ARM64.ActiveCfg = Release|ARM64
+ {EA892842-E3C6-45B3-9D3F-3C1FE41D5239}.Release|x64.ActiveCfg = Release|x64
+ {EA892842-E3C6-45B3-9D3F-3C1FE41D5239}.Release|x64.Build.0 = Release|x64
+ {EA892842-E3C6-45B3-9D3F-3C1FE41D5239}.Release|x86.ActiveCfg = Release|x86
+ {EA892842-E3C6-45B3-9D3F-3C1FE41D5239}.Release|x86.Build.0 = Release|x86
+ {94E1D7EA-F932-4C7F-8EE8-5DEFD8474D05}.Debug|ARM.ActiveCfg = Debug|ARM
+ {94E1D7EA-F932-4C7F-8EE8-5DEFD8474D05}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {94E1D7EA-F932-4C7F-8EE8-5DEFD8474D05}.Debug|x64.ActiveCfg = Debug|x64
+ {94E1D7EA-F932-4C7F-8EE8-5DEFD8474D05}.Debug|x64.Build.0 = Debug|x64
+ {94E1D7EA-F932-4C7F-8EE8-5DEFD8474D05}.Debug|x86.ActiveCfg = Debug|x86
+ {94E1D7EA-F932-4C7F-8EE8-5DEFD8474D05}.Debug|x86.Build.0 = Debug|x86
+ {94E1D7EA-F932-4C7F-8EE8-5DEFD8474D05}.Release|ARM.ActiveCfg = Release|ARM
+ {94E1D7EA-F932-4C7F-8EE8-5DEFD8474D05}.Release|ARM64.ActiveCfg = Release|ARM64
+ {94E1D7EA-F932-4C7F-8EE8-5DEFD8474D05}.Release|x64.ActiveCfg = Release|x64
+ {94E1D7EA-F932-4C7F-8EE8-5DEFD8474D05}.Release|x64.Build.0 = Release|x64
+ {94E1D7EA-F932-4C7F-8EE8-5DEFD8474D05}.Release|x86.ActiveCfg = Release|x86
+ {94E1D7EA-F932-4C7F-8EE8-5DEFD8474D05}.Release|x86.Build.0 = Release|x86
+ {756947F1-26D7-49ED-A4E8-8C4F126182C8}.Debug|ARM.ActiveCfg = Debug|ARM
+ {756947F1-26D7-49ED-A4E8-8C4F126182C8}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {756947F1-26D7-49ED-A4E8-8C4F126182C8}.Debug|x64.ActiveCfg = Debug|x64
+ {756947F1-26D7-49ED-A4E8-8C4F126182C8}.Debug|x64.Build.0 = Debug|x64
+ {756947F1-26D7-49ED-A4E8-8C4F126182C8}.Debug|x86.ActiveCfg = Debug|x86
+ {756947F1-26D7-49ED-A4E8-8C4F126182C8}.Debug|x86.Build.0 = Debug|x86
+ {756947F1-26D7-49ED-A4E8-8C4F126182C8}.Release|ARM.ActiveCfg = Release|ARM
+ {756947F1-26D7-49ED-A4E8-8C4F126182C8}.Release|ARM64.ActiveCfg = Release|ARM64
+ {756947F1-26D7-49ED-A4E8-8C4F126182C8}.Release|x64.ActiveCfg = Release|x64
+ {756947F1-26D7-49ED-A4E8-8C4F126182C8}.Release|x64.Build.0 = Release|x64
+ {756947F1-26D7-49ED-A4E8-8C4F126182C8}.Release|x86.ActiveCfg = Release|x86
+ {756947F1-26D7-49ED-A4E8-8C4F126182C8}.Release|x86.Build.0 = Release|x86
+ {E3AEC9A4-D1A3-448D-B980-F82894792AF1}.Debug|ARM.ActiveCfg = Debug|ARM
+ {E3AEC9A4-D1A3-448D-B980-F82894792AF1}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {E3AEC9A4-D1A3-448D-B980-F82894792AF1}.Debug|x64.ActiveCfg = Debug|x64
+ {E3AEC9A4-D1A3-448D-B980-F82894792AF1}.Debug|x64.Build.0 = Debug|x64
+ {E3AEC9A4-D1A3-448D-B980-F82894792AF1}.Debug|x86.ActiveCfg = Debug|x86
+ {E3AEC9A4-D1A3-448D-B980-F82894792AF1}.Debug|x86.Build.0 = Debug|x86
+ {E3AEC9A4-D1A3-448D-B980-F82894792AF1}.Release|ARM.ActiveCfg = Release|ARM
+ {E3AEC9A4-D1A3-448D-B980-F82894792AF1}.Release|ARM64.ActiveCfg = Release|ARM64
+ {E3AEC9A4-D1A3-448D-B980-F82894792AF1}.Release|x64.ActiveCfg = Release|x64
+ {E3AEC9A4-D1A3-448D-B980-F82894792AF1}.Release|x64.Build.0 = Release|x64
+ {E3AEC9A4-D1A3-448D-B980-F82894792AF1}.Release|x86.ActiveCfg = Release|x86
+ {E3AEC9A4-D1A3-448D-B980-F82894792AF1}.Release|x86.Build.0 = Release|x86
+ {C44DB047-5DF0-4732-98F4-A181D3AD8A7F}.Debug|ARM.ActiveCfg = Debug|ARM
+ {C44DB047-5DF0-4732-98F4-A181D3AD8A7F}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {C44DB047-5DF0-4732-98F4-A181D3AD8A7F}.Debug|x64.ActiveCfg = Debug|x64
+ {C44DB047-5DF0-4732-98F4-A181D3AD8A7F}.Debug|x64.Build.0 = Debug|x64
+ {C44DB047-5DF0-4732-98F4-A181D3AD8A7F}.Debug|x86.ActiveCfg = Debug|x86
+ {C44DB047-5DF0-4732-98F4-A181D3AD8A7F}.Debug|x86.Build.0 = Debug|x86
+ {C44DB047-5DF0-4732-98F4-A181D3AD8A7F}.Release|ARM.ActiveCfg = Release|ARM
+ {C44DB047-5DF0-4732-98F4-A181D3AD8A7F}.Release|ARM64.ActiveCfg = Release|ARM64
+ {C44DB047-5DF0-4732-98F4-A181D3AD8A7F}.Release|x64.ActiveCfg = Release|x64
+ {C44DB047-5DF0-4732-98F4-A181D3AD8A7F}.Release|x64.Build.0 = Release|x64
+ {C44DB047-5DF0-4732-98F4-A181D3AD8A7F}.Release|x86.ActiveCfg = Release|x86
+ {C44DB047-5DF0-4732-98F4-A181D3AD8A7F}.Release|x86.Build.0 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -558,6 +707,18 @@ Global
{80F0EC48-5536-49D6-8ED1-B1F4CED88073} = {6D41796B-9904-40B8-BBCB-40B2D1BAE44B}
{0E0ACA62-A92F-44CF-BD41-AEB541946DF8} = {CFB651EC-DAA4-4A11-ABCD-C77F90602EB5}
{8DB50E24-9599-4890-939D-C87C1EC5DDAD} = {CFB651EC-DAA4-4A11-ABCD-C77F90602EB5}
+ {EE5B4B23-5D4B-4DFB-8DC9-4DBB1B735CC8} = {5ECC38F0-16FD-47E1-B8DC-8C474008AD55}
+ {5ECC38F0-16FD-47E1-B8DC-8C474008AD55} = {CFB651EC-DAA4-4A11-ABCD-C77F90602EB5}
+ {6FBE79A9-9D6D-4436-9F84-797ED1C9F676} = {5ECC38F0-16FD-47E1-B8DC-8C474008AD55}
+ {F0D6034B-5368-4B13-BBB9-4ABBC535AA0E} = {5ECC38F0-16FD-47E1-B8DC-8C474008AD55}
+ {1AB3E799-A573-4704-9AC3-FF7D6BBA8D6D} = {5ECC38F0-16FD-47E1-B8DC-8C474008AD55}
+ {2059A2D5-6E35-4CCF-A385-8A442FC6AD95} = {5ECC38F0-16FD-47E1-B8DC-8C474008AD55}
+ {5EC7393C-CEBA-42F2-9105-D39315C602EC} = {5ECC38F0-16FD-47E1-B8DC-8C474008AD55}
+ {EA892842-E3C6-45B3-9D3F-3C1FE41D5239} = {5ECC38F0-16FD-47E1-B8DC-8C474008AD55}
+ {94E1D7EA-F932-4C7F-8EE8-5DEFD8474D05} = {5ECC38F0-16FD-47E1-B8DC-8C474008AD55}
+ {756947F1-26D7-49ED-A4E8-8C4F126182C8} = {5ECC38F0-16FD-47E1-B8DC-8C474008AD55}
+ {E3AEC9A4-D1A3-448D-B980-F82894792AF1} = {5ECC38F0-16FD-47E1-B8DC-8C474008AD55}
+ {C44DB047-5DF0-4732-98F4-A181D3AD8A7F} = {5ECC38F0-16FD-47E1-B8DC-8C474008AD55}
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 d7281bf9e..5d8b5b025 100644
--- a/src/cswinrt/code_writers.h
+++ b/src/cswinrt/code_writers.h
@@ -3110,6 +3110,29 @@ private % AsInternal(InterfaceTag<%> _) => % ?? Make_%();
db_path.stem().string());
}
+ void write_winrt_helper_type_attribute(writer& w, TypeDef const& type)
+ {
+ if (get_category(type) == category::struct_type && is_type_blittable(type))
+ {
+ w.write(R"([global::WinRT.WindowsRuntimeHelperType])");
+ return;
+ }
+
+ w.write(R"([global::WinRT.WindowsRuntimeHelperType(typeof(%%))])",
+ bind(type, typedef_name_type::ABI, false),
+ bind([&](writer& w)
+ {
+ if (distance(type.GenericParam()) == 0)
+ {
+ return;
+ }
+
+ // Writes out the generic definition without the types.
+ separator s{ w };
+ w.write("<%>", bind_each([&](writer& /*w*/, GenericParam const& /*gp*/){ s(); }, type.GenericParam()));
+ }));
+ }
+
auto get_invoke_info(writer& w, MethodDef const& method, uint32_t const& abi_methods_start_index = INSPECTABLE_METHOD_COUNT)
{
TypeDef const& type = method.Parent();
@@ -5773,8 +5796,16 @@ IInspectableVftbl = global::WinRT.IInspectable.Vftbl.AbiToProjectionVftable,
void write_authoring_metadata_type(writer& w, TypeDef const& type)
{
- w.write("%%internal class % {}\n",
+ w.write("%%%internal class % {}\n",
bind(type),
+ [&](writer& w)
+ {
+ auto category = get_category(type);
+ if (category == category::delegate_type || category == category::struct_type)
+ {
+ write_winrt_helper_type_attribute(w, type);
+ }
+ },
bind(type, false),
bind(type, typedef_name_type::CCW, false));
}
@@ -5827,7 +5858,7 @@ IInspectableVftbl = global::WinRT.IInspectable.Vftbl.AbiToProjectionVftable,
XLANG_ASSERT(get_category(type) == category::interface_type);
auto type_name = write_type_name_temp(w, type, "%", typedef_name_type::CCW);
- w.write(R"(%%
+ w.write(R"(%%%
%% interface %%
{%
}
@@ -5835,6 +5866,7 @@ IInspectableVftbl = global::WinRT.IInspectable.Vftbl.AbiToProjectionVftable,
// Interface
bind(type),
bind(type),
+ bind(type),
bind(type, false),
is_exclusive_to(type) || (is_projection_internal(type) || (settings.internal || settings.embedded)) ? "internal" : "public",
type_name,
@@ -6199,7 +6231,7 @@ return global::System.Runtime.InteropServices.CustomQueryInterfaceResult.NotHand
auto base_semantics = get_type_semantics(type.Extends());
auto from_abi_new = !std::holds_alternative(base_semantics) ? "new " : "";
- w.write(R"(%[global::WinRT.ProjectedRuntimeClass(typeof(%))]
+ w.write(R"(%%[global::WinRT.ProjectedRuntimeClass(typeof(%))]
%internal %class %%
{
public %(% comp)
@@ -6224,6 +6256,7 @@ private readonly % _comp;
}
)",
bind(type),
+ bind(type),
default_interface_name,
bind(type, false),
bind(type),
@@ -6272,7 +6305,7 @@ private readonly % _comp;
gc_pressure_amount = amount == 0 ? 12000 : amount == 1 ? 120000 : 1200000;
}
- w.write(R"(%[global::WinRT.ProjectedRuntimeClass(nameof(_default))]
+ w.write(R"(%%[global::WinRT.ProjectedRuntimeClass(nameof(_default))]
%% %class %%, IEquatable<%>
{
public %IntPtr ThisPtr => _default.ThisPtr;
@@ -6307,6 +6340,7 @@ private % AsInternal(InterfaceTag<%> _) => _default;
}
)",
bind(type),
+ bind(type),
bind(type, false),
internal_accessibility(),
bind(type),
@@ -6438,8 +6472,8 @@ _defaultLazy = new Lazy<%>(() => GetDefaultReference<%.Vftbl>());
auto default_interface_typedef = for_typedef(w, get_type_semantics(get_default_interface(type)), [&](auto&& iface) { return iface; });
auto is_manually_gen_default_interface = is_manually_generated_iface(default_interface_typedef);
- w.write(R"(%
-[global::WinRT.ProjectedRuntimeClass(nameof(_default))]
+ w.write(R"(%%
+[global::WinRT.ProjectedRuntimeClass(typeof(%))]
[global::WinRT.ObjectReferenceWrapper(nameof(_inner))]
%% %class %%, IWinRTObject, IEquatable<%>
{
@@ -6475,6 +6509,8 @@ private struct InterfaceTag{};
}
)",
bind(type),
+ bind(type),
+ default_interface_name,
bind(type, true),
internal_accessibility(),
bind(type),
@@ -6719,9 +6755,10 @@ public static ObjectReferenceValue CreateMarshaler2(% obj) => MarshalInterface<%
}
method_signature signature{ get_delegate_invoke(type) };
- w.write(R"(%%% delegate % %(%);
+ w.write(R"(%%%% delegate % %(%);
)",
bind(type),
+ bind(type),
bind(type, false),
internal_accessibility(),
bind(signature),
@@ -7114,7 +7151,7 @@ global::WinRT.ComWrappersSupport.FindObject<%>(%).Invoke(%)
fields.emplace_back(field_info);
}
- w.write(R"(%%% struct %: IEquatable<%>
+ w.write(R"(%%%% struct %: IEquatable<%>
{
%
public %(%)
@@ -7131,6 +7168,7 @@ public override int GetHashCode() => %;
)",
// struct
bind(type),
+ bind(type),
bind(type, true),
internal_accessibility(),
name,
@@ -7692,4 +7730,31 @@ bind(invokeMethodSig));
typeNameToDefinitionMap[eventTypeCode] = eventClass;
}
}
+
+ void add_base_type_entry(TypeDef const& classType, concurrency::concurrent_unordered_map& typeNameToBaseTypeMap)
+ {
+ writer w("");
+ auto base_type = get_type_semantics(classType.Extends());
+ bool has_base_type = !std::holds_alternative(base_type);
+ if (has_base_type)
+ {
+ int numChars = (int)strlen("global::");
+ auto&& typeName = w.write_temp("%", bind(classType, typedef_name_type::Projected, true)).substr(numChars);
+ auto&& baseTypeName = w.write_temp("%", bind(base_type, typedef_name_type::Projected, true)).substr(numChars);
+ typeNameToBaseTypeMap[typeName] = baseTypeName;
+ }
+ }
+
+ void write_file_header(writer& w)
+ {
+ w.write(R"(//------------------------------------------------------------------------------
+//
+// This file was generated by cswinrt.exe version %
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+)", VERSION_STRING);
+ }
}
diff --git a/src/cswinrt/main.cpp b/src/cswinrt/main.cpp
index 345663a12..f4449b065 100644
--- a/src/cswinrt/main.cpp
+++ b/src/cswinrt/main.cpp
@@ -174,11 +174,11 @@ Where is one or more of:
task_group group;
- concurrency::concurrent_unordered_map typeNameToDefinitionMap;
+ concurrency::concurrent_unordered_map typeNameToEventDefinitionMap, typeNameToBaseTypeMap;
bool projectionFileWritten = false;
for (auto&& ns_members : c.namespaces())
{
- group.add([&ns_members, &componentActivatableClasses, &projectionFileWritten, &typeNameToDefinitionMap]
+ group.add([&ns_members, &componentActivatableClasses, &projectionFileWritten, &typeNameToEventDefinitionMap, &typeNameToBaseTypeMap]
{
auto&& [ns, members] = ns_members;
std::string_view currentType = "";
@@ -219,13 +219,15 @@ Where is one or more of:
else
{
write_class(w, type);
+ add_base_type_entry(type, typeNameToBaseTypeMap);
}
if (settings.component && componentActivatableClasses.count(type) == 1)
{
write_factory_class(w, type);
}
}
- write_temp_class_event_source_subclass(helperWriter, type, typeNameToDefinitionMap);
+
+ write_temp_class_event_source_subclass(helperWriter, type, typeNameToEventDefinitionMap);
break;
case category::delegate_type:
write_delegate(w, type);
@@ -236,7 +238,7 @@ Where is one or more of:
break;
case category::interface_type:
write_interface(w, type);
- write_temp_interface_event_source_subclass(helperWriter, type, typeNameToDefinitionMap);
+ write_temp_interface_event_source_subclass(helperWriter, type, typeNameToEventDefinitionMap);
break;
case category::struct_type:
if (is_api_contract_type(type))
@@ -330,15 +332,7 @@ Where is one or more of:
group.add([&componentActivatableClasses, &projectionFileWritten]
{
writer wm;
- wm.write(R"(//------------------------------------------------------------------------------
-//
-// This file was generated by cswinrt.exe version %
-//
-// Changes to this file may cause incorrect behavior and will be lost if
-// the code is regenerated.
-//
-//------------------------------------------------------------------------------
-)", VERSION_STRING);
+ write_file_header(wm);
write_module_activation_factory(wm, componentActivatableClasses);
wm.flush_to_file(settings.output_folder / (std::string("WinRT_Module") + ".cs"));
projectionFileWritten = true;
@@ -346,24 +340,48 @@ Where is one or more of:
}
group.get();
+
writer eventHelperWriter("WinRT");
- eventHelperWriter.write(R"(//------------------------------------------------------------------------------
-//
-// This file was generated by cswinrt.exe version %
-//
-// Changes to this file may cause incorrect behavior and will be lost if
-// the code is regenerated.
-//
-//------------------------------------------------------------------------------
-)", VERSION_STRING);
+ write_file_header(eventHelperWriter);
eventHelperWriter.write("namespace WinRT\n{\n%\n}", bind([&](writer& w) {
- for (auto&& [key, value] : typeNameToDefinitionMap)
+ for (auto&& [key, value] : typeNameToEventDefinitionMap)
{
w.write("%", value);
}
}));
eventHelperWriter.flush_to_file(settings.output_folder / "WinRTEventHelpers.cs");
+ if (!typeNameToBaseTypeMap.empty())
+ {
+ writer baseTypeWriter("WinRT");
+ write_file_header(baseTypeWriter);
+ baseTypeWriter.write(R"(namespace WinRT
+{
+internal static class ProjectionTypesInitializer
+{
+internal readonly static System.Collections.Generic.Dictionary TypeNameToBaseTypeNameMapping = new System.Collections.Generic.Dictionary(%, System.StringComparer.Ordinal)
+{
+%
+};
+
+[System.Runtime.CompilerServices.ModuleInitializer]
+internal static void InitalizeProjectionTypes()
+{
+ComWrappersSupport.RegisterProjectionTypeBaseTypeMapping(TypeNameToBaseTypeNameMapping);
+}
+}
+})",
+ typeNameToBaseTypeMap.size(),
+ bind([&](writer& w) {
+ for (auto&& [key, value] : typeNameToBaseTypeMap)
+ {
+ w.write(R"(["%"] = "%",)", key, value);
+ w.write("\n");
+ }
+ }));
+ baseTypeWriter.flush_to_file(settings.output_folder / "WinRTBaseTypeMappingHelper.cs");
+ }
+
if (projectionFileWritten)
{
for (auto&& string : strings::base)
@@ -373,15 +391,7 @@ Where is one or more of:
continue;
}
writer ws;
- ws.write(R"(//------------------------------------------------------------------------------
-//
-// This file was generated by cswinrt.exe version %
-//
-// Changes to this file may cause incorrect behavior and will be lost if
-// the code is regenerated.
-//
-//------------------------------------------------------------------------------
-)", VERSION_STRING);
+ write_file_header(ws);
ws.write(string.value);
ws.flush_to_file(settings.output_folder / (std::string(string.name) + ".cs"));
}
diff --git a/src/cswinrt/strings/WinRT.cs b/src/cswinrt/strings/WinRT.cs
index feb564980..52bac92f2 100644
--- a/src/cswinrt/strings/WinRT.cs
+++ b/src/cswinrt/strings/WinRT.cs
@@ -845,19 +845,19 @@ internal static class InterfaceIIDs
}
}
+#if !NET
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Method)]
internal sealed class ModuleInitializerAttribute : Attribute { }
}
+#endif
namespace WinRT
{
internal static class ProjectionInitializer
{
-#pragma warning disable 0436
[ModuleInitializer]
-#pragma warning restore 0436
internal static void InitalizeProjection()
{
ComWrappersSupport.RegisterProjectionAssembly(typeof(ProjectionInitializer).Assembly);
diff --git a/src/cswinrt/strings/additions/Microsoft.UI.Xaml.Controls.Primitives/Microsoft.UI.Xaml.Controls.Primitives.cs b/src/cswinrt/strings/additions/Microsoft.UI.Xaml.Controls.Primitives/Microsoft.UI.Xaml.Controls.Primitives.cs
index 3a39fd93e..6fc65bf3a 100644
--- a/src/cswinrt/strings/additions/Microsoft.UI.Xaml.Controls.Primitives/Microsoft.UI.Xaml.Controls.Primitives.cs
+++ b/src/cswinrt/strings/additions/Microsoft.UI.Xaml.Controls.Primitives/Microsoft.UI.Xaml.Controls.Primitives.cs
@@ -3,7 +3,8 @@ namespace Microsoft.UI.Xaml.Controls.Primitives
{
using Windows.Foundation;
- [global::WinRT.WindowsRuntimeType("Microsoft.UI")]
+ [global::WinRT.WindowsRuntimeType("Microsoft.UI")]
+ [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Microsoft.UI.Xaml.Controls.Primitives.GeneratorPosition))]
[StructLayout(LayoutKind.Sequential)]
#if EMBED
internal
diff --git a/src/cswinrt/strings/additions/Microsoft.UI.Xaml.Media.Animation/Microsoft.UI.Xaml.Media.Animation.cs b/src/cswinrt/strings/additions/Microsoft.UI.Xaml.Media.Animation/Microsoft.UI.Xaml.Media.Animation.cs
index 8eeb51f6a..f267a9613 100644
--- a/src/cswinrt/strings/additions/Microsoft.UI.Xaml.Media.Animation/Microsoft.UI.Xaml.Media.Animation.cs
+++ b/src/cswinrt/strings/additions/Microsoft.UI.Xaml.Media.Animation/Microsoft.UI.Xaml.Media.Animation.cs
@@ -3,7 +3,8 @@ namespace Microsoft.UI.Xaml.Media.Animation
{
using Windows.Foundation;
- [global::WinRT.WindowsRuntimeType("Microsoft.UI")]
+ [global::WinRT.WindowsRuntimeType("Microsoft.UI")]
+ [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Microsoft.UI.Xaml.Media.Animation.KeyTime))]
[StructLayout(LayoutKind.Sequential)]
#if EMBED
internal
@@ -90,7 +91,8 @@ enum RepeatBehaviorType
Forever
}
- [global::WinRT.WindowsRuntimeType("Microsoft.UI")]
+ [global::WinRT.WindowsRuntimeType("Microsoft.UI")]
+ [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Microsoft.UI.Xaml.Media.Animation.RepeatBehavior))]
[StructLayout(LayoutKind.Sequential)]
#if EMBED
internal
diff --git a/src/cswinrt/strings/additions/Microsoft.UI.Xaml.Media.Media3D/Microsoft.UI.Xaml.Media.Media3D.cs b/src/cswinrt/strings/additions/Microsoft.UI.Xaml.Media.Media3D/Microsoft.UI.Xaml.Media.Media3D.cs
index 8d1ca129e..88ff2ccd8 100644
--- a/src/cswinrt/strings/additions/Microsoft.UI.Xaml.Media.Media3D/Microsoft.UI.Xaml.Media.Media3D.cs
+++ b/src/cswinrt/strings/additions/Microsoft.UI.Xaml.Media.Media3D/Microsoft.UI.Xaml.Media.Media3D.cs
@@ -3,7 +3,8 @@ namespace Microsoft.UI.Xaml.Media.Media3D
{
using Windows.Foundation;
- [global::WinRT.WindowsRuntimeType("Microsoft.UI")]
+ [global::WinRT.WindowsRuntimeType("Microsoft.UI")]
+ [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Microsoft.UI.Xaml.Media.Media3D.Matrix3D))]
[StructLayout(LayoutKind.Sequential)]
#if EMBED
internal
diff --git a/src/cswinrt/strings/additions/Microsoft.UI.Xaml.Media/Microsoft.UI.Xaml.Media.cs b/src/cswinrt/strings/additions/Microsoft.UI.Xaml.Media/Microsoft.UI.Xaml.Media.cs
index 14a7436b5..e8f91861b 100644
--- a/src/cswinrt/strings/additions/Microsoft.UI.Xaml.Media/Microsoft.UI.Xaml.Media.cs
+++ b/src/cswinrt/strings/additions/Microsoft.UI.Xaml.Media/Microsoft.UI.Xaml.Media.cs
@@ -3,7 +3,8 @@ namespace Microsoft.UI.Xaml.Media
{
using Windows.Foundation;
- [global::WinRT.WindowsRuntimeType("Microsoft.UI")]
+ [global::WinRT.WindowsRuntimeType("Microsoft.UI")]
+ [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Microsoft.UI.Xaml.Media.Matrix))]
[StructLayout(LayoutKind.Sequential)]
#if EMBED
internal
diff --git a/src/cswinrt/strings/additions/Microsoft.UI.Xaml/Microsoft.UI.Xaml.cs b/src/cswinrt/strings/additions/Microsoft.UI.Xaml/Microsoft.UI.Xaml.cs
index c96e1ff61..f901fb1ad 100644
--- a/src/cswinrt/strings/additions/Microsoft.UI.Xaml/Microsoft.UI.Xaml.cs
+++ b/src/cswinrt/strings/additions/Microsoft.UI.Xaml/Microsoft.UI.Xaml.cs
@@ -3,7 +3,8 @@ namespace Microsoft.UI.Xaml
{
using Windows.Foundation;
- [global::WinRT.WindowsRuntimeType("Microsoft.UI")]
+ [global::WinRT.WindowsRuntimeType("Microsoft.UI")]
+ [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Microsoft.UI.Xaml.CornerRadius))]
[StructLayout(LayoutKind.Sequential)]
#if EMBED
internal
@@ -163,7 +164,8 @@ enum GridUnitType
Star,
}
- [global::WinRT.WindowsRuntimeType("Microsoft.UI")]
+ [global::WinRT.WindowsRuntimeType("Microsoft.UI")]
+ [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Microsoft.UI.Xaml.GridLength))]
[StructLayout(LayoutKind.Sequential)]
#if EMBED
internal
@@ -280,7 +282,8 @@ internal string ToString(global::System.Globalization.CultureInfo cultureInfo)
}
}
- [global::WinRT.WindowsRuntimeType("Microsoft.UI")]
+ [global::WinRT.WindowsRuntimeType("Microsoft.UI")]
+ [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Microsoft.UI.Xaml.Thickness))]
[StructLayout(LayoutKind.Sequential)]
#if EMBED
internal
@@ -406,7 +409,8 @@ enum DurationType
Forever
}
- [global::WinRT.WindowsRuntimeType("Microsoft.UI")]
+ [global::WinRT.WindowsRuntimeType("Microsoft.UI")]
+ [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Microsoft.UI.Xaml.Duration))]
[StructLayout(LayoutKind.Sequential)]
#if EMBED
internal
diff --git a/src/cswinrt/strings/additions/Windows.Storage.Streams/IBufferByteAccess.cs b/src/cswinrt/strings/additions/Windows.Storage.Streams/IBufferByteAccess.cs
index 2b86bac62..9cccb23a2 100644
--- a/src/cswinrt/strings/additions/Windows.Storage.Streams/IBufferByteAccess.cs
+++ b/src/cswinrt/strings/additions/Windows.Storage.Streams/IBufferByteAccess.cs
@@ -3,7 +3,8 @@ namespace Windows.Storage.Streams
using global::System;
[global::WinRT.WindowsRuntimeType("Windows.Foundation.UniversalApiContract")]
- [Guid("905a0fef-bc53-11df-8c49-001e4fc686da")]
+ [Guid("905a0fef-bc53-11df-8c49-001e4fc686da")]
+ [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Windows.Storage.Streams.IBufferByteAccess))]
internal interface IBufferByteAccess
{
IntPtr Buffer { get; }
diff --git a/src/cswinrt/strings/additions/Windows.Storage.Streams/IMarshal.cs b/src/cswinrt/strings/additions/Windows.Storage.Streams/IMarshal.cs
index 47d7a3834..6af6c0586 100644
--- a/src/cswinrt/strings/additions/Windows.Storage.Streams/IMarshal.cs
+++ b/src/cswinrt/strings/additions/Windows.Storage.Streams/IMarshal.cs
@@ -6,7 +6,8 @@ internal enum MSHCTX : int { Local = 0, NoSharedMem = 1, DifferentMachine = 2, I
internal enum MSHLFLAGS : int { Normal = 0, TableStrong = 1, TableWeak = 2, NoPing = 4 }
[global::WinRT.WindowsRuntimeType("Windows.Foundation.UniversalApiContract")]
- [Guid("00000003-0000-0000-c000-000000000046")]
+ [Guid("00000003-0000-0000-c000-000000000046")]
+ [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Com.IMarshal))]
internal interface IMarshal
{
unsafe void GetUnmarshalClass(Guid* riid, IntPtr pv, MSHCTX dwDestContext, IntPtr pvDestContext, MSHLFLAGS mshlFlags, Guid* pCid);
diff --git a/src/cswinrt/strings/additions/Windows.Storage/IStorageFolderHandleAccess.cs b/src/cswinrt/strings/additions/Windows.Storage/IStorageFolderHandleAccess.cs
index 6d53313de..2b9f841a1 100644
--- a/src/cswinrt/strings/additions/Windows.Storage/IStorageFolderHandleAccess.cs
+++ b/src/cswinrt/strings/additions/Windows.Storage/IStorageFolderHandleAccess.cs
@@ -7,7 +7,8 @@ namespace Windows.Storage
{
using Microsoft.Win32.SafeHandles;
// Available in 14393 (RS1) and later
- [Guid("DF19938F-5462-48A0-BE65-D2A3271A08D6")]
+ [Guid("DF19938F-5462-48A0-BE65-D2A3271A08D6")]
+ [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Windows.Storage.IStorageFolderHandleAccess))]
internal interface IStorageFolderHandleAccess
{
SafeFileHandle Create(
diff --git a/src/cswinrt/strings/additions/Windows.Storage/IStorageItemHandleAccess.cs b/src/cswinrt/strings/additions/Windows.Storage/IStorageItemHandleAccess.cs
index a797f91f2..ecd1bab08 100644
--- a/src/cswinrt/strings/additions/Windows.Storage/IStorageItemHandleAccess.cs
+++ b/src/cswinrt/strings/additions/Windows.Storage/IStorageItemHandleAccess.cs
@@ -6,7 +6,8 @@ namespace Windows.Storage
{
using Microsoft.Win32.SafeHandles;
// Available in 14393 (RS1) and later
- [Guid("5CA296B2-2C25-4D22-B785-B885C8201E6A")]
+ [Guid("5CA296B2-2C25-4D22-B785-B885C8201E6A")]
+ [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Windows.Storage.IStorageItemHandleAccess))]
internal interface IStorageItemHandleAccess
{
SafeFileHandle Create(
diff --git a/src/cswinrt/strings/additions/Windows.UI/Windows.UI.cs b/src/cswinrt/strings/additions/Windows.UI/Windows.UI.cs
index 913b030a4..001598028 100644
--- a/src/cswinrt/strings/additions/Windows.UI/Windows.UI.cs
+++ b/src/cswinrt/strings/additions/Windows.UI/Windows.UI.cs
@@ -4,7 +4,8 @@ namespace Windows.UI
using global::System;
using global::System.Globalization;
- [global::WinRT.WindowsRuntimeType("Windows.Foundation.UniversalApiContract")]
+ [global::WinRT.WindowsRuntimeType("Windows.Foundation.UniversalApiContract")]
+ [global::WinRT.WindowsRuntimeHelperType(typeof(global::ABI.Windows.UI.Color))]
[StructLayout(LayoutKind.Sequential)]
#if EMBED
internal