Skip to content

System.Type Marshaling #2129

Merged
manodasanW merged 195 commits intostaging/3.0from
user/kythant/TypeHandling
Feb 7, 2026
Merged

System.Type Marshaling #2129
manodasanW merged 195 commits intostaging/3.0from
user/kythant/TypeHandling

Conversation

@kythant
Copy link
Copy Markdown

@kythant kythant commented Nov 25, 2025

No description provided.

@kythant kythant closed this Nov 25, 2025
@kythant kythant reopened this Nov 26, 2025
@kythant kythant closed this Nov 27, 2025
@kythant kythant reopened this Dec 1, 2025
kythant and others added 17 commits December 1, 2025 15:59
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.
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.
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.
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.
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.
Sergio0694 and others added 26 commits February 4, 2026 10:54
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 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.
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.).
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.
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 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.
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.
* 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>
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.
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.
Copy link
Copy Markdown
Member

@Sergio0694 Sergio0694 left a comment

Choose a reason for hiding this comment

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

SHIP ITTTTTTTT :shipit:

@manodasanW manodasanW merged commit 410c3a3 into staging/3.0 Feb 7, 2026
11 checks passed
@kythant kythant deleted the user/kythant/TypeHandling branch February 7, 2026 19:14
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.

3 participants