Special case 'IStringable' and manually project it#2227
Merged
Sergio0694 merged 7 commits intouser/kythant/TypeHandlingfrom Feb 6, 2026
Merged
Special case 'IStringable' and manually project it#2227Sergio0694 merged 7 commits intouser/kythant/TypeHandlingfrom
Sergio0694 merged 7 commits intouser/kythant/TypeHandlingfrom
Conversation
Add a new IStringable interface to src/WinRT.Runtime2/Windows.Foundation to represent objects as strings for WinRT interop. The file includes XML documentation, a Microsoft MIT license header, and WinRT metadata attributes (WindowsRuntimeMetadata, Guid, ContractVersion). It also documents that managed types should override object.ToString rather than directly implementing IStringable.
Introduce ABI bindings and marshalling support for Windows.Foundation.IStringable. Adds a new file defining the IStringable marshaller, interop methods, vtable layout (IStringableVftbl), the managed-to-unmanaged IStringableImpl with an unmanaged ToString entry, and a DynamicInterfaceCastable implementation for runtime casting. Also includes assembly TypeMap and TypeMapAssociation attributes to map the WinRT metadata and support trimming and runtime interop.
Switch IStringable marshalling to WindowsRuntimeUnsealedObjectMarshaller and add a ComWrappers callback and managed wrapper for projected IStringable instances. Introduces IStringableComWrappersCallback to create WindowsRuntimeStringable wrappers (special-casing Windows.Foundation.Uri runtime class names to handle System.Uri custom mapping), plus the WindowsRuntimeStringable implementation and interface plumbing. Also adds System.Diagnostics.CodeAnalysis using, makes IStringable.ToString return a non-nullable string, and updates the interface impl to match the non-nullable signature.
Introduce a TypeReference for Windows.Foundation.IStringable in InteropReferences and update WindowsRuntimeExtensions to include IStringable in the set of recognized WinRT types. This ensures IStringable is available for signature comparisons and treated as a WinRT interface during interop generation.
There was a problem hiding this comment.
Pull request overview
This pull request adds manual projection support for the Windows.Foundation.IStringable interface to fix edge cases with System.Uri. The implementation follows the established pattern for manually projected Windows Runtime interfaces.
Changes:
- Added manual projection for
IStringableinterface with full ABI marshalling support - Included special handling for
Windows.Foundation.Uriruntime class name to prevent marshalling conflicts withSystem.Uri - Updated the interop generator to recognize
IStringableas a manually projected interface
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| src/WinRT.Runtime2/Windows.Foundation/IStringable.cs | Defines the public IStringable interface with metadata attributes and documentation |
| src/WinRT.Runtime2/ABI/Windows.Foundation/IStringable.cs | Implements ABI marshalling, COM wrappers, vtable bindings, and special Uri handling for IStringable |
| src/WinRT.Interop.Generator/References/InteropReferences.cs | Adds type reference for IStringable to generator infrastructure |
| src/WinRT.Interop.Generator/Extensions/WindowsRuntimeExtensions.cs | Registers IStringable as a manually projected interface in generator logic |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Add an entry for IStringable to the cswinrt helpers type mapping, mapping it to Windows.Foundation.IStringable so the generator recognizes and handles IStringable types correctly.
manodasanW
approved these changes
Feb 5, 2026
Update the T4 template to map IStringable to the projected type (Windows.Foundation.IStringable), and regenerate the WellKnownInterfaceIIDs.g.cs XML doc to reflect this mapping. Also remove stray BOM/hidden characters from the template and generated file headers.
manodasanW
added a commit
that referenced
this pull request
Feb 7, 2026
* WindowsRuntimeMarshallingInfo.TryGetInfo in Type ConvertToManaged * ChkPt * ChkPt * Surgey on test cases: Will Revert * Add WinRT.SourceGenerator2 to UnitTest.csproj * Remove IReference * Fix typemap not being used. * Some unit tests * It should be AssemblyQualifiedName * metadata scenario TypeMarshaling test * ProxyType out parameter WIP * CustomTypeReference GOTO * Fix up conditions on Custom vs Metadata types * ExtractTypeName should take in ReadOnlySpan * Revert "Surgey on test cases: Will Revert" This reverts commit ff83e55. * Add more primitive type cases * Refactor/Fix trimmed metadata test * TODO comment * comments * Refactor TypeMarshaller.ConvertToUnmanagedUnsafe logic Simplifies and clarifies the handling of TypeReference creation, including improved comments and restructuring for primitive and proxy types. Ensures more consistent reporting of TypeKind and streamlines marshalling info usage. * Optimize type name slicing with JIT unrolling * Refactor TypeReference to use ReadOnlySpan<char> for Name Changed the TypeReference.Name field from string? to ReadOnlySpan<char> for improved memory safety and performance. Updated marshalling logic and related references to accommodate the new type. * Add WindowsRuntimeMetadata attributes to ABI types Added [WindowsRuntimeMetadata] attributes to ABI type classes in WinRT.Runtime2 to specify their associated Windows contracts. This improves metadata clarity and contract mapping for types such as Boolean, Byte, Char, DateTimeOffset, Double, EventHandler, Exception, Guid, Int16, Int32, Int64, Numerics types, Object, Single, String, TimeSpan, Type, UInt16, UInt32, UInt64, and Uri. * Add TypeMapAssociation and WinRT metadata to ABI interfaces Introduces TypeMapAssociation attributes for DynamicInterfaceCastableImplementationTypeMapGroup to INotifyDataErrorInfo, IDisposable, and IServiceProvider ABI interfaces. Also adds WindowsRuntimeMetadata and WindowsRuntimeClassName attributes to their respective interface implementations for improved WinRT interop. * Improve TypeMarshaller to handle C# primitive types Added logic to TypeMarshaller to support round-tripping C# primitive types (e.g., System.SByte) that are not Windows Runtime types. This ensures such types can be resolved even if not found in the WindowsRuntimeMarshallingInfo lookup. * TestTypePropertyWithIServiceProvider() * Refactor metadata type detection in marshalling info Replaces the _isProxyType flag with a volatile int _isMetadataType to track whether a type is defined in metadata. Adds deferred attribute lookup for custom-mapped types and exposes IsMetadataType property. Updates constructors and related logic to use the new flag, improving clarity and correctness in type marshalling scenarios. * Refactor TypeMarshaller to improve type kind detection Updated TypeMarshaller to use WindowsRuntimeMarshallingInfo for detecting projected or custom-mapped Windows Runtime types before handling primitives. This change ensures correct TypeKind assignment and aligns behavior with C++/WinRT, while simplifying the logic for custom and primitive type handling. * Tests for Timespan and CLosable * Reapply "Surgey on test cases: Will Revert" This reverts commit 3879ccf. * Add back ToString() * Add 'WindowsRuntimeMetadataTypeNameAttribute' * Add 'WindowsRuntimeMetadataTypeMapGroup' * Add WindowsRuntimeMetadataInfo for type metadata caching Introduces WindowsRuntimeMetadataInfo, an internal class providing cached metadata information and mapping for Windows Runtime types. This enables efficient lookup and handling of type metadata, supporting marshalling and attribute resolution for projected and proxy types. * Clarify XML documentation in WindowsRuntimeMarshallingInfo Added clarification to XML comments regarding custom-mapped types and fixed a minor typo in the parameter documentation for GetMetadataProviderType. * Add PublicType property to WindowsRuntimeMetadataInfo Introduces a PublicType property that lazily initializes and caches the public type using the WindowsRuntimeMappedTypeAttribute. This change improves type mapping and aligns with the implementation in WindowsRuntimeMarshallingInfo. * Improve handling of nullable types in type marshalling Refactored TypeMarshaller to correctly handle 'Nullable<T>' types by using the underlying type for lookups and skipping metadata table lookup for nullable types. Updated TypeReference to use string for Name and improved marshalling logic. Enhanced WindowsRuntimeMetadataInfo to track and expose the public type for metadata mapping. * supress IL3050:Calling members annotated with 'RequiresDynamicCodeAttribute' may break functionality when AOT compiling * WindowsRuntimeMetadataTypeMapGroup: * Test cases with TestComponent and TestComponentCsharp * TestComponentCsharp Class Test * refactor code gen on disable and restore on IL2026 * Add WindowsRuntimeReferenceTypeAttribute class Introduces the WindowsRuntimeReferenceTypeAttribute for annotating Windows Runtime value types with their associated reference types. This attribute is intended for use with the type marshalling infrastructure and is marked obsolete for internal implementation details. * Add ReferenceType property to WindowsRuntimeMarshallingInfo Introduces a ReferenceType property to WindowsRuntimeMarshallingInfo to provide the constructed Nullable<T> type for value types. Updates TypeMarshaller to use this property for value types instead of constructing Nullable<T> directly, improving type resolution and attribute validation. * Adding WindowsRuntimeReferenceType attribute on CodeWriters.h * Refactor reference type handling in marshalling info Replaces the ReferenceType property with GetReferenceType and TryGetReferenceType methods for improved error handling and caching. Introduces a placeholder WindowsRuntimeReferenceTypeAttribute for cases where the reference type is missing. Also updates placeholder attribute instance declarations to be readonly. * Add support for metadata type name caching and retrieval Introduces a volatile field to cache the metadata type name and implements GetMetadataTypeName and TryGetMetadataTypeName methods for retrieving it. This enables efficient access to metadata type names for marshalling scenarios, with error handling for unsupported types. * Refactor reference type handling in marshalling info Replaces the cached WindowsRuntimeReferenceTypeAttribute with a cached Type for reference type. Removes GetReferenceType and TryGetReferenceType methods, introducing a ReferenceType property for direct access and caching. This simplifies reference type retrieval and improves code clarity. * Enhance Type marshalling for Windows Runtime types Refactors Type marshalling logic to use WindowsRuntimeMarshallingInfo for improved detection of projected and custom-mapped Windows Runtime types. Adds new assembly and class attributes for TypeName metadata, updates handling of nullable types, and clarifies logic for primitive and metadata type name resolution. Also adds TODOs for further handling of specific IReference and delegate types. * Add WindowsRuntime type mapping attributes Introduces [TypeMap] and related attributes for WindowsRuntime type mapping in ABI classes, including metadata type names and reference types. Updates marshaller and interface implementations to use fully qualified type names for clarity and consistency with WindowsRuntime interop. * Improve runtime class name retrieval logic Refactored TypeMarshaller and WindowsRuntimeMarshallingInfo to use a new TryGetRuntimeClassName method for safer and more flexible runtime class name retrieval. This change improves handling of cases where metadata type names are unavailable and ensures better error reporting for unsupported types. * Convert TestProperty tests to use InlineData * Handle custom-mapped interface types in TypeMarshaller Added logic to use WindowsRuntimeMetadataInfo lookup for interface types that do not have proxy type map entries or projected types, ensuring correct metadata type name is used during marshalling. * Add WindowsRuntimeMetadataTypeMapGroup associations Introduced TypeMapAssociation attributes for WindowsRuntimeMetadataTypeMapGroup in ABI types including IDisposable, IServiceProvider, AsyncActionCompletedHandler, IVectorChangedEventArgs, IAsyncAction, and IAsyncInfo to improve type mapping and metadata handling. * Fix Expected result for Timespan and Type * Add WindowsRuntimeMetadataTypeName attribute in Object.cs * Update type map attribute to MetadataTypeMapGroup Replaces WindowsRuntimeComWrappersTypeMapGroup with WindowsRuntimeMetadataTypeMapGroup in Matrix3x2, Matrix4x4, Plane, Quaternion, and Vector2 type map attributes for improved metadata handling. * Remove redundant metadata attribute from Object.cs Deleted the [WindowsRuntimeMetadataTypeName("Object")] attribute from the Object class as it was unnecessary. This helps clean up the code and avoid redundant metadata. * Add new TypeMapAssemblyTarget attributes Added TypeMapAssemblyTarget attributes for WindowsRuntimeMetadataTypeMapGroup and DynamicInterfaceCastableImplementationTypeMapGroup to support additional type mapping scenarios in generated assemblies. * Update ABI for INotifyDataErrorInfo to use fully qualified names Refactored ABI.System.ComponentModel.INotifyDataErrorInfo to consistently use fully qualified type names for global::System.ComponentModel.INotifyDataErrorInfo throughout the file. Added new TypeMap and TypeMapAssociation attributes for WindowsRuntimeMetadataTypeMapGroup, and improved documentation comments for clarity. This enhances type safety and interoperability with Windows Runtime metadata. * Refactor placeholder marshaller attribute implementation Replaces PlaceholderWindowsRuntimeComWrappersMarshallerAttribute with WindowsRuntimeComWrappersMarshallerAttributePlaceholder in a new file and updates all references. Removes the old placeholder and related reference type attribute from WindowsRuntimeMarshallingInfo.cs for improved clarity and maintainability. * Refactor placeholder attribute for dynamic interface castable Replaces PlaceholderDynamicInterfaceCastableImplementationForwarderAttribute with DynamicInterfaceCastableImplementationForwarderAttributePlaceholder and moves its implementation to a new file. Updates all references to use the new class name, improving clarity and organization. * Replace PlaceholderNullAgileReference with NullPlaceholder Refactors ContextAwareObjectReference to use NullPlaceholder.Instance instead of PlaceholderNullAgileReference.Instance. Removes the now-unused PlaceholderNullAgileReference class. * Fix tests * Add WindowsRuntimeMappedType attributes to ABI types Added [WindowsRuntimeMappedType] attributes to various ABI types in the WinRT.Runtime2 project. This change improves type mapping between .NET types and their Windows Runtime counterparts, enhancing interop and metadata clarity. * Add WindowsRuntimeMappedMetadataAttribute class Introduces the WindowsRuntimeMappedMetadataAttribute for annotating custom-mapped types with their source Windows Runtime metadata file. The attribute is marked obsolete and is intended for internal use. * Update metadata type detection for custom-mapped types Replaces the check for WindowsRuntimeMetadataAttribute with WindowsRuntimeMappedMetadataAttribute for proxy types, ensuring correct identification of custom-mapped types. Adds a Debug.Assert to verify the code path is only triggered for proxy types. Also updates a comment for clarity and removes the unused isMetadataType argument in one constructor call. * Replace WindowsRuntimeMetadata with WindowsRuntimeMappedMetadata Updated all ABI type files to use the [WindowsRuntimeMappedMetadata] attribute instead of [WindowsRuntimeMetadata] for contract mapping. This change standardizes the attribute usage across all relevant types in the WinRT.Runtime2 ABI layer. * Rename TypeToMarshallingInfoTable to TypeToMetadataInfoTable Refactored the static ConditionalWeakTable field to improve naming consistency and clarity. Updated all references to use the new name, reflecting its purpose of mapping types to metadata info rather than marshalling info. * Add metadata attributes to EventRegistrationToken struct Added WindowsRuntimeMetadataTypeName and WindowsRuntimeReferenceType attributes to the EventRegistrationToken struct to enhance metadata and type information for interop scenarios. * Refactor ABI type mappings to use non-global type names Updated ABI files for IVectorChangedEventArgs, IAsyncAction, and IAsyncInfo to use direct type references instead of global::Windows.Foundation.* type names. Removed redundant TypeMapAssociation attributes and adjusted marshaller and interface implementation code accordingly. Also removed an unused attribute from EventRegistrationToken. These changes improve code clarity and maintainability by reducing reliance on global type names and streamlining type mapping. * Refactor marshalling info retrieval for anonymous objects Introduced GetAnonymousInspectableMarshallingInfo to centralize logic for retrieving marshalling info for anonymous objects, including special cases for Exception and Type. This improves code clarity and maintainability by removing repeated logic and handling custom exception and Type instances more explicitly. * Enhance TypeMarshaller with special case handling Added special handling for projected types, exceptions, and System.Type in TypeMarshaller. Improved logic for mapping metadata types to CLR types, including handling for KeyValuePair and delegate types. These changes improve accuracy and round-tripping of type information during marshalling. * Improve type marshalling and remove redundant attributes Enhanced TypeMarshaller to better handle value types and delegates without explicit metadata names, and to properly bypass marshalling for Nullable<KeyValuePair<,>> types. Removed redundant [WindowsRuntimeMetadataTypeName] attributes from Point, Rect, and Size to align with updated marshalling logic. * Fix runtime class name retrieval in marshalling info Replaces usage of _metadataTypeName with _runtimeClassName when retrieving the cached runtime class name, ensuring the correct value is returned. * Fix IXamlServiceProvider not being excluded correctly * Fix Namespaces conflicts from merge * Enable TypeMarshaling Test case for NoMetadata scenario and add a new test case for where there is a metadata scenario * Try not building TypeMarshalingTest in arm or arm64 * Add test case for Nullable and Exception * Handle KeyValuePair<,> in TypeMarshaller Added special handling for KeyValuePair<,> types in the TypeMarshaller to ensure the correct runtime class name is used for marshalling. Updated comments to clarify logic and removed outdated TODO. * Add custom case and fix IReferenceName update * Add explicit error handling for missing mapped type attribute Replaces Debug.Assert with a NotSupportedException when the WindowsRuntimeMappedTypeAttribute is missing on the metadata provider type in both WindowsRuntimeMarshallingInfo and WindowsRuntimeMetadataInfo. This provides clearer error reporting and guidance for unexpected code generation issues. * Remove obsolete TODO comments in TypeMarshaller Deleted outdated TODO comments regarding type map entries for non-generic interfaces, value types, and delegate types in TypeMarshaller. No functional code changes were made. * Add support for WindowsRuntimeMetadataTypeMapGroup attributes Introduces methods and references to handle TypeMap and TypeMapAssociation attributes for WindowsRuntimeMetadataTypeMapGroup in InteropCustomAttributeFactory and InteropReferences. This enables generation and referencing of custom attributes using the new type map group. * Refactor TypeMarshaller type reference logic Reorganized conditional checks for nullable and projected types in TypeMarshaller. Ensures special handling for types that cannot be used in Nullable<T> and improves clarity by nesting projected and metadata info lookups under a single nullable check. * Add support for WindowsRuntimeMetadataTypeNameAttribute Introduces handling for the WindowsRuntimeMetadataTypeNameAttribute in InteropTypeDefinitionBuilder and InteropReferences. This allows proxy types to optionally emit the metadata type name attribute and reference the original managed type when required. * Add support for WindowsRuntimeMappedMetadataAttribute Introduces handling for the WindowsRuntimeMappedMetadataAttribute in proxy type generation. Updates relevant builders and references to allow optional inclusion of mapped metadata information when generating interop types. * Add KeyValuePair.Proxy method and update usage Introduces a static Proxy method to InteropTypeDefinitionBuilder.KeyValuePair for creating proxy types for KeyValuePair<TKey, TValue>. Updates InteropGenerator.Emit to use the new method, improving clarity and encapsulation for KeyValuePair proxy generation. * Add IsGenericType property to TypeSignatureExtensions Introduces the IsGenericType property to determine if a TypeSignature represents a constructed generic type. * Refactor type name generation and add MetadataTypeNameGenerator Introduces MetadataTypeNameGenerator to handle Windows Runtime metadata type name generation, including generic and array types. Refactors RuntimeClassNameGenerator to delegate type name formatting to the new helper, improving code reuse and maintainability. Adds error handling for unresolved types and clarifies logic for IReference wrapping. * Refactor delegate and KeyValuePair type map attribute methods Updated TypeMapAttributes methods in Delegate and KeyValuePair builders to accept TypeSignature instead of GenericInstanceTypeSignature. Added a static Proxy method to InteropTypeDefinitionBuilder.Delegate for delegate proxy type creation, and updated usage in InteropGenerator.Emit to use the new method. * Clarify comment on handling metadata type names Expanded the comment to mention that generic delegate types are also handled by using '[WindowsRuntimeMetadataTypeName]'. No code changes were made. * Fix typo in MetadataTypeNameGenerator method names Corrected 'GetMetadataTyoeName' and 'AppendMetadataTyoeName' to 'GetMetadataTypeName' and 'AppendMetadataTypeName' in MetadataTypeNameGenerator and updated all references. This improves code clarity and consistency. * Add metadataTypeName to TypeMapAttributes calls Introduces a new metadataTypeName parameter to TypeMapAttributes and updates all relevant builder calls to include it, defaulting to null where not required. This enables emitting additional type map attributes for metadata type mapping, supporting improved marshalling scenarios such as Windows Runtime delegate types. * Fix attribute argument to use metadataTypeName Replaces the use of runtimeClassName with metadataTypeName when setting the WindowsRuntimeMetadataTypeNameAttribute. This ensures the correct type name is used in the custom attribute. * Refactor type map parameters for clarity and extensibility Renames proxyTypeMap* parameters to marshallingTypeMap* and adds metadataTypeMap* parameters across InteropTypeDefinitionBuilder and related builders. Updates attribute emission logic to support both marshalling and metadata type map associations, improving clarity and future extensibility. * Update proxy type definition for interface and SZ array types Clarified the summary to specify proxy types are for interfaces or SZ array types. Added comments and set 'referenceMappedType' to true to ensure the '[WindowsRuntimeMappedType]' attribute is emitted, enabling 'TypeName' marshalling to retrieve the runtime class name. * Fix metadata type map assignments in type builders Set metadataTypeMapSourceType and metadataTypeMapProxyType to appropriate values in IList, IReadOnlyList, and interface type builder methods. This ensures correct type mapping for metadata generation. * Refactor proxy type generation for SZ arrays and interfaces Introduces a dedicated Proxy method for SZ array types in InteropTypeDefinitionBuilder.SzArray, separating it from the interface proxy logic. Updates all call sites to use the new method for arrays and renames the parameter for interface proxies to improve clarity. * Simplify cref in XML doc for proxyType parameter Updated the XML documentation for the proxyType parameter to reference only Proxy, removing the method signature for clarity and maintainability. * Add UnitTests and comments to organize * Update proxy attribute emission for interface types Emit '[WindowsRuntimeMetadataTypeName]' instead of a runtime class name when generating proxies for interface types. This supports mapping generic interface names during 'TypeName' marshalling, as runtime class names are not needed for interfaces. * Refactor TypeMarshaller value type handling logic Reorganizes the logic for handling value types in TypeMarshaller. Now, KeyValuePair<,> is explicitly checked before falling back to marshalling info for other value types, improving clarity and correctness in type selection. * Refactor ABI System.Collections interfaces and marshallers Replaces global::System.Collections type references with direct type usage (e.g., IEnumerable, IEnumerator, IList) in ABI marshaller and implementation files. Refactors and exposes ComWrappersMarshallerAttribute classes as public, adds missing attributes, and introduces a new Interface helper in DynamicCustomMappedTypeMapEntriesBuilder to streamline interface mapping logic. * Add WindowsRuntimeMapped attributes to DataErrorsChangedEventArgs Annotated DataErrorsChangedEventArgs ABI type with WindowsRuntimeMappedMetadata and WindowsRuntimeMappedType attributes to improve metadata mapping and type resolution. * Refactor marshaller attribute resolution and type mapping Extracted marshaller attribute type resolution into GetMarshallerAttributeType to reduce code duplication. Replaced ManagedOnlyTypeOrInterface with ManagedOnlyType, simplifying parameters and usage. Updated method calls and removed redundant marshaller attribute resolution logic from multiple locations. * Refactor type mapping for event args and update marshallers Renamed internal builder methods for clarity, distinguishing between interface and delegate type mappings. Updated NotifyCollectionChangedEventArgs and PropertyChangedEventArgs ABI files to remove unnecessary TypeMapAssociation attributes, simplify type references, and improve marshaller and attribute declarations for consistency and maintainability. * Refactor delegate type mapping to use DelegateType method Replaces calls to ManagedOnlyDelegateType with DelegateType for delegate type mappings, and updates related method signatures and invocations for consistency. This change streamlines delegate type handling and unifies the mapping logic. * Add ClassType helper for custom-mapped class types Introduces a new private ClassType method to handle custom-mapped class types, mirroring the existing DelegateType logic. Updates relevant calls to use ClassType instead of DelegateType for class types, improving clarity and separation of concerns in type mapping. * Support 'IBindableVectorView' for RCWs and 'Type' marshalling (#2207) * Add WindowsRuntimeReadOnlyList implementation Introduces WindowsRuntimeReadOnlyList, a sealed class implementing projected Windows Runtime readonly IList types. This class provides optimized enumeration support and interface projection for Windows Runtime objects, improving performance and integration with .NET. * Add IReadOnlyListComWrappersMarshallerAttribute Introduces a custom marshaller attribute for IReadOnlyList in the WinRT.Runtime2 ABI. This enables proper marshalling of IReadOnlyList types, aligning with .NET naming conventions and supporting XAML configurations. * Handle IBindableVectorView in TypeMarshaller Return null for 'IBindableVectorView' in TypeMarshaller to avoid resolving a marshalling info instance for which there is no .NET equivalent. This prevents failures when the type map contains an entry but no public type exists. * Make mappedType parameter nullable in Proxy method Updated the Proxy method in InteropTypeDefinitionBuilder to accept a nullable TypeSignature for mappedType, and adjusted its usage accordingly. This change allows for cases where a mapped type may not be provided, improving flexibility in interop type generation. * Refactor IBindableVectorView type mapping logic Replaces WindowsRuntimeExposedType with IBindableVectorViewType to clarify and specialize the handling of IBindableVectorView type mapping. Updates logic to generate proxy types and type map attributes for both CCW and RCW scenarios, improving maintainability and correctness for Windows.UI.Xaml and Microsoft.UI.Xaml projections. * Refactor Proxy method to remove referenceMappedType param Removed the 'referenceMappedType' parameter from InteropTypeDefinitionBuilder.Proxy and updated all call sites to use only the 'mappedType' parameter. The logic now adds the WindowsRuntimeMappedType attribute if 'mappedType' is not null, simplifying the method signature and usage. * Fix typo in comment in DynamicCustomMappedTypeMapEntriesBuilder Corrected 'tye' to 'type' in a comment to improve code documentation clarity. * Remove 'sealed' from override members in bindable classes Removed the 'sealed' modifier from HasUnwrappableNativeObjectReference and IsOverridableInterface overrides in WindowsRuntimeEnumerable, WindowsRuntimeList, and WindowsRuntimeReadOnlyList. This change allows further overriding in derived classes if needed. * Rename WindowsRuntimeIterator to WindowsRuntimeEnumerator Renamed the WindowsRuntimeIterator class and related references to WindowsRuntimeEnumerator for improved clarity and consistency with .NET naming conventions. * Adjust marshaller type resolution and errors Use Resolve(module) directly when resolving ComWrappers marshaller attribute types and update related error handling. Change CustomMappedTypeComWrappersMarshallerAttributeTypeResolveError to take a TypeSignature, add a new NonProjectedTypeComWrappersMarshallerAttributeTypeResolveError(TypeReference, string) for non-projected WinRT types (used for IBindableVectorView), and update the thrown exceptions to provide the correct context (passing the custom-mapped type where appropriate). These changes improve diagnostics and fix the type-resolution call sites. * Update and reorganize UnitTest cases and add type argument InlineData * Add Custom cases with Generic interfaces * Generic Delegates Unit Tests Custom * Add nested cases * Functional Test cases WIP * Use WindowsRuntimeMetadataTypeMapGroup for Guid Switch the assembly TypeMap generic from WindowsRuntimeComWrappersTypeMapGroup to WindowsRuntimeMetadataTypeMapGroup for the Guid mapping. The mapping still targets ABI.System.Guid and trims to System.Guid; this change updates the type map group to the metadata-based group (improving metadata/trimming/tooling alignment). * Add roundtrip tests * Use WindowsRuntimeMetadataTypeMapGroup for Point * Enable point * refactoring src/Tests/FunctionalTests/TypeMarshaling/Program.cs * WindowsRuntimeMetadataTypeMapGroup typos for Exception.cs and String.cs * Add TypeMapAssociation for INotify interfaces Add assembly-level TypeMapAssociation attributes to associate INotifyPropertyChanged and INotifyCollectionChanged with their respective ABI proxy implementation types (INotifyPropertyChangedInterfaceImpl and INotifyCollectionChangedInterfaceImpl). This enables the DynamicInterfaceCastableImplementationTypeMapGroup to locate the proxy types for interop/ComWrappers scenarios. Changes applied to the corresponding ABI files for ComponentModel and Collections.Specialized. * Shorten IEnumerator type references Replace fully-qualified "global::System.Collections.IEnumerator" with the simpler "IEnumerator" in IEnumerable-related marshaller and implementation methods (GetEnumerator implementations and return types) in src/WinRT.Runtime2/ABI/System/Collections/IEnumerable.cs for consistency and readability. No behavioral changes intended. * Add InterfaceType entries for INotify interfaces Add InterfaceType calls to emit dynamic custom mapped type map entries for INotifyPropertyChanged and INotifyCollectionChanged. Each entry supplies Windows and Microsoft XAML metadata, the trim target (using the respective reference type signature), interopReferences, module, and useWindowsUIXamlProjections. Keeps TODO notes to also emit the IDIC interface. * Conditionally add ComWrappers marshaller attribute Make the WindowsRuntimeComWrappersMarshaller attribute optional when generating interop proxy types. Add a new useComWrappersMarshallerAttribute flag to InterfaceType call sites and its signature; only look up and pass the marshaller attribute TypeDefinition when requested. Update InteropTypeDefinitionBuilder to accept a nullable attribute type and only emit the custom attribute if it's non-null. This avoids unnecessary lookups/emission for interfaces that don't require a ComWrappers marshaller (e.g. INotifyPropertyChanged) while still enabling it for types that do (e.g. IEnumerable). Files changed: DynamicCustomMappedTypeMapEntriesBuilder.cs, InteropTypeDefinitionBuilder.cs. * Add WindowsRuntimeClassName attribute to DataErrorsChangedEventArgs Add the [WindowsRuntimeClassName("Microsoft.UI.Xaml.Data.DataErrorsChangedEventArgs")] attribute to the ABI.System.ComponentModel.DataErrorsChangedEventArgs declaration so the ABI type is associated with the correct WinRT class name. This clarifies runtime metadata for WinRT interop and mapping to Microsoft.UI.Xaml.Data.DataErrorsChangedEventArgs. * Add all Mapped Types * Add Nullable cases * Add tests for WeakReference * Add nullable KVP tests for custom * Fix typo in IAsyncAction.cs * Update Functional Test cases * Refactor TypeMarshaling/Program.cs * Remove WindowsRuntimeMappedMetadata attribute Remove the [WindowsRuntimeMappedMetadata("Windows.Foundation.FoundationContract")] attribute from ABI.System.EventHandler and add a clarifying comment. This prevents automatic Windows Runtime mapping for EventHandler so that marshalling typeof(EventHandler) remains a custom type and aligns with existing special-case marshalling behavior. * Remove WinRT attributes from IDisposable impl Remove the WindowsRuntimeMappedMetadata and WindowsRuntimeClassName attributes from the DynamicInterfaceCastable implementation of global::System.IDisposable (IDisposableInterfaceImpl in ABI/System/IDisposable.cs). This change strips unnecessary WinRT annotations from the interface implementation; no other code modifications were made. * RuntimeClassnameAttributes on Enums * Tests for nullable projected struct and enum * Add cases to functional test * Fix error IDs in 'WellKnownInteropExceptions' * Update winmd library to address assert in debug build * Handle mixed 'IDIC' proxy and impl types in 'cswinrtgen' (#2220) * Add ICommand custom-mapped type support Add support for System.Windows.Input.ICommand as a custom-mapped WinRT type. Creates a new InterfaceImpl type and explicit interface implementations (CanExecute, Execute and CanExecuteChanged add/remove) in a new builder file; registers type map attributes for ICommand; adds ICommand member references to InteropReferences; adds GetMethodsType helper and corresponding WellKnownInteropException when the associated Methods type cannot be resolved. Also adjusts TypeMapAttributes usage for metadata/runtime names and includes minor comments. * Add INotifyPropertyChanged mapping and builders Introduce support for System.ComponentModel.INotifyPropertyChanged: add a new partial builder (DynamicCustomMappedTypeMapEntriesBuilder.INotifyPropertyChanged.cs) that emits an InterfaceImpl type with add/remove accessors and the PropertyChanged event, and register a TypeMap via a new INotifyPropertyChangedInterfaceType helper in DynamicCustomMappedTypeMapEntriesBuilder.cs. Also add MemberReference entries for the add/remove PropertyChanged accessors to InteropReferences. Additionally, fix a local variable name in the ICommand builder file (canExecuteChangedProperty) to improve clarity. * Rename INotifyPropertyChanged members in builder Fix variable and method names in DynamicCustomMappedTypeMapEntriesBuilder to correctly reference System.ComponentModel.INotifyPropertyChanged.PropertyChanged. Renamed the add/remove method variables from the incorrect ICommandCanExecuteChanged names to add_INotifyPropertyChangedPropertyChangedMethod and remove_INotifyPropertyChangedPropertyChangedMethod, and renamed the event variable to propertyChangedProperty. No functional changes; this improves clarity and correctness of the implementation. * Add INotifyCollectionChanged mapping and impl Introduce support for System.Collections.Specialized.INotifyCollectionChanged by: - Adding a new builder (DynamicCustomMappedTypeMapEntriesBuilder.INotifyCollectionChanged.cs) that emits an InterfaceImpl type with explicit add/remove accessors and an event using DynamicInterfaceCastableImplementation. - Registering the INotifyCollectionChanged type in DynamicCustomMappedTypeMapEntriesBuilder (creates proxy/type-map attributes and wires the InterfaceImpl). - Adding MemberReference properties for the CollectionChanged add/remove accessors to InteropReferences. This enables generation of the proxy/interface mapping and dynamic interface castable implementation for collection-changed event handling. * Remove DynamicInterfaceCastable implementations Delete IDynamicInterfaceCastable implementations and associated TypeMapAssociation attributes from ABI files for INotifyCollectionChanged, INotifyPropertyChanged, and ICommand. The changes remove the generated dynamic interface wrapper types and leave only the static ABI helper implementations in these files, simplifying the ABI surface. * Import called method references into module Ensure method references are imported into the target module before emitting Call instructions. Replace direct references to forwardedMethod, forwardedMethod1, forwardedMethod2, and eventMethod with their imported equivalents (e.g. forwardedMethod.Import(module)) in WellKnownCilMethodBodyFactory to avoid cross-module reference issues when generating IL. * Fix member references to INotify interfaces Update InteropReferences.cs to use the correct interfaces when creating MemberReference instances for event add/remove methods. The properties for add/remove CollectionChanged and add/remove PropertyChanged previously referenced ICommand; they now reference INotifyCollectionChanged and INotifyPropertyChanged respectively so the member refs point to the proper interfaces. * Cache MemberReference lookups in InteropReferences Use a backing field (field ??= ...) to cache MemberReference instances for event adder/remover properties (ICommand.add/remove_CanExecuteChanged, INotifyCollectionChanged.add/remove_CollectionChanged, INotifyPropertyChanged.add/remove_PropertyChanged). This avoids recreating the MemberReference on each access; method signatures are unchanged. * Rename local variable to methodsTypeReference Rename the local TypeReference variable from comWrappersMarshallerTypeReference to methodsTypeReference to better reflect that it references the generated "{Type}Methods" type. Update its use in the Resolve check; behavior remains the same (throws if the methods type can't be resolved). This improves clarity of the code. * Remove stray 'interop.' from XML docs Remove accidental 'interop.' tokens from XML doc <summary> comments in DynamicCustomMappedTypeMapEntriesBuilder.cs. Cleans up the summaries for the methods that retrieve the marshaller attribute and the "Methods" type for a custom-mapped type; no behavioral changes. * Simplify type qualifiers and ABI references Remove redundant global:: and System qualifiers from XML doc comments and event handler signatures, and replace fully-qualified ABI namespace usages with shorter identifiers where appropriate. This cleans up verbosity and improves readability/consistency across interop and ABI files (NotifyCollectionChangedEventHandler, PropertyChangedEventHandler, IObservableMap/Vector method impls, WindowsRuntimeObjectReferenceValue, TypeKind, and WindowsRuntimeObject). * Add TypeMap and WindowsRuntimeReferenceType attrs Add assembly TypeMap entries to map the WinRT type "Windows.Foundation.PropertyType" to the local PropertyType type for both metadata and COM wrappers (including a trimTarget). Also annotate Windows.Foundation.PropertyType with WindowsRuntimeReferenceType(typeof(PropertyType?)) to mark it as a WinRT reference/nullable projection, improving interop and trimming behavior. * Add PropertyType reference and include in checks Expose Windows.Foundation.PropertyType in InteropReferences and update WindowsRuntimeExtensions to treat PropertyType as a recognized special/primitive Windows Runtime type. This ensures PropertyType can be resolved and matched by SignatureComparer in type checks alongside other foundation types (Point, Rect, Size, etc.). * Move opaque marshalling helper to TypeMapInfo Introduce WindowsRuntimeMarshallingInfo.GetOpaqueInfo(object) to centralize logic for selecting marshalling info for opaque/anonymous managed objects (special-casing Exception and Type, otherwise falling back to object). Update WindowsRuntimeComWrappers to call the new helper and remove the duplicate private GetAnonymousInspectableMarshallingInfo implementation. This refactors and consolidates marshalling selection into the TypeMapInfo class and uses AggressiveInlining for the new helper. * Use TryGetInfo with opaque fallback Retrieve WindowsRuntimeMarshallingInfo via TryGetInfo and fall back to GetOpaqueInfo when an exact match isn't available (e.g., types marshalled as object or RuntimeType). Reuse the resolved marshallingInfo to obtain vtable info and runtime class name instead of repeatedly calling GetInfo(instance.GetType()). This makes IInspectable implementations more robust for edge cases like Exception or marshalled-as-object instances. * Add missing `NotifyCollectionChangedAction` custom-mapped type (#2224) * Add marshaller and IIDs for NotifyCollectionChangedAction Introduce marshaling support for NotifyCollectionChangedAction and add corresponding interface IIDs.\n\n- Add NotifyCollectionChangedActionMarshaller and ComWrappers marshaller (new ABI file) to box/unbox the enum as a WinRT value type and provide vtable entries.\n- Update NotifyCollectionChangedEventArgs marshaller to reference the renamed IID_NotifyCollectionChangedEventArgs.\n- Add new GUID constants for IReferenceOfNotifyCollectionChangedAction to WellKnownWindowsInterfaceIIDs (generated) and update related IID names for NotifyCollectionChangedEventArgs.\n- Update template sources (.tt) and generated WellKnownXamlInterfaceIIDs to expose IID_NotifyCollectionChangedEventArgs and IID_IReferenceOfNotifyCollectionChangedAction.\n\nThese changes enable proper projection and COM interop for NotifyCollectionChangedAction values and their IReference wrappers in XAML/WinRT projections. * Set runtime & metadata names for proxy type Previously the proxy type used a null runtimeClassName (and later a null metadataTypeName) because the metadata type name wasn't fixed. Change updates the proxy/type-map calls to supply both runtime and metadata names via RuntimeClassNameGenerator.GetRuntimeClassName and MetadataTypeNameGenerator.GetMetadataTypeName, and updates the comment to note the proxy can be instantiated/boxed so both names are required. * Map and mark AsyncStatus for WinRT reference Add an assembly TypeMap mapping the WinRT metadata type "Windows.Foundation.AsyncStatus" to the managed AsyncStatus (with trimTarget set) to enable correct metadata-based type resolution and trimming. Also add a WindowsRuntimeReferenceType attribute to AsyncStatus (typeof(AsyncStatus?)) so it can be treated as an IReference<T> nullable reference for proper WinRT marshalling. * Add WindowsRuntimeReferenceType support Introduce support for WindowsRuntimeReferenceType by adding a referenceType parameter to InteropTypeDefinitionBuilder and emitting a WindowsRuntimeReferenceTypeAttribute when a reference type is provided (used to retrieve boxed types like Nullable<T>). Wire the new parameter through multiple builder call sites (passing null where not applicable). Add InteropReferences entries for WindowsRuntimeReferenceTypeAttribute and its constructor, and add a TypeReference for NotifyCollectionChangedAction. * Add ValueType builder and notify collection action Introduce a ValueType helper in DynamicCustomMappedTypeMapEntriesBuilder to create proxy types and TypeMapAttribute entries for custom-mapped value types (including boxed Nullable<T> reference types and marshaller attributes). Register NotifyCollectionChangedAction by calling ValueType with the appropriate trimTarget. Also update WindowsRuntimeExtensions to treat NotifyCollectionChangedAction as a known runtime type. * Fix namespace for NotifyCollectionChangedAction Update namespace from ABI.Windows.Foundation to ABI.System.Collections.Specialized to match the file path and the NotifyCollectionChangedAction marshaller, aligning the type with its intended namespace. * Get test passing * Fix Duplicate Key Issue on IEnumerator * Enable ICommand on Functional Tests * Treat NotifyCollectionChangedAction as value type Change trim target for NotifyCollectionChangedAction from ToReferenceTypeSignature() to ToValueTypeSignature() in DynamicCustomMappedTypeMapEntriesBuilder.cs. This ensures the enum is treated as a value type during interop code generation and fixes trimming/marshalling behavior. * Fix Namespace error on WindowsRuntimeReferenceTypeAttribute in InteropReferences * Add tests for NotifyCollectionChangedAction * rename to write_value_type_winrt_classname_attribute src/cswinrt/code_writers.h * Fix xml comment on WindowsRuntimeReferenceTypeAttribute * Move WindowsRuntimeReferenceTypeAttribute to the right location * Special case 'IStringable' and manually project it (#2227) * Add Windows.Foundation.IStringable interface Add a new IStringable interface to src/WinRT.Runtime2/Windows.Foundation to represent objects as strings for WinRT interop. The file includes XML documentation, a Microsoft MIT license header, and WinRT metadata attributes (WindowsRuntimeMetadata, Guid, ContractVersion). It also documents that managed types should override object.ToString rather than directly implementing IStringable. * Add ABI marshalling for IStringable Introduce ABI bindings and marshalling support for Windows.Foundation.IStringable. Adds a new file defining the IStringable marshaller, interop methods, vtable layout (IStringableVftbl), the managed-to-unmanaged IStringableImpl with an unmanaged ToString entry, and a DynamicInterfaceCastable implementation for runtime casting. Also includes assembly TypeMap and TypeMapAssociation attributes to map the WinRT metadata and support trimming and runtime interop. * Add IStringable ComWrappers callback and wrapper Switch IStringable marshalling to WindowsRuntimeUnsealedObjectMarshaller and add a ComWrappers callback and managed wrapper for projected IStringable instances. Introduces IStringableComWrappersCallback to create WindowsRuntimeStringable wrappers (special-casing Windows.Foundation.Uri runtime class names to handle System.Uri custom mapping), plus the WindowsRuntimeStringable implementation and interface plumbing. Also adds System.Diagnostics.CodeAnalysis using, makes IStringable.ToString return a non-nullable string, and updates the interface impl to match the non-nullable signature. * Add IStringable reference and runtime check Introduce a TypeReference for Windows.Foundation.IStringable in InteropReferences and update WindowsRuntimeExtensions to include IStringable in the set of recognized WinRT types. This ensures IStringable is available for signature comparisons and treated as a WinRT interface during interop generation. * Add IStringable mapping to type map Add an entry for IStringable to the cswinrt helpers type mapping, mapping it to Windows.Foundation.IStringable so the generator recognizes and handles IStringable types correctly. * Fix IID used for IStringable * Map IStringable to Windows.Foundation.IStringable Update the T4 template to map IStringable to the projected type (Windows.Foundation.IStringable), and regenerate the WellKnownInterfaceIIDs.g.cs XML doc to reflect this mapping. Also remove stray BOM/hidden characters from the template and generated file headers. --------- Co-authored-by: Manodasan Wignarajah <mawign@microsoft.com> * Add IStringable to UnitTests * Add IStrigable to FunctionalTests/TypeMarshaling and fixup numbers with a 50 number gap in between each section * Skip SZ arrays in IReference detection Prevent SZ (single-dimension zero-based) array types from being treated as IReference`1 wrappers when generating runtime class names. Adds an explicit check for SzArrayTypeSignature and extends the comment to explain that resolving an SZ array's signature yields the element type, which could otherwise cause arrays to be misclassified as requiring IReference support. * Add array cases * Add test for Int32?[] * Move placeholder forwarder attribute to new file Extract the PlaceholderDynamicInterfaceCastableForwarderAttribute into its own file as DynamicInterfaceCastableForwarderAttributePlaceholder and update references. The placeholder type (single shared Instance) remains functionally the same and returns false from IsInterfaceImplemented. Remove the duplicate embedded placeholder class from DynamicInterfaceCastableImplementationInfo and update null/instance checks to use the new type name for clarity and separation of concerns. --------- Co-authored-by: Manodasan Wignarajah <mawign@microsoft.com> Co-authored-by: Sergio Pedri <sergio0694@live.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.
Title. Fixes some edge cases with
System.Uri.