diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index f44b28c3fe..baae5c4217 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -265,7 +265,7 @@ Not all WinRT types are generated automatically by the projection writer into SD #### Custom-mapped types -These are built-in C#/.NET types that are mapped to WinRT types. Because the .NET type already exists in the BCL (and is not owned by CsWinRT), it cannot be "projected" in the usual sense. Instead, CsWinRT associates the necessary WinRT metadata with it via attributes such as `[WindowsRuntimeMappedMetadata]` and dedicated ABI marshalling code in the `ABI/System/` directory. Some of these types map to identically-named WinRT types (e.g. `int` ↔ `Int32`, `Guid` ↔ `Guid`), while others map to a different WinRT type entirely. The `EventHandler` delegate is especially noteworthy: the non-generic `System.EventHandler` is handled as a special case (see `ABI/System/EventHandler.cs`), while `System.EventHandler` maps to `Windows.Foundation.EventHandler`, and `System.EventHandler` (a two-parameter generic delegate projected by CsWinRT) maps to `Windows.Foundation.TypedEventHandler`. +These are built-in C#/.NET types that are mapped to WinRT types. Because the .NET type already exists in the BCL (and is not owned by CsWinRT), it cannot be "projected" in the usual sense. Instead, CsWinRT associates the necessary WinRT metadata with it via attributes such as `[WindowsRuntimeType]` (a parameterless marker; see below) and dedicated ABI marshalling code in the `ABI/System/` directory. Some of these types map to identically-named WinRT types (e.g. `int` ↔ `Int32`, `Guid` ↔ `Guid`), while others map to a different WinRT type entirely. The `EventHandler` delegate is especially noteworthy: the non-generic `System.EventHandler` is handled as a special case (see `ABI/System/EventHandler.cs`), while `System.EventHandler` maps to `Windows.Foundation.EventHandler`, and `System.EventHandler` (a two-parameter generic delegate projected by CsWinRT) maps to `Windows.Foundation.TypedEventHandler`. The following table lists all custom-mapped types where the .NET type maps to a **differently-named** WinRT type: @@ -323,6 +323,12 @@ These are WinRT types that are defined directly in `WinRT.Runtime` rather than b Some of these types — particularly the bindable collection interfaces (`IEnumerable`, `IList`) and XAML-related types — have **different IIDs and/or runtime class names** depending on whether `Windows.UI.Xaml.*` (UWP XAML) or `Microsoft.UI.Xaml.*` (WinUI) support is being used (controlled by the `CsWinRTUseWindowsUIXamlProjections` MSBuild property). This requires further special handling in both the generated projection code and the interop generator to ensure that the correct marshalling and metadata info is associated with them at publish time. +#### The `[WindowsRuntimeType]` marker and the metadata-types lookup + +Every projected type, plus every proxy type for a custom-mapped type, is tagged with the parameterless, implementation-only **`[WindowsRuntimeType]`** marker (`Attributes/WindowsRuntimeTypeAttribute.cs`). The runtime and the build tools only ever check for the *presence* of this marker to decide whether a type participates in Windows Runtime marshalling — they never read any per-type metadata value at runtime. Proxy types are distinguished from projected types by `[WindowsRuntimeMappedType]` (which proxies carry to point at their public type); the `System.EventHandler` proxy intentionally stays unmarked, as it is a pure custom type rather than a real Windows Runtime metadata type. + +The mapping from a projected type to its source `.winmd` module name (its "contract"/"stem") — needed only by build-time tooling (the interop and WinMD generators) — is **not** stored on each type. Instead, the projection generator emits a single centralized, fully trimmable lookup type, **`ABI.WindowsRuntimeMetadataTypes`**, carrying one **`[WindowsRuntimeMetadata(typeof(T), "stem")]`** entry per projected type (`Attributes/WindowsRuntimeMetadataAttribute.cs`, repurposed to a `(Type, string)`, `class`-targeting, `AllowMultiple` attribute). This mirrors how `ABI.WindowsRuntimeDefaultInterfaces` centralizes default interfaces, and lets the metadata be dead-code-eliminated when unused. Both the marker and the lookup type are implementation-only and are stripped from reference projections. `WinRT.Runtime`'s own manually-projected types do not contribute to a lookup type: the interop generator addresses them with the well-known `#CsWinRT` assembly identifier, and the WinMD generator reads their contract from the real `[ContractVersion]` metadata in the `WinRT.Runtime` reference assembly. + ### 2. WinRT.SourceGenerator2 (`src/Authoring/WinRT.SourceGenerator2/`) A Roslyn incremental source generator and diagnostic analyzer package. Runs at **design time** (IntelliSense) and **build time**. It is intentionally lightweight — heavy codegen is deferred to the post-build CLI tools. @@ -635,7 +641,7 @@ A small build project that produces **`WindowsRuntime.Internal.winmd`** — the **Project settings:** -- **Target**: `net10.0-windows10.0.26100.1` (the `.1` TFM revision selects the `cswinrt3` Windows SDK projection reference assemblies, which carry `[WindowsRuntimeMetadata]` attributes the WinMD generator reads) +- **Target**: `net10.0-windows10.0.26100.1` (the `.1` TFM revision selects the `cswinrt3` Windows SDK projection reference assemblies, which carry the `[ContractVersion]` (and `[WindowsRuntimeType]`) Windows Runtime metadata the WinMD generator reads) - **Assembly name**: `WindowsRuntime.Internal` - **Nullable**: `disable` (the Windows Runtime type system does not support nullability annotations) - **WindowsSdkPackageVersion**: pinned (e.g. `10.0.26100.85-preview`) so the .NET SDK adds the implicit framework reference to the matching `Microsoft.Windows.SDK.NET.Ref` package diff --git a/.github/skills/interop-generator/SKILL.md b/.github/skills/interop-generator/SKILL.md index 673a9d5f99..eaafdc2657 100644 --- a/.github/skills/interop-generator/SKILL.md +++ b/.github/skills/interop-generator/SKILL.md @@ -287,7 +287,7 @@ The generator processes two categories of assemblies: - `System.Collections.Concurrent.ConditionalWeakTable<,>` — Memory semantics conflict **Type inclusion criteria:** -- Must be a projected Windows Runtime type. A type is recognized as projected in any of three ways: it carries the per-type `[WindowsRuntimeMetadata]` attribute (implementation projections and types in `WinRT.Runtime.dll`); it is a public type from an authored component assembly (`IsComponentWindowsRuntimeType`); or it is defined in a reference projection assembly marked `[WindowsRuntimeReferenceAssembly]` (`IsReferenceProjectionWindowsRuntimeType`). The latter two do **not** carry the per-type `[WindowsRuntimeMetadata]` attribute — reference projections shipped in NuGet packages have it stripped (it is an implementation-only attribute, absent from the `WinRT.Runtime.dll` reference assembly they compile against), so the interop generator recognizes them by their assembly-level marker instead. +- Must be a projected Windows Runtime type. A type is recognized as projected in any of three ways: it carries the per-type `[WindowsRuntimeType]` marker (implementation projections and types in `WinRT.Runtime.dll`); it is a public type from an authored component assembly (`IsComponentWindowsRuntimeType`); or it is defined in a reference projection assembly marked `[WindowsRuntimeReferenceAssembly]` (`IsReferenceProjectionWindowsRuntimeType`). The latter two do **not** carry the per-type `[WindowsRuntimeType]` marker — reference projections shipped in NuGet packages have it stripped (it is an implementation-only attribute, absent from the `WinRT.Runtime.dll` reference assembly they compile against), so the interop generator recognizes them by their assembly-level marker instead. - Generic types must be fully constructed (no open generic parameters) - Type hierarchy must be fully resolvable (no missing dependencies) - Must not be a managed-only type (types that never cross the Windows Runtime boundary) @@ -732,7 +732,7 @@ Almost everything the generated code calls into lives in `WinRT.Runtime.dll` as - **Collection adapters and adapter extensions** (`WindowsRuntime.InteropServices`, under `Collections/`) — `IListAdapter`, `IReadOnlyListAdapter`, `IDictionaryAdapter`, `IReadOnlyDictionaryAdapter`, `IEnumerableAdapter`, `IEnumeratorAdapter`, `BindableIReadOnlyListAdapter`, plus the per-element-category `*AdapterReferenceTypeExtensions` / `*BlittableValueTypeExtensions` / `*ManagedValueTypeExtensions` / `*UnmanagedValueTypeExtensions` / `*KeyValuePairTypeExtensions` / `*NullableTypeExtensions` types. Generated `GetMany` and collection vtable bodies call into the adapter extensions. - **Object reference and ComWrappers infrastructure** (`WindowsRuntime.InteropServices`, under `ObjectReference/`, `Callbacks/`) — `WindowsRuntimeObjectReference`, `WindowsRuntimeObjectReferenceValue`, and the callback interfaces `IWindowsRuntimeObjectComWrappersCallback`, `IWindowsRuntimeArrayComWrappersCallback`, `IWindowsRuntimeUnsealedObjectComWrappersCallback`. Generated methods take/return `WindowsRuntimeObjectReference`/`WindowsRuntimeObjectReferenceValue` and manage COM lifetime (`AsValue`, `GetThisPtrUnsafe`, `Dispose`); generated ComWrappers callbacks implement the callback interfaces. - **Event sources** (`WindowsRuntime.InteropServices`, mostly under `Events/`) — `EventSource`, `EventHandlerEventSource`/`EventHandlerEventSource`, `EventRegistrationToken`, `EventRegistrationTokenTable`, `IObservableVectorEventSourceFactory`, `IObservableMapEventSourceFactory`. Generated event marshalling derives from or instantiates these. -- **Type-map groups and metadata/marshalling attributes** (`WindowsRuntime`, `WindowsRuntime.InteropServices`, under `TypeMapGroups/`, `Attributes/`) — the markers `WindowsRuntimeComWrappersTypeMapGroup`, `WindowsRuntimeMetadataTypeMapGroup`, `DynamicInterfaceCastableImplementationTypeMapGroup`, and the attributes stamped onto generated types: `WindowsRuntimeMetadataAttribute`, `WindowsRuntimeMappedMetadataAttribute`, `WindowsRuntimeMetadataTypeNameAttribute`, `WindowsRuntimeDefaultInterfaceAttribute`, `WindowsRuntimeExclusiveToInterfaceAttribute`, `WindowsRuntimeReferenceTypeAttribute`, `WindowsRuntimeManagedOnlyTypeAttribute`, `WindowsRuntimeMappedTypeAttribute`, `WindowsRuntimeComWrappersMarshallerAttribute`. +- **Type-map groups and metadata/marshalling attributes** (`WindowsRuntime`, `WindowsRuntime.InteropServices`, under `TypeMapGroups/`, `Attributes/`) — the markers `WindowsRuntimeComWrappersTypeMapGroup`, `WindowsRuntimeMetadataTypeMapGroup`, `DynamicInterfaceCastableImplementationTypeMapGroup`, and the attributes stamped onto generated types: `WindowsRuntimeTypeAttribute` (the parameterless marker placed on projected/proxy types; the type → source `.winmd`-stem mapping is centralized on the `ABI.WindowsRuntimeMetadataTypes` lookup type via `WindowsRuntimeMetadataAttribute(typeof(T), "stem")` instead of on each type), `WindowsRuntimeMetadataTypeNameAttribute`, `WindowsRuntimeDefaultInterfaceAttribute`, `WindowsRuntimeExclusiveToInterfaceAttribute`, `WindowsRuntimeReferenceTypeAttribute`, `WindowsRuntimeManagedOnlyTypeAttribute`, `WindowsRuntimeMappedTypeAttribute`, `WindowsRuntimeComWrappersMarshallerAttribute`. - **IID table and error helpers** (`WindowsRuntime.InteropServices`) — `WellKnownInterfaceIIDs` (the generator emits `get_IID(...)` calls and reads the reserved-IID set) and `RestrictedErrorInfo` (`ThrowExceptionForHR`, etc., used in generated async/collection bodies to translate HRESULTs to exceptions). Because these APIs are absent from the `WinRT.Runtime.dll` reference assembly, the generated `WinRT.Interop.dll` references types that exist only in the implementation assembly, and the generator emits assembly-level `[IgnoresAccessChecksTo]` to reach the non-public members among them. This is also why `cswinrtinteropgen` must be version-matched to the `WinRT.Runtime.dll` it targets (see "Version compatibility" above): the shape of these types can change at any time. diff --git a/.github/skills/interop-generator/references/name-mangling-scheme.md b/.github/skills/interop-generator/references/name-mangling-scheme.md index 9db179e955..fe3dcdcd6f 100644 --- a/.github/skills/interop-generator/references/name-mangling-scheme.md +++ b/.github/skills/interop-generator/references/name-mangling-scheme.md @@ -38,7 +38,7 @@ These are the well-known assemblies and their compact identifiers: Compact identifiers are prefixed with `#` to distinguish them from user-defined assembly names. -For types not belonging to any well-known assembly, the implementation also derives the assembly identifier from the type's `[WindowsRuntimeMetadata]` value (the source `.winmd` module name, i.e. its "stem") instead of the actual assembly name. This allows types carrying WinRT metadata to be identified by their canonical Windows Runtime name rather than the .NET assembly they happen to live in. The stem is read directly from the attribute when present — implementation projections, the authored component projection, and manually projected types in `WinRT.Runtime.dll` all carry it. Reference projections shipped in Windows Runtime projection NuGet packages have the attribute **stripped** (it is an implementation-only attribute, absent from the `WinRT.Runtime.dll` reference assembly they compile against); for a type defined in such a reference projection (detected via `IsReferenceProjectionWindowsRuntimeType`), the stem is instead recovered from the matching type in the third-party implementation projection (`WinRT.Projection.dll`), located through `RuntimeContext.GetLoadedAssemblies()`. This recovery is essential because the projection writer encodes that very same stem into the `[UnsafeAccessorType]` references it emits into the implementation projection, and the reference projection's own assembly name can differ from the stem (e.g. when several `.winmd` files are merged into a single projection assembly, as with WinUI / Windows App SDK). If the stem cannot be found anywhere, the raw assembly name is used as-is. The recovery logic lives in `GetWindowsRuntimeMetadataName` (`src/WinRT.Interop.Generator/Extensions/WindowsRuntimeExtensions.cs`). +For types not belonging to any well-known assembly, the implementation also derives the assembly identifier from the type's source `.winmd` module name (its "stem") instead of the actual assembly name. This allows types carrying WinRT metadata to be identified by their canonical Windows Runtime name rather than the .NET assembly they happen to live in. The stem is no longer stored on each projected type; it is recorded on a single centralized, trimmable lookup type — `ABI.WindowsRuntimeMetadataTypes` — which carries one `[WindowsRuntimeMetadata(typeof(T), "stem")]` entry per projected type, emitted into the implementation projection by the projection writer. `GetWindowsRuntimeMetadataName` selects the right implementation projection for the type (via `GetImplementationProjectionModule`: the Windows SDK, Windows SDK XAML, or merged third-party projection) and looks the type up by namespace and name in that module's `GetWindowsRuntimeMetadataTypesLookup()` (a cached read of the lookup type's attributes). This works uniformly for types resolved from implementation projections and from reference projections, since both select the same implementation projection that carries the lookup type. This stem is the authoritative value the projection writer encodes into the `[UnsafeAccessorType]` references it emits into that same implementation projection, and the projection's own assembly name can differ from the stem (e.g. when several `.winmd` files are merged into a single projection assembly, as with WinUI / Windows App SDK). If the stem cannot be found, the raw assembly name is used as-is. The lookup logic lives in `GetWindowsRuntimeMetadataName` (`src/WinRT.Interop.Generator/Extensions/WindowsRuntimeExtensions.cs`) and `GetWindowsRuntimeMetadataTypesLookup` (`ModuleDefinitionExtensions.WindowsRuntimeMetadataTypesLookup.cs`). > [!NOTE] > Not all BCL types live in `System.Runtime`. For example, the `System.Numerics` types (`Matrix3x2`, `Matrix4x4`, `Plane`, `Quaternion`, `Vector2`, `Vector3`, `Vector4`) are in the `System.Numerics.Vectors` assembly, so their assembly identifier is `System-Numerics-Vectors` (not `#corlib`) after the `.` → `-` substitution. The assembly used is always the one from the type's actual metadata scope, not the namespace. diff --git a/src/WinRT.Interop.Generator/Builders/DynamicCustomMappedTypeMapEntriesBuilder.cs b/src/WinRT.Interop.Generator/Builders/DynamicCustomMappedTypeMapEntriesBuilder.cs index e93ecaa7b8..e61de0b1a5 100644 --- a/src/WinRT.Interop.Generator/Builders/DynamicCustomMappedTypeMapEntriesBuilder.cs +++ b/src/WinRT.Interop.Generator/Builders/DynamicCustomMappedTypeMapEntriesBuilder.cs @@ -604,7 +604,7 @@ private static void IBindableVectorViewType( // Define the type map entries. We only need one in the marshalling external type map. We can use 'IEnumerable' // as the trim target for the specialized RCW type (since the 'IReadOnlyList' interface does not exist in .NET). - // This is also why we don't need to emit the '[WindowsRuntimeMappedMetadata]' attribute on the proxy type above. + // This is also why we don't need to emit the '[WindowsRuntimeType]' marker on the proxy type above. InteropTypeDefinitionBuilder.TypeMapAttributes( runtimeClassName: runtimeClassName, metadataTypeName: null, diff --git a/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.SzArray.cs b/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.SzArray.cs index 36c8df6095..e33e620b01 100644 --- a/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.SzArray.cs +++ b/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.SzArray.cs @@ -572,8 +572,8 @@ public static void Proxy( bool useWindowsUIXamlProjections, out TypeDefinition proxyType) { - // This is a proxy for Windows Runtime arrays, so we also need to emit the '[WindowsRuntimeMappedMetadata]' - // attribute, so that during 'TypeName' marshalling we can detect whether the type is a metadata type. Note + // This is a proxy for Windows Runtime arrays, so we also need to emit the '[WindowsRuntimeType]' + // marker, so that during 'TypeName' marshalling we can detect whether the type is a metadata type. Note // that arrays with element types that are not Windows Runtime types will still have entries in the marshalling // type map (as they're treated the same as normal user-defined types), so this allows us to distinguish them. InteropTypeDefinitionBuilder.Proxy( diff --git a/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.cs b/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.cs index c179c5295d..640e59266d 100644 --- a/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.cs +++ b/src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.cs @@ -750,7 +750,7 @@ public static void Proxy( /// /// The namespace for the type. /// The type name. - /// The name of the mapped metadata for the proxy type (if , the attribute will be omitted). + /// Signals whether the proxy represents a Windows Runtime metadata type: when non-, the [WindowsRuntimeType] marker is emitted (the string value itself is not emitted; the runtime only checks for the marker's presence). When , no marker is emitted. /// The runtime class name for the managed type (if , the attribute will be omitted). /// The metadata type name for the managed type (if , the attribute will be omitted). /// The for the mapped type the proxy type is for (if , the attribute will be omitted). @@ -781,14 +781,13 @@ public static void Proxy( module.TopLevelTypes.Add(proxyType); - // Add the '[WindowsRuntimeMappedMetadata]' attribute with the provided .winmd name, if available + // Mark metadata-type proxies with '[WindowsRuntimeType]' (the runtime only checks for its presence). + // Proxies that don't represent a Windows Runtime metadata type (mappedMetadata is null) stay unmarked. if (mappedMetadata is not null) { proxyType.CustomAttributes.Add(new CustomAttribute( - constructor: interopReferences.WindowsRuntimeMappedMetadataAttribute_ctor, - signature: new CustomAttributeSignature(new CustomAttributeArgument( - argumentType: interopReferences.String, - value: mappedMetadata)))); + constructor: interopReferences.WindowsRuntimeTypeAttribute_ctor, + signature: new CustomAttributeSignature())); } // Add the '[WindowsRuntimeClassName]' attribute with the provided runtime class name, if available diff --git a/src/WinRT.Interop.Generator/Extensions/ModuleDefinitionExtensions.WindowsRuntimeMetadataTypesLookup.cs b/src/WinRT.Interop.Generator/Extensions/ModuleDefinitionExtensions.WindowsRuntimeMetadataTypesLookup.cs new file mode 100644 index 0000000000..f948d4009e --- /dev/null +++ b/src/WinRT.Interop.Generator/Extensions/ModuleDefinitionExtensions.WindowsRuntimeMetadataTypesLookup.cs @@ -0,0 +1,83 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +using System; +using System.Collections.Frozen; +using System.Collections.Generic; +using System.Runtime.CompilerServices; +using AsmResolver; +using AsmResolver.DotNet; +using AsmResolver.DotNet.Signatures; + +namespace WindowsRuntime.InteropGenerator; + +/// +internal partial class ModuleDefinitionExtensions +{ + /// + /// Gets a lookup of source .winmd module names ("stems") for projected Windows Runtime types in a given + /// module. The lookup is built from the [WindowsRuntimeMetadata] attributes on the + /// WindowsRuntimeMetadataTypes type in the ABI namespace. The resulting dictionary maps projected + /// types (by namespace and name) to their source .winmd stem. + /// + /// The input instance. + /// The resulting metadata-types lookup. + public static IReadOnlyDictionary<(Utf8String? Namespace, Utf8String? Name), Utf8String> GetWindowsRuntimeMetadataTypesLookup(this ModuleDefinition module) + { + return WindowsRuntimeMetadataTypesLookupCache.Instance.GetOrAdd( + key: module, + valueFactory: static module => + { + TypeDefinition? windowsRuntimeMetadataTypesType = null; + + // Find the 'WindowsRuntimeMetadataTypes' lookup type in the ABI namespace + foreach (TypeDefinition type in module.TopLevelTypes) + { + // Rather than using the lookup, which we don't really need here since we're only + // doing a single find operation, we just scan the types to find the one we need. + if (type.Namespace is Utf8String ns && ns.AsSpan().SequenceEqual("ABI"u8) && + type.Name is Utf8String name && name.AsSpan().SequenceEqual("WindowsRuntimeMetadataTypes"u8)) + { + windowsRuntimeMetadataTypesType = type; + + break; + } + } + + // We didn't find the target type, so this module is likely invalid. We don't need + // to do anything here, lookups would just fail and report the correct diagnostics. + if (windowsRuntimeMetadataTypesType is null) + { + return FrozenDictionary<(Utf8String?, Utf8String?), Utf8String>.Empty; + } + + Dictionary<(Utf8String?, Utf8String?), Utf8String> builder = []; + + // Enumerate all attributes on the lookup type and extract projected type to .winmd stem pairs + foreach (CustomAttribute attribute in windowsRuntimeMetadataTypesType.CustomAttributes) + { + // Match '[WindowsRuntimeMetadata(typeof(), "")]' + if (attribute.Signature is not { FixedArguments: [{ Element: TypeSignature projectedType }, { Element: Utf8String stem }] }) + { + continue; + } + + // Add the current pair to the map we're building + builder[(projectedType.Namespace, projectedType.Name)] = stem; + } + + return builder.ToFrozenDictionary(); + }); + } +} + +/// +/// Contains a shared cache of metadata-types lookups, to speed up search operations. +/// +file static class WindowsRuntimeMetadataTypesLookupCache +{ + /// + /// The singleton metadata-types lookups map. + /// + public static readonly ConditionalWeakTable> Instance = []; +} diff --git a/src/WinRT.Interop.Generator/Extensions/WindowsRuntimeExtensions.cs b/src/WinRT.Interop.Generator/Extensions/WindowsRuntimeExtensions.cs index 9dac091225..8210ccb4d4 100644 --- a/src/WinRT.Interop.Generator/Extensions/WindowsRuntimeExtensions.cs +++ b/src/WinRT.Interop.Generator/Extensions/WindowsRuntimeExtensions.cs @@ -25,7 +25,7 @@ internal static class WindowsRuntimeExtensions /// Checks whether a represents a projected Windows Runtime type. /// /// Whether the type represents a projected Windows Runtime type. - public bool IsProjectedWindowsRuntimeType => member.HasCustomAttribute(WellKnownMetadataNames.WindowsRuntime, WellKnownMetadataNames.WindowsRuntimeMetadataAttribute); + public bool IsProjectedWindowsRuntimeType => member.HasCustomAttribute(WellKnownMetadataNames.WindowsRuntime, WellKnownMetadataNames.WindowsRuntimeTypeAttribute); /// /// Checks whether a (expected to be an ) represents a Windows Runtime reference assembly. @@ -778,61 +778,30 @@ public bool IsWindowsRuntimeManagedOnlyType(InteropReferences interopReferences) } /// - /// Gets the Windows Runtime metadata name for a , if available. - /// - /// The Windows Runtime metadata name from the WindowsRuntimeMetadataAttribute, or if not found. - public Utf8String? GetWindowsRuntimeMetadataName() - { - CustomAttribute? attribute = type.FindCustomAttributes("WindowsRuntime"u8, "WindowsRuntimeMetadataAttribute"u8).FirstOrDefault(); - - return attribute?.Signature?.FixedArguments?[0]?.Element as Utf8String; - } - - /// - /// Gets the Windows Runtime metadata name for a , recovering it from the - /// implementation projection when the type comes from a reference projection. + /// Gets the Windows Runtime metadata name for a (i.e. the source .winmd module name). /// /// The instance to use. - /// The Windows Runtime metadata name (i.e. the source .winmd module name), or if not found. + /// The Windows Runtime metadata name, or if not found. /// /// - /// The per-type [WindowsRuntimeMetadata] attribute is present on implementation projections, the - /// authored component projection, and manually projected types in WinRT.Runtime.dll, so for those the - /// value is read directly off the type. + /// The type -> source .winmd stem mapping is no longer carried on each projected type. It lives on the + /// centralized ABI.WindowsRuntimeMetadataTypes lookup type in the implementation projection (so the + /// build-time-only metadata can be trimmed away when unused). This selects the right implementation projection for + /// the type (via ) and looks the type up by namespace and name. /// /// - /// Reference projections shipped in Windows Runtime projection NuGet packages have that attribute stripped (it - /// is an implementation-only attribute, absent from the WinRT.Runtime.dll reference assembly they compile - /// against). For a type defined in such a reference projection, the source .winmd stem is recovered from - /// the matching type in the implementation projection (located via ), - /// which retains it. That is the authoritative value the interop type-name marker must agree with: the projection - /// writer encodes the very same stem into the [UnsafeAccessorType] references it emits into that - /// implementation projection, so falling back to the reference projection's own assembly name (which can differ - /// from the stem, e.g. when several .winmd files are merged into one projection) would produce mismatched names. + /// This is the authoritative value the interop type-name marker must agree with: the projection writer encodes the + /// very same stem into the [UnsafeAccessorType] references it emits into that implementation projection. It + /// works uniformly for types resolved from implementation projections and from reference projections (the latter + /// don't carry the lookup type, but resolve to the same implementation projection that does). /// /// public Utf8String? GetWindowsRuntimeMetadataName(InteropDefinitions interopDefinitions) { - // Fast path: the attribute is present directly on the type (implementation projections, authored - // components, and 'WinRT.Runtime.dll' types all carry '[WindowsRuntimeMetadata]'). - if (type.GetWindowsRuntimeMetadataName() is { } metadataName) - { - return metadataName; - } - - // The only remaining case we can recover is a type from a reference projection, whose per-type attribute - // was stripped. For those, the metadata name lives on the matching type in the implementation projection. - if (!type.IsReferenceProjectionWindowsRuntimeType) - { - return null; - } - - // Resolve the equivalent type in the right implementation projection (via the cached top-level types - // lookup) and read the '[WindowsRuntimeMetadata]' attribute off it, which it retains. if (type.GetImplementationProjectionModule(interopDefinitions) is { } projectionModule && - projectionModule.GetTopLevelTypesLookup().TryGetValue((type.Namespace, type.Name), out TypeDefinition? projectionType)) + projectionModule.GetWindowsRuntimeMetadataTypesLookup().TryGetValue((type.Namespace, type.Name), out Utf8String? metadataName)) { - return projectionType.GetWindowsRuntimeMetadataName(); + return metadataName; } return null; @@ -1259,9 +1228,9 @@ file static class WellKnownMetadataNames public static readonly Utf8String WindowsRuntimeInteropServices = "WindowsRuntime.InteropServices"u8; /// - /// The "WindowsRuntimeMetadataAttribute" text. + /// The "WindowsRuntimeTypeAttribute" text. /// - public static readonly Utf8String WindowsRuntimeMetadataAttribute = "WindowsRuntimeMetadataAttribute"u8; + public static readonly Utf8String WindowsRuntimeTypeAttribute = "WindowsRuntimeTypeAttribute"u8; /// /// The "WindowsRuntimeReferenceAssemblyAttribute" text. diff --git a/src/WinRT.Interop.Generator/References/InteropReferences.cs b/src/WinRT.Interop.Generator/References/InteropReferences.cs index 77c1e2ed9d..0f06e9cfed 100644 --- a/src/WinRT.Interop.Generator/References/InteropReferences.cs +++ b/src/WinRT.Interop.Generator/References/InteropReferences.cs @@ -721,14 +721,9 @@ public InteropReferences( public TypeReference WindowsRuntimeExclusiveToInterfaceAttribute => field ??= _windowsRuntimeModule.CreateTypeReference("WindowsRuntime"u8, "WindowsRuntimeExclusiveToInterfaceAttribute"u8); /// - /// Gets the for WindowsRuntime.WindowsRuntimeMetadataAttribute. + /// Gets the for WindowsRuntime.WindowsRuntimeTypeAttribute. /// - public TypeReference WindowsRuntimeMetadataAttribute => field ??= _windowsRuntimeModule.CreateTypeReference("WindowsRuntime"u8, "WindowsRuntimeMetadataAttribute"u8); - - /// - /// Gets the for WindowsRuntime.WindowsRuntimeMappedMetadataAttribute. - /// - public TypeReference WindowsRuntimeMappedMetadataAttribute => field ??= _windowsRuntimeModule.CreateTypeReference("WindowsRuntime"u8, "WindowsRuntimeMappedMetadataAttribute"u8); + public TypeReference WindowsRuntimeTypeAttribute => field ??= _windowsRuntimeModule.CreateTypeReference("WindowsRuntime"u8, "WindowsRuntimeTypeAttribute"u8); /// /// Gets the for WindowsRuntime.WindowsRuntimeReferenceTypeAttribute. @@ -2539,12 +2534,12 @@ public InteropReferences( parameterTypes: [_corLibTypeFactory.String])); /// - /// Gets the for 's constructor. + /// Gets the for 's constructor. /// - public MemberReference WindowsRuntimeMappedMetadataAttribute_ctor => field ??= WindowsRuntimeMappedMetadataAttribute + public MemberReference WindowsRuntimeTypeAttribute_ctor => field ??= WindowsRuntimeTypeAttribute .CreateMemberReference(".ctor", MethodSignature.CreateInstance( returnType: _corLibTypeFactory.Void, - parameterTypes: [_corLibTypeFactory.String])); + parameterTypes: [])); /// /// Gets the for 's constructor. diff --git a/src/WinRT.Projection.Writer/Factories/MetadataAttributeFactory.cs b/src/WinRT.Projection.Writer/Factories/MetadataAttributeFactory.cs index cc3ba08608..0439b03e73 100644 --- a/src/WinRT.Projection.Writer/Factories/MetadataAttributeFactory.cs +++ b/src/WinRT.Projection.Writer/Factories/MetadataAttributeFactory.cs @@ -79,7 +79,8 @@ public static string GetFileHeader() } /// - /// Writes a [WindowsRuntimeMetadata("<stem>")] attribute decorating with its source .winmd module name. + /// Writes the per-type [WindowsRuntimeType] marker decorating , and records the + /// type's source .winmd stem into the centralized metadata-types map for later emission. /// Skipped entirely in reference-projection mode. /// /// The writer to emit to. @@ -98,18 +99,20 @@ public static void WriteWinRTMetadataAttribute(IndentedTextWriter writer, Projec } /// - /// A callback emitting the attribute body (no trailing newline) so it can be interpolated into a multiline template. Emits nothing in reference-projection mode. + /// A callback emitting the marker (no trailing newline) so it can be interpolated into a multiline template. Emits nothing in reference-projection mode. public static IndentedTextWriterCallback WriteWinRTMetadataAttribute(ProjectionEmitContext context, TypeDefinition type) { return writer => WriteWinRTMetadataAttributeBody(writer, context, type); } /// - /// Writes just the attribute body (no trailing newline) for . - /// In reference-projection mode this emits nothing: [WindowsRuntimeMetadata] is an implementation-only - /// type, stripped from the WinRT.Runtime reference assembly that a reference projection compiles against. - /// It is only consumed (by the interop generator) from implementation projections, never from the reference - /// projections shipped in Windows Runtime projection NuGet packages. + /// Writes just the marker body (no trailing newline) for , + /// and records the type's source .winmd stem into + /// for the centralized ABI.WindowsRuntimeMetadataTypes lookup type. + /// In reference-projection mode this emits nothing and records nothing: [WindowsRuntimeType] is an + /// implementation-only type, stripped from the WinRT.Runtime reference assembly that a reference projection + /// compiles against. It is only consumed (by the interop generator) from implementation projections, never from the + /// reference projections shipped in Windows Runtime projection NuGet packages. /// internal static void WriteWinRTMetadataAttributeBody(IndentedTextWriter writer, ProjectionEmitContext context, TypeDefinition type) { @@ -118,9 +121,19 @@ internal static void WriteWinRTMetadataAttributeBody(IndentedTextWriter writer, return; } - string path = context.Cache.GetSourcePath(type); - string stem = string.IsNullOrEmpty(path) ? string.Empty : Path.GetFileNameWithoutExtension(path); - writer.Write($"[WindowsRuntimeMetadata(\"{stem}\")]"); + writer.Write("[WindowsRuntimeType]"); + + // Record the type -> .winmd-stem mapping for the centralized lookup type. The metadata value is build-time + // only (consumed by the interop generator), so keeping it off the type itself lets it be trimmed away. + if (context.WindowsRuntimeMetadataTypeEntries is { } entries) + { + string path = context.Cache.GetSourcePath(type); + string stem = string.IsNullOrEmpty(path) ? string.Empty : Path.GetFileNameWithoutExtension(path); + (string typeNs, string typeName) = type.Names(); + string globalName = TypedefNameWriter.BuildGlobalQualifiedName(typeNs, typeName); + + _ = entries.TryAdd(globalName, stem); + } } /// @@ -537,6 +550,43 @@ public static void WriteExclusiveToInterfacesClass(Settings settings, IReadOnlyL WriteInterfaceMapClass(settings, sortedEntries, "WindowsRuntimeExclusiveToInterface", "WindowsRuntimeExclusiveToInterfaces", "WindowsRuntimeExclusiveToInterfaces.cs"); } + /// + /// Writes the generated WindowsRuntimeMetadataTypes.cs file: an ABI namespace-level static class + /// decorated with one [WindowsRuntimeMetadata(typeof(<type>), "<stem>")] per projected type, + /// mapping it to the source .winmd module name. This centralizes the (build-time only) metadata mapping so + /// it can be trimmed away when not needed, mirroring . + /// + /// The active projection settings. + /// The (projected-type-name -> .winmd stem) entries, sorted for determinism. + public static void WriteWindowsRuntimeMetadataTypesClass(Settings settings, IReadOnlyList> sortedEntries) + { + if (sortedEntries.Count == 0) + { + return; + } + + using IndentedTextWriterOwner wOwner = IndentedTextWriterPool.GetOrCreate(); + IndentedTextWriter w = wOwner.Writer; + WriteFileHeader(w); + w.WriteLine("using System;"); + w.WriteLine("using WindowsRuntime;"); + w.WriteLine(); + w.WriteLine("#pragma warning disable CSWINRT3001"); + w.WriteLine(); + w.WriteLine("namespace ABI"); + using (w.WriteBlock()) + { + foreach (KeyValuePair kv in sortedEntries) + { + w.WriteLine($"[WindowsRuntimeMetadata(typeof({kv.Key}), \"{kv.Value}\")]"); + } + + w.WriteLine("internal static class WindowsRuntimeMetadataTypes;"); + } + + w.FlushToFile(Path.Combine(settings.OutputFolder, "WindowsRuntimeMetadataTypes.cs")); + } + /// /// Shared template for emitting an ABI namespace-level static class decorated with one /// per entry from (mapping diff --git a/src/WinRT.Projection.Writer/Generation/ProjectionEmitContext.cs b/src/WinRT.Projection.Writer/Generation/ProjectionEmitContext.cs index 1be2c4aa9e..5b2df98626 100644 --- a/src/WinRT.Projection.Writer/Generation/ProjectionEmitContext.cs +++ b/src/WinRT.Projection.Writer/Generation/ProjectionEmitContext.cs @@ -2,6 +2,7 @@ // Licensed under the MIT License. using System; +using System.Collections.Concurrent; using WindowsRuntime.ProjectionWriter.Metadata; using WindowsRuntime.ProjectionWriter.Resolvers; @@ -14,7 +15,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 (projected-type-name -> source .winmd stem) map to record into while emitting per-type markers, or outside the per-namespace type-emission pass. +internal sealed class ProjectionEmitContext( + Settings settings, + MetadataCache cache, + string currentNamespace, + ConcurrentDictionary? windowsRuntimeMetadataTypeEntries = null) { /// /// Gets the active projection settings. @@ -31,6 +37,13 @@ internal sealed class ProjectionEmitContext(Settings settings, MetadataCache cac /// public string CurrentNamespace { get; } = currentNamespace; + /// + /// Gets the (projected-type-name -> source .winmd stem) map that per-type marker emission records into, + /// or when not in the per-namespace type-emission pass. Emitted at the end of generation + /// as the centralized ABI.WindowsRuntimeMetadataTypes lookup type. + /// + public ConcurrentDictionary? WindowsRuntimeMetadataTypeEntries { get; } = windowsRuntimeMetadataTypeEntries; + /// /// Gets a value indicating whether the writer is currently emitting inside an /// ABI.<Ns> namespace block. Set by diff --git a/src/WinRT.Projection.Writer/Generation/ProjectionGenerator.Namespace.cs b/src/WinRT.Projection.Writer/Generation/ProjectionGenerator.Namespace.cs index 5275e36818..5a347301a4 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, state.WindowsRuntimeMetadataTypeEntries); 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..2fb4a1568d 100644 --- a/src/WinRT.Projection.Writer/Generation/ProjectionGenerator.cs +++ b/src/WinRT.Projection.Writer/Generation/ProjectionGenerator.cs @@ -112,6 +112,13 @@ public void Run() MetadataAttributeFactory.WriteDefaultInterfacesClass(_settings, sorted); } + if (state.WindowsRuntimeMetadataTypeEntries.Count > 0 && !_settings.ReferenceProjection) + { + List> sorted = [.. state.WindowsRuntimeMetadataTypeEntries]; + sorted.Sort((a, b) => StringComparer.Ordinal.Compare(a.Key, b.Key)); + MetadataAttributeFactory.WriteWindowsRuntimeMetadataTypesClass(_settings, sorted); + } + if (!state.ExclusiveToInterfaceEntries.IsEmpty && _settings.Component && !_settings.ReferenceProjection) { List> sorted = [.. state.ExclusiveToInterfaceEntries]; diff --git a/src/WinRT.Projection.Writer/Generation/ProjectionGeneratorRunState.cs b/src/WinRT.Projection.Writer/Generation/ProjectionGeneratorRunState.cs index 915781e84a..0dac3a0851 100644 --- a/src/WinRT.Projection.Writer/Generation/ProjectionGeneratorRunState.cs +++ b/src/WinRT.Projection.Writer/Generation/ProjectionGeneratorRunState.cs @@ -47,6 +47,14 @@ internal sealed class ProjectionGeneratorRunState /// public ConcurrentDictionary AuthoredTypeNameToMetadataMap { get; } = []; + /// + /// Gets the (projected-type-name -> source .winmd stem) map populated as a side effect of + /// emitting the per-type [WindowsRuntimeType] marker (see + /// ). It is emitted at the + /// end of generation as the centralized, trimmable ABI.WindowsRuntimeMetadataTypes lookup type. + /// + public ConcurrentDictionary WindowsRuntimeMetadataTypeEntries { get; } = []; + /// /// Tracked via so any number of work items can mark "I wrote a /// projection file" concurrently without a torn read. Use diff --git a/src/WinRT.Projection.Writer/Resources/Additions/Microsoft.UI.Xaml.Media.Animation/Microsoft.UI.Xaml.Media.Animation.KeyTime.cs b/src/WinRT.Projection.Writer/Resources/Additions/Microsoft.UI.Xaml.Media.Animation/Microsoft.UI.Xaml.Media.Animation.KeyTime.cs index 61e8f3509a..9d3429d4eb 100644 --- a/src/WinRT.Projection.Writer/Resources/Additions/Microsoft.UI.Xaml.Media.Animation/Microsoft.UI.Xaml.Media.Animation.KeyTime.cs +++ b/src/WinRT.Projection.Writer/Resources/Additions/Microsoft.UI.Xaml.Media.Animation/Microsoft.UI.Xaml.Media.Animation.KeyTime.cs @@ -3,8 +3,8 @@ namespace Microsoft.UI.Xaml.Media.Animation { using global::Windows.Foundation; - [WindowsRuntimeMetadata("Microsoft.UI")] #if !CSWINRT_REFERENCE_PROJECTION + [WindowsRuntimeType] [WindowsRuntimeClassName("Windows.Foundation.IReference`1")] [ABI.Microsoft.UI.Xaml.Media.Animation.KeyTimeComWrappersMarshaller] #endif diff --git a/src/WinRT.Projection.Writer/Resources/Additions/Microsoft.UI.Xaml.Media.Animation/Microsoft.UI.Xaml.Media.Animation.RepeatBehavior.cs b/src/WinRT.Projection.Writer/Resources/Additions/Microsoft.UI.Xaml.Media.Animation/Microsoft.UI.Xaml.Media.Animation.RepeatBehavior.cs index 972909273e..314ace50e7 100644 --- a/src/WinRT.Projection.Writer/Resources/Additions/Microsoft.UI.Xaml.Media.Animation/Microsoft.UI.Xaml.Media.Animation.RepeatBehavior.cs +++ b/src/WinRT.Projection.Writer/Resources/Additions/Microsoft.UI.Xaml.Media.Animation/Microsoft.UI.Xaml.Media.Animation.RepeatBehavior.cs @@ -3,8 +3,8 @@ namespace Microsoft.UI.Xaml.Media.Animation { using global::Windows.Foundation; - [WindowsRuntimeMetadata("Microsoft.UI")] #if !CSWINRT_REFERENCE_PROJECTION + [WindowsRuntimeType] [WindowsRuntimeClassName("Windows.Foundation.IReference`1")] [ABI.Microsoft.UI.Xaml.Media.Animation.RepeatBehaviorComWrappersMarshaller] #endif diff --git a/src/WinRT.Projection.Writer/Resources/Additions/Microsoft.UI.Xaml.Media.Media3D/Microsoft.UI.Xaml.Media.Media3D.Matrix3D.cs b/src/WinRT.Projection.Writer/Resources/Additions/Microsoft.UI.Xaml.Media.Media3D/Microsoft.UI.Xaml.Media.Media3D.Matrix3D.cs index 873cc52c02..79c8cf5ea7 100644 --- a/src/WinRT.Projection.Writer/Resources/Additions/Microsoft.UI.Xaml.Media.Media3D/Microsoft.UI.Xaml.Media.Media3D.Matrix3D.cs +++ b/src/WinRT.Projection.Writer/Resources/Additions/Microsoft.UI.Xaml.Media.Media3D/Microsoft.UI.Xaml.Media.Media3D.Matrix3D.cs @@ -3,8 +3,8 @@ namespace Microsoft.UI.Xaml.Media.Media3D { using global::Windows.Foundation; - [WindowsRuntimeMetadata("Microsoft.UI")] #if !CSWINRT_REFERENCE_PROJECTION + [WindowsRuntimeType] [WindowsRuntimeClassName("Windows.Foundation.IReference`1")] [ABI.Microsoft.UI.Xaml.Media.Media3D.Matrix3DComWrappersMarshaller] #endif diff --git a/src/WinRT.Projection.Writer/Resources/Additions/Microsoft.UI.Xaml/Microsoft.UI.Xaml.CornerRadius.cs b/src/WinRT.Projection.Writer/Resources/Additions/Microsoft.UI.Xaml/Microsoft.UI.Xaml.CornerRadius.cs index 539d6ac177..c9113ca314 100644 --- a/src/WinRT.Projection.Writer/Resources/Additions/Microsoft.UI.Xaml/Microsoft.UI.Xaml.CornerRadius.cs +++ b/src/WinRT.Projection.Writer/Resources/Additions/Microsoft.UI.Xaml/Microsoft.UI.Xaml.CornerRadius.cs @@ -3,8 +3,8 @@ namespace Microsoft.UI.Xaml { using global::Windows.Foundation; - [WindowsRuntimeMetadata("Microsoft.UI")] #if !CSWINRT_REFERENCE_PROJECTION + [WindowsRuntimeType] [WindowsRuntimeClassName("Windows.Foundation.IReference`1")] [ABI.Microsoft.UI.Xaml.CornerRadiusComWrappersMarshaller] #endif diff --git a/src/WinRT.Projection.Writer/Resources/Additions/Microsoft.UI.Xaml/Microsoft.UI.Xaml.Duration.cs b/src/WinRT.Projection.Writer/Resources/Additions/Microsoft.UI.Xaml/Microsoft.UI.Xaml.Duration.cs index 524df87d27..d44f825ea0 100644 --- a/src/WinRT.Projection.Writer/Resources/Additions/Microsoft.UI.Xaml/Microsoft.UI.Xaml.Duration.cs +++ b/src/WinRT.Projection.Writer/Resources/Additions/Microsoft.UI.Xaml/Microsoft.UI.Xaml.Duration.cs @@ -3,8 +3,8 @@ namespace Microsoft.UI.Xaml { using global::Windows.Foundation; - [WindowsRuntimeMetadata("Microsoft.UI")] #if !CSWINRT_REFERENCE_PROJECTION + [WindowsRuntimeType] [WindowsRuntimeClassName("Windows.Foundation.IReference`1")] [ABI.Microsoft.UI.Xaml.DurationComWrappersMarshaller] #endif diff --git a/src/WinRT.Projection.Writer/Resources/Additions/Microsoft.UI.Xaml/Microsoft.UI.Xaml.GridLength.cs b/src/WinRT.Projection.Writer/Resources/Additions/Microsoft.UI.Xaml/Microsoft.UI.Xaml.GridLength.cs index 78a1fabadb..76dd7f1140 100644 --- a/src/WinRT.Projection.Writer/Resources/Additions/Microsoft.UI.Xaml/Microsoft.UI.Xaml.GridLength.cs +++ b/src/WinRT.Projection.Writer/Resources/Additions/Microsoft.UI.Xaml/Microsoft.UI.Xaml.GridLength.cs @@ -3,8 +3,8 @@ namespace Microsoft.UI.Xaml { using global::Windows.Foundation; - [WindowsRuntimeMetadata("Microsoft.UI")] #if !CSWINRT_REFERENCE_PROJECTION + [WindowsRuntimeType] [WindowsRuntimeClassName("Windows.Foundation.IReference`1")] [ABI.Microsoft.UI.Xaml.GridLengthComWrappersMarshaller] #endif diff --git a/src/WinRT.Projection.Writer/Resources/Additions/Windows.UI.Xaml.Media.Animation/Windows.UI.Xaml.Media.Animation.KeyTime.cs b/src/WinRT.Projection.Writer/Resources/Additions/Windows.UI.Xaml.Media.Animation/Windows.UI.Xaml.Media.Animation.KeyTime.cs index 0b5d196c20..24c8e73261 100644 --- a/src/WinRT.Projection.Writer/Resources/Additions/Windows.UI.Xaml.Media.Animation/Windows.UI.Xaml.Media.Animation.KeyTime.cs +++ b/src/WinRT.Projection.Writer/Resources/Additions/Windows.UI.Xaml.Media.Animation/Windows.UI.Xaml.Media.Animation.KeyTime.cs @@ -3,8 +3,8 @@ namespace Windows.UI.Xaml.Media.Animation { using global::Windows.Foundation; - [WindowsRuntimeMetadata("Windows.Foundation.UniversalApiContract")] #if !CSWINRT_REFERENCE_PROJECTION + [WindowsRuntimeType] [WindowsRuntimeClassName("Windows.Foundation.IReference`1")] [ABI.Windows.UI.Xaml.Media.Animation.KeyTimeComWrappersMarshaller] #endif diff --git a/src/WinRT.Projection.Writer/Resources/Additions/Windows.UI.Xaml.Media.Animation/Windows.UI.Xaml.Media.Animation.RepeatBehavior.cs b/src/WinRT.Projection.Writer/Resources/Additions/Windows.UI.Xaml.Media.Animation/Windows.UI.Xaml.Media.Animation.RepeatBehavior.cs index c19f73bc48..0f867a6b91 100644 --- a/src/WinRT.Projection.Writer/Resources/Additions/Windows.UI.Xaml.Media.Animation/Windows.UI.Xaml.Media.Animation.RepeatBehavior.cs +++ b/src/WinRT.Projection.Writer/Resources/Additions/Windows.UI.Xaml.Media.Animation/Windows.UI.Xaml.Media.Animation.RepeatBehavior.cs @@ -3,8 +3,8 @@ namespace Windows.UI.Xaml.Media.Animation { using global::Windows.Foundation; - [WindowsRuntimeMetadata("Windows.Foundation.UniversalApiContract")] #if !CSWINRT_REFERENCE_PROJECTION + [WindowsRuntimeType] [WindowsRuntimeClassName("Windows.Foundation.IReference`1")] [ABI.Windows.UI.Xaml.Media.Animation.RepeatBehaviorComWrappersMarshaller] #endif diff --git a/src/WinRT.Projection.Writer/Resources/Additions/Windows.UI.Xaml.Media.Media3D/Windows.UI.Xaml.Media.Media3D.Matrix3D.cs b/src/WinRT.Projection.Writer/Resources/Additions/Windows.UI.Xaml.Media.Media3D/Windows.UI.Xaml.Media.Media3D.Matrix3D.cs index f11fe74cbb..34c82130d8 100644 --- a/src/WinRT.Projection.Writer/Resources/Additions/Windows.UI.Xaml.Media.Media3D/Windows.UI.Xaml.Media.Media3D.Matrix3D.cs +++ b/src/WinRT.Projection.Writer/Resources/Additions/Windows.UI.Xaml.Media.Media3D/Windows.UI.Xaml.Media.Media3D.Matrix3D.cs @@ -3,8 +3,8 @@ namespace Windows.UI.Xaml.Media.Media3D { using global::Windows.Foundation; - [WindowsRuntimeMetadata("Windows.Foundation.UniversalApiContract")] #if !CSWINRT_REFERENCE_PROJECTION + [WindowsRuntimeType] [WindowsRuntimeClassName("Windows.Foundation.IReference`1")] [ABI.Windows.UI.Xaml.Media.Media3D.Matrix3DComWrappersMarshaller] #endif diff --git a/src/WinRT.Projection.Writer/Resources/Additions/Windows.UI.Xaml/Windows.UI.Xaml.CornerRadius.cs b/src/WinRT.Projection.Writer/Resources/Additions/Windows.UI.Xaml/Windows.UI.Xaml.CornerRadius.cs index 0e51a5163c..03bf3c2650 100644 --- a/src/WinRT.Projection.Writer/Resources/Additions/Windows.UI.Xaml/Windows.UI.Xaml.CornerRadius.cs +++ b/src/WinRT.Projection.Writer/Resources/Additions/Windows.UI.Xaml/Windows.UI.Xaml.CornerRadius.cs @@ -3,8 +3,8 @@ namespace Windows.UI.Xaml { using global::Windows.Foundation; - [WindowsRuntimeMetadata("Windows.Foundation.UniversalApiContract")] #if !CSWINRT_REFERENCE_PROJECTION + [WindowsRuntimeType] [WindowsRuntimeClassName("Windows.Foundation.IReference`1")] [ABI.Windows.UI.Xaml.CornerRadiusComWrappersMarshaller] #endif diff --git a/src/WinRT.Projection.Writer/Resources/Additions/Windows.UI.Xaml/Windows.UI.Xaml.Duration.cs b/src/WinRT.Projection.Writer/Resources/Additions/Windows.UI.Xaml/Windows.UI.Xaml.Duration.cs index d8dd051cb9..095ed31f36 100644 --- a/src/WinRT.Projection.Writer/Resources/Additions/Windows.UI.Xaml/Windows.UI.Xaml.Duration.cs +++ b/src/WinRT.Projection.Writer/Resources/Additions/Windows.UI.Xaml/Windows.UI.Xaml.Duration.cs @@ -3,8 +3,8 @@ namespace Windows.UI.Xaml { using global::Windows.Foundation; - [WindowsRuntimeMetadata("Windows.Foundation.UniversalApiContract")] #if !CSWINRT_REFERENCE_PROJECTION + [WindowsRuntimeType] [WindowsRuntimeClassName("Windows.Foundation.IReference`1")] [ABI.Windows.UI.Xaml.DurationComWrappersMarshaller] #endif diff --git a/src/WinRT.Projection.Writer/Resources/Additions/Windows.UI.Xaml/Windows.UI.Xaml.GridLength.cs b/src/WinRT.Projection.Writer/Resources/Additions/Windows.UI.Xaml/Windows.UI.Xaml.GridLength.cs index 15be3b17a7..63ce9d3d13 100644 --- a/src/WinRT.Projection.Writer/Resources/Additions/Windows.UI.Xaml/Windows.UI.Xaml.GridLength.cs +++ b/src/WinRT.Projection.Writer/Resources/Additions/Windows.UI.Xaml/Windows.UI.Xaml.GridLength.cs @@ -3,8 +3,8 @@ namespace Windows.UI.Xaml { using global::Windows.Foundation; - [WindowsRuntimeMetadata("Windows.Foundation.UniversalApiContract")] #if !CSWINRT_REFERENCE_PROJECTION + [WindowsRuntimeType] [WindowsRuntimeClassName("Windows.Foundation.IReference`1")] [ABI.Windows.UI.Xaml.GridLengthComWrappersMarshaller] #endif diff --git a/src/WinRT.Runtime2/ABI/System/Boolean.cs b/src/WinRT.Runtime2/ABI/System/Boolean.cs index 6d993add02..7e0f60ae72 100644 --- a/src/WinRT.Runtime2/ABI/System/Boolean.cs +++ b/src/WinRT.Runtime2/ABI/System/Boolean.cs @@ -31,7 +31,7 @@ namespace ABI.System; /// /// ABI type for . /// -[WindowsRuntimeMappedMetadata("Windows.Foundation.FoundationContract")] +[WindowsRuntimeType] [WindowsRuntimeClassName("Windows.Foundation.IReference`1")] [WindowsRuntimeMetadataTypeName("Boolean")] [WindowsRuntimeMappedType(typeof(bool))] diff --git a/src/WinRT.Runtime2/ABI/System/Byte.cs b/src/WinRT.Runtime2/ABI/System/Byte.cs index d9cbee4b33..263ce7f116 100644 --- a/src/WinRT.Runtime2/ABI/System/Byte.cs +++ b/src/WinRT.Runtime2/ABI/System/Byte.cs @@ -31,7 +31,7 @@ namespace ABI.System; /// /// ABI type for . /// -[WindowsRuntimeMappedMetadata("Windows.Foundation.FoundationContract")] +[WindowsRuntimeType] [WindowsRuntimeClassName("Windows.Foundation.IReference`1")] [WindowsRuntimeMetadataTypeName("UInt8")] [WindowsRuntimeMappedType(typeof(byte))] diff --git a/src/WinRT.Runtime2/ABI/System/Char.cs b/src/WinRT.Runtime2/ABI/System/Char.cs index f6d3f6a9a5..2a82e90607 100644 --- a/src/WinRT.Runtime2/ABI/System/Char.cs +++ b/src/WinRT.Runtime2/ABI/System/Char.cs @@ -31,7 +31,7 @@ namespace ABI.System; /// /// ABI type for . /// -[WindowsRuntimeMappedMetadata("Windows.Foundation.FoundationContract")] +[WindowsRuntimeType] [WindowsRuntimeClassName("Windows.Foundation.IReference`1")] [WindowsRuntimeMetadataTypeName("Char16")] [WindowsRuntimeMappedType(typeof(char))] diff --git a/src/WinRT.Runtime2/ABI/System/ComponentModel/DataErrorsChangedEventArgs.cs b/src/WinRT.Runtime2/ABI/System/ComponentModel/DataErrorsChangedEventArgs.cs index 19925235f7..253c686e46 100644 --- a/src/WinRT.Runtime2/ABI/System/ComponentModel/DataErrorsChangedEventArgs.cs +++ b/src/WinRT.Runtime2/ABI/System/ComponentModel/DataErrorsChangedEventArgs.cs @@ -25,7 +25,7 @@ namespace ABI.System.ComponentModel; /// ABI type for . /// /// -[WindowsRuntimeMappedMetadata("Microsoft.UI.Xaml.WinUIContract")] +[WindowsRuntimeType] [WindowsRuntimeClassName("Microsoft.UI.Xaml.Data.DataErrorsChangedEventArgs")] [WindowsRuntimeMappedType(typeof(global::System.ComponentModel.DataErrorsChangedEventArgs))] [DataErrorsChangedEventArgsComWrappersMarshaller] diff --git a/src/WinRT.Runtime2/ABI/System/ComponentModel/INotifyDataErrorInfo.cs b/src/WinRT.Runtime2/ABI/System/ComponentModel/INotifyDataErrorInfo.cs index 7a22da264b..6271cd5369 100644 --- a/src/WinRT.Runtime2/ABI/System/ComponentModel/INotifyDataErrorInfo.cs +++ b/src/WinRT.Runtime2/ABI/System/ComponentModel/INotifyDataErrorInfo.cs @@ -36,7 +36,7 @@ namespace ABI.System.ComponentModel; /// /// ABI type for . /// -[WindowsRuntimeMappedMetadata("Microsoft.UI.Xaml.WinUIContract")] +[WindowsRuntimeType] [WindowsRuntimeMetadataTypeName("Microsoft.UI.Xaml.Data.INotifyDataErrorInfo")] [WindowsRuntimeMappedType(typeof(global::System.ComponentModel.INotifyDataErrorInfo))] file static class INotifyDataErrorInfo; diff --git a/src/WinRT.Runtime2/ABI/System/DateTimeOffset.cs b/src/WinRT.Runtime2/ABI/System/DateTimeOffset.cs index 0f0b6b18b7..b0960cdac2 100644 --- a/src/WinRT.Runtime2/ABI/System/DateTimeOffset.cs +++ b/src/WinRT.Runtime2/ABI/System/DateTimeOffset.cs @@ -32,7 +32,7 @@ namespace ABI.System; /// ABI type for . /// /// -[WindowsRuntimeMappedMetadata("Windows.Foundation.FoundationContract")] +[WindowsRuntimeType] [WindowsRuntimeClassName("Windows.Foundation.IReference`1")] [WindowsRuntimeMetadataTypeName("Windows.Foundation.DateTime")] [WindowsRuntimeMappedType(typeof(global::System.DateTimeOffset))] diff --git a/src/WinRT.Runtime2/ABI/System/Double.cs b/src/WinRT.Runtime2/ABI/System/Double.cs index aaee82f743..953b5e4835 100644 --- a/src/WinRT.Runtime2/ABI/System/Double.cs +++ b/src/WinRT.Runtime2/ABI/System/Double.cs @@ -31,7 +31,7 @@ namespace ABI.System; /// /// ABI type for . /// -[WindowsRuntimeMappedMetadata("Windows.Foundation.FoundationContract")] +[WindowsRuntimeType] [WindowsRuntimeClassName("Windows.Foundation.IReference`1")] [WindowsRuntimeMetadataTypeName("Double")] [WindowsRuntimeMappedType(typeof(double))] diff --git a/src/WinRT.Runtime2/ABI/System/EventHandler.cs b/src/WinRT.Runtime2/ABI/System/EventHandler.cs index d65e9c9cd5..0ecd2a0f69 100644 --- a/src/WinRT.Runtime2/ABI/System/EventHandler.cs +++ b/src/WinRT.Runtime2/ABI/System/EventHandler.cs @@ -30,7 +30,7 @@ namespace ABI.System; // All native objects reporting their runtime class name as 'Windows.Foundation.IReference`1>' // will be marshalled as 'EventHandler'. We only special case marshalling to managed from an exact pointer to a native // delegate instance. This is mostly just needed to allow implementing 'ICommand.CanExecuteChanged' over native objects. -// - We also don't use '[WindowsRuntimeMappedMetadata]', so when marshalling 'typeof(EventHandler)', it will be a custom type. +// - We also don't apply '[WindowsRuntimeType]', so when marshalling 'typeof(EventHandler)', it will be a custom type. // // This is also why some ABI methods for 'EventHandler' are either missing or not implemented. diff --git a/src/WinRT.Runtime2/ABI/System/Exception.cs b/src/WinRT.Runtime2/ABI/System/Exception.cs index fb569395f8..98a29acd2d 100644 --- a/src/WinRT.Runtime2/ABI/System/Exception.cs +++ b/src/WinRT.Runtime2/ABI/System/Exception.cs @@ -32,7 +32,7 @@ namespace ABI.System; /// ABI type for . /// /// -[WindowsRuntimeMappedMetadata("Windows.Foundation.FoundationContract")] +[WindowsRuntimeType] [WindowsRuntimeClassName("Windows.Foundation.IReference`1")] [WindowsRuntimeMetadataTypeName("Windows.Foundation.HResult")] [WindowsRuntimeMappedType(typeof(global::System.Exception))] diff --git a/src/WinRT.Runtime2/ABI/System/Guid.cs b/src/WinRT.Runtime2/ABI/System/Guid.cs index 50eb1e89b2..647ac0ba6e 100644 --- a/src/WinRT.Runtime2/ABI/System/Guid.cs +++ b/src/WinRT.Runtime2/ABI/System/Guid.cs @@ -31,7 +31,7 @@ namespace ABI.System; /// /// ABI type for . /// -[WindowsRuntimeMappedMetadata("Windows.Foundation.FoundationContract")] +[WindowsRuntimeType] [WindowsRuntimeClassName("Windows.Foundation.IReference`1")] [WindowsRuntimeMetadataTypeName("Guid")] [WindowsRuntimeMappedType(typeof(global::System.Guid))] diff --git a/src/WinRT.Runtime2/ABI/System/IDisposable.cs b/src/WinRT.Runtime2/ABI/System/IDisposable.cs index 805b02cf73..c1e8a977d8 100644 --- a/src/WinRT.Runtime2/ABI/System/IDisposable.cs +++ b/src/WinRT.Runtime2/ABI/System/IDisposable.cs @@ -32,7 +32,7 @@ namespace ABI.System; /// /// ABI type for . /// -[WindowsRuntimeMappedMetadata("Windows.Foundation.FoundationContract")] +[WindowsRuntimeType] [WindowsRuntimeMetadataTypeName("Windows.Foundation.IClosable")] [WindowsRuntimeMappedType(typeof(global::System.IDisposable))] file static class IDisposable; diff --git a/src/WinRT.Runtime2/ABI/System/IServiceProvider.cs b/src/WinRT.Runtime2/ABI/System/IServiceProvider.cs index 0f90747c18..6bed3f5dc2 100644 --- a/src/WinRT.Runtime2/ABI/System/IServiceProvider.cs +++ b/src/WinRT.Runtime2/ABI/System/IServiceProvider.cs @@ -32,7 +32,7 @@ namespace ABI.System; /// /// ABI type for . /// -[WindowsRuntimeMappedMetadata("Microsoft.UI.Xaml.WinUIContract")] +[WindowsRuntimeType] [WindowsRuntimeMetadataTypeName("Microsoft.UI.Xaml.IXamlServiceProvider")] [WindowsRuntimeMappedType(typeof(global::System.IServiceProvider))] file static class IServiceProvider; diff --git a/src/WinRT.Runtime2/ABI/System/Int16.cs b/src/WinRT.Runtime2/ABI/System/Int16.cs index 50a303c21c..17434125c9 100644 --- a/src/WinRT.Runtime2/ABI/System/Int16.cs +++ b/src/WinRT.Runtime2/ABI/System/Int16.cs @@ -31,7 +31,7 @@ namespace ABI.System; /// /// ABI type for . /// -[WindowsRuntimeMappedMetadata("Windows.Foundation.FoundationContract")] +[WindowsRuntimeType] [WindowsRuntimeClassName("Windows.Foundation.IReference`1")] [WindowsRuntimeMetadataTypeName("Int16")] [WindowsRuntimeMappedType(typeof(short))] diff --git a/src/WinRT.Runtime2/ABI/System/Int32.cs b/src/WinRT.Runtime2/ABI/System/Int32.cs index bea1b46ad0..a5bdc10bc2 100644 --- a/src/WinRT.Runtime2/ABI/System/Int32.cs +++ b/src/WinRT.Runtime2/ABI/System/Int32.cs @@ -31,7 +31,7 @@ namespace ABI.System; /// /// ABI type for . /// -[WindowsRuntimeMappedMetadata("Windows.Foundation.FoundationContract")] +[WindowsRuntimeType] [WindowsRuntimeClassName("Windows.Foundation.IReference`1")] [WindowsRuntimeMetadataTypeName("Int32")] [WindowsRuntimeMappedType(typeof(int))] diff --git a/src/WinRT.Runtime2/ABI/System/Int64.cs b/src/WinRT.Runtime2/ABI/System/Int64.cs index 621577f8cc..566bf3daac 100644 --- a/src/WinRT.Runtime2/ABI/System/Int64.cs +++ b/src/WinRT.Runtime2/ABI/System/Int64.cs @@ -31,7 +31,7 @@ namespace ABI.System; /// /// ABI type for . /// -[WindowsRuntimeMappedMetadata("Windows.Foundation.FoundationContract")] +[WindowsRuntimeType] [WindowsRuntimeClassName("Windows.Foundation.IReference`1")] [WindowsRuntimeMetadataTypeName("Int64")] [WindowsRuntimeMappedType(typeof(long))] diff --git a/src/WinRT.Runtime2/ABI/System/Numerics/Matrix3x2.cs b/src/WinRT.Runtime2/ABI/System/Numerics/Matrix3x2.cs index ec958b2a69..9b4536a3b2 100644 --- a/src/WinRT.Runtime2/ABI/System/Numerics/Matrix3x2.cs +++ b/src/WinRT.Runtime2/ABI/System/Numerics/Matrix3x2.cs @@ -33,7 +33,7 @@ namespace ABI.System.Numerics; /// ABI type for . /// /// -[WindowsRuntimeMappedMetadata("Windows.Foundation.UniversalApiContract")] +[WindowsRuntimeType] [WindowsRuntimeClassName("Windows.Foundation.IReference`1")] [WindowsRuntimeMetadataTypeName("Windows.Foundation.Numerics.Matrix3x2")] [WindowsRuntimeMappedType(typeof(global::System.Numerics.Matrix3x2))] diff --git a/src/WinRT.Runtime2/ABI/System/Numerics/Matrix4x4.cs b/src/WinRT.Runtime2/ABI/System/Numerics/Matrix4x4.cs index d7a3ff7d5a..5fa2f0b276 100644 --- a/src/WinRT.Runtime2/ABI/System/Numerics/Matrix4x4.cs +++ b/src/WinRT.Runtime2/ABI/System/Numerics/Matrix4x4.cs @@ -33,7 +33,7 @@ namespace ABI.System.Numerics; /// ABI type for . /// /// -[WindowsRuntimeMappedMetadata("Windows.Foundation.UniversalApiContract")] +[WindowsRuntimeType] [WindowsRuntimeClassName("Windows.Foundation.IReference`1")] [WindowsRuntimeMetadataTypeName("Windows.Foundation.Numerics.Matrix4x4")] [WindowsRuntimeMappedType(typeof(global::System.Numerics.Matrix4x4))] diff --git a/src/WinRT.Runtime2/ABI/System/Numerics/Plane.cs b/src/WinRT.Runtime2/ABI/System/Numerics/Plane.cs index 0246bba713..dfe4fe0aa8 100644 --- a/src/WinRT.Runtime2/ABI/System/Numerics/Plane.cs +++ b/src/WinRT.Runtime2/ABI/System/Numerics/Plane.cs @@ -33,7 +33,7 @@ namespace ABI.System.Numerics; /// ABI type for . /// /// -[WindowsRuntimeMappedMetadata("Windows.Foundation.UniversalApiContract")] +[WindowsRuntimeType] [WindowsRuntimeClassName("Windows.Foundation.IReference`1")] [WindowsRuntimeMetadataTypeName("Windows.Foundation.Numerics.Plane")] [WindowsRuntimeMappedType(typeof(global::System.Numerics.Plane))] diff --git a/src/WinRT.Runtime2/ABI/System/Numerics/Quaternion.cs b/src/WinRT.Runtime2/ABI/System/Numerics/Quaternion.cs index 853916a0f6..f9e30c2887 100644 --- a/src/WinRT.Runtime2/ABI/System/Numerics/Quaternion.cs +++ b/src/WinRT.Runtime2/ABI/System/Numerics/Quaternion.cs @@ -33,7 +33,7 @@ namespace ABI.System.Numerics; /// ABI type for . /// /// -[WindowsRuntimeMappedMetadata("Windows.Foundation.UniversalApiContract")] +[WindowsRuntimeType] [WindowsRuntimeClassName("Windows.Foundation.IReference`1")] [WindowsRuntimeMetadataTypeName("Windows.Foundation.Numerics.Quaternion")] [WindowsRuntimeMappedType(typeof(global::System.Numerics.Quaternion))] diff --git a/src/WinRT.Runtime2/ABI/System/Numerics/Vector2.cs b/src/WinRT.Runtime2/ABI/System/Numerics/Vector2.cs index cd10654163..10979775c8 100644 --- a/src/WinRT.Runtime2/ABI/System/Numerics/Vector2.cs +++ b/src/WinRT.Runtime2/ABI/System/Numerics/Vector2.cs @@ -33,7 +33,7 @@ namespace ABI.System.Numerics; /// ABI type for . /// /// -[WindowsRuntimeMappedMetadata("Windows.Foundation.UniversalApiContract")] +[WindowsRuntimeType] [WindowsRuntimeClassName("Windows.Foundation.IReference`1")] [WindowsRuntimeMetadataTypeName("Windows.Foundation.Numerics.Vector2")] [WindowsRuntimeMappedType(typeof(global::System.Numerics.Vector2))] diff --git a/src/WinRT.Runtime2/ABI/System/Numerics/Vector3.cs b/src/WinRT.Runtime2/ABI/System/Numerics/Vector3.cs index f32ae5c989..ae0887b1e2 100644 --- a/src/WinRT.Runtime2/ABI/System/Numerics/Vector3.cs +++ b/src/WinRT.Runtime2/ABI/System/Numerics/Vector3.cs @@ -33,7 +33,7 @@ namespace ABI.System.Numerics; /// ABI type for . /// /// -[WindowsRuntimeMappedMetadata("Windows.Foundation.UniversalApiContract")] +[WindowsRuntimeType] [WindowsRuntimeClassName("Windows.Foundation.IReference`1")] [WindowsRuntimeMetadataTypeName("Windows.Foundation.Numerics.Vector3")] [WindowsRuntimeMappedType(typeof(global::System.Numerics.Vector3))] diff --git a/src/WinRT.Runtime2/ABI/System/Numerics/Vector4.cs b/src/WinRT.Runtime2/ABI/System/Numerics/Vector4.cs index f6fb040d36..7704f96601 100644 --- a/src/WinRT.Runtime2/ABI/System/Numerics/Vector4.cs +++ b/src/WinRT.Runtime2/ABI/System/Numerics/Vector4.cs @@ -33,7 +33,7 @@ namespace ABI.System.Numerics; /// ABI type for . /// /// -[WindowsRuntimeMappedMetadata("Windows.Foundation.UniversalApiContract")] +[WindowsRuntimeType] [WindowsRuntimeClassName("Windows.Foundation.IReference`1")] [WindowsRuntimeMetadataTypeName("Windows.Foundation.Numerics.Vector4")] [WindowsRuntimeMappedType(typeof(global::System.Numerics.Vector4))] diff --git a/src/WinRT.Runtime2/ABI/System/Object.cs b/src/WinRT.Runtime2/ABI/System/Object.cs index ecfd3b21e4..bdf629cba7 100644 --- a/src/WinRT.Runtime2/ABI/System/Object.cs +++ b/src/WinRT.Runtime2/ABI/System/Object.cs @@ -21,7 +21,7 @@ namespace ABI.System; /// /// ABI type for . /// -[WindowsRuntimeMappedMetadata("Windows.Foundation.FoundationContract")] +[WindowsRuntimeType] [WindowsRuntimeClassName("Object")] [WindowsRuntimeMappedType(typeof(object))] [ObjectComWrappersMarshaller] diff --git a/src/WinRT.Runtime2/ABI/System/Single.cs b/src/WinRT.Runtime2/ABI/System/Single.cs index 5957badf43..3a519f2fc8 100644 --- a/src/WinRT.Runtime2/ABI/System/Single.cs +++ b/src/WinRT.Runtime2/ABI/System/Single.cs @@ -31,7 +31,7 @@ namespace ABI.System; /// /// ABI type for . /// -[WindowsRuntimeMappedMetadata("Windows.Foundation.FoundationContract")] +[WindowsRuntimeType] [WindowsRuntimeClassName("Windows.Foundation.IReference`1")] [WindowsRuntimeMetadataTypeName("Single")] [WindowsRuntimeMappedType(typeof(float))] diff --git a/src/WinRT.Runtime2/ABI/System/String.cs b/src/WinRT.Runtime2/ABI/System/String.cs index 8e62c51654..6282efa43a 100644 --- a/src/WinRT.Runtime2/ABI/System/String.cs +++ b/src/WinRT.Runtime2/ABI/System/String.cs @@ -32,7 +32,7 @@ namespace ABI.System; /// /// ABI type for . /// -[WindowsRuntimeMappedMetadata("Windows.Foundation.FoundationContract")] +[WindowsRuntimeType] [WindowsRuntimeClassName("Windows.Foundation.IReference`1")] [WindowsRuntimeMetadataTypeName("String")] [WindowsRuntimeMappedType(typeof(string))] diff --git a/src/WinRT.Runtime2/ABI/System/TimeSpan.cs b/src/WinRT.Runtime2/ABI/System/TimeSpan.cs index 1763e43dfa..c8b045e76b 100644 --- a/src/WinRT.Runtime2/ABI/System/TimeSpan.cs +++ b/src/WinRT.Runtime2/ABI/System/TimeSpan.cs @@ -32,7 +32,7 @@ namespace ABI.System; /// ABI type for . /// /// -[WindowsRuntimeMappedMetadata("Windows.Foundation.FoundationContract")] +[WindowsRuntimeType] [WindowsRuntimeClassName("Windows.Foundation.IReference`1")] [WindowsRuntimeMetadataTypeName("Windows.Foundation.TimeSpan")] [WindowsRuntimeMappedType(typeof(global::System.TimeSpan))] diff --git a/src/WinRT.Runtime2/ABI/System/Type.cs b/src/WinRT.Runtime2/ABI/System/Type.cs index eb5e52dab2..4a83fe2e42 100644 --- a/src/WinRT.Runtime2/ABI/System/Type.cs +++ b/src/WinRT.Runtime2/ABI/System/Type.cs @@ -39,7 +39,7 @@ namespace ABI.System; /// ABI type for . /// /// -[WindowsRuntimeMappedMetadata("Windows.Foundation.UniversalApiContract")] +[WindowsRuntimeType] [WindowsRuntimeClassName("Windows.Foundation.IReference`1")] [WindowsRuntimeMetadataTypeName("Windows.UI.Xaml.Interop.TypeName")] [WindowsRuntimeMappedType(typeof(global::System.Type))] @@ -312,13 +312,13 @@ public static ManagedTypeReference ToManagedTypeReference(global::System.Type va { // For projected types (not custom-mapped, but possibly manually projected, like e.g. 'IAsyncInfo'), we // can always just use the fully qualified type name (as it will always match the one in the .winmd file). - // We can check if a given type matches this by just checking whether it has '[WindowsRuntimeMetadata]'. + // We can check if a given type matches this by just checking whether it has '[WindowsRuntimeType]'. // Note that we're intentionally skipping generic types, as for those we need the 'cswinrtinteropgen' info. // Additionally, this path isn't taken if we have a nullable value type, which avoids the lookup too and // for component project types in authoring scenarios. if (!value.IsGenericType) { - if (value.IsDefined(typeof(WindowsRuntimeMetadataAttribute))) + if (value.IsDefined(typeof(WindowsRuntimeTypeAttribute))) { return new(value.FullName!, TypeKind.Metadata); } diff --git a/src/WinRT.Runtime2/ABI/System/UInt16.cs b/src/WinRT.Runtime2/ABI/System/UInt16.cs index 10d05a5271..56a76c0a3a 100644 --- a/src/WinRT.Runtime2/ABI/System/UInt16.cs +++ b/src/WinRT.Runtime2/ABI/System/UInt16.cs @@ -31,7 +31,7 @@ namespace ABI.System; /// /// ABI type for . /// -[WindowsRuntimeMappedMetadata("Windows.Foundation.FoundationContract")] +[WindowsRuntimeType] [WindowsRuntimeClassName("Windows.Foundation.IReference`1")] [WindowsRuntimeMetadataTypeName("UInt16")] [WindowsRuntimeMappedType(typeof(ushort))] diff --git a/src/WinRT.Runtime2/ABI/System/UInt32.cs b/src/WinRT.Runtime2/ABI/System/UInt32.cs index da34839df7..75d4558195 100644 --- a/src/WinRT.Runtime2/ABI/System/UInt32.cs +++ b/src/WinRT.Runtime2/ABI/System/UInt32.cs @@ -31,7 +31,7 @@ namespace ABI.System; /// /// ABI type for . /// -[WindowsRuntimeMappedMetadata("Windows.Foundation.FoundationContract")] +[WindowsRuntimeType] [WindowsRuntimeClassName("Windows.Foundation.IReference`1")] [WindowsRuntimeMetadataTypeName("UInt32")] [WindowsRuntimeMappedType(typeof(uint))] diff --git a/src/WinRT.Runtime2/ABI/System/UInt64.cs b/src/WinRT.Runtime2/ABI/System/UInt64.cs index 1d92e8f02d..7949e0122a 100644 --- a/src/WinRT.Runtime2/ABI/System/UInt64.cs +++ b/src/WinRT.Runtime2/ABI/System/UInt64.cs @@ -31,7 +31,7 @@ namespace ABI.System; /// /// ABI type for . /// -[WindowsRuntimeMappedMetadata("Windows.Foundation.FoundationContract")] +[WindowsRuntimeType] [WindowsRuntimeClassName("Windows.Foundation.IReference`1")] [WindowsRuntimeMetadataTypeName("UInt64")] [WindowsRuntimeMappedType(typeof(ulong))] diff --git a/src/WinRT.Runtime2/ABI/System/Uri.cs b/src/WinRT.Runtime2/ABI/System/Uri.cs index 1c0beb64d9..7cb4d20814 100644 --- a/src/WinRT.Runtime2/ABI/System/Uri.cs +++ b/src/WinRT.Runtime2/ABI/System/Uri.cs @@ -25,7 +25,7 @@ namespace ABI.System; /// ABI type for . /// /// -[WindowsRuntimeMappedMetadata("Windows.Foundation.FoundationContract")] +[WindowsRuntimeType] [WindowsRuntimeClassName("Windows.Foundation.Uri")] [WindowsRuntimeMappedType(typeof(global::System.Uri))] [UriComWrappersMarshaller] diff --git a/src/WinRT.Runtime2/ABI/Windows.Foundation/IStringable.cs b/src/WinRT.Runtime2/ABI/Windows.Foundation/IStringable.cs index 600fbc53ce..7a0b20b616 100644 --- a/src/WinRT.Runtime2/ABI/Windows.Foundation/IStringable.cs +++ b/src/WinRT.Runtime2/ABI/Windows.Foundation/IStringable.cs @@ -33,7 +33,7 @@ namespace ABI.Windows.Foundation; /// /// ABI type for . /// -[WindowsRuntimeMappedMetadata("Windows.Foundation.FoundationContract")] +[WindowsRuntimeType] [WindowsRuntimeMetadataTypeName("Windows.Foundation.IStringable")] [WindowsRuntimeMappedType(typeof(global::Windows.Foundation.IStringable))] file static class IStringable; diff --git a/src/WinRT.Runtime2/Attributes/WindowsRuntimeMappedMetadataAttribute.cs b/src/WinRT.Runtime2/Attributes/WindowsRuntimeMappedMetadataAttribute.cs deleted file mode 100644 index c6a4bb7912..0000000000 --- a/src/WinRT.Runtime2/Attributes/WindowsRuntimeMappedMetadataAttribute.cs +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -#define WINDOWS_RUNTIME_IMPLEMENTATION_ONLY_FILE - -using System; - -namespace WindowsRuntime; - -/// -/// Indicates the mapped source Windows Runtime metadata file (.winmd) that a given custom-mapped type is from. -/// -[AttributeUsage( - AttributeTargets.Class | - AttributeTargets.Struct | - AttributeTargets.Enum | - AttributeTargets.Interface | - AttributeTargets.Delegate, - AllowMultiple = false, - Inherited = false)] -[WindowsRuntimeImplementationOnlyMember] -public sealed class WindowsRuntimeMappedMetadataAttribute : Attribute -{ - /// - /// Creates a new instance with the specified parameters. - /// - /// The name of the mapped source Windows Runtime metadata file (.winmd) that the current custom-mapped type is from. - public WindowsRuntimeMappedMetadataAttribute(string name) - { - Name = name; - } - - /// - /// Gets the name of the mapped source Windows Runtime metadata file (.winmd) that the current custom-mapped type is from. - /// - public string Name { get; } -} diff --git a/src/WinRT.Runtime2/Attributes/WindowsRuntimeMetadataAttribute.cs b/src/WinRT.Runtime2/Attributes/WindowsRuntimeMetadataAttribute.cs index 4a672e15e5..ca4c779ca8 100644 --- a/src/WinRT.Runtime2/Attributes/WindowsRuntimeMetadataAttribute.cs +++ b/src/WinRT.Runtime2/Attributes/WindowsRuntimeMetadataAttribute.cs @@ -8,30 +8,33 @@ namespace WindowsRuntime; /// -/// Indicates the source Windows Runtime metadata file (.winmd) that a given projected type is from. +/// Associates a projected Windows Runtime type with the source Windows Runtime metadata file (.winmd) that it is from. +/// This attribute is applied to a centralized lookup type (ABI.WindowsRuntimeMetadataTypes) rather than being placed +/// on the projected type itself, so that the metadata mapping (only consumed by build-time tooling) can be trimmed away when +/// not needed. The projected type itself is instead decorated with the parameterless . /// -[AttributeUsage( - AttributeTargets.Class | - AttributeTargets.Struct | - AttributeTargets.Enum | - AttributeTargets.Interface | - AttributeTargets.Delegate, - AllowMultiple = false, - Inherited = false)] +[AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = false)] [WindowsRuntimeImplementationOnlyMember] public sealed class WindowsRuntimeMetadataAttribute : Attribute { /// /// Creates a new instance with the specified parameters. /// - /// The name of the source Windows Runtime metadata file (.winmd) that the current projected type is from. - public WindowsRuntimeMetadataAttribute(string name) + /// The projected Windows Runtime type that the metadata is for. + /// The name of the source Windows Runtime metadata file (.winmd) that is from. + public WindowsRuntimeMetadataAttribute(Type type, string name) { + Type = type; Name = name; } /// - /// Gets the name of the source Windows Runtime metadata file (.winmd) that the current projected type is from. + /// Gets the projected Windows Runtime type that the metadata is for. + /// + public Type Type { get; } + + /// + /// Gets the name of the source Windows Runtime metadata file (.winmd) that is from. /// public string Name { get; } } diff --git a/src/WinRT.Runtime2/Attributes/WindowsRuntimeTypeAttribute.cs b/src/WinRT.Runtime2/Attributes/WindowsRuntimeTypeAttribute.cs new file mode 100644 index 0000000000..59eb5f2b4d --- /dev/null +++ b/src/WinRT.Runtime2/Attributes/WindowsRuntimeTypeAttribute.cs @@ -0,0 +1,30 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +#define WINDOWS_RUNTIME_IMPLEMENTATION_ONLY_FILE + +using System; + +namespace WindowsRuntime; + +/// +/// Indicates that a given type is a Windows Runtime type (either a projected type, or a proxy type for a custom-mapped type). +/// +/// +/// This is a marker attribute carrying no data: it only signals that the decorated type participates in Windows Runtime +/// marshalling. The mapping from a projected type to its source Windows Runtime metadata file (.winmd) is instead recorded +/// on the centralized ABI.WindowsRuntimeMetadataTypes lookup type (via ), +/// so that the (build-time only) metadata can be trimmed away when not needed. +/// +[AttributeUsage( + AttributeTargets.Class | + AttributeTargets.Struct | + AttributeTargets.Enum | + AttributeTargets.Interface | + AttributeTargets.Delegate, + AllowMultiple = false, + Inherited = false)] +[WindowsRuntimeImplementationOnlyMember] +public sealed class WindowsRuntimeTypeAttribute : Attribute +{ +} diff --git a/src/WinRT.Runtime2/InteropServices/Activation/IActivationFactory.cs b/src/WinRT.Runtime2/InteropServices/Activation/IActivationFactory.cs index 171dbdc5d3..fbc5a98fce 100644 --- a/src/WinRT.Runtime2/InteropServices/Activation/IActivationFactory.cs +++ b/src/WinRT.Runtime2/InteropServices/Activation/IActivationFactory.cs @@ -13,7 +13,7 @@ namespace WindowsRuntime.InteropServices; /// [Guid("00000035-0000-0000-C000-000000000046")] #if WINDOWS_RUNTIME_IMPLEMENTATION_ASSEMBLY -[WindowsRuntimeMetadata("Windows.Foundation.FoundationContract")] +[WindowsRuntimeType] #endif [EditorBrowsable(EditorBrowsableState.Never)] public interface IActivationFactory diff --git a/src/WinRT.Runtime2/InteropServices/Events/EventRegistrationToken.cs b/src/WinRT.Runtime2/InteropServices/Events/EventRegistrationToken.cs index c31ba3e0e7..db2d06d871 100644 --- a/src/WinRT.Runtime2/InteropServices/Events/EventRegistrationToken.cs +++ b/src/WinRT.Runtime2/InteropServices/Events/EventRegistrationToken.cs @@ -12,7 +12,7 @@ namespace WindowsRuntime.InteropServices; /// /// #if WINDOWS_RUNTIME_IMPLEMENTATION_ASSEMBLY -[WindowsRuntimeMetadata("Windows.Foundation.FoundationContract")] +[WindowsRuntimeType] [WindowsRuntimeClassName("Windows.Foundation.IReference`1")] [WindowsRuntimeReferenceType(typeof(EventRegistrationToken?))] [ABI.WindowsRuntime.InteropServices.EventRegistrationTokenComWrappersMarshaller] diff --git a/src/WinRT.Runtime2/InteropServices/TypeMapInfo/WindowsRuntimeMarshallingInfo.cs b/src/WinRT.Runtime2/InteropServices/TypeMapInfo/WindowsRuntimeMarshallingInfo.cs index 06c31b568f..04080c4e34 100644 --- a/src/WinRT.Runtime2/InteropServices/TypeMapInfo/WindowsRuntimeMarshallingInfo.cs +++ b/src/WinRT.Runtime2/InteropServices/TypeMapInfo/WindowsRuntimeMarshallingInfo.cs @@ -256,11 +256,16 @@ public bool IsMetadataType [MethodImpl(MethodImplOptions.NoInlining)] bool InitializeIsMetadataType() { - // We want to make sure that this code path is actually only triggered for proxy types, which - // are only for custom-mapped types. So '[WindowsRuntimeMetadata]' should not be defined here. - Debug.Assert(!_metadataProviderType.IsDefined(typeof(WindowsRuntimeMetadataAttribute), inherit: false)); + // This path is only reached for proxy types (custom-mapped types); projected types are + // classified eagerly. A proxy is never a bare projected type: if it carries + // '[WindowsRuntimeType]' it must also carry '[WindowsRuntimeMappedType]' (a real metadata + // proxy, e.g. 'System.Guid'); otherwise it carries neither (a pure custom type that is not + // itself a Windows Runtime metadata type, e.g. 'System.EventHandler'). + Debug.Assert( + !_metadataProviderType.IsDefined(typeof(WindowsRuntimeTypeAttribute), inherit: false) || + _metadataProviderType.IsDefined(typeof(WindowsRuntimeMappedTypeAttribute), inherit: false)); - bool isMetadataType = _metadataProviderType.IsDefined(typeof(WindowsRuntimeMappedMetadataAttribute), inherit: false); + bool isMetadataType = _metadataProviderType.IsDefined(typeof(WindowsRuntimeTypeAttribute), inherit: false); _isMetadataType = isMetadataType ? 1 : 0; @@ -754,13 +759,13 @@ bool Load([NotNullWhen(true)] out string? metadataTypeName) /// The resulting instance. private static WindowsRuntimeMarshallingInfo CreateMarshallingInfo(Type metadataProviderType) { - // If '[WindowsRuntimeMetadata]' is defined, this is a projected type, so it's the public type too. - // Otherwise, we don't know what the public type is at this point. We could look it up now, but - // since we don't need that information right away, we can delay this to later to reduce the - // overhead at startup. That value is only needed e.g. when associating native memory for vtables. - return metadataProviderType.IsDefined(typeof(WindowsRuntimeMetadataAttribute), inherit: false) - ? new(metadataProviderType, metadataProviderType, isMetadataType: true) - : new(metadataProviderType, publicType: null); + // A projected type is its own metadata source and public type. A proxy type (for a custom-mapped + // type) instead carries '[WindowsRuntimeMappedType]' pointing to the public type. We don't resolve + // the public type for a proxy here: that value is only needed later (e.g. when associating native + // memory for vtables), so we defer it to reduce the overhead at startup. + return metadataProviderType.IsDefined(typeof(WindowsRuntimeMappedTypeAttribute), inherit: false) + ? new(metadataProviderType, publicType: null) + : new(metadataProviderType, metadataProviderType, isMetadataType: true); } /// @@ -770,7 +775,7 @@ private static WindowsRuntimeMarshallingInfo CreateMarshallingInfo(Type metadata /// The resulting instance, if created successfully. private static WindowsRuntimeMarshallingInfo? GetMetadataProviderType(Type managedType) { - bool isMetadataType = managedType.IsDefined(typeof(WindowsRuntimeMetadataAttribute), inherit: false); + bool isMetadataType = managedType.IsDefined(typeof(WindowsRuntimeTypeAttribute), inherit: false); // Same as above: if the type is a projected type, then it is also used as the metadata source. // We need to special-case generic types, as the marshalling code for them is also on proxies. diff --git a/src/WinRT.Runtime2/InteropServices/TypeMapInfo/WindowsRuntimeMetadataInfo.cs b/src/WinRT.Runtime2/InteropServices/TypeMapInfo/WindowsRuntimeMetadataInfo.cs index f9f2e444f0..2140a8b72c 100644 --- a/src/WinRT.Runtime2/InteropServices/TypeMapInfo/WindowsRuntimeMetadataInfo.cs +++ b/src/WinRT.Runtime2/InteropServices/TypeMapInfo/WindowsRuntimeMetadataInfo.cs @@ -197,9 +197,11 @@ string InitializeMetadataTypeName() /// The resulting instance. private static WindowsRuntimeMetadataInfo CreateMetadataInfo(Type metadataProviderType) { - return metadataProviderType.IsDefined(typeof(WindowsRuntimeMetadataAttribute), inherit: false) - ? new(metadataProviderType, metadataProviderType) - : new(metadataProviderType, publicType: null); + // A projected type is its own metadata source and public type. A proxy type (for a custom-mapped + // type) instead carries '[WindowsRuntimeMappedType]' pointing to the public type, resolved lazily. + return metadataProviderType.IsDefined(typeof(WindowsRuntimeMappedTypeAttribute), inherit: false) + ? new(metadataProviderType, publicType: null) + : new(metadataProviderType, metadataProviderType); } /// @@ -210,7 +212,7 @@ private static WindowsRuntimeMetadataInfo CreateMetadataInfo(Type metadataProvid private static WindowsRuntimeMetadataInfo? GetMetadataProviderType(Type managedType) { // Same as above: if the type is a projected type, then it is also used as the metadata source - if (managedType.IsDefined(typeof(WindowsRuntimeMetadataAttribute), inherit: false) && !managedType.IsGenericType) + if (managedType.IsDefined(typeof(WindowsRuntimeTypeAttribute), inherit: false) && !managedType.IsGenericType) { return new(managedType, managedType); } diff --git a/src/WinRT.Runtime2/Windows.Foundation/AsyncActionCompletedHandler.cs b/src/WinRT.Runtime2/Windows.Foundation/AsyncActionCompletedHandler.cs index 9ab29608bd..b7f3f6deb8 100644 --- a/src/WinRT.Runtime2/Windows.Foundation/AsyncActionCompletedHandler.cs +++ b/src/WinRT.Runtime2/Windows.Foundation/AsyncActionCompletedHandler.cs @@ -16,7 +16,7 @@ namespace Windows.Foundation; #if WINDOWS_RUNTIME_REFERENCE_ASSEMBLY [ContractVersion(typeof(FoundationContract), 65536u)] #elif WINDOWS_RUNTIME_IMPLEMENTATION_ASSEMBLY -[WindowsRuntimeMetadata("Windows.Foundation.FoundationContract")] +[WindowsRuntimeType] [WindowsRuntimeClassName("Windows.Foundation.IReference`1")] [ABI.Windows.Foundation.AsyncActionCompletedHandlerComWrappersMarshaller] #endif diff --git a/src/WinRT.Runtime2/Windows.Foundation/AsyncActionProgressHandler{TProgress}.cs b/src/WinRT.Runtime2/Windows.Foundation/AsyncActionProgressHandler{TProgress}.cs index 15588c5054..dccd2809f6 100644 --- a/src/WinRT.Runtime2/Windows.Foundation/AsyncActionProgressHandler{TProgress}.cs +++ b/src/WinRT.Runtime2/Windows.Foundation/AsyncActionProgressHandler{TProgress}.cs @@ -17,6 +17,6 @@ namespace Windows.Foundation; #if WINDOWS_RUNTIME_REFERENCE_ASSEMBLY [ContractVersion(typeof(FoundationContract), 65536u)] #elif WINDOWS_RUNTIME_IMPLEMENTATION_ASSEMBLY -[WindowsRuntimeMetadata("Windows.Foundation.FoundationContract")] +[WindowsRuntimeType] #endif public delegate void AsyncActionProgressHandler(IAsyncActionWithProgress asyncInfo, TProgress progressInfo); \ No newline at end of file diff --git a/src/WinRT.Runtime2/Windows.Foundation/AsyncActionWithProgressCompletedHandler{TProgress}.cs b/src/WinRT.Runtime2/Windows.Foundation/AsyncActionWithProgressCompletedHandler{TProgress}.cs index 44ece01fc6..48fd8686c8 100644 --- a/src/WinRT.Runtime2/Windows.Foundation/AsyncActionWithProgressCompletedHandler{TProgress}.cs +++ b/src/WinRT.Runtime2/Windows.Foundation/AsyncActionWithProgressCompletedHandler{TProgress}.cs @@ -17,6 +17,6 @@ namespace Windows.Foundation; #if WINDOWS_RUNTIME_REFERENCE_ASSEMBLY [ContractVersion(typeof(FoundationContract), 65536u)] #elif WINDOWS_RUNTIME_IMPLEMENTATION_ASSEMBLY -[WindowsRuntimeMetadata("Windows.Foundation.FoundationContract")] +[WindowsRuntimeType] #endif public delegate void AsyncActionWithProgressCompletedHandler(IAsyncActionWithProgress asyncInfo, AsyncStatus asyncStatus); \ No newline at end of file diff --git a/src/WinRT.Runtime2/Windows.Foundation/AsyncOperationCompletedHandler{TResult}.cs b/src/WinRT.Runtime2/Windows.Foundation/AsyncOperationCompletedHandler{TResult}.cs index a8bff10332..312140b21d 100644 --- a/src/WinRT.Runtime2/Windows.Foundation/AsyncOperationCompletedHandler{TResult}.cs +++ b/src/WinRT.Runtime2/Windows.Foundation/AsyncOperationCompletedHandler{TResult}.cs @@ -17,6 +17,6 @@ namespace Windows.Foundation; #if WINDOWS_RUNTIME_REFERENCE_ASSEMBLY [ContractVersion(typeof(FoundationContract), 65536u)] #elif WINDOWS_RUNTIME_IMPLEMENTATION_ASSEMBLY -[WindowsRuntimeMetadata("Windows.Foundation.FoundationContract")] +[WindowsRuntimeType] #endif public delegate void AsyncOperationCompletedHandler(IAsyncOperation asyncInfo, AsyncStatus asyncStatus); \ No newline at end of file diff --git a/src/WinRT.Runtime2/Windows.Foundation/AsyncOperationProgressHandler{TResult, TProgress}.cs b/src/WinRT.Runtime2/Windows.Foundation/AsyncOperationProgressHandler{TResult, TProgress}.cs index a64d72eef8..011a344f93 100644 --- a/src/WinRT.Runtime2/Windows.Foundation/AsyncOperationProgressHandler{TResult, TProgress}.cs +++ b/src/WinRT.Runtime2/Windows.Foundation/AsyncOperationProgressHandler{TResult, TProgress}.cs @@ -18,6 +18,6 @@ namespace Windows.Foundation; #if WINDOWS_RUNTIME_REFERENCE_ASSEMBLY [ContractVersion(typeof(FoundationContract), 65536u)] #elif WINDOWS_RUNTIME_IMPLEMENTATION_ASSEMBLY -[WindowsRuntimeMetadata("Windows.Foundation.FoundationContract")] +[WindowsRuntimeType] #endif public delegate void AsyncOperationProgressHandler(IAsyncOperationWithProgress asyncInfo, TProgress progressInfo); \ No newline at end of file diff --git a/src/WinRT.Runtime2/Windows.Foundation/AsyncOperationWithProgressCompletedHandler{TResult, TProgress}.cs b/src/WinRT.Runtime2/Windows.Foundation/AsyncOperationWithProgressCompletedHandler{TResult, TProgress}.cs index 6795f337fc..86ffedb94b 100644 --- a/src/WinRT.Runtime2/Windows.Foundation/AsyncOperationWithProgressCompletedHandler{TResult, TProgress}.cs +++ b/src/WinRT.Runtime2/Windows.Foundation/AsyncOperationWithProgressCompletedHandler{TResult, TProgress}.cs @@ -18,6 +18,6 @@ namespace Windows.Foundation; #if WINDOWS_RUNTIME_REFERENCE_ASSEMBLY [ContractVersion(typeof(FoundationContract), 65536u)] #elif WINDOWS_RUNTIME_IMPLEMENTATION_ASSEMBLY -[WindowsRuntimeMetadata("Windows.Foundation.FoundationContract")] +[WindowsRuntimeType] #endif public delegate void AsyncOperationWithProgressCompletedHandler(IAsyncOperationWithProgress asyncInfo, AsyncStatus asyncStatus); \ No newline at end of file diff --git a/src/WinRT.Runtime2/Windows.Foundation/AsyncStatus.cs b/src/WinRT.Runtime2/Windows.Foundation/AsyncStatus.cs index aa8934b50a..f3abaeff72 100644 --- a/src/WinRT.Runtime2/Windows.Foundation/AsyncStatus.cs +++ b/src/WinRT.Runtime2/Windows.Foundation/AsyncStatus.cs @@ -17,7 +17,7 @@ namespace Windows.Foundation; [SupportedOSPlatform("Windows10.0.10240.0")] [ContractVersion(typeof(FoundationContract), 65536u)] #elif WINDOWS_RUNTIME_IMPLEMENTATION_ASSEMBLY -[WindowsRuntimeMetadata("Windows.Foundation.FoundationContract")] +[WindowsRuntimeType] [WindowsRuntimeClassName("Windows.Foundation.IReference`1")] [WindowsRuntimeReferenceType(typeof(AsyncStatus?))] [ABI.Windows.Foundation.AsyncStatusComWrappersMarshaller] diff --git a/src/WinRT.Runtime2/Windows.Foundation/Collections/CollectionChange.cs b/src/WinRT.Runtime2/Windows.Foundation/Collections/CollectionChange.cs index 812e2490cb..188e9f9765 100644 --- a/src/WinRT.Runtime2/Windows.Foundation/Collections/CollectionChange.cs +++ b/src/WinRT.Runtime2/Windows.Foundation/Collections/CollectionChange.cs @@ -23,7 +23,7 @@ namespace Windows.Foundation.Collections; [SupportedOSPlatform("Windows10.0.10240.0")] [ContractVersion(typeof(FoundationContract), 65536u)] #elif WINDOWS_RUNTIME_IMPLEMENTATION_ASSEMBLY -[WindowsRuntimeMetadata("Windows.Foundation.FoundationContract")] +[WindowsRuntimeType] [WindowsRuntimeClassName("Windows.Foundation.IReference`1")] [WindowsRuntimeMetadataTypeName("Windows.Foundation.Collections.CollectionChange")] [WindowsRuntimeReferenceType(typeof(CollectionChange?))] diff --git a/src/WinRT.Runtime2/Windows.Foundation/Collections/IMapChangedEventArgs{K}.cs b/src/WinRT.Runtime2/Windows.Foundation/Collections/IMapChangedEventArgs{K}.cs index d84ddd8d03..6ce2f13c99 100644 --- a/src/WinRT.Runtime2/Windows.Foundation/Collections/IMapChangedEventArgs{K}.cs +++ b/src/WinRT.Runtime2/Windows.Foundation/Collections/IMapChangedEventArgs{K}.cs @@ -17,7 +17,7 @@ namespace Windows.Foundation.Collections; #if WINDOWS_RUNTIME_REFERENCE_ASSEMBLY [ContractVersion(typeof(FoundationContract), 65536u)] #elif WINDOWS_RUNTIME_IMPLEMENTATION_ASSEMBLY -[WindowsRuntimeMetadata("Windows.Foundation.FoundationContract")] +[WindowsRuntimeType] #endif public interface IMapChangedEventArgs { diff --git a/src/WinRT.Runtime2/Windows.Foundation/Collections/IObservableMap{K, V}.cs b/src/WinRT.Runtime2/Windows.Foundation/Collections/IObservableMap{K, V}.cs index 122d1a40c5..c86cb8a9be 100644 --- a/src/WinRT.Runtime2/Windows.Foundation/Collections/IObservableMap{K, V}.cs +++ b/src/WinRT.Runtime2/Windows.Foundation/Collections/IObservableMap{K, V}.cs @@ -20,7 +20,7 @@ namespace Windows.Foundation.Collections; #if WINDOWS_RUNTIME_REFERENCE_ASSEMBLY [ContractVersion(typeof(FoundationContract), 65536u)] #elif WINDOWS_RUNTIME_IMPLEMENTATION_ASSEMBLY -[WindowsRuntimeMetadata("Windows.Foundation.FoundationContract")] +[WindowsRuntimeType] #endif public interface IObservableMap : IDictionary, ICollection>, IEnumerable>, IEnumerable { diff --git a/src/WinRT.Runtime2/Windows.Foundation/Collections/IObservableVector{T}.cs b/src/WinRT.Runtime2/Windows.Foundation/Collections/IObservableVector{T}.cs index 04bb276b81..d3a58ccbca 100644 --- a/src/WinRT.Runtime2/Windows.Foundation/Collections/IObservableVector{T}.cs +++ b/src/WinRT.Runtime2/Windows.Foundation/Collections/IObservableVector{T}.cs @@ -19,7 +19,7 @@ namespace Windows.Foundation.Collections; #if WINDOWS_RUNTIME_REFERENCE_ASSEMBLY [ContractVersion(typeof(FoundationContract), 65536u)] #elif WINDOWS_RUNTIME_IMPLEMENTATION_ASSEMBLY -[WindowsRuntimeMetadata("Windows.Foundation.FoundationContract")] +[WindowsRuntimeType] #endif public interface IObservableVector : IList, ICollection, IEnumerable, IEnumerable { diff --git a/src/WinRT.Runtime2/Windows.Foundation/Collections/IVectorChangedEventArgs.cs b/src/WinRT.Runtime2/Windows.Foundation/Collections/IVectorChangedEventArgs.cs index be5dac0673..a6b6030d6d 100644 --- a/src/WinRT.Runtime2/Windows.Foundation/Collections/IVectorChangedEventArgs.cs +++ b/src/WinRT.Runtime2/Windows.Foundation/Collections/IVectorChangedEventArgs.cs @@ -16,7 +16,7 @@ namespace Windows.Foundation.Collections; #if WINDOWS_RUNTIME_REFERENCE_ASSEMBLY [ContractVersion(typeof(FoundationContract), 65536u)] #elif WINDOWS_RUNTIME_IMPLEMENTATION_ASSEMBLY -[WindowsRuntimeMetadata("Windows.Foundation.FoundationContract")] +[WindowsRuntimeType] #endif public interface IVectorChangedEventArgs { diff --git a/src/WinRT.Runtime2/Windows.Foundation/Collections/MapChangedEventHandler{K, V}.cs b/src/WinRT.Runtime2/Windows.Foundation/Collections/MapChangedEventHandler{K, V}.cs index c8c66a6b36..84551b61c7 100644 --- a/src/WinRT.Runtime2/Windows.Foundation/Collections/MapChangedEventHandler{K, V}.cs +++ b/src/WinRT.Runtime2/Windows.Foundation/Collections/MapChangedEventHandler{K, V}.cs @@ -18,6 +18,6 @@ namespace Windows.Foundation.Collections; #if WINDOWS_RUNTIME_REFERENCE_ASSEMBLY [ContractVersion(typeof(FoundationContract), 65536u)] #elif WINDOWS_RUNTIME_IMPLEMENTATION_ASSEMBLY -[WindowsRuntimeMetadata("Windows.Foundation.FoundationContract")] +[WindowsRuntimeType] #endif public delegate void MapChangedEventHandler(IObservableMap sender, IMapChangedEventArgs @event); \ No newline at end of file diff --git a/src/WinRT.Runtime2/Windows.Foundation/Collections/VectorChangedEventHandler{T}.cs b/src/WinRT.Runtime2/Windows.Foundation/Collections/VectorChangedEventHandler{T}.cs index 04bb4ae807..cb21aedef7 100644 --- a/src/WinRT.Runtime2/Windows.Foundation/Collections/VectorChangedEventHandler{T}.cs +++ b/src/WinRT.Runtime2/Windows.Foundation/Collections/VectorChangedEventHandler{T}.cs @@ -17,6 +17,6 @@ namespace Windows.Foundation.Collections; #if WINDOWS_RUNTIME_REFERENCE_ASSEMBLY [ContractVersion(typeof(FoundationContract), 65536u)] #elif WINDOWS_RUNTIME_IMPLEMENTATION_ASSEMBLY -[WindowsRuntimeMetadata("Windows.Foundation.FoundationContract")] +[WindowsRuntimeType] #endif public delegate void VectorChangedEventHandler(IObservableVector sender, IVectorChangedEventArgs @event); \ No newline at end of file diff --git a/src/WinRT.Runtime2/Windows.Foundation/IAsyncAction.cs b/src/WinRT.Runtime2/Windows.Foundation/IAsyncAction.cs index adb173307c..291a94649e 100644 --- a/src/WinRT.Runtime2/Windows.Foundation/IAsyncAction.cs +++ b/src/WinRT.Runtime2/Windows.Foundation/IAsyncAction.cs @@ -23,7 +23,7 @@ namespace Windows.Foundation; #if WINDOWS_RUNTIME_REFERENCE_ASSEMBLY [ContractVersion(typeof(FoundationContract), 65536u)] #elif WINDOWS_RUNTIME_IMPLEMENTATION_ASSEMBLY -[WindowsRuntimeMetadata("Windows.Foundation.FoundationContract")] +[WindowsRuntimeType] #endif public interface IAsyncAction : IAsyncInfo { diff --git a/src/WinRT.Runtime2/Windows.Foundation/IAsyncActionWithProgress{TProgress}.cs b/src/WinRT.Runtime2/Windows.Foundation/IAsyncActionWithProgress{TProgress}.cs index 331cf989c5..9aa641a688 100644 --- a/src/WinRT.Runtime2/Windows.Foundation/IAsyncActionWithProgress{TProgress}.cs +++ b/src/WinRT.Runtime2/Windows.Foundation/IAsyncActionWithProgress{TProgress}.cs @@ -24,7 +24,7 @@ namespace Windows.Foundation; #if WINDOWS_RUNTIME_REFERENCE_ASSEMBLY [ContractVersion(typeof(FoundationContract), 65536u)] #elif WINDOWS_RUNTIME_IMPLEMENTATION_ASSEMBLY -[WindowsRuntimeMetadata("Windows.Foundation.FoundationContract")] +[WindowsRuntimeType] #endif public interface IAsyncActionWithProgress : IAsyncInfo { diff --git a/src/WinRT.Runtime2/Windows.Foundation/IAsyncInfo.cs b/src/WinRT.Runtime2/Windows.Foundation/IAsyncInfo.cs index 889596a1ac..b51274ae75 100644 --- a/src/WinRT.Runtime2/Windows.Foundation/IAsyncInfo.cs +++ b/src/WinRT.Runtime2/Windows.Foundation/IAsyncInfo.cs @@ -17,7 +17,7 @@ namespace Windows.Foundation; #if WINDOWS_RUNTIME_REFERENCE_ASSEMBLY [ContractVersion(typeof(FoundationContract), 65536u)] #elif WINDOWS_RUNTIME_IMPLEMENTATION_ASSEMBLY -[WindowsRuntimeMetadata("Windows.Foundation.FoundationContract")] +[WindowsRuntimeType] #endif public interface IAsyncInfo { diff --git a/src/WinRT.Runtime2/Windows.Foundation/IAsyncOperationWithProgress{TResult, TProgress}.cs b/src/WinRT.Runtime2/Windows.Foundation/IAsyncOperationWithProgress{TResult, TProgress}.cs index 588e399700..147a44273d 100644 --- a/src/WinRT.Runtime2/Windows.Foundation/IAsyncOperationWithProgress{TResult, TProgress}.cs +++ b/src/WinRT.Runtime2/Windows.Foundation/IAsyncOperationWithProgress{TResult, TProgress}.cs @@ -26,7 +26,7 @@ namespace Windows.Foundation; #if WINDOWS_RUNTIME_REFERENCE_ASSEMBLY [ContractVersion(typeof(FoundationContract), 65536u)] #elif WINDOWS_RUNTIME_IMPLEMENTATION_ASSEMBLY -[WindowsRuntimeMetadata("Windows.Foundation.FoundationContract")] +[WindowsRuntimeType] #endif public interface IAsyncOperationWithProgress : IAsyncInfo { diff --git a/src/WinRT.Runtime2/Windows.Foundation/IAsyncOperation{TResult}.cs b/src/WinRT.Runtime2/Windows.Foundation/IAsyncOperation{TResult}.cs index 4f085a6ce8..f48de5edc7 100644 --- a/src/WinRT.Runtime2/Windows.Foundation/IAsyncOperation{TResult}.cs +++ b/src/WinRT.Runtime2/Windows.Foundation/IAsyncOperation{TResult}.cs @@ -24,7 +24,7 @@ namespace Windows.Foundation; #if WINDOWS_RUNTIME_REFERENCE_ASSEMBLY [ContractVersion(typeof(FoundationContract), 65536u)] #elif WINDOWS_RUNTIME_IMPLEMENTATION_ASSEMBLY -[WindowsRuntimeMetadata("Windows.Foundation.FoundationContract")] +[WindowsRuntimeType] #endif public interface IAsyncOperation : IAsyncInfo { diff --git a/src/WinRT.Runtime2/Windows.Foundation/IMemoryBufferReference.cs b/src/WinRT.Runtime2/Windows.Foundation/IMemoryBufferReference.cs index f0a6fef368..7028bcafa8 100644 --- a/src/WinRT.Runtime2/Windows.Foundation/IMemoryBufferReference.cs +++ b/src/WinRT.Runtime2/Windows.Foundation/IMemoryBufferReference.cs @@ -17,7 +17,7 @@ namespace Windows.Foundation; #if WINDOWS_RUNTIME_REFERENCE_ASSEMBLY [ContractVersion(typeof(UniversalApiContract), 65536u)] #elif WINDOWS_RUNTIME_IMPLEMENTATION_ASSEMBLY -[WindowsRuntimeMetadata("Windows.Foundation.UniversalApiContract")] +[WindowsRuntimeType] #endif public interface IMemoryBufferReference : IDisposable { diff --git a/src/WinRT.Runtime2/Windows.Foundation/IStringable.cs b/src/WinRT.Runtime2/Windows.Foundation/IStringable.cs index 8bbae45779..7f76bfe317 100644 --- a/src/WinRT.Runtime2/Windows.Foundation/IStringable.cs +++ b/src/WinRT.Runtime2/Windows.Foundation/IStringable.cs @@ -22,7 +22,7 @@ namespace Windows.Foundation; #if WINDOWS_RUNTIME_REFERENCE_ASSEMBLY [ContractVersion(typeof(FoundationContract), 65536u)] #elif WINDOWS_RUNTIME_IMPLEMENTATION_ASSEMBLY -[WindowsRuntimeMetadata("Windows.Foundation.FoundationContract")] +[WindowsRuntimeType] #endif public interface IStringable { diff --git a/src/WinRT.Runtime2/Windows.Foundation/Metadata/ApiContractAttribute.cs b/src/WinRT.Runtime2/Windows.Foundation/Metadata/ApiContractAttribute.cs index 6d8f1457fd..51d0f166b0 100644 --- a/src/WinRT.Runtime2/Windows.Foundation/Metadata/ApiContractAttribute.cs +++ b/src/WinRT.Runtime2/Windows.Foundation/Metadata/ApiContractAttribute.cs @@ -13,7 +13,7 @@ namespace Windows.Foundation.Metadata; /// Specifies that the type represents an API contract. /// #if WINDOWS_RUNTIME_IMPLEMENTATION_ASSEMBLY -[WindowsRuntimeMetadata("Windows.Foundation.FoundationContract")] +[WindowsRuntimeType] #elif WINDOWS_RUNTIME_REFERENCE_ASSEMBLY [SupportedOSPlatform("Windows10.0.10240.0")] [ContractVersion(typeof(FoundationContract), 65536u)] diff --git a/src/WinRT.Runtime2/Windows.Foundation/Metadata/ContractVersionAttribute.cs b/src/WinRT.Runtime2/Windows.Foundation/Metadata/ContractVersionAttribute.cs index 4d89f98ffc..3f45fa1d54 100644 --- a/src/WinRT.Runtime2/Windows.Foundation/Metadata/ContractVersionAttribute.cs +++ b/src/WinRT.Runtime2/Windows.Foundation/Metadata/ContractVersionAttribute.cs @@ -15,7 +15,7 @@ namespace Windows.Foundation.Metadata; /// Indicates the version of the API contract. /// #if WINDOWS_RUNTIME_IMPLEMENTATION_ASSEMBLY -[WindowsRuntimeMetadata("Windows.Foundation.FoundationContract")] +[WindowsRuntimeType] #elif WINDOWS_RUNTIME_REFERENCE_ASSEMBLY [SupportedOSPlatform("Windows10.0.10240.0")] [ContractVersion(typeof(FoundationContract), 65536u)] diff --git a/src/WinRT.Runtime2/Windows.Foundation/Point.cs b/src/WinRT.Runtime2/Windows.Foundation/Point.cs index f8dc71c390..e299dbd3fd 100644 --- a/src/WinRT.Runtime2/Windows.Foundation/Point.cs +++ b/src/WinRT.Runtime2/Windows.Foundation/Point.cs @@ -23,7 +23,7 @@ namespace Windows.Foundation; [SupportedOSPlatform("Windows10.0.10240.0")] [ContractVersion(typeof(FoundationContract), 65536u)] #elif WINDOWS_RUNTIME_IMPLEMENTATION_ASSEMBLY -[WindowsRuntimeMetadata("Windows.Foundation.FoundationContract")] +[WindowsRuntimeType] [WindowsRuntimeClassName("Windows.Foundation.IReference`1")] [WindowsRuntimeReferenceType(typeof(Point?))] [ABI.Windows.Foundation.PointComWrappersMarshaller] diff --git a/src/WinRT.Runtime2/Windows.Foundation/PropertyType.cs b/src/WinRT.Runtime2/Windows.Foundation/PropertyType.cs index 8268acd583..79323da9cb 100644 --- a/src/WinRT.Runtime2/Windows.Foundation/PropertyType.cs +++ b/src/WinRT.Runtime2/Windows.Foundation/PropertyType.cs @@ -17,7 +17,7 @@ namespace Windows.Foundation; [SupportedOSPlatform("Windows10.0.10240.0")] [ContractVersion(typeof(FoundationContract), 65536u)] #elif WINDOWS_RUNTIME_IMPLEMENTATION_ASSEMBLY -[WindowsRuntimeMetadata("Windows.Foundation.FoundationContract")] +[WindowsRuntimeType] [WindowsRuntimeClassName("Windows.Foundation.IReference`1")] [WindowsRuntimeReferenceType(typeof(PropertyType?))] [ABI.Windows.Foundation.PropertyTypeComWrappersMarshaller] diff --git a/src/WinRT.Runtime2/Windows.Foundation/Rect.cs b/src/WinRT.Runtime2/Windows.Foundation/Rect.cs index 48df48bc50..6c899b63bb 100644 --- a/src/WinRT.Runtime2/Windows.Foundation/Rect.cs +++ b/src/WinRT.Runtime2/Windows.Foundation/Rect.cs @@ -25,7 +25,7 @@ namespace Windows.Foundation; [SupportedOSPlatform("Windows10.0.10240.0")] [ContractVersion(typeof(FoundationContract), 65536u)] #elif WINDOWS_RUNTIME_IMPLEMENTATION_ASSEMBLY -[WindowsRuntimeMetadata("Windows.Foundation.FoundationContract")] +[WindowsRuntimeType] [WindowsRuntimeClassName("Windows.Foundation.IReference`1")] [WindowsRuntimeReferenceType(typeof(Rect?))] [ABI.Windows.Foundation.RectComWrappersMarshaller] diff --git a/src/WinRT.Runtime2/Windows.Foundation/Size.cs b/src/WinRT.Runtime2/Windows.Foundation/Size.cs index 6e8b344177..9d366807d6 100644 --- a/src/WinRT.Runtime2/Windows.Foundation/Size.cs +++ b/src/WinRT.Runtime2/Windows.Foundation/Size.cs @@ -22,7 +22,7 @@ namespace Windows.Foundation; [SupportedOSPlatform("Windows10.0.10240.0")] [ContractVersion(typeof(FoundationContract), 65536u)] #elif WINDOWS_RUNTIME_IMPLEMENTATION_ASSEMBLY -[WindowsRuntimeMetadata("Windows.Foundation.FoundationContract")] +[WindowsRuntimeType] [WindowsRuntimeClassName("Windows.Foundation.IReference`1")] [WindowsRuntimeReferenceType(typeof(Size?))] [ABI.Windows.Foundation.SizeComWrappersMarshaller] diff --git a/src/WinRT.Runtime2/Windows.Storage.Streams/IBuffer.cs b/src/WinRT.Runtime2/Windows.Storage.Streams/IBuffer.cs index f3512b3d0f..259add455b 100644 --- a/src/WinRT.Runtime2/Windows.Storage.Streams/IBuffer.cs +++ b/src/WinRT.Runtime2/Windows.Storage.Streams/IBuffer.cs @@ -18,7 +18,7 @@ namespace Windows.Storage.Streams; #if WINDOWS_RUNTIME_REFERENCE_ASSEMBLY [ContractVersion(typeof(UniversalApiContract), 65536u)] #elif WINDOWS_RUNTIME_IMPLEMENTATION_ASSEMBLY -[WindowsRuntimeMetadata("Windows.Foundation.UniversalApiContract")] +[WindowsRuntimeType] #endif public interface IBuffer { diff --git a/src/WinRT.Runtime2/Windows.Storage.Streams/IInputStream.cs b/src/WinRT.Runtime2/Windows.Storage.Streams/IInputStream.cs index 2ac73d2111..5d91992118 100644 --- a/src/WinRT.Runtime2/Windows.Storage.Streams/IInputStream.cs +++ b/src/WinRT.Runtime2/Windows.Storage.Streams/IInputStream.cs @@ -18,7 +18,7 @@ namespace Windows.Storage.Streams; #if WINDOWS_RUNTIME_REFERENCE_ASSEMBLY [ContractVersion(typeof(UniversalApiContract), 65536u)] #elif WINDOWS_RUNTIME_IMPLEMENTATION_ASSEMBLY -[WindowsRuntimeMetadata("Windows.Foundation.UniversalApiContract")] +[WindowsRuntimeType] #endif public interface IInputStream : IDisposable { diff --git a/src/WinRT.Runtime2/Windows.Storage.Streams/IOutputStream.cs b/src/WinRT.Runtime2/Windows.Storage.Streams/IOutputStream.cs index 75d02c2c4e..0933b30098 100644 --- a/src/WinRT.Runtime2/Windows.Storage.Streams/IOutputStream.cs +++ b/src/WinRT.Runtime2/Windows.Storage.Streams/IOutputStream.cs @@ -18,7 +18,7 @@ namespace Windows.Storage.Streams; #if WINDOWS_RUNTIME_REFERENCE_ASSEMBLY [ContractVersion(typeof(UniversalApiContract), 65536u)] #elif WINDOWS_RUNTIME_IMPLEMENTATION_ASSEMBLY -[WindowsRuntimeMetadata("Windows.Foundation.UniversalApiContract")] +[WindowsRuntimeType] #endif public interface IOutputStream : IDisposable { diff --git a/src/WinRT.Runtime2/Windows.Storage.Streams/IRandomAccessStream.cs b/src/WinRT.Runtime2/Windows.Storage.Streams/IRandomAccessStream.cs index bac93ee020..51c737bd1e 100644 --- a/src/WinRT.Runtime2/Windows.Storage.Streams/IRandomAccessStream.cs +++ b/src/WinRT.Runtime2/Windows.Storage.Streams/IRandomAccessStream.cs @@ -18,7 +18,7 @@ namespace Windows.Storage.Streams; #if WINDOWS_RUNTIME_REFERENCE_ASSEMBLY [ContractVersion(typeof(UniversalApiContract), 65536u)] #elif WINDOWS_RUNTIME_IMPLEMENTATION_ASSEMBLY -[WindowsRuntimeMetadata("Windows.Foundation.UniversalApiContract")] +[WindowsRuntimeType] #endif public interface IRandomAccessStream : IDisposable, IInputStream, IOutputStream { diff --git a/src/WinRT.Runtime2/Windows.Storage.Streams/InputStreamOptions.cs b/src/WinRT.Runtime2/Windows.Storage.Streams/InputStreamOptions.cs index 4961feeed1..0fe17de163 100644 --- a/src/WinRT.Runtime2/Windows.Storage.Streams/InputStreamOptions.cs +++ b/src/WinRT.Runtime2/Windows.Storage.Streams/InputStreamOptions.cs @@ -20,7 +20,7 @@ namespace Windows.Storage.Streams; [SupportedOSPlatform("Windows10.0.10240.0")] [ContractVersion(typeof(UniversalApiContract), 65536u)] #elif WINDOWS_RUNTIME_IMPLEMENTATION_ASSEMBLY -[WindowsRuntimeMetadata("Windows.Foundation.UniversalApiContract")] +[WindowsRuntimeType] [WindowsRuntimeClassName("Windows.Foundation.IReference`1")] [WindowsRuntimeReferenceType(typeof(InputStreamOptions?))] [ABI.Windows.Storage.Streams.InputStreamOptionsComWrappersMarshaller] diff --git a/src/WinRT.WinMD.Generator/Extensions/ModuleDefinitionExtensions.cs b/src/WinRT.WinMD.Generator/Extensions/ModuleDefinitionExtensions.cs new file mode 100644 index 0000000000..9bba62d503 --- /dev/null +++ b/src/WinRT.WinMD.Generator/Extensions/ModuleDefinitionExtensions.cs @@ -0,0 +1,75 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +using System.Collections.Frozen; +using System.Collections.Generic; +using System.Runtime.CompilerServices; +using AsmResolver.DotNet; +using AsmResolver.DotNet.Signatures; + +namespace WindowsRuntime.WinMDGenerator; + +/// +/// Extension methods for . +/// +internal static class ModuleDefinitionExtensions +{ + /// + /// Gets a lookup of source .winmd module names ("stems") for projected Windows Runtime types in a given + /// module. The lookup is built from the [WindowsRuntimeMetadata] attributes on the + /// WindowsRuntimeMetadataTypes type in the ABI namespace (only present in implementation + /// projections). The resulting dictionary maps projected types (by namespace and name) to their source + /// .winmd stem. + /// + /// The input instance. + /// The resulting metadata-types lookup. + public static IReadOnlyDictionary<(string? Namespace, string? Name), string> GetWindowsRuntimeMetadataTypesLookup(this ModuleDefinition module) + { + return WindowsRuntimeMetadataTypesLookupCache.Instance.GetOrAdd( + key: module, + valueFactory: static module => + { + TypeDefinition? windowsRuntimeMetadataTypesType = null; + + foreach (TypeDefinition type in module.TopLevelTypes) + { + if (type.Namespace?.Value == "ABI" && type.Name?.Value == "WindowsRuntimeMetadataTypes") + { + windowsRuntimeMetadataTypesType = type; + + break; + } + } + + if (windowsRuntimeMetadataTypesType is null) + { + return FrozenDictionary<(string?, string?), string>.Empty; + } + + Dictionary<(string?, string?), string> builder = []; + + // Enumerate all attributes on the lookup type and extract projected type to .winmd stem pairs + foreach (CustomAttribute attribute in windowsRuntimeMetadataTypesType.CustomAttributes) + { + // Match '[WindowsRuntimeMetadata(typeof(), "")]' + if (attribute.Signature is { FixedArguments: [{ Element: TypeSignature projectedType }, { Element: { } stem }] }) + { + builder[(projectedType.Namespace, projectedType.Name)] = stem.ToString()!; + } + } + + return builder.ToFrozenDictionary(); + }); + } +} + +/// +/// Contains a shared cache of metadata-types lookups, to speed up search operations. +/// +file static class WindowsRuntimeMetadataTypesLookupCache +{ + /// + /// The singleton metadata-types lookups map. + /// + public static readonly ConditionalWeakTable> Instance = []; +} diff --git a/src/WinRT.WinMD.Generator/Extensions/TypeDefinitionExtensions.cs b/src/WinRT.WinMD.Generator/Extensions/TypeDefinitionExtensions.cs index 17817ec611..a4606299d0 100644 --- a/src/WinRT.WinMD.Generator/Extensions/TypeDefinitionExtensions.cs +++ b/src/WinRT.WinMD.Generator/Extensions/TypeDefinitionExtensions.cs @@ -16,14 +16,15 @@ internal static class TypeDefinitionExtensions extension(TypeDefinition type) { /// - /// Checks whether the type is a Windows Runtime type (has the [WindowsRuntimeMetadata] attribute). + /// Checks whether the type is a Windows Runtime type (has the [WindowsRuntimeType] marker). /// /// - /// Types marked with [WindowsRuntimeMetadata] are projected Windows Runtime types that come - /// from CsWinRT-generated projection assemblies. This attribute indicates the type has a - /// corresponding Windows Runtime definition and carries metadata about its contract assembly. + /// Types marked with [WindowsRuntimeType] are projected Windows Runtime types that come + /// from CsWinRT-generated projection assemblies. This marker indicates the type has a corresponding + /// Windows Runtime definition. The source contract assembly is recorded separately on the centralized + /// ABI.WindowsRuntimeMetadataTypes lookup type (the WindowsRuntimeAssemblyName property). /// - public bool IsWindowsRuntimeType => type.FindCustomAttributes("WindowsRuntime", "WindowsRuntimeMetadataAttribute").Any(); + public bool IsWindowsRuntimeType => type.FindCustomAttributes("WindowsRuntime", "WindowsRuntimeTypeAttribute").Any(); /// /// Checks whether the type is a Windows Runtime API contract (has the [ApiContract] attribute). @@ -69,33 +70,26 @@ public int? VersionAttributeValue } /// - /// Gets the Windows Runtime contract assembly name from [WindowsRuntimeMetadata] attribute on the type, if present. + /// Gets the Windows Runtime contract assembly name (i.e. the source .winmd module name) for the type, if available. /// /// /// The Windows Runtime contract assembly name (e.g. "Microsoft.UI.Xaml"), or - /// if the type does not have a [WindowsRuntimeMetadata] attribute. + /// if no mapping is found for the type. /// /// - /// For types from projection assemblies (e.g. Microsoft.WinUI), this returns the original - /// Windows Runtime contract assembly name so the WinMD can reference types correctly. + /// For types from projection assemblies (e.g. Microsoft.WinUI), this returns the original Windows Runtime + /// contract assembly name so the WinMD can reference types correctly. The mapping is no longer carried on each + /// type: it lives on the centralized ABI.WindowsRuntimeMetadataTypes lookup type in the implementation + /// projection (so the build-time-only metadata can be trimmed away), and is read from the type's declaring module. /// public string? WindowsRuntimeAssemblyName { get { - // If the type doesn't have the '[WindowsRuntimeMetadata]' attribute, stop here - if (type.FindCustomAttributes("WindowsRuntime", "WindowsRuntimeMetadataAttribute").FirstOrDefault() is not CustomAttribute attribute) - { - return null; - } - - // Extract the assembly name from the attribute signature, if possible - if (attribute.Signature is { FixedArguments: [{ Element: object assemblyName }] }) - { - return assemblyName.ToString(); - } - - return null; + return type.DeclaringModule is { } module && + module.GetWindowsRuntimeMetadataTypesLookup().TryGetValue((type.Namespace?.Value, type.Name?.Value), out string? stem) + ? stem + : null; } } } diff --git a/src/WinRT.WinMD.Generator/Writers/WinMDWriter.TypeMapping.cs b/src/WinRT.WinMD.Generator/Writers/WinMDWriter.TypeMapping.cs index 07a492aa10..6bd7a58fc9 100644 --- a/src/WinRT.WinMD.Generator/Writers/WinMDWriter.TypeMapping.cs +++ b/src/WinRT.WinMD.Generator/Writers/WinMDWriter.TypeMapping.cs @@ -199,7 +199,7 @@ private ITypeDefOrRef ImportTypeReference(ITypeDefOrRef type) } // For Windows Runtime types from projection assemblies, use the Windows Runtime contract assembly name - // from the '[WindowsRuntimeMetadata]' attribute instead of the projection assembly name. + // from the centralized ABI.WindowsRuntimeMetadataTypes lookup type instead of the projection assembly name. // E.g., 'StackPanel' from 'Microsoft.WinUI' → 'Microsoft.UI.Xaml' in the WinMD. string assembly = GetAssemblyNameFromScope(typeRef.Scope); TypeDefinition? resolvedType = SafeResolve(typeRef);