diff --git a/src/WinRT.Generator.Core/Extensions/SignatureComparerExtensions.cs b/src/WinRT.Generator.Core/Extensions/SignatureComparerExtensions.cs
new file mode 100644
index 0000000000..9ecb901c03
--- /dev/null
+++ b/src/WinRT.Generator.Core/Extensions/SignatureComparerExtensions.cs
@@ -0,0 +1,27 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+using AsmResolver.DotNet.Signatures;
+
+namespace WindowsRuntime.Generator;
+
+///
+/// Extensions for .
+///
+internal static class SignatureComparerExtensions
+{
+ ///
+ /// Backing field for the extension property.
+ ///
+ private static readonly SignatureComparer IgnoreVersion = new(SignatureComparisonFlags.VersionAgnostic);
+
+ extension(SignatureComparer)
+ {
+ ///
+ /// Gets a shared, version-agnostic , suitable for comparing
+ /// AsmResolver entities (e.g. as the
+ /// for a of ).
+ ///
+ public static SignatureComparer IgnoreVersion => IgnoreVersion;
+ }
+}
diff --git a/src/WinRT.Generator.Core/WinRT.Generator.Core.csproj b/src/WinRT.Generator.Core/WinRT.Generator.Core.csproj
index 5e0d083a0e..ecbb167af5 100644
--- a/src/WinRT.Generator.Core/WinRT.Generator.Core.csproj
+++ b/src/WinRT.Generator.Core/WinRT.Generator.Core.csproj
@@ -40,5 +40,8 @@
+
+
+
diff --git a/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.IObservableMap2.cs b/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.IObservableMap2.cs
index ea4708ee8d..0654706c64 100644
--- a/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.IObservableMap2.cs
+++ b/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.IObservableMap2.cs
@@ -5,6 +5,7 @@
using AsmResolver.DotNet;
using AsmResolver.DotNet.Signatures;
using AsmResolver.PE.DotNet.Metadata.Tables;
+using WindowsRuntime.Generator;
using WindowsRuntime.InteropGenerator.Factories;
using WindowsRuntime.InteropGenerator.Generation;
using WindowsRuntime.InteropGenerator.Helpers;
@@ -533,4 +534,4 @@ public static void ImplType(
implType.Properties.Add(mapChangedTableProperty);
}
}
-}
\ No newline at end of file
+}
diff --git a/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.IObservableVector1.cs b/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.IObservableVector1.cs
index 90707e9a96..7f325ee78a 100644
--- a/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.IObservableVector1.cs
+++ b/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.IObservableVector1.cs
@@ -5,6 +5,7 @@
using AsmResolver.DotNet;
using AsmResolver.DotNet.Signatures;
using AsmResolver.PE.DotNet.Metadata.Tables;
+using WindowsRuntime.Generator;
using WindowsRuntime.InteropGenerator.Factories;
using WindowsRuntime.InteropGenerator.Generation;
using WindowsRuntime.InteropGenerator.Helpers;
@@ -521,4 +522,4 @@ public static void ImplType(
emitState.TrackTypeDefinition(implType, vectorType, "Impl");
}
}
-}
\ No newline at end of file
+}
diff --git a/src/WinRT.Interop.Generator/Discovery/InteropTypeDiscovery.Generics.cs b/src/WinRT.Interop.Generator/Discovery/InteropTypeDiscovery.Generics.cs
index 6eed89eebd..28f6bcf97f 100644
--- a/src/WinRT.Interop.Generator/Discovery/InteropTypeDiscovery.Generics.cs
+++ b/src/WinRT.Interop.Generator/Discovery/InteropTypeDiscovery.Generics.cs
@@ -3,6 +3,7 @@
using AsmResolver.DotNet;
using AsmResolver.DotNet.Signatures;
+using WindowsRuntime.Generator;
using WindowsRuntime.InteropGenerator.Errors;
using WindowsRuntime.InteropGenerator.Generation;
using WindowsRuntime.InteropGenerator.Helpers;
@@ -636,4 +637,4 @@ private static void TryTrackManagedGenericTypeInstance(
interopReferences: interopReferences,
module: module);
}
-}
\ No newline at end of file
+}
diff --git a/src/WinRT.Interop.Generator/Discovery/InteropTypeDiscovery.cs b/src/WinRT.Interop.Generator/Discovery/InteropTypeDiscovery.cs
index c044ab3e13..7bc0a97670 100644
--- a/src/WinRT.Interop.Generator/Discovery/InteropTypeDiscovery.cs
+++ b/src/WinRT.Interop.Generator/Discovery/InteropTypeDiscovery.cs
@@ -7,6 +7,7 @@
using System.Linq;
using AsmResolver.DotNet;
using AsmResolver.DotNet.Signatures;
+using WindowsRuntime.Generator;
using WindowsRuntime.InteropGenerator.Errors;
using WindowsRuntime.InteropGenerator.Generation;
using WindowsRuntime.InteropGenerator.Helpers;
@@ -562,4 +563,4 @@ private static bool TryAddExposedInterfaceType(
return true;
}
-}
\ No newline at end of file
+}
diff --git a/src/WinRT.Interop.Generator/Extensions/ComExtensions.cs b/src/WinRT.Interop.Generator/Extensions/ComExtensions.cs
index 20719c0ae4..7df003065d 100644
--- a/src/WinRT.Interop.Generator/Extensions/ComExtensions.cs
+++ b/src/WinRT.Interop.Generator/Extensions/ComExtensions.cs
@@ -4,6 +4,7 @@
using System.Diagnostics.CodeAnalysis;
using AsmResolver.DotNet;
using AsmResolver.DotNet.Signatures;
+using WindowsRuntime.Generator;
using WindowsRuntime.InteropGenerator.References;
namespace WindowsRuntime.InteropGenerator;
@@ -72,4 +73,4 @@ public bool TryGetInterfaceInformationType(InteropReferences interopReferences,
return true;
}
}
-}
\ No newline at end of file
+}
diff --git a/src/WinRT.Interop.Generator/Extensions/IHasCustomAttributeExtensions.cs b/src/WinRT.Interop.Generator/Extensions/IHasCustomAttributeExtensions.cs
index b124170267..132090edf1 100644
--- a/src/WinRT.Interop.Generator/Extensions/IHasCustomAttributeExtensions.cs
+++ b/src/WinRT.Interop.Generator/Extensions/IHasCustomAttributeExtensions.cs
@@ -5,6 +5,7 @@
using AsmResolver;
using AsmResolver.DotNet;
using AsmResolver.DotNet.Signatures;
+using WindowsRuntime.Generator;
namespace WindowsRuntime.InteropGenerator;
@@ -100,4 +101,4 @@ public static bool HasCustomAttribute(this IHasCustomAttribute member, ITypeDesc
{
return TryGetCustomAttribute(member, attributeType, out _);
}
-}
\ No newline at end of file
+}
diff --git a/src/WinRT.Interop.Generator/Extensions/ModuleDefinitionExtensions.cs b/src/WinRT.Interop.Generator/Extensions/ModuleDefinitionExtensions.cs
index c50cc44e7d..4e6e1ba2e6 100644
--- a/src/WinRT.Interop.Generator/Extensions/ModuleDefinitionExtensions.cs
+++ b/src/WinRT.Interop.Generator/Extensions/ModuleDefinitionExtensions.cs
@@ -9,6 +9,7 @@
using AsmResolver.DotNet;
using AsmResolver.DotNet.Signatures;
using AsmResolver.PE.DotNet.Metadata.Tables;
+using WindowsRuntime.Generator;
using WindowsRuntime.InteropGenerator.Helpers;
using WindowsRuntime.InteropGenerator.Visitors;
@@ -304,4 +305,4 @@ public static IEnumerable OrderByFullyQualifiedName(this IEnum
{
return modules.Order(ModuleDefinitionComparer.Instance);
}
-}
\ No newline at end of file
+}
diff --git a/src/WinRT.Interop.Generator/Extensions/SignatureComparerExtensions.cs b/src/WinRT.Interop.Generator/Extensions/SignatureComparerExtensions.cs
index a0b6ac98e9..6b9cf3b1e1 100644
--- a/src/WinRT.Interop.Generator/Extensions/SignatureComparerExtensions.cs
+++ b/src/WinRT.Interop.Generator/Extensions/SignatureComparerExtensions.cs
@@ -12,20 +12,8 @@ namespace WindowsRuntime.InteropGenerator;
///
internal static class SignatureComparerExtensions
{
-#pragma warning disable IDE0052 // TODO: remove this once Roslyn bug is fixed
- ///
- /// Backing field for .
- ///
- private static readonly SignatureComparer IgnoreVersion = new(SignatureComparisonFlags.VersionAgnostic);
-#pragma warning restore IDE0052
-
extension(SignatureComparer comparer)
{
- ///
- /// An immutable default instance of , with .
- ///
- public static SignatureComparer IgnoreVersion => IgnoreVersion;
-
///
/// Creates an instance for a pair of values.
///
diff --git a/src/WinRT.Interop.Generator/Extensions/TypeDefinitionExtensions.cs b/src/WinRT.Interop.Generator/Extensions/TypeDefinitionExtensions.cs
index 888c334b37..cb0849aef3 100644
--- a/src/WinRT.Interop.Generator/Extensions/TypeDefinitionExtensions.cs
+++ b/src/WinRT.Interop.Generator/Extensions/TypeDefinitionExtensions.cs
@@ -8,6 +8,7 @@
using AsmResolver.DotNet;
using AsmResolver.DotNet.Signatures;
using AsmResolver.PE.DotNet.Metadata.Tables;
+using WindowsRuntime.Generator;
#pragma warning disable IDE0046
@@ -344,4 +345,4 @@ public IEnumerable EnumerateGenericInstanceInterfa
}
}
}
-}
\ No newline at end of file
+}
diff --git a/src/WinRT.Interop.Generator/Extensions/WindowsRuntimeExtensions.cs b/src/WinRT.Interop.Generator/Extensions/WindowsRuntimeExtensions.cs
index ce70b8a1a2..581fdb3faf 100644
--- a/src/WinRT.Interop.Generator/Extensions/WindowsRuntimeExtensions.cs
+++ b/src/WinRT.Interop.Generator/Extensions/WindowsRuntimeExtensions.cs
@@ -8,6 +8,7 @@
using AsmResolver.DotNet;
using AsmResolver.DotNet.Signatures;
using AsmResolver.PE.DotNet.Metadata.Tables;
+using WindowsRuntime.Generator;
using WindowsRuntime.InteropGenerator.References;
#pragma warning disable IDE0046
@@ -1186,4 +1187,4 @@ file static class WellKnownMetadataNames
/// The "WindowsRuntimeComponentAssemblyAttribute" text.
///
public static readonly Utf8String WindowsRuntimeComponentAssemblyAttribute = "WindowsRuntimeComponentAssemblyAttribute"u8;
-}
\ No newline at end of file
+}
diff --git a/src/WinRT.Interop.Generator/Factories/InteropMethodDefinitionFactory.IReadOnlyDictionary2Impl.cs b/src/WinRT.Interop.Generator/Factories/InteropMethodDefinitionFactory.IReadOnlyDictionary2Impl.cs
index 27c0f0fe4c..9f5262fc3f 100644
--- a/src/WinRT.Interop.Generator/Factories/InteropMethodDefinitionFactory.IReadOnlyDictionary2Impl.cs
+++ b/src/WinRT.Interop.Generator/Factories/InteropMethodDefinitionFactory.IReadOnlyDictionary2Impl.cs
@@ -6,6 +6,7 @@
using AsmResolver.DotNet.Signatures;
using AsmResolver.PE.DotNet.Cil;
using AsmResolver.PE.DotNet.Metadata.Tables;
+using WindowsRuntime.Generator;
using WindowsRuntime.InteropGenerator.Generation;
using WindowsRuntime.InteropGenerator.References;
using static AsmResolver.PE.DotNet.Cil.CilOpCodes;
@@ -512,4 +513,4 @@ public static MethodDefinition Split(
return splitMethod;
}
}
-}
\ No newline at end of file
+}
diff --git a/src/WinRT.Interop.Generator/Factories/InteropMethodDefinitionFactory.IReadOnlyList1Impl.cs b/src/WinRT.Interop.Generator/Factories/InteropMethodDefinitionFactory.IReadOnlyList1Impl.cs
index 8abfa8e72d..1844bc4c0c 100644
--- a/src/WinRT.Interop.Generator/Factories/InteropMethodDefinitionFactory.IReadOnlyList1Impl.cs
+++ b/src/WinRT.Interop.Generator/Factories/InteropMethodDefinitionFactory.IReadOnlyList1Impl.cs
@@ -6,6 +6,7 @@
using AsmResolver.DotNet.Signatures;
using AsmResolver.PE.DotNet.Cil;
using AsmResolver.PE.DotNet.Metadata.Tables;
+using WindowsRuntime.Generator;
using WindowsRuntime.InteropGenerator.Generation;
using WindowsRuntime.InteropGenerator.References;
using static AsmResolver.PE.DotNet.Cil.CilOpCodes;
@@ -493,4 +494,4 @@ _ when elementType.IsTypeOfException(interopReferences) => interopReferences.IRe
return getManyImplMethod;
}
}
-}
\ No newline at end of file
+}
diff --git a/src/WinRT.Interop.Generator/Generation/InteropGenerator.Discover.cs b/src/WinRT.Interop.Generator/Generation/InteropGenerator.Discover.cs
index 42760ba3c2..54196bf645 100644
--- a/src/WinRT.Interop.Generator/Generation/InteropGenerator.Discover.cs
+++ b/src/WinRT.Interop.Generator/Generation/InteropGenerator.Discover.cs
@@ -10,6 +10,7 @@
using AsmResolver.DotNet;
using AsmResolver.DotNet.Signatures;
using AsmResolver.PE;
+using WindowsRuntime.Generator;
using WindowsRuntime.Generator.Errors;
using WindowsRuntime.Generator.Extensions;
using WindowsRuntime.Generator.References;
@@ -618,4 +619,4 @@ private static string[] GetAssembliesToProcess(InteropGeneratorArgs args)
return [.. assembliesToProcess];
}
-}
\ No newline at end of file
+}
diff --git a/src/WinRT.Interop.Generator/Generation/InteropGeneratorDiscoveryState.cs b/src/WinRT.Interop.Generator/Generation/InteropGeneratorDiscoveryState.cs
index 979bba7ef9..7b747a0c0f 100644
--- a/src/WinRT.Interop.Generator/Generation/InteropGeneratorDiscoveryState.cs
+++ b/src/WinRT.Interop.Generator/Generation/InteropGeneratorDiscoveryState.cs
@@ -6,6 +6,7 @@
using System.Diagnostics.CodeAnalysis;
using AsmResolver.DotNet;
using AsmResolver.DotNet.Signatures;
+using WindowsRuntime.Generator;
using WindowsRuntime.InteropGenerator.Errors;
using WindowsRuntime.InteropGenerator.Models;
@@ -572,4 +573,4 @@ private void ThrowIfReadOnly()
throw WellKnownInteropExceptions.DiscoveryStateChangeAfterMakeReadOnlyError();
}
}
-}
\ No newline at end of file
+}
diff --git a/src/WinRT.Interop.Generator/Generation/InteropGeneratorEmitState.cs b/src/WinRT.Interop.Generator/Generation/InteropGeneratorEmitState.cs
index 265b99f1e7..ab07191566 100644
--- a/src/WinRT.Interop.Generator/Generation/InteropGeneratorEmitState.cs
+++ b/src/WinRT.Interop.Generator/Generation/InteropGeneratorEmitState.cs
@@ -8,6 +8,7 @@
using AsmResolver.DotNet.Code.Cil;
using AsmResolver.DotNet.Signatures;
using AsmResolver.PE.DotNet.Cil;
+using WindowsRuntime.Generator;
using WindowsRuntime.InteropGenerator.Errors;
using WindowsRuntime.InteropGenerator.Models;
@@ -394,4 +395,4 @@ private void ThrowIfReadOnly()
throw WellKnownInteropExceptions.EmitStateChangeAfterMakeReadOnlyError();
}
}
-}
\ No newline at end of file
+}
diff --git a/src/WinRT.Interop.Generator/Helpers/TypeExclusions.cs b/src/WinRT.Interop.Generator/Helpers/TypeExclusions.cs
index 74b5ab7994..2356b13fec 100644
--- a/src/WinRT.Interop.Generator/Helpers/TypeExclusions.cs
+++ b/src/WinRT.Interop.Generator/Helpers/TypeExclusions.cs
@@ -4,6 +4,7 @@
using System;
using AsmResolver.DotNet;
using AsmResolver.DotNet.Signatures;
+using WindowsRuntime.Generator;
using WindowsRuntime.InteropGenerator.References;
namespace WindowsRuntime.InteropGenerator.Helpers;
diff --git a/src/WinRT.Interop.Generator/Helpers/WindowsRuntimeTypeAnalyzer.cs b/src/WinRT.Interop.Generator/Helpers/WindowsRuntimeTypeAnalyzer.cs
index 7831c0771d..85b31842cb 100644
--- a/src/WinRT.Interop.Generator/Helpers/WindowsRuntimeTypeAnalyzer.cs
+++ b/src/WinRT.Interop.Generator/Helpers/WindowsRuntimeTypeAnalyzer.cs
@@ -5,6 +5,7 @@
using System.Diagnostics.CodeAnalysis;
using AsmResolver.DotNet;
using AsmResolver.DotNet.Signatures;
+using WindowsRuntime.Generator;
using WindowsRuntime.InteropGenerator.References;
namespace WindowsRuntime.InteropGenerator.Helpers;
diff --git a/src/WinRT.Interop.Generator/Models/TypeSignatureEquatableSet.Builder.cs b/src/WinRT.Interop.Generator/Models/TypeSignatureEquatableSet.Builder.cs
index 6f33602c2b..199d2b2ec6 100644
--- a/src/WinRT.Interop.Generator/Models/TypeSignatureEquatableSet.Builder.cs
+++ b/src/WinRT.Interop.Generator/Models/TypeSignatureEquatableSet.Builder.cs
@@ -5,6 +5,7 @@
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using AsmResolver.DotNet.Signatures;
+using WindowsRuntime.Generator;
namespace WindowsRuntime.InteropGenerator.Models;
@@ -122,4 +123,4 @@ public TypeSignatureEquatableSet MoveToEquatableSet()
return new(set);
}
}
-}
\ No newline at end of file
+}
diff --git a/src/WinRT.Interop.Generator/Models/TypeSignatureEquatableSet.cs b/src/WinRT.Interop.Generator/Models/TypeSignatureEquatableSet.cs
index 6620f2705b..f051e8c390 100644
--- a/src/WinRT.Interop.Generator/Models/TypeSignatureEquatableSet.cs
+++ b/src/WinRT.Interop.Generator/Models/TypeSignatureEquatableSet.cs
@@ -6,6 +6,7 @@
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using AsmResolver.DotNet.Signatures;
+using WindowsRuntime.Generator;
using WindowsRuntime.InteropGenerator.Helpers;
namespace WindowsRuntime.InteropGenerator.Models;
@@ -220,4 +221,4 @@ IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
-}
\ No newline at end of file
+}
diff --git a/src/WinRT.Interop.Generator/References/WellKnownInterfaceIIDs.cs b/src/WinRT.Interop.Generator/References/WellKnownInterfaceIIDs.cs
index fafda0e0fb..a6384152ca 100644
--- a/src/WinRT.Interop.Generator/References/WellKnownInterfaceIIDs.cs
+++ b/src/WinRT.Interop.Generator/References/WellKnownInterfaceIIDs.cs
@@ -6,6 +6,7 @@
using System.Collections.Generic;
using AsmResolver.DotNet;
using AsmResolver.DotNet.Signatures;
+using WindowsRuntime.Generator;
using WindowsRuntime.InteropGenerator.Errors;
using WindowsRuntime.InteropGenerator.Factories;
diff --git a/src/WinRT.Interop.Generator/Resolvers/InteropImplTypeResolver.cs b/src/WinRT.Interop.Generator/Resolvers/InteropImplTypeResolver.cs
index 1e6dd29662..f635942b8d 100644
--- a/src/WinRT.Interop.Generator/Resolvers/InteropImplTypeResolver.cs
+++ b/src/WinRT.Interop.Generator/Resolvers/InteropImplTypeResolver.cs
@@ -5,6 +5,7 @@
using AsmResolver.DotNet;
using AsmResolver.DotNet.Signatures;
using AsmResolver.PE.DotNet.Metadata.Tables;
+using WindowsRuntime.Generator;
using WindowsRuntime.InteropGenerator.Factories;
using WindowsRuntime.InteropGenerator.Generation;
using WindowsRuntime.InteropGenerator.References;
diff --git a/src/WinRT.Interop.Generator/Resolvers/InteropInterfaceEntriesResolver.cs b/src/WinRT.Interop.Generator/Resolvers/InteropInterfaceEntriesResolver.cs
index 0de717e4f6..6c2e6a6a84 100644
--- a/src/WinRT.Interop.Generator/Resolvers/InteropInterfaceEntriesResolver.cs
+++ b/src/WinRT.Interop.Generator/Resolvers/InteropInterfaceEntriesResolver.cs
@@ -7,6 +7,7 @@
using AsmResolver.DotNet;
using AsmResolver.DotNet.Code.Cil;
using AsmResolver.DotNet.Signatures;
+using WindowsRuntime.Generator;
using WindowsRuntime.InteropGenerator.Generation;
using WindowsRuntime.InteropGenerator.Models;
using WindowsRuntime.InteropGenerator.References;
diff --git a/src/WinRT.Interop.Generator/Rewriters/InteropMethodRewriter.ManagedParameter.cs b/src/WinRT.Interop.Generator/Rewriters/InteropMethodRewriter.ManagedParameter.cs
index c61d54484b..b547b1d2bd 100644
--- a/src/WinRT.Interop.Generator/Rewriters/InteropMethodRewriter.ManagedParameter.cs
+++ b/src/WinRT.Interop.Generator/Rewriters/InteropMethodRewriter.ManagedParameter.cs
@@ -6,6 +6,7 @@
using AsmResolver.DotNet.Collections;
using AsmResolver.DotNet.Signatures;
using AsmResolver.PE.DotNet.Cil;
+using WindowsRuntime.Generator;
using WindowsRuntime.InteropGenerator.Errors;
using WindowsRuntime.InteropGenerator.Generation;
using WindowsRuntime.InteropGenerator.References;
@@ -116,4 +117,4 @@ public static void RewriteMethod(
}
}
}
-}
\ No newline at end of file
+}
diff --git a/src/WinRT.Interop.Generator/Rewriters/InteropMethodRewriter.ManagedValue.cs b/src/WinRT.Interop.Generator/Rewriters/InteropMethodRewriter.ManagedValue.cs
index fd61a5c9f7..f7a69c98e0 100644
--- a/src/WinRT.Interop.Generator/Rewriters/InteropMethodRewriter.ManagedValue.cs
+++ b/src/WinRT.Interop.Generator/Rewriters/InteropMethodRewriter.ManagedValue.cs
@@ -5,6 +5,7 @@
using AsmResolver.DotNet.Code.Cil;
using AsmResolver.DotNet.Signatures;
using AsmResolver.PE.DotNet.Cil;
+using WindowsRuntime.Generator;
using WindowsRuntime.InteropGenerator.Errors;
using WindowsRuntime.InteropGenerator.Generation;
using WindowsRuntime.InteropGenerator.References;
@@ -99,4 +100,4 @@ public static void RewriteMethod(
}
}
}
-}
\ No newline at end of file
+}
diff --git a/src/WinRT.Interop.Generator/Rewriters/InteropMethodRewriter.NativeParameter.cs b/src/WinRT.Interop.Generator/Rewriters/InteropMethodRewriter.NativeParameter.cs
index ad3a7d7c42..0185da8c63 100644
--- a/src/WinRT.Interop.Generator/Rewriters/InteropMethodRewriter.NativeParameter.cs
+++ b/src/WinRT.Interop.Generator/Rewriters/InteropMethodRewriter.NativeParameter.cs
@@ -7,6 +7,7 @@
using AsmResolver.DotNet.Collections;
using AsmResolver.DotNet.Signatures;
using AsmResolver.PE.DotNet.Cil;
+using WindowsRuntime.Generator;
using WindowsRuntime.InteropGenerator.Errors;
using WindowsRuntime.InteropGenerator.Generation;
using WindowsRuntime.InteropGenerator.References;
@@ -425,4 +426,4 @@ private static void RewriteBodyForTypeOfType(
});
}
}
-}
\ No newline at end of file
+}
diff --git a/src/WinRT.Interop.Generator/Rewriters/InteropMethodRewriter.ReturnValue.cs b/src/WinRT.Interop.Generator/Rewriters/InteropMethodRewriter.ReturnValue.cs
index ae4462938c..02eed83a6a 100644
--- a/src/WinRT.Interop.Generator/Rewriters/InteropMethodRewriter.ReturnValue.cs
+++ b/src/WinRT.Interop.Generator/Rewriters/InteropMethodRewriter.ReturnValue.cs
@@ -5,6 +5,7 @@
using AsmResolver.DotNet.Code.Cil;
using AsmResolver.DotNet.Signatures;
using AsmResolver.PE.DotNet.Cil;
+using WindowsRuntime.Generator;
using WindowsRuntime.InteropGenerator.Errors;
using WindowsRuntime.InteropGenerator.Generation;
using WindowsRuntime.InteropGenerator.References;
@@ -221,4 +222,4 @@ private static void RewriteBody(
});
}
}
-}
\ No newline at end of file
+}
diff --git a/src/WinRT.Projection.Generator/Generation/ProjectionGenerator.Generate.cs b/src/WinRT.Projection.Generator/Generation/ProjectionGenerator.Generate.cs
index b64717ab0e..469a0a3333 100644
--- a/src/WinRT.Projection.Generator/Generation/ProjectionGenerator.Generate.cs
+++ b/src/WinRT.Projection.Generator/Generation/ProjectionGenerator.Generate.cs
@@ -109,6 +109,11 @@ private static void BuildWriterOptions(
List excludes = [];
List winmdInputs = [];
+ // Paths to the managed implementation assemblies of the component(s) being projected, scanned
+ // by the projection writer for implementation details (e.g. the static fields backing XAML
+ // dependency properties) that are not present in the .winmd metadata
+ List componentImplementationAssemblies = [];
+
// Filter out .winmd files from the resolver paths
string[] resolverPaths = [.. args.ReferenceAssemblyPaths
.Where(p => !p.EndsWith(".winmd", StringComparison.OrdinalIgnoreCase))];
@@ -137,9 +142,15 @@ private static void BuildWriterOptions(
ModuleDefinition refModule = ModuleDefinition.FromFile(refPath, resolver.ReaderParameters);
- if (IsComponentAssembly(refModule) && refModule.Assembly?.Name is Utf8String name)
+ if (IsComponentAssembly(refModule))
{
- _ = componentAssemblyNameSet.Add(name.Value);
+ // Keep the path so the projection writer can inspect the managed implementation
+ componentImplementationAssemblies.Add(refPath);
+
+ if (refModule.Assembly?.Name is Utf8String name)
+ {
+ _ = componentAssemblyNameSet.Add(name.Value);
+ }
}
}
@@ -272,6 +283,7 @@ private static void BuildWriterOptions(
Include = includes,
Exclude = excludes,
Component = componentMode,
+ ComponentImplementationAssemblyPaths = componentImplementationAssemblies,
MaxDegreesOfParallelism = args.MaxDegreesOfParallelism,
CancellationToken = args.Token,
};
diff --git a/src/WinRT.Projection.Writer/Factories/ComponentFactory.cs b/src/WinRT.Projection.Writer/Factories/ComponentFactory.cs
index 4c559d9c35..c2e29a11ba 100644
--- a/src/WinRT.Projection.Writer/Factories/ComponentFactory.cs
+++ b/src/WinRT.Projection.Writer/Factories/ComponentFactory.cs
@@ -50,12 +50,20 @@ public static void AddMetadataTypeEntry(ProjectionEmitContext context, TypeDefin
///
/// Writes the per-runtime-class server-activation-factory type for component mode.
///
+ /// The writer to emit the factory class to.
+ /// The active projection emit context.
+ /// The activatable runtime class to emit a factory for.
public static void WriteFactoryClass(IndentedTextWriter writer, ProjectionEmitContext context, TypeDefinition type)
{
(string typeNs, string typeName) = type.Names();
string projectedTypeName = TypedefNameWriter.BuildGlobalQualifiedName(typeNs, typeName);
string factoryTypeName = $"{IdentifierEscaping.StripBackticks(typeName)}ServerActivationFactory";
+ // The static constructor that forces the authored type's class constructor to run before
+ // activation is only needed when the type registers dependency properties, so consult the
+ // component's managed implementation assemblies (the .winmd doesn't carry those fields).
+ bool emitStaticConstructor = context.StaticConstructorAnalyzer.RequiresStaticConstructor(type.FullName);
+
// Writes the set of interfaces implemented by the factory class ('IActivationFactory' is always included)
void WriteBaseInterfaceList(IndentedTextWriter writer)
{
@@ -90,6 +98,27 @@ void WriteActivateInstanceBody(IndentedTextWriter writer)
}
}
+ // Writes the static constructor that forces the projected type's class constructor to run
+ // before activation, so any dependency properties it registers (as static fields) are set
+ // up in time. Types that don't register any don't need it, so the callback emits nothing
+ // for them and the factory omits the constructor entirely, keeping the factory body a
+ // single interpolated template in either case
+ void WriteStaticConstructor(IndentedTextWriter writer)
+ {
+ if (!emitStaticConstructor)
+ {
+ return;
+ }
+
+ writer.WriteLine();
+ writer.WriteLine(isMultiline: true, $$"""
+ static {{factoryTypeName}}()
+ {
+ global::System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(typeof({{projectedTypeName}}).TypeHandle);
+ }
+ """);
+ }
+
// Helper wrapper to write additional methods
void WriteAdditionalActivationFactoryMethods(IndentedTextWriter writer)
{
@@ -101,12 +130,8 @@ void WriteAdditionalActivationFactoryMethods(IndentedTextWriter writer)
internal sealed class {{factoryTypeName}} : {{WriteBaseInterfaceList}}
{
private static readonly {{factoryTypeName}} _factory = new();
+ {{WriteStaticConstructor}}
- static {{factoryTypeName}}()
- {
- global::System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(typeof({{projectedTypeName}}).TypeHandle);
- }
-
public static unsafe void* Make()
{
return global::WindowsRuntime.InteropServices.Marshalling.WindowsRuntimeInterfaceMarshaller
diff --git a/src/WinRT.Projection.Writer/Generation/ProjectionEmitContext.cs b/src/WinRT.Projection.Writer/Generation/ProjectionEmitContext.cs
index 1be2c4aa9e..405cc1ce0b 100644
--- a/src/WinRT.Projection.Writer/Generation/ProjectionEmitContext.cs
+++ b/src/WinRT.Projection.Writer/Generation/ProjectionEmitContext.cs
@@ -14,7 +14,12 @@ namespace WindowsRuntime.ProjectionWriter.Generation;
/// The active projection settings.
/// The metadata cache for the current generation.
/// The namespace currently being emitted (or when not in a per-namespace pass).
-internal sealed class ProjectionEmitContext(Settings settings, MetadataCache cache, string currentNamespace)
+/// The analyzer over the component's managed implementation assemblies (component mode).
+internal sealed class ProjectionEmitContext(
+ Settings settings,
+ MetadataCache cache,
+ string currentNamespace,
+ ComponentStaticConstructorAnalyzer staticConstructorAnalyzer)
{
///
/// Gets the active projection settings.
@@ -53,6 +58,14 @@ internal sealed class ProjectionEmitContext(Settings settings, MetadataCache cac
///
public AbiTypeKindResolver AbiTypeKindResolver { get; } = new AbiTypeKindResolver(cache);
+ ///
+ /// Gets the analyzer over the component's managed implementation assemblies (component mode).
+ /// It exposes implementation details that are absent from the .winmd metadata (e.g. the
+ /// static fields backing XAML dependency properties), computed on demand as types are
+ /// emitted. The same instance is shared by every emit context, so its memoization is reused.
+ ///
+ public ComponentStaticConstructorAnalyzer StaticConstructorAnalyzer { get; } = staticConstructorAnalyzer;
+
///
/// Gets a value indicating whether platform-attribute computation should suppress platforms
/// that are less than or equal to . Used to apply class-scope platform
diff --git a/src/WinRT.Projection.Writer/Generation/ProjectionGenerator.Component.cs b/src/WinRT.Projection.Writer/Generation/ProjectionGenerator.Component.cs
index 68b1260e15..39e0d8f939 100644
--- a/src/WinRT.Projection.Writer/Generation/ProjectionGenerator.Component.cs
+++ b/src/WinRT.Projection.Writer/Generation/ProjectionGenerator.Component.cs
@@ -4,6 +4,8 @@
using System.Collections.Generic;
using System.IO;
using AsmResolver.DotNet;
+using AsmResolver.DotNet.Signatures;
+using WindowsRuntime.Generator;
using WindowsRuntime.ProjectionWriter.Factories;
using WindowsRuntime.ProjectionWriter.Metadata;
using WindowsRuntime.ProjectionWriter.Writers;
@@ -28,7 +30,7 @@ internal sealed partial class ProjectionGenerator
///
private (HashSet ComponentActivatable, Dictionary> ByModule) DiscoverComponentActivatableTypes()
{
- HashSet componentActivatable = [];
+ HashSet componentActivatable = new(SignatureComparer.IgnoreVersion);
Dictionary> componentByModule = [];
if (!_settings.Component)
@@ -53,7 +55,7 @@ internal sealed partial class ProjectionGenerator
if (!componentByModule.TryGetValue(moduleName, out HashSet? set))
{
- set = [];
+ set = new(SignatureComparer.IgnoreVersion);
componentByModule[moduleName] = set;
}
diff --git a/src/WinRT.Projection.Writer/Generation/ProjectionGenerator.GeneratedIids.cs b/src/WinRT.Projection.Writer/Generation/ProjectionGenerator.GeneratedIids.cs
index 62fd1b7349..1af69abb26 100644
--- a/src/WinRT.Projection.Writer/Generation/ProjectionGenerator.GeneratedIids.cs
+++ b/src/WinRT.Projection.Writer/Generation/ProjectionGenerator.GeneratedIids.cs
@@ -62,7 +62,7 @@ internal void WriteGeneratedInterfaceIidsFile()
bool iidWritten = false;
HashSet interfacesFromClassesEmitted = [];
- ProjectionEmitContext guidContext = new(_settings, _cache, "ABI");
+ ProjectionEmitContext guidContext = new(_settings, _cache, "ABI", _staticConstructorAnalyzer);
using IndentedTextWriterOwner guidIndentedOwner = IndentedTextWriterPool.GetOrCreate();
IndentedTextWriter guidIndented = guidIndentedOwner.Writer;
IidExpressionGenerator.WriteInterfaceIidsBegin(guidIndented);
diff --git a/src/WinRT.Projection.Writer/Generation/ProjectionGenerator.Namespace.cs b/src/WinRT.Projection.Writer/Generation/ProjectionGenerator.Namespace.cs
index 5275e36818..70d19b5363 100644
--- a/src/WinRT.Projection.Writer/Generation/ProjectionGenerator.Namespace.cs
+++ b/src/WinRT.Projection.Writer/Generation/ProjectionGenerator.Namespace.cs
@@ -27,7 +27,7 @@ internal bool ProcessNamespace(string ns, NamespaceMembers members, ProjectionGe
ConcurrentBag> exclusiveToInterfaceEntries = state.ExclusiveToInterfaceEntries;
ConcurrentDictionary authoredTypeNameToMetadataMap = state.AuthoredTypeNameToMetadataMap;
HashSet componentActivatable = state.ComponentActivatable;
- ProjectionEmitContext context = new(_settings, _cache, ns);
+ ProjectionEmitContext context = new(_settings, _cache, ns, _staticConstructorAnalyzer);
using IndentedTextWriterOwner writerOwner = IndentedTextWriterPool.GetOrCreate();
IndentedTextWriter writer = writerOwner.Writer;
diff --git a/src/WinRT.Projection.Writer/Generation/ProjectionGenerator.cs b/src/WinRT.Projection.Writer/Generation/ProjectionGenerator.cs
index 3b07176cce..5f5d8a4383 100644
--- a/src/WinRT.Projection.Writer/Generation/ProjectionGenerator.cs
+++ b/src/WinRT.Projection.Writer/Generation/ProjectionGenerator.cs
@@ -48,6 +48,15 @@ internal sealed partial class ProjectionGenerator(Settings settings, MetadataCac
private readonly MetadataCache _cache = cache;
private readonly CancellationToken _token = token;
+ ///
+ /// Analyzes the component's managed implementation assemblies to decide which activation
+ /// factories must force the authored type's class constructor to run. Created once and shared
+ /// by every emit context, so its memoization cache is reused across namespaces. Empty (and
+ /// unused) outside component mode, where no implementation assemblies are provided.
+ ///
+ private readonly ComponentStaticConstructorAnalyzer _staticConstructorAnalyzer =
+ new(ComponentImplementationMetadata.Load(settings.ComponentImplementationAssemblies));
+
///
/// Runs the projection-generation pipeline end-to-end.
///
diff --git a/src/WinRT.Projection.Writer/Generation/Settings.cs b/src/WinRT.Projection.Writer/Generation/Settings.cs
index 47490fd359..f5c2dc29c8 100644
--- a/src/WinRT.Projection.Writer/Generation/Settings.cs
+++ b/src/WinRT.Projection.Writer/Generation/Settings.cs
@@ -102,6 +102,14 @@ public TypeFilter AdditionFilter
///
public bool Component { get; init; }
+ ///
+ /// Gets the paths to the managed implementation assemblies of the authored Windows Runtime
+ /// component(s) being projected. Used in component mode to inspect implementation details that
+ /// are absent from the input .winmd metadata (e.g. the static fields backing XAML
+ /// dependency properties). May be empty when those assemblies are not available.
+ ///
+ public HashSet ComponentImplementationAssemblies { get; } = [];
+
///
/// Gets or sets a value indicating whether [ExclusiveTo] interfaces are emitted as public rather than internal.
///
diff --git a/src/WinRT.Projection.Writer/Metadata/ComponentImplementationMetadata.cs b/src/WinRT.Projection.Writer/Metadata/ComponentImplementationMetadata.cs
new file mode 100644
index 0000000000..e4c049c718
--- /dev/null
+++ b/src/WinRT.Projection.Writer/Metadata/ComponentImplementationMetadata.cs
@@ -0,0 +1,75 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+using System.Collections.Generic;
+using AsmResolver.DotNet;
+
+namespace WindowsRuntime.ProjectionWriter.Metadata;
+
+///
+/// Resolves authored Windows Runtime types from the managed implementation assemblies (.dll)
+/// of the component(s) being projected, by full name. The managed assemblies carry implementation
+/// details (such as the static fields backing XAML dependency properties) that are not
+/// present in the .winmd metadata, so consumers resolve the managed type here and inspect it
+/// directly.
+///
+///
+/// Loading only builds a name index over the assemblies' types. No per-type analysis is performed
+/// up front: callers resolve just the types they care about (see
+/// ), keeping the cost proportional to what is used.
+///
+internal sealed class ComponentImplementationMetadata
+{
+ /// The authored types indexed by full name (ordinal, the default string equality).
+ private readonly Dictionary _typesByFullName;
+
+ private ComponentImplementationMetadata(Dictionary typesByFullName)
+ {
+ _typesByFullName = typesByFullName;
+ }
+
+ ///
+ /// Loads the managed implementation assemblies and indexes their types by full name. When the
+ /// input is empty, the returned instance resolves nothing and always
+ /// returns .
+ ///
+ /// The managed implementation assembly paths to load.
+ /// The loaded metadata.
+ public static ComponentImplementationMetadata Load(IEnumerable assemblyPaths)
+ {
+ Dictionary typesByFullName = [];
+
+ foreach (string assemblyPath in assemblyPaths)
+ {
+ ModuleDefinition module = ModuleDefinition.FromFile(assemblyPath);
+
+ foreach (TypeDefinition type in module.GetAllTypes())
+ {
+ string fullName = type.FullName;
+
+ // Skip the '' pseudo-type and only index the first definition for a given
+ // full name (multiple component assemblies should never define the same type)
+ if (string.IsNullOrEmpty(fullName) || type.Name?.Value is "")
+ {
+ continue;
+ }
+
+ _ = typesByFullName.TryAdd(fullName, type);
+ }
+ }
+
+ return new ComponentImplementationMetadata(typesByFullName);
+ }
+
+ ///
+ /// Resolves the authored type with the given full name from the loaded implementation
+ /// assemblies, or if no such type is present (e.g. a framework type, or
+ /// when no implementation assemblies were loaded).
+ ///
+ /// The full name of the type to resolve.
+ /// The resolved , or .
+ public TypeDefinition? Resolve(string fullName)
+ {
+ return _typesByFullName.GetValueOrDefault(fullName);
+ }
+}
diff --git a/src/WinRT.Projection.Writer/Metadata/ComponentStaticConstructorAnalyzer.cs b/src/WinRT.Projection.Writer/Metadata/ComponentStaticConstructorAnalyzer.cs
new file mode 100644
index 0000000000..851092253c
--- /dev/null
+++ b/src/WinRT.Projection.Writer/Metadata/ComponentStaticConstructorAnalyzer.cs
@@ -0,0 +1,127 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+using System.Collections.Concurrent;
+using AsmResolver.DotNet;
+using AsmResolver.DotNet.Signatures;
+using WindowsRuntime.Generator;
+using WindowsRuntime.ProjectionWriter.References;
+
+namespace WindowsRuntime.ProjectionWriter.Metadata;
+
+///
+/// Decides whether the activation factory generated for an authored Windows Runtime class must
+/// force the class constructor to run before activation, i.e. whether the class (or an authored
+/// base class) registers any XAML dependency properties.
+///
+///
+/// Dependency properties are registered in static fields of type DependencyProperty,
+/// so they only exist in the managed implementation assemblies, not in the .winmd metadata.
+/// The analyzer resolves each queried type lazily via
+/// and walks its base chain on demand, memoizing the result per visited type so that shared
+/// hierarchies (e.g. several controls deriving from a common authored base) are traversed once. A
+/// single instance is shared by all per-namespace emit contexts and queried from the parallel
+/// emission work items, so the memoization cache is concurrent.
+///
+internal sealed class ComponentStaticConstructorAnalyzer
+{
+ /// The resolver used to look up authored types (and their base types) by full name.
+ private readonly ComponentImplementationMetadata _metadata;
+
+ ///
+ /// Memoizes, per visited type, whether it requires the class constructor to run. Concurrent
+ /// because the analyzer is queried from the parallel emission work items. Keyed with the
+ /// version-agnostic , the standard comparer for AsmResolver entities.
+ ///
+ private readonly ConcurrentDictionary _cache = new(SignatureComparer.IgnoreVersion);
+
+ ///
+ /// Creates a new over the given metadata.
+ ///
+ /// The resolver for the component's managed implementation types.
+ public ComponentStaticConstructorAnalyzer(ComponentImplementationMetadata metadata)
+ {
+ _metadata = metadata;
+ }
+
+ ///
+ /// Determines whether the activation factory for the authored type identified by
+ /// must force the type's class constructor to run before
+ /// activation.
+ ///
+ /// The full name of the authored type.
+ /// if the static constructor is required; otherwise, .
+ ///
+ /// If the type cannot be resolved from the scanned implementation assemblies, this returns
+ /// : we cannot prove the constructor is unnecessary, so it is kept (this
+ /// also covers the case where no implementation assemblies are available).
+ ///
+ public bool RequiresStaticConstructor(string typeFullName)
+ {
+ TypeDefinition? type = _metadata.Resolve(typeFullName);
+
+ return type is null || RequiresStaticConstructor(type);
+ }
+
+ ///
+ /// Memoized core: whether (or an authored base type) registers a
+ /// dependency property.
+ ///
+ /// The resolved authored type to inspect.
+ /// if the static constructor is required; otherwise, .
+ private bool RequiresStaticConstructor(TypeDefinition type)
+ {
+ if (_cache.TryGetValue(type, out bool cached))
+ {
+ return cached;
+ }
+
+ // The type itself registers a dependency property, or an authored base type does. The base
+ // walk stops at the first type outside the scanned assemblies (e.g. a framework base type),
+ // because framework dependency properties are registered by the framework itself. Inheritance
+ // can't cycle, so a plain recursion (memoized below) always terminates.
+ bool result =
+ DeclaresDependencyProperty(type) ||
+ (type.BaseType is { } baseType &&
+ _metadata.Resolve(baseType.FullName) is { } baseDefinition &&
+ RequiresStaticConstructor(baseDefinition));
+
+ _cache[type] = result;
+
+ return result;
+ }
+
+ ///
+ /// Returns whether declares any static field whose type is the
+ /// XAML DependencyProperty (in either Microsoft.UI.Xaml or Windows.UI.Xaml).
+ ///
+ /// The type to inspect.
+ /// if the type declares such a field; otherwise, .
+ private static bool DeclaresDependencyProperty(TypeDefinition type)
+ {
+ foreach (FieldDefinition field in type.Fields)
+ {
+ if (!field.IsStatic)
+ {
+ continue;
+ }
+
+ TypeSignature? fieldType = field.Signature?.FieldType;
+
+ if (fieldType is null)
+ {
+ continue;
+ }
+
+ (string ns, string name) = fieldType.Names();
+
+ if (name == WellKnownTypeNames.DependencyProperty &&
+ (ns == WellKnownNamespaces.MicrosoftUIXaml || ns == WellKnownNamespaces.WindowsUIXaml))
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+}
diff --git a/src/WinRT.Projection.Writer/ProjectionWriter.cs b/src/WinRT.Projection.Writer/ProjectionWriter.cs
index 943dafdee0..e07785cd8b 100644
--- a/src/WinRT.Projection.Writer/ProjectionWriter.cs
+++ b/src/WinRT.Projection.Writer/ProjectionWriter.cs
@@ -57,6 +57,7 @@ public static void Run(ProjectionWriterOptions options)
settings.Include.UnionWith(options.Include);
settings.Exclude.UnionWith(options.Exclude);
settings.AdditionExclude.UnionWith(options.AdditionExclude);
+ settings.ComponentImplementationAssemblies.UnionWith(options.ComponentImplementationAssemblyPaths);
settings.MakeReadOnly();
diff --git a/src/WinRT.Projection.Writer/ProjectionWriterOptions.cs b/src/WinRT.Projection.Writer/ProjectionWriterOptions.cs
index 6c9bd4e772..03a56008c0 100644
--- a/src/WinRT.Projection.Writer/ProjectionWriterOptions.cs
+++ b/src/WinRT.Projection.Writer/ProjectionWriterOptions.cs
@@ -46,6 +46,19 @@ public sealed class ProjectionWriterOptions
///
public bool Component { get; init; }
+ ///
+ /// Optional paths to the managed implementation assemblies (.dll) of the authored
+ /// Windows Runtime component(s) being projected. Only meaningful in mode.
+ ///
+ ///
+ /// The input .winmd metadata does not carry implementation details such as the
+ /// static fields backing XAML dependency properties, so the writer consults these
+ /// managed assemblies to decide whether each generated activation factory needs to force the
+ /// authored type's class constructor to run before activation. When the list is empty (e.g. the
+ /// managed assembly is not available yet), the writer conservatively keeps that constructor.
+ ///
+ public IReadOnlyList ComponentImplementationAssemblyPaths { get; init; } = [];
+
///
/// Make exclusive-to interfaces public in the projection (default is internal).
///
diff --git a/src/WinRT.Projection.Writer/References/WellKnownNamespaces.cs b/src/WinRT.Projection.Writer/References/WellKnownNamespaces.cs
index 333546ce6f..7c8e5fca9a 100644
--- a/src/WinRT.Projection.Writer/References/WellKnownNamespaces.cs
+++ b/src/WinRT.Projection.Writer/References/WellKnownNamespaces.cs
@@ -37,4 +37,14 @@ internal static class WellKnownNamespaces
/// The Windows.UI.Xaml.Interop namespace.
///
public const string WindowsUIXamlInterop = "Windows.UI.Xaml.Interop";
+
+ ///
+ /// The Windows.UI.Xaml namespace (UWP XAML, where DependencyProperty lives in that mode).
+ ///
+ public const string WindowsUIXaml = "Windows.UI.Xaml";
+
+ ///
+ /// The Microsoft.UI.Xaml namespace (WinUI, where DependencyProperty lives in that mode).
+ ///
+ public const string MicrosoftUIXaml = "Microsoft.UI.Xaml";
}
diff --git a/src/WinRT.Projection.Writer/References/WellKnownTypeNames.cs b/src/WinRT.Projection.Writer/References/WellKnownTypeNames.cs
index 5e1435571c..12a84dae7d 100644
--- a/src/WinRT.Projection.Writer/References/WellKnownTypeNames.cs
+++ b/src/WinRT.Projection.Writer/References/WellKnownTypeNames.cs
@@ -52,4 +52,11 @@ internal static class WellKnownTypeNames
/// The Windows SDK XAML TypeName struct (the WinMD source for ).
///
public const string TypeName = "TypeName";
+
+ ///
+ /// The XAML DependencyProperty type (in either Microsoft.UI.Xaml for WinUI or
+ /// Windows.UI.Xaml for UWP XAML). Authored types register dependency properties as
+ /// static fields of this type.
+ ///
+ public const string DependencyProperty = "DependencyProperty";
}
diff --git a/src/WinRT.Projection.Writer/WinRT.Projection.Writer.csproj b/src/WinRT.Projection.Writer/WinRT.Projection.Writer.csproj
index 3c100fcc61..34eb111fcb 100644
--- a/src/WinRT.Projection.Writer/WinRT.Projection.Writer.csproj
+++ b/src/WinRT.Projection.Writer/WinRT.Projection.Writer.csproj
@@ -30,7 +30,7 @@
+
- $(NoWarn);IDE0010;IDE0022;IDE0046;IDE0060;IDE0072
+ $(NoWarn);IDE0010;IDE0022;IDE0028;IDE0046;IDE0060;IDE0072
+
+
+
+