Skip to content

Pass WinRT.* generated .dll-s to 'cswinrtgen'#2235

Open
Sergio0694 wants to merge 19 commits intostaging/3.0from
user/sergiopedri/cswinrtgen-authoring-dll
Open

Pass WinRT.* generated .dll-s to 'cswinrtgen'#2235
Sergio0694 wants to merge 19 commits intostaging/3.0from
user/sergiopedri/cswinrtgen-authoring-dll

Conversation

@Sergio0694
Copy link
Member

Title. This also allows hiding all implementation detail attributes from the reference assemblies.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the CsWinRT toolchain so cswinrtgen can consume the generated WinRT.* assemblies (eg. WinRT.Projection.dll, optionally WinRT.Component.dll) to retrieve metadata that is intentionally hidden from reference assemblies, enabling reference projections to omit implementation-detail attributes.

Changes:

  • Suppress emitting certain implementation-detail attributes in reference projections (eg. default interface / reference type attributes).
  • Extend cswinrtgen (WinRT.Interop.Generator) to accept/load WinRT.Projection.dll (required) and WinRT.Component.dll (optional) and use them for IID/default-interface resolution.
  • Refactor IID/signature generation helpers to flow InteropDefinitions and add a cached top-level type lookup for faster resolution.

Reviewed changes

Copilot reviewed 37 out of 37 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
src/cswinrt/code_writers.h Skips emitting some attributes for reference_projection; adjusts delegate emission formatting.
src/WinRT.Interop.Generator/WinRT.Interop.Generator.csproj Switches C# LangVersion to 14.0.
src/WinRT.Interop.Generator/References/InteropReferences.cs Clarifies docs around WinRT runtime module scope.
src/WinRT.Interop.Generator/References/InteropDefinitions.cs Adds projection/component module references to definitions object and renames interop module field.
src/WinRT.Interop.Generator/Helpers/SignatureGenerator.cs Threads InteropDefinitions through signature generation; adds IID lookup helpers using projection module.
src/WinRT.Interop.Generator/Helpers/SignatureGenerator.Projections.cs Updates projection signature helpers to use new IID/default-interface resolution logic.
src/WinRT.Interop.Generator/Helpers/GuidGenerator.cs Updates IID creation to use updated signature generation API.
src/WinRT.Interop.Generator/Generation/InteropGeneratorDiscoveryState.cs Tracks loaded WinRT.Projection.dll and optional WinRT.Component.dll modules.
src/WinRT.Interop.Generator/Generation/InteropGeneratorArgs.cs Adds CLI args for projection/component assembly paths.
src/WinRT.Interop.Generator/Generation/InteropGeneratorArgs.Parsing.cs Parses new CLI args from response file.
src/WinRT.Interop.Generator/Generation/InteropGeneratorArgs.Formatting.cs Emits new CLI args into response file.
src/WinRT.Interop.Generator/Generation/InteropGenerator.Emit.cs Constructs InteropDefinitions with projection/component modules; propagates definitions through emit path.
src/WinRT.Interop.Generator/Generation/InteropGenerator.Discover.cs Loads projection/component modules before discovering other inputs.
src/WinRT.Interop.Generator/Generation/InteropGenerator.DebugRepro.cs Includes projection/component assemblies in debug repro pack/unpack.
src/WinRT.Interop.Generator/Factories/InteropCustomAttributeFactory.cs Updates GUID attribute factory to use new IID generation API.
src/WinRT.Interop.Generator/Extensions/WindowsRuntimeExtensions.cs Adds helper to identify Windows Runtime component assemblies via attribute.
src/WinRT.Interop.Generator/Extensions/ModuleDefinitionExtensions.cs Makes extension class partial and adds TryGetType helper.
src/WinRT.Interop.Generator/Extensions/ModuleDefinitionExtensions.TypesLookup.cs Adds cached TopLevelTypes lookup via frozen dictionary + weak table.
src/WinRT.Interop.Generator/Builders/WindowsRuntimeTypeHierarchyBuilder.cs Removes unnecessary unsafe on Lookup signature.
src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.cs Updates IID creation calls to pass InteropDefinitions.
src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.IReadOnlyList1.cs Threads InteropDefinitions to GUID attribute creation for generated types.
src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.IReadOnlyDictionary2.cs Threads InteropDefinitions to GUID attribute creation for generated types.
src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.IObservableVector1.cs Threads InteropDefinitions to GUID attribute creation for generated types.
src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.IObservableMap2.cs Threads InteropDefinitions to GUID attribute creation for generated types.
src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.IMapChangedEventArgs1.cs Threads InteropDefinitions to GUID attribute creation for generated types.
src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.IList1.cs Threads InteropDefinitions to GUID attribute creation for generated types.
src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.IEnumerator1.cs Threads InteropDefinitions to IID + GUID attribute creation for generated types.
src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.IEnumerable1.cs Threads InteropDefinitions to GUID attribute creation for generated types.
src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.IDictionary2.cs Threads InteropDefinitions to GUID attribute creation for generated types.
src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.IAsyncOperationWithProgress2.cs Threads InteropDefinitions to GUID attribute creation for generated types.
src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.IAsyncOperation1.cs Threads InteropDefinitions to GUID attribute creation for generated types.
src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.IAsyncActionWithProgress1.cs Threads InteropDefinitions to GUID attribute creation for generated types.
src/WinRT.Interop.Generator/Builders/InteropTypeDefinitionBuilder.Delegate.cs Updates delegate IID generation calls to pass InteropDefinitions.
src/WinRT.Interop.Generator/Builders/DynamicCustomMappedTypeMapEntriesBuilder.cs Threads InteropDefinitions through dynamic custom-mapped type map entry generation.
src/WinRT.Interop.Generator/Builders/DynamicCustomMappedTypeMapEntriesBuilder.INotifyPropertyChanged.cs Threads InteropDefinitions to GUID attribute creation for dynamic mapped type.
src/WinRT.Interop.Generator/Builders/DynamicCustomMappedTypeMapEntriesBuilder.INotifyCollectionChanged.cs Threads InteropDefinitions to GUID attribute creation for dynamic mapped type.
src/WinRT.Interop.Generator/Builders/DynamicCustomMappedTypeMapEntriesBuilder.ICommand.cs Threads InteropDefinitions to GUID attribute creation for dynamic mapped type.
Comments suppressed due to low confidence (2)

src/WinRT.Interop.Generator/Helpers/SignatureGenerator.Projections.cs:157

  • In Delegate(...), the IID resolution check is inverted: the method currently returns null when an IID is successfully retrieved and returns a signature using Guid.Empty when it fails. Flip the condition so the method returns null only when IID resolution fails, and returns delegate({iid}) when it succeeds.
    src/WinRT.Interop.Generator/Helpers/SignatureGenerator.cs:206
  • These 'if' statements can be combined.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@Sergio0694 Sergio0694 force-pushed the user/sergiopedri/cswinrtgen-authoring-dll branch 5 times, most recently from e72b8ed to e986c13 Compare February 13, 2026 17:28
@Sergio0694 Sergio0694 marked this pull request as ready for review February 13, 2026 17:28
@Sergio0694 Sergio0694 force-pushed the user/sergiopedri/cswinrtgen-authoring-dll branch 2 times, most recently from a46db08 to 02098de Compare February 13, 2026 19:27
Sergio0694 and others added 18 commits February 13, 2026 18:06
Add explicit support for WinRT.Projection.dll and optional WinRT.Authoring.dll in the interop generator. Introduces WinRTProjectionAssemblyPath and WinRTAuthoringAssemblyPath to InteropGeneratorArgs (parsing and .rsp formatting), wires them through the debug repro flow, and copies/hash-maps these inputs into the temporary output directory via a new CopyHashedFileToDirectory helper. Also adds WindowsRuntimeAuthoringAssemblyAttribute detection in WindowsRuntimeExtensions and brings in System.Diagnostics.CodeAnalysis for a NotNullIfNotNull annotation.
Load WinRT.Projection.dll (and optional WinRT.Authoring.dll) early during discovery and store their ModuleDefinition instances in the discovery state. Adds LoadWinRTModules to InteropGenerator.Discover to read the projection/authoring assemblies, check for cancellation, and call discovery tracking. Extends InteropGeneratorDiscoveryState with nullable backing fields, public properties, and TrackWinRTProjectionModuleDefinition / TrackWinRTAuthoringModuleDefinition methods (with MemberNotNull and ThrowIfReadOnly), and adds the required System.Diagnostics.CodeAnalysis import.
Change InteropDefinitions to accept three ModuleDefinition parameters: the interop module (renamed to windowsRuntimeInteropModule), the Windows Runtime projection module, and the Windows Runtime authoring module. Update all WellKnownTypeDefinitionFactory usages to reference the renamed interop module field, add properties for the projection and authoring modules, and update the emitter to pass discoveryState.WinRTProjectionModuleDefinition and WinRTAuthoringModuleDefinition. Minor doc comments updated to clarify intended DLL names (WinRT.Interop.dll, WinRT.Projection.dll, WinRT.Authoring.dll, WinRT.Runtime.dll).
When generating reference projections, avoid emitting projection-specific metadata: return early from write_winrt_reference_type_attribute and write_default_interface_attribute when settings.reference_projection is set, and stop writing GUID attributes for delegates in that mode. Also adjust delegate formatting placeholders. This keeps reference-only builds free of WinRT projection attributes.
Propagate InteropDefinitions through signature and IID generation and related builders. Added InteropDefinitions parameters to GuidGenerator.CreateIID and SignatureGenerator.GetSignature (and their helper methods), updated InteropCustomAttributeFactory.Guid, DynamicCustomMappedTypeMapEntriesBuilder, InteropTypeDefinitionBuilder.* InterfaceImpl methods, InteropGenerator.Emit call sites, and related XML docs. This ensures signature and GUID computation can use InteropDefinitions (e.g. projection/definition info) and threads the dependency through all callers.
Move IID resolution logic out of GuidGenerator into SignatureGenerator and add a dedicated attribute-based lookup. Introduce TryGetIIDFromWellKnownInterfaceIIDsOrAttribute and TryGetIIDFromAttribute to resolve IIDs from well-known mappings, GuidAttribute, or projected types in the WindowsRuntimeProjectionModule, and update signature generation helpers to accept InteropDefinitions and call the new methods. Add ModuleDefinitionExtensions.TryGetType (with nullable annotations) and make GetType use it, improving lookup semantics and error handling. Remove the now-duplicated method from GuidGenerator and tidy up related using directives.
Introduce GetTopLevelTypesLookup as an extension that caches a module's top-level types in a ConditionalWeakTable-backed FrozenDictionary to speed lookups. Make ModuleDefinitionExtensions partial and update SignatureGenerator to call GetTopLevelTypesLookup().TryGetValue instead of ModuleDefinition.TryGetType when resolving projected delegate types and default interfaces.
Refactor references from "Authoring" to "Component" across the generator. Changes include:
- Rename metadata/attribute constant and assembly-check helper to reference "WindowsRuntimeComponentAssembly".
- Replace WinRTAuthoringAssemblyPath with WinRTComponentAssemblyPath (and its command-line argument --winrt-component-assembly-path).
- Update discovery, debug-repro, emit, formatting and parsing code to use the component assembly naming and tracking APIs.
- Update InteropDefinitions to accept and expose a WindowsRuntimeComponentModule and adjust constructor/field names.
- Change the projection CLI argument name to --winrt-projection-assembly-path.

This is primarily a naming/ABI cleanup; note that command-line argument names and some public/internal identifiers changed and may be a breaking change for callers/scripts.
Rename the discovery state's WinRTAuthoringModuleDefinition property to WinRTComponentModuleDefinition, update the backing field XML comment, and adjust the InteropGenerator.Emit usage to pass WinRTComponentModuleDefinition. This aligns the property name with WinRT.Component.dll and is a non-functional rename to reduce confusion.
Allow the WinRT component module to be optional by changing the InteropDefinitions constructor parameter and WindowsRuntimeComponentModule property to ModuleDefinition?. Update the call site in InteropGenerator.Emit.cs to pass discoveryState.WinRTComponentModuleDefinition without the null-forgiving operator. This supports scenarios where the WinRT component assembly may be absent.
Update the XML documentation in SignatureGenerator to state that the method attempts to retrieve the IID for a given type by checking the System.Runtime.InteropServices.GuidAttribute applied to it, instead of referring to a "default interface signature". This improves clarity for readers of the interop helper.
Refactor InteropNames to use clearer WindowsRuntime-prefixed identifiers and add constants for projection, component, and runtime dll names. Update InteropGenerator emit and logging code to use WindowsRuntimeInteropAssemblyNameUtf8 and WindowsRuntimeInteropDllName/WindowsRuntimeInteropDllNameUtf8 for assembly/module creation, disk output path, and generation log. This is a rename-only change to improve naming clarity; behavior is unchanged.
Add validation in InteropGenerator.Discover to detect and reject transitive references whose filename matches reserved DLL names (WinRT.Projection.dll, WinRT.Component.dll, WinRT.Interop.dll). Introduce WellKnownInteropExceptions.ReservedDllNameReferenceError (id 85) to provide a clear error when a .dll name starting with the 'WinRT.' prefix is referenced, preventing invalid/reserved DLL usage.
Add path-mismatch validation for reserved private implementation DLLs and improve debug-repro handling. Introduces two new WellKnownInteropExceptions for reserved DLL original-path mismatches. In InteropGenerator.DebugRepro, adjust tracking of projection/component hashed names and detect cases where a private implementation assembly is supplied with a different path than the reference set, throwing a clear error for debug repro generation. In InteropGenerator.Discover, enforce that WinRT.Projection.dll and WinRT.Component.dll paths match the explicitly passed properties, skip those files during discovery, and ensure WinRT.Interop.dll is never accepted as an input. These changes prevent invalid/mismatched reserved assembly inputs and provide clearer diagnostics.
Move the destinationPath calculation, File.Copy, and cancellation check to occur after the uniqueness/validation logic. This prevents prematurely copying assemblies (which could lead to duplicated .dll files in the debug repro) before confirming the file is unique and allowed to be added (special-case handling for private implementation detail assemblies). No functional change other than reordering to avoid accidental duplicates and to ensure cancellation is checked after validation.
Change visibility of two helper methods in SignatureGenerator.cs from public to private: TryGetIIDFromWellKnownInterfaceIIDsOrAttribute and TryGetIIDFromAttribute. This reduces the public API surface and enforces encapsulation; no functional changes to method logic.
@Sergio0694 Sergio0694 force-pushed the user/sergiopedri/cswinrtgen-authoring-dll branch from aa0d6b5 to 1077a7e Compare February 14, 2026 02:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants