Add support for custom overload names to the WinMD generator - #2454
Merged
Conversation
Port custom overload name support from PR #2275 (CsWinRT 2.x) to the CsWinRT 3.0 WinMD generator (cswinrtwinmdgen). When an authored method carries [Windows.Foundation.Metadata.Overload("Name")], emit that name in the generated .winmd instead of an auto-generated sequential one. windows-rs consumers require explicit overload names because Rust has no method overloading. - Record author-specified overload names while emitting interface methods and honor them in AddOverloadAttributesForType; stop copying the [Overload] attribute verbatim so it is never duplicated. - Select the default overload (which keeps the original name) from the [DefaultOverload] attribute rather than metadata order, so an author-specified name is not dropped when the default is not declared first. - Auto-generated names skip any name already used by another method or an author-specified overload, avoiding collisions. - Emit [Overload] only on interfaces (authored and synthesized), matching the Windows Runtime metadata convention; runtime classes expose their ABI through interfaces (consistent with CsWinRT 2.x). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add the ICustomOverloadNames interface and CustomOverloadNamesClass authoring types, and the CustomOverloadNames consumption test. The test validates that author-specified [Overload] names (LookupByIndex, LookupByFlag, TransformNumber) appear in the generated projection's ABI vtables, on both an authored interface and a class's synthesized interface. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…lt selection
Extend the overload-name tests to cover behaviors beyond the original PR:
- Verify the auto-generated ABI name (Transform2) coexists with an author-
specified one (TransformNumber) in the same overload group.
- OverloadCollisionClass: an author-specified overload name matching the auto
pattern ("M2") forces the auto-generated name of the remaining overload to
skip it ("M3").
- DefaultOverloadNotFirstClass / IDefaultOverloadNotFirst: [DefaultOverload] on
a non-first overload keeps the original ABI name, while the author-specified
name ("GetByIndex") on the first overload is still honored.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This was referenced Jun 18, 2026
manodasanW
approved these changes
Jul 24, 2026
Sergio0694
added a commit
that referenced
this pull request
Jul 28, 2026
The custom overload names change (#2454) took error ids 0011 and 0012 for 'WindowsSdkNotFound' and 'CannotReadWindowsSdkXml', so renumber the new by-reference array/span parameter errors to 0013 and 0014 and update the tests and the testing skill accordingly. Also update the new test project for the build changes on staging: drop 'LangVersion' (now centralized in 'src/Directory.Build.props') and drop the removed 'ARM' platform from the solution entry (#2472, #2489). Finally, fix the stale 'GlobalPropertiesToRemove' mention in the testing skill, which the project file replaced with 'UndefineProperties'. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 8ec1fee3-01c2-4213-baf0-bed82d056068
Sergio0694
added a commit
that referenced
this pull request
Jul 28, 2026
The range was already stale at '0001'-'0010': the custom overload names change (#2454) added 0011 and 0012. This adds 0013 and 0014, so bump the documented range to '0001'-'0014'. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 8ec1fee3-01c2-4213-baf0-bed82d056068
Sergio0694
added a commit
that referenced
this pull request
Jul 28, 2026
… tests (#2443) * Fix custom-modifier type erasure in the WinMD generator type mapping MapTypeSignatureToOutput had no handling for CustomModifierTypeSignature, so any modifier-wrapped type fell through to the 'System.Object' fallback and was silently erased. This affects 'in' parameters on abstract/virtual/interface/delegate members, where the C# compiler emits a 'modreq(InAttribute)' on the by-reference type. For example, a COM interop 'in Guid riid' was emitted as '[in] object' instead of '[in] Guid&'. Strip leading custom modifiers before dispatching on the underlying type. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Validate unsupported array/span parameter conventions in the WinMD generator Windows Runtime arrays use one of three conventions (ReadOnlySpan<T> for PassArray, Span<T> for FillArray, or 'out T[]' for ReceiveArray), and spans are always passed by value. The generator previously emitted invalid metadata for a few shapes: 'ref T[]'/'in T[]' became '[in] T[]&', and 'out Span<T>'/'out ReadOnlySpan<T>' became a ReceiveArray. Reject these with clear errors (CSWINRTWINMDGEN0011 for by-reference arrays, CSWINRTWINMDGEN0012 for by-reference spans), while preserving the deliberate COM interop 'ref'/'in' scalar behavior (e.g. 'ref Guid riid' -> '[in]') and the by-value array PassArray default. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Add WinMD generator parameter-convention failure tests Add a WinMDGeneratorTest project that runs the actual cswinrtwinmdgen tool end-to-end: it compiles small C# inputs with Roslyn, invokes the generator as a subprocess, and asserts a non-zero exit code plus the expected CSWINRTWINMDGEN error. The project deliberately focuses on failure cases (unsupported 'ref'/'in' arrays and 'out' spans), which can be exercised here without failing the build; the supported '.winmd' shapes (PassArray/FillArray/ReceiveArray) are covered by the authoring tests. The generator exposes no internals to the test project. Registers the project in the solution. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Add WinMD generator invocation and invalid-input failure tests Extend the WinMDGeneratorTest harness with a custom-response-file overload and a public CompileComponent helper, then add Test_InvalidInputs covering the generator's remaining end-to-end failure modes: a missing response file (CSWINRTWINMDGEN0001), a malformed or duplicate-argument response file (0002), a missing required or unparseable argument (0003), a missing or corrupt input assembly (0004), an unwritable output path (0006), and a missing debug-repro directory (0008). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Move WinMD generator TypeSignature helpers into an extension file Move StripCustomModifiers (previously a private method in WinMDWriter.TypeMapping) and the span predicates into a new Extensions/TypeSignatureExtensions.cs, matching the existing TypeDefinitionExtensions pattern. Rename IsSpan/IsReadOnlySpan to IsTypeOfSpan/IsTypeOfReadOnlySpan as extension methods, consistent with the interop generator's IsTypeOf* extensions. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Add AssertSuccess/AssertFailure helpers to collapse WinMD generator tests Rename the test helper to WinMDGeneratorRunner and give it AssertSuccess/AssertFailure entry points that run the generator and make the exit-code and error-output assertions, so each test is a single call. The run mechanics (Run, RunTool, GetGeneratorPath, the failure-result assertion, cleanup) are private; only the assertion entry points and CompileComponent (used by the response-file factory scenarios) are public. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Take full response file content as a single string in WinMD generator tests Change the AssertFailure response-file factory from Func<string, IReadOnlyList<string>> to Func<string, string> so callers provide the entire '.rsp' content as one multiline raw interpolated string instead of a list of per-line expressions. The runner now writes the content verbatim with File.WriteAllText. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Document the WinMDGeneratorTest project in the testing skill Add a 'WinMD generator tests' section describing the new src/Tests/WinMDGeneratorTest project (end-to-end failure-case tests for cswinrtwinmdgen), add a routing-table row, and bump the primary test area count to 6. Also add a matching per-project verification step to the update-testing-instructions skill and renumber the subsequent steps. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix stale comment in WinMDGeneratorTest project file The tests run the generator tool end-to-end as a subprocess rather than exercising its managed logic in-process, so update the comment that justifies 'CsWinRTEnabled=false' to match. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Move new WinMD generator errors after the existing ones Define the by-reference array/span parameter errors (0011/0012) after the debug-repro errors (0008-0010) instead of in the middle, so the methods appear in ascending error-id order. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Build the WinMD generator framework-dependent in the test project (NETSDK1151) The generator's PublishAot build is self-contained, which a non self-contained executable cannot reference (NETSDK1151). Replace GlobalPropertiesToRemove for RuntimeIdentifier with UndefineProperties for BuildToolArch, PublishBuildTool, RuntimeIdentifier and SelfContained so the tool is built framework-dependent for the build host, matching the proven WinRT.Internal reference pattern. The output stays under net10.0 (no RID subfolder), so the tool path used by the tests is unchanged. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Wrap long exception messages for readability Split long interpolated exception message strings into multi-line concatenated strings in src/WinRT.WinMD.Generator/Errors/WellKnownWinMDExceptions.cs (ByReferenceArrayParameterNotSupported and ByReferenceSpanParameterNotSupported) to improve readability and line-length compliance; no functional behavior changes. * Adapt the WinMD generator parameter validation to staging/3.0 The custom overload names change (#2454) took error ids 0011 and 0012 for 'WindowsSdkNotFound' and 'CannotReadWindowsSdkXml', so renumber the new by-reference array/span parameter errors to 0013 and 0014 and update the tests and the testing skill accordingly. Also update the new test project for the build changes on staging: drop 'LangVersion' (now centralized in 'src/Directory.Build.props') and drop the removed 'ARM' platform from the solution entry (#2472, #2489). Finally, fix the stale 'GlobalPropertiesToRemove' mention in the testing skill, which the project file replaced with 'UndefineProperties'. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 8ec1fee3-01c2-4213-baf0-bed82d056068 * Update the WinMD generator error id range in the instructions The range was already stale at '0001'-'0010': the custom overload names change (#2454) added 0011 and 0012. This adds 0013 and 0014, so bump the documented range to '0001'-'0014'. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 8ec1fee3-01c2-4213-baf0-bed82d056068 --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 8ec1fee3-01c2-4213-baf0-bed82d056068
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
Honor an author-applied
[Windows.Foundation.Metadata.Overload("Name")]attribute when generating a component's.winmd, emitting that name instead of an auto-generated sequential one. This ports #2275 (which targeted CsWinRT 2.x) to the CsWinRT 3.0 WinMD generator.Motivation
Rust (windows-rs) and some other Windows Runtime consumers cannot represent overloaded methods, so they rely on the
[Overload]attribute to give each overload a distinct, ergonomic ABI name. Previously, author-specified names were ignored and the generator always auto-generated sequential suffixes (Method2,Method3, …). PR #2275 added support for honoring them in CsWinRT 2.x. CsWinRT 3.0 produces the.winmdwith a different, post-build tool (cswinrtwinmdgen, which analyzes the compiled.dllwith AsmResolver rather than running a Roslyn source generator), so the behavior had to be re-implemented there.Changes
Generator (
src/WinRT.WinMD.Generator/):Writers/WinMDWriter.Finalization.cs:AddOverloadAttributesForTypenow honors an author-specified[Overload("...")]name when present (otherwise it keeps auto-generating a sequential name). It also selects the default overload (the one that keeps the original ABI name) from the[DefaultOverload]attribute rather than from metadata order, so an author-specified name is not dropped when the default is not declared first, and auto-generated names skip any name already used by another member or overload to avoid collisions. Adds theRecordUserSpecifiedOverloadNameandHasDefaultOverloadAttributehelpers.Writers/WinMDWriter.Members.cs: records the author-specified overload name while emitting interface methods (authored and synthesized), so finalization can honor it.Writers/WinMDWriter.Attributes.cs:ShouldCopyAttributeno longer copies[Overload]verbatim; it is emitted exactly once by the overload phase as the single source of truth, preventing duplicates.Writers/WinMDWriter.cs: adds the_userSpecifiedOverloadNamesmap.[Overload]is emitted only on interfaces (authored and synthesized), not on runtime classes, matching the Windows Runtime metadata convention and CsWinRT 2.x (a runtime class exposes its ABI through interfaces).Tests:
src/Tests/AuthoringTest/Program.cs: theICustomOverloadNamesinterface andCustomOverloadNamesClassfrom PR Add support for custom overload names to CsWinMD #2275, plus types covering additional behaviors (OverloadCollisionClass,IDefaultOverloadNotFirst/DefaultOverloadNotFirstClass).src/Tests/AuthoringConsumptionTest/test.cpp: the portedCustomOverloadNamesconsumption test, plus new tests for an auto-generated name coexisting with an author-specified one, collision avoidance, and[DefaultOverload]on a non-first overload.src/Tests/AuthoringConsumptionTest/AuthoringConsumptionTest.exe.manifest:activatableClassentries for the newly activatable test classes (includingCustomOverloadNamesClass, whose entry the original PR omitted).