Add reference assembly support for WinRT.Runtime#2396
Open
Sergio0694 wants to merge 28 commits intostaging/3.0from
Open
Add reference assembly support for WinRT.Runtime#2396Sergio0694 wants to merge 28 commits intostaging/3.0from
Sergio0694 wants to merge 28 commits intostaging/3.0from
Conversation
ca98352 to
cab1a35
Compare
Introduce an internal sealed attribute to mark implementation-only members for WinRT runtime. The attribute targets all members, is non-inherited, and is conditional on WINDOWS_RUNTIME_REFERENCE_ASSEMBLY so it is emitted only in reference assemblies; this makes it explicit which members are implementation-only and allows them to be stripped from the runtime DLL. Added at src/WinRT.Runtime2/Attributes/WindowsRuntimeImplementationOnlyMemberAttribute.cs.
…members Replace the combination of [EditorBrowsable(Never)] and [Obsolete(...)] with the single [WindowsRuntimeImplementationOnlyMember] attribute on implementation-only members across WinRT.Runtime. Co-Authored-By: Copilot <223556219+Copilot@users.noreply.github.com>
Delete WindowsRuntimeConstants.cs which contained constants for WinRT private implementation detail messaging, the PrivateImplementationDetailObsoleteDiagnosticId (CSWINRT3001), and the CsWinRT diagnostics URL format. These constants have been removed from the project.
Delete the NoWarn entry and its comment for CSWINRT3001 from src/WinRT.Runtime2/WinRT.Runtime.csproj so warnings about '[Obsolete]' private implementation details are no longer suppressed. This change surfaces those warnings for visibility during builds.
Delete the NoWarn entry and accompanying comment that suppressed AD0001 analyzer warnings from WinRT.Runtime.csproj. This removes the previous workaround for the ILLink analyzer exception so AD0001 warnings will no longer be globally suppressed; signing and other project settings are unchanged.
Move the concrete implementation of WindowsRuntimeObject into a new partial file (WindowsRuntimeObject.Impl.cs) and make WindowsRuntimeObject a partial/ref-assembly-friendly type. Update WindowsRuntimeObject.cs to conditionally include implementation-only usings under WINDOWS_RUNTIME_REFERENCE_ASSEMBLY. Adjust project file to use WINDOWS_RUNTIME_REFERENCE_ASSEMBLY for reference-assembly builds (replacing REFERENCE_ASSEMBLY in comments and DefineConstants) and remove the earlier DefineConstants injection in the normal build group. Also remove the UnreachableException extension method from WindowsRuntimeExceptionExtensions.cs. These changes prepare the codebase for trimmed/reference assembly builds and separate implementation details from the reference surface.
Replace the hard-coded 'ABI\**\*.cs' removal with a dynamic scan that drops every compile item whose file contains '[WindowsRuntimeImplementationOnlyMember]'. Runs inside a target so MSBuild applies item batching to the '%(FullPath)' metadata access. Co-Authored-By: Copilot <223556219+Copilot@users.noreply.github.com>
When building reference assemblies (CsWinRTBuildReferenceAssembly == true), remove all ABI source files from compilation by adding a Compile Remove for ABI\**\*.cs. These ABI types aren't needed in reference assemblies and can contain internal-only types that would be kept otherwise and cause build errors. A clarifying comment was also added to explain the rationale.
…ENTATION_ASSEMBLY Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…public types Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Remove the conditional compilation (#if WINDOWS_RUNTIME_REFERENCE_ASSEMBLY / #endif) around the [SupportedOSPlatform("windows10.0.10240.0")] attribute in AsyncInfo and WindowsRuntimeTaskExtensions so the attribute is always emitted. This ensures these APIs are annotated for Windows platform compatibility even when the WINDOWS_RUNTIME_REFERENCE_ASSEMBLY symbol is not defined.
Surround Windows.Foundation.Metadata and System.Runtime.Versioning using directives with #if WINDOWS_RUNTIME_REFERENCE_ASSEMBLY across many sources so metadata attributes are only included for reference-assembly builds. Add WINDOWS_RUNTIME_IMPLEMENTATION_ASSEMBLY to DefineConstants in the csproj for normal implementation builds to simplify #if logic (and update related comments to reference WINDOWS_RUNTIME_REFERENCE_ASSEMBLY). Also tidy WindowsRuntimeObject by replacing throw null! with throw null.
Define an implementation-only marker in several interop source files and update the project to produce a reference assembly build. Added #define WINDOWS_RUNTIME_IMPLEMENTATION_ONLY_FILE to selected InteropServices files, enabled CsWinRTBuildReferenceAssembly, and added MSBuild rules to exclude files that contain the marker (or the existing [WindowsRuntimeImplementationOnlyMember] attribute), ABI types, and other implementation-only folders from the reference-assembly compile. This provides a simple file-level opt-out for sources that reference internal types so the reference assembly can build cleanly.
Wrap method bodies that reference implementation-only types with #if WINDOWS_RUNTIME_REFERENCE_ASSEMBLY/#else/#endif so the reference assembly build (CsWinRTBuildReferenceAssembly=true) compiles successfully. Co-Authored-By: Copilot <223556219+Copilot@users.noreply.github.com>
Mark interop structs with [StructLayout(LayoutKind.Sequential)] to ensure correct memory layout for COM/WinRT interop: ComCallData, HSTRING_HEADER, and its nested union. Add missing System.Runtime.InteropServices using directives. Also disable CS1574 in WindowsRuntimeFeatureSwitches.cs to suppress documentation reference warnings.
Co-Authored-By: Copilot <223556219+Copilot@users.noreply.github.com>
This diagnostic is no longer applicable now that the private implementation detail [Obsolete] attributes have been removed. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Update copilot-instructions.md and interop-generator SKILL.md to reflect that private implementation detail types are now excluded from the reference assembly via #if !REFERENCE_ASSEMBLY, rather than being marked with [Obsolete] and [EditorBrowsable(Never)] attributes. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Expand the version compatibility section to explain how the interop generator uses WinRT.Runtime's implementation assembly (not the reference assembly) to access private implementation detail APIs, with concrete examples of the type categories involved. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Update copilot-instructions.md and the interop-generator and update-copilot-instructions skills to describe the actual mechanism used to build the WinRT.Runtime reference assembly: the WINDOWS_RUNTIME_REFERENCE_ASSEMBLY and WINDOWS_RUNTIME_IMPLEMENTATION_ASSEMBLY define constants, the [WindowsRuntimeImplementationOnlyMember] attribute (which triggers MSBuild file removal), the #define WINDOWS_RUNTIME_IMPLEMENTATION_ONLY_FILE opt-out, and the wholesale folder removals. Co-Authored-By: Copilot <223556219+Copilot@users.noreply.github.com>
Add a <Compile Remove> entry to src/WinRT.Runtime2/WinRT.Runtime.csproj to exclude Exceptions/**/*.cs from compilation. This matches other implementation-only folders removed from the project (e.g. ABI, InteropServices) to minimize the number of code changes and reduce the build surface.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Adjust conditional compilation and attribute placement for WinRT metadata types. Add conditional import of System.Runtime.Versioning and split ApiContractAttribute between implementation (WindowsRuntimeMetadata) and reference (SupportedOSPlatform + ContractVersion) builds, moving AttributeUsage to a shared location. Do the same reordering for ContractVersionAttribute, and remove redundant remarks comments from FoundationContract and UniversalApiContract to clean up source.
d83014f to
b89f76a
Compare
Treat [ApiContract] like [ContractVersion] in the metadata attribute filter: only emit it for reference projections and skip it when generating implementation assemblies. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
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
Add reference assembly support for
WinRT.Runtimeso the NuGet package ships with a stripped-down public API surface inref\net10.0\and the full implementation inlib\net10.0\. Implementation-detail types and members are removed from the reference assembly via a combination of the new[WindowsRuntimeImplementationOnlyMember]marker attribute, a#define WINDOWS_RUNTIME_IMPLEMENTATION_ONLY_FILEper-file opt-out, wholesale folder exclusions, andWINDOWS_RUNTIME_REFERENCE_ASSEMBLY/WINDOWS_RUNTIME_IMPLEMENTATION_ASSEMBLYdefine constants for the few cases that need finer-grained conditional code.This supersedes #2377, which used a different mechanism (
#if !REFERENCE_ASSEMBLYguards sprinkled across ~400 files plus[Obsolete]/[EditorBrowsable(Never)]attributes on the public-but-implementation-only APIs). The new approach is much less invasive in source files and produces a cleaner reference assembly.Motivation
WinRT.Runtimeexposes many public types and members that are "private implementation details" — they have to be public so generated projection code in other assemblies can call them, but they are not part of the versioned API surface and should not be visible to downstream consumers. Previously these were marked with[Obsolete]+[EditorBrowsable(Never)], which left them visible in IntelliSense and reflection and prevented us from cleanly evolving the implementation.With reference assembly support:
lib\net10.0\) withWINDOWS_RUNTIME_IMPLEMENTATION_ASSEMBLYdefined.CsWinRTBuildReferenceAssembly=trueproduces the reference assembly (ref\net10.0\) withWINDOWS_RUNTIME_REFERENCE_ASSEMBLYdefined, with all implementation-only sources removed and remaining method bodies stubbed withthrow null.The interop generator and other CsWinRT build tools continue to consume the full implementation assembly, so they retain access to all the private implementation detail APIs they need.
Changes
src/WinRT.Runtime2/Attributes/WindowsRuntimeImplementationOnlyMemberAttribute.cs: new internal[Conditional("WINDOWS_RUNTIME_REFERENCE_ASSEMBLY")]marker attribute applied at the top of every implementation-only top-level typesrc/WinRT.Runtime2/WinRT.Runtime.csproj: defineWINDOWS_RUNTIME_IMPLEMENTATION_ASSEMBLYfor normal builds andWINDOWS_RUNTIME_REFERENCE_ASSEMBLYfor reference assembly builds; add MSBuild target that scans compile items and removes any source containing[WindowsRuntimeImplementationOnlyMember]or the#define WINDOWS_RUNTIME_IMPLEMENTATION_ONLY_FILEmarker; remove implementation-only folders (ABI\,NativeObjects\, mostInteropServices\subfolders) wholesale from the reference assembly compile.csfiles insrc/WinRT.Runtime2/: add the[WindowsRuntimeImplementationOnlyMember]marker on implementation-only top-level types, or#define WINDOWS_RUNTIME_IMPLEMENTATION_ONLY_FILEat the top of files that should be removed wholesale; conditionally include using directives forWindows.Foundation.Metadata/System.Runtime.Versioningonly in the implementation build; stub remaining method bodies in the reference assembly withthrow nullsrc/WinRT.Runtime2/WindowsRuntimeObject.cs+WindowsRuntimeObject.Impl.cs: splitWindowsRuntimeObjectinto a partial class so the public surface (class declaration + abstract members) lives in the reference assembly and the concrete implementation lives inWindowsRuntimeObject.Impl.cs; restoreHasUnwrappableNativeObjectReferenceandIsOverridableInterfacetoabstract(reverting the temporary workaround from Hide HasUnwrappableNativeObjectReference and IsOverridableInterface from reference projections #2371)build/AzurePipelineTemplates/CsWinRT-Build-Steps.ymlandnuget/Microsoft.Windows.CsWinRT.nuspec: build pipeline runs the reference assembly build and packs both the reference and implementation assemblies into the NuGetdocs/diagnostics/cswinrt30001.md(deleted): theCSWINRT3001diagnostic for the previous[Obsolete]-based approach is no longer applicablesrc/WinRT.Runtime2/Properties/WindowsRuntimeConstants.cs(deleted): file only contained constants for the removed[Obsolete]messages.github/copilot-instructions.md,.github/skills/interop-generator/SKILL.md,.github/skills/update-copilot-instructions/SKILL.md: document the new reference assembly mechanism (define constants, marker attribute, file-level opt-out, folder exclusions) and how the interop generator continues to use the implementation assembly[StructLayout(LayoutKind.Sequential)]toComCallDataandHSTRING_HEADER, suppressCS1574inWindowsRuntimeFeatureSwitches.cs, strip[SupportedOSPlatform]and[ContractVersion]from public types in the impl assembly, remove the unusedUnreachableExceptionextension method