Add [WindowsRuntimeType] marker and centralize WinRT metadata mapping#2467
Draft
Sergio0694 wants to merge 5 commits into
Draft
Add [WindowsRuntimeType] marker and centralize WinRT metadata mapping#2467Sergio0694 wants to merge 5 commits into
Sergio0694 wants to merge 5 commits into
Conversation
The per-type [WindowsRuntimeMetadata("contract")] attribute served two purposes:
marking a type as a Windows Runtime type (presence) and recording the source
.winmd stem (value). The runtime only ever reads the presence; the value is used
exclusively by build-time tooling. Carrying the string on every projected type is
pure metadata overhead at runtime.
Split the two concerns:
- Add a parameterless [WindowsRuntimeType] marker attribute (implementation-only),
applied to every projected type and to proxy types for custom-mapped types.
- Repurpose [WindowsRuntimeMetadata] into a (Type, string) attribute targeting a
single class with AllowMultiple, so the type -> .winmd-stem mapping can live on a
centralized, trimmable lookup type (emitted by the projection generator in a later
change) instead of on each type.
- Remove [WindowsRuntimeMappedMetadata]; proxy types now use [WindowsRuntimeType].
Update the runtime metadata/marshalling lookups accordingly: presence checks now use
[WindowsRuntimeType], and the projected-vs-proxy distinction (previously inferred from
[WindowsRuntimeMetadata] vs [WindowsRuntimeMappedMetadata]) now uses [WindowsRuntimeMappedType],
which proxy types already carry to point at their public type. The 'System.EventHandler'
proxy intentionally remains unmarked (a pure custom type, not a metadata type).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Replace the per-type [WindowsRuntimeMetadata("stem")] attribute emitted on every
projected type with the parameterless [WindowsRuntimeType] marker, and move the
type -> source .winmd-stem mapping to a centralized ABI.WindowsRuntimeMetadataTypes
lookup type carrying one [WindowsRuntimeMetadata(typeof(T), "stem")] per projected
type. This mirrors how ABI.WindowsRuntimeDefaultInterfaces centralizes default
interfaces, and lets the (build-time only) metadata be trimmed away when unused.
The mapping is recorded as a side effect of emitting the per-type marker (the single
chokepoint), so the lookup set never drifts from the set of types that actually carry
the marker (e.g. enums are not projected in component mode). Both emission and the
lookup type are skipped in reference-projection mode, where [WindowsRuntimeType] is
stripped along with the rest of the implementation-only surface.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Update the interop generator for the [WindowsRuntimeType] marker + centralized
metadata mapping:
- IsProjectedWindowsRuntimeType now checks for [WindowsRuntimeType] (the parameterless
marker) instead of the per-type [WindowsRuntimeMetadata] attribute.
- GetWindowsRuntimeMetadataName now reads the source .winmd stem from the
ABI.WindowsRuntimeMetadataTypes lookup type in the implementation projection (via a
new GetWindowsRuntimeMetadataTypesLookup module extension, mirroring
GetDefaultInterfacesLookup), rather than from a per-type attribute. This works
uniformly for types resolved from implementation and reference projections, since both
select the same implementation projection that carries the lookup type.
- Generated proxy types now emit the parameterless [WindowsRuntimeType] marker instead of
[WindowsRuntimeMappedMetadata("<contract>")]; the runtime only checks for its presence.
- InteropReferences/WellKnownMetadataNames swap the [WindowsRuntimeMetadata]/
[WindowsRuntimeMappedMetadata] references for [WindowsRuntimeType].
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Update the WinMD generator for the [WindowsRuntimeType] marker + centralized metadata mapping, mirroring the interop generator: - IsWindowsRuntimeType now checks for the [WindowsRuntimeType] marker. - WindowsRuntimeAssemblyName now reads the source .winmd contract assembly name from the centralized ABI.WindowsRuntimeMetadataTypes lookup type in the type's declaring module (via a new GetWindowsRuntimeMetadataTypesLookup module extension), instead of from a per-type [WindowsRuntimeMetadata] attribute. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…okup
Document the split of [WindowsRuntimeMetadata("contract")] into the parameterless
[WindowsRuntimeType] marker plus the centralized, trimmable ABI.WindowsRuntimeMetadataTypes
lookup type: a new subsection in the copilot instructions, the updated type-inclusion and
generated-attribute notes in the interop generator skill, and the rewritten metadata-name
derivation in the name-mangling reference.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
5362e08 to
c140feb
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Splits the dual-purpose
[WindowsRuntimeMetadata("contract")]attribute into a parameterless[WindowsRuntimeType]marker placed on every projected/proxy type, plus a single centralized, fully-trimmableABI.WindowsRuntimeMetadataTypeslookup type that carries the type -> source.winmdmapping (one[WindowsRuntimeMetadata(typeof(T), "stem")]entry per type). This mirrors howABI.WindowsRuntimeDefaultInterfacesalready centralizes default-interface metadata.Motivation
The old
[WindowsRuntimeMetadata]attribute did two unrelated jobs at once: it acted as the "this is a Windows Runtime type" marker, and it also carried the source.winmdmodule name (the "contract"/"stem") as a string on every single projected type. That string is never read at runtime — the runtime only ever checks for the presence of the attribute. The stem is needed only by build-time tooling (the interop and WinMD generators), and now that reference projections exist, those generators already have to recover that information through a lookup against the implementation projection.Given that, carrying a per-type string everywhere is pure overhead. Moving to a parameterless marker removes a string from the metadata of every projected type, and relocating the type -> stem mapping onto one dedicated lookup type means the entire mapping is dead-code-eliminated by ILLink/ILC whenever it isn't needed. The net result is smaller metadata with no loss of functionality.
Changes
src/WinRT.Runtime2/Attributes/: add the new parameterless, implementation-onlyWindowsRuntimeTypeAttributemarker; repurposeWindowsRuntimeMetadataAttributeto a(Type, string),class-targeting,AllowMultipleattribute used only on the centralized lookup type; delete the now-redundantWindowsRuntimeMappedMetadataAttribute.src/WinRT.Runtime2/(manually-projected types +ABI/proxy types): replace the per-type[WindowsRuntimeMetadata("...")]/[WindowsRuntimeMappedMetadata("...")]attributes with the parameterless[WindowsRuntimeType]marker across all manually-projected types and custom-mapped proxy types.src/WinRT.Runtime2/InteropServices/TypeMapInfo/: update the runtime lookups (WindowsRuntimeMetadataInfo,WindowsRuntimeMarshallingInfo) to recognize Windows Runtime types via[WindowsRuntimeType], and to distinguish projected vs. proxy types via[WindowsRuntimeMappedType].src/WinRT.Projection.Writer/: emit[WindowsRuntimeType]per projected type, and emit the centralizedABI.WindowsRuntimeMetadataTypeslookup type (implementation projections only) carrying the[WindowsRuntimeMetadata(typeof(T), "stem")]entries, wired through the generator run state, emit context, and finalization step (mirroring the default-interfaces flow).src/WinRT.Projection.Writer/Resources/Additions/(XAML structs): update the 12 hand-authored full-replacement XAML struct additions (CornerRadius,Duration,GridLength,KeyTime,RepeatBehavior,Matrix3Dfor both WinUI and UWP XAML) to use[WindowsRuntimeType], placed inside the existing#if !CSWINRT_REFERENCE_PROJECTIONblock alongside the other implementation-only attributes.src/WinRT.Interop.Generator/: recognize projected types via[WindowsRuntimeType]; read the source.winmdstem from the centralizedABI.WindowsRuntimeMetadataTypeslookup on the resolved implementation projection (newGetWindowsRuntimeMetadataTypesLookupreader); emit the parameterless marker on generated proxy types.src/WinRT.WinMD.Generator/: recognize Windows Runtime types via[WindowsRuntimeType]and recover the assembly/contract name from the centralized lookup type instead of from a per-type attribute..github/: updatecopilot-instructions.mdand the interop generator skill (SKILL.md+references/name-mangling-scheme.md) to document the new marker and the centralized metadata-types lookup.Validation
Built every affected project, and validated end-to-end locally by running the projection writer over the Windows SDK union metadata: the full generated Windows SDK projection (including all XAML namespaces and the new lookup type) compiles cleanly against the new runtime. An AsmResolver probe confirmed the consumption-side lookup correctly reads the emitted entries.