Carry over all applications of repeated Windows Runtime attributes - #2493
Merged
Sergio Pedri (Sergio0694) merged 2 commits intoJul 31, 2026
Merged
Sergio Pedri (Sergio0694) merged 2 commits into
Sergio Pedri (Sergio0694) merged 2 commits into
Conversation
|
Azure Pipelines: There may be pipelines that require an authorized user to comment /azp run to run. |
Sergio Pedri (Sergio0694)
requested a review
from Manodasan Wignarajah (manodasanW)
July 28, 2026 22:18
Sergio Pedri (Sergio0694)
force-pushed
the
user/sergiopedri/fix-repeated-winrt-attributes
branch
from
July 29, 2026 00:56
7cd8a0c to
0111192
Compare
Sergio Pedri (Sergio0694)
force-pushed
the
user/sergiopedri/fix-repeated-winrt-attributes
branch
2 times, most recently
from
July 29, 2026 05:20
a0d02ff to
5ca1f3e
Compare
Sergio Pedri (Sergio0694)
changed the base branch from
staging/3.0
to
user/sergiopedri/erase-winrt-attribute-generics
July 29, 2026 05:27
Sergio Pedri (Sergio0694)
force-pushed
the
user/sergiopedri/fix-repeated-winrt-attributes
branch
3 times, most recently
from
July 29, 2026 17:10
33afe82 to
ed02190
Compare
Sergio Pedri (Sergio0694)
force-pushed
the
user/sergiopedri/fix-repeated-winrt-attributes
branch
from
July 29, 2026 17:47
ed02190 to
642181e
Compare
|
Azure Pipelines: There may be pipelines that require an authorized user to comment /azp run to run. |
Sergio Pedri (Sergio0694)
force-pushed
the
user/sergiopedri/fix-repeated-winrt-attributes
branch
from
July 29, 2026 20:27
48d5a58 to
5e398cc
Compare
Sergio Pedri (Sergio0694)
force-pushed
the
user/sergiopedri/fix-repeated-winrt-attributes
branch
from
July 29, 2026 22:35
5e398cc to
1722df3
Compare
Manodasan Wignarajah (manodasanW)
approved these changes
Jul 31, 2026
Base automatically changed from
user/sergiopedri/erase-winrt-attribute-generics
to
staging/3.0
July 31, 2026 18:27
'CustomAttributeFactory.WriteCustomAttributes' accumulated the attributes to carry over into a dictionary keyed by the projected attribute name, so when a Windows Runtime type carried the same '[allowmultiple]' attribute more than once (e.g. several '[TemplateVisualState]' applications on a control), every application except the last was silently dropped from the projection. The attributes are now collected into an ordered list with one entry per application, so all of them are emitted. Also fixes a latent issue in the same method where several '[ContractVersion]' attributes would merge their platform strings into the argument list of a single '[SupportedOSPlatform]', which is not a valid constructor shape: only the first resolved platform is emitted now, matching the existing member-level behavior in 'WritePlatformAttributeBody'. Additionally, the Windows Runtime '[AllowMultiple]' to .NET 'AttributeUsage(AllowMultiple = true)' mapping now also applies when the metadata carries no '[AttributeUsage]', by synthesizing one. Otherwise the projected attribute type would silently fall back to the .NET default of 'AllowMultiple = false' and could not be applied more than once. Fixes #2491 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 37dfc23a-6ce8-4c65-a890-5ca8ff319f27
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 37dfc23a-6ce8-4c65-a890-5ca8ff319f27
Sergio Pedri (Sergio0694)
force-pushed
the
user/sergiopedri/fix-repeated-winrt-attributes
branch
from
July 31, 2026 18:27
1722df3 to
b6e3e79
Compare
Sergio Pedri (Sergio0694)
deleted the
user/sergiopedri/fix-repeated-winrt-attributes
branch
July 31, 2026 21:11
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
Fixes #2491: when a Windows Runtime type carries the same
[allowmultiple]attribute more than once, the projection only kept one of the applications. All applications are now carried over.Motivation
CustomAttributeFactory.WriteCustomAttributesaccumulated the attributes to carry over into aDictionary<string, List<string>>keyed by the projected attribute's full name, and assigned withattributes[fullAttrName] = args. Windows Runtime attributes marked[allowmultiple](for instance[TemplateVisualState]) can legitimately be applied several times to the same type, so every application after the first silently overwrote the previous one and was lost from the generated projection.The issue report shows this with a control declaring eight
[TemplateVisualState]attributes in its.idl: the.winmdcontains all eight, but the generated C# only carries a single one.Two adjacent problems in the same method are fixed at the same time:
Several
[ContractVersion]attributes merged their computed platform strings into the argument list of a single[SupportedOSPlatform], which is not a valid constructor shape. Only the first resolved platform is emitted now, which matches the pre-existing member-level behavior inWritePlatformAttributeBody.The Windows Runtime
[AllowMultiple]metadata attribute has no .NET counterpart: it maps to theAllowMultiplenamed argument of[AttributeUsage]on the projected attribute type. That mapping only happened when the metadata also carried an[AttributeUsage]. When it didn't, the projected attribute type silently fell back to the .NET default ofAllowMultiple = falseand could not be applied more than once. An[AttributeUsage(AttributeTargets.All, AllowMultiple = true)]is now synthesized in that case.Changes
src/WinRT.Projection.Writer/Factories/CustomAttributeFactory.cs: collect the carried-over attributes into an ordered list with one entry per application instead of a dictionary keyed by attribute name, so repeated applications are all emitted; emit at most one[SupportedOSPlatform]; synthesize an[AttributeUsage]when the metadata only carries[AllowMultiple].src/Tests/TestComponentCSharp/TestComponentCSharp.idl: add an[allowmultiple]attribute (MyRepeatableAttribute,attr_repeatable) and aRepeatedAttributeTestruntime class carrying several of its applications, interleaved with a non-repeatable attribute, plus one exact-duplicate application (MIDL accepts those for repeatable attributes, and reflection reports both).src/Tests/UnitTest/TestComponentCSharp_Tests.cs: addTestRepeatedAttributesAreProjected, verifying every application survives the projection with the right arguments and that a non-repeatable attribute is still projected exactly once, andTestAllowMultipleIsProjectedOnAttributeUsage, verifying the[AllowMultiple]toAttributeUsage(AllowMultiple = ...)mapping in both directions.Validation
Ran
cswinrtprojectionrefgenover the entire Windows SDK (reference projection and merged projection modes) and over the full WinUI surface, before and after the change: the generated sources are byte-identical, so no existing projection is affected.Built
TestComponentCSharp.winmdwith MIDL from the new.idland projected it before and after: the only difference is the newly preserved attribute applications.Verified against MIDL that duplicated applications of a non-repeatable attribute are rejected (
MIDL2096) while duplicated applications of an[allowmultiple]attribute are accepted and preserved in the.winmd, so the emission is intentionally faithful rather than de-duplicating.