-
Notifications
You must be signed in to change notification settings - Fork 122
Add technical docs on generic interfaces codegen #1989
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add technical docs on generic interfaces codegen #1989
Conversation
jevansaks
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Posting my comments but I got a little lost in this writeup so I think we need an in-person review of some of this if you want thoughtful feedback.
|
|
||
| This type derives from `WindowsRuntimeObject`, which provides all the usual support for IDIC, generated COM interfaces, and more. If needed, these RCW types (one per generic interface) can also contain additional state necessary to properly map the Windows Runtime interface behavior to the managed one. This is the case for `IEnumerator<T>`, which is slightly different than `IIterator<T>`, for instance. | ||
|
|
||
| Next, an interface is needed for each "Methods" implementation, for each generic interface. For `IIterator<T>`, it looks like this: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was mostly with you until this point. "An interface is needed" -- why? How does this connect to the scenarios above? I assume there's some general-purpose C#/WinRT machinery that is trying to reach out for this, but when/where?
| } | ||
| ``` | ||
|
|
||
| This is conceptually similar to `IWindowsRuntimeComWrappersCallback` (which is used for delegates and sealed runtime class names), with the main difference being that it is specialized for unsealed types (and interfaces). In this case, implementations need to know the runtime class name of the native object, to determine whether they can marshal it via the fast path using a statically visible RCW type (see below), or whether they should fallback to the logic to marshal arbitrary opaque object that is used when no static type information is available (which involves going through the interop type lookup to get the marshalling info, etc.). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pretend I don't know anything about the current C#/WinRT implementation in this regard. What do I need to know/care about to evaluate this proposal? :)
* Emit 'IIterableMethods' types
* Emit 'NativeObject' type for 'IEnumerable<T>'
* Emit 'ComWrappersCallback' type
* Emit 'ComWrappersMarshallerAttribute' type
* Emit 'Marshaller' type
* Emit 'InterfaceImpl' type
* Emit proxy types for 'IEnumerable<T>'
* Add 'WindowsRuntimeReadOnlyList<T>'
* Add infrastructure types for 'IReadOnlyList<T>'
* Add infrastructure types for 'IList<T>'
* Add 'WindowsRuntimeList<T>', minor tweaks
* Update WindowsRuntimeEnumerator{T}.cs
* Use 'field' keyword
* Minor tweaks, remove 'unsafe'
* Add infrastructure types for 'IReadOnlyDictionary<K, V>'
* Add 'ReadOnlyDictionaryKeyCollection<,>'
* Add 'ReadOnlyDictionaryValueCollection<,>'
* Use new collection types
* Add infrastructure types for 'IDictionary<K, V>'
* Emit 'IReadOnlyList1Vftbl' type
* Emit 'IList1Vftbl' type
* Emit 'IReadOnlyDictionary2Vftbl' type
* Emit 'IDictionary2Vftbl' type
* Emit 'IReadOnlyList<T>' vtable types
* Emit 'IVectorViewMethods' types
* Add missing 'BeforeFieldInit'-s
* Emit 'IReadOnlyListMethods' types
* Add 'IReadOnlyListAdapter<T>'
* Rework RCW types for generic collections
* Rework RCW types for generic dictionaries
* Implement missing dictionary methods
* Update codegen for 'IEnumerator<T>'
* Update codegen for 'IEnumerable<T>'
* Refactor 'ComputeReadOnlySpanHash'
* Add new 'ModuleDefinition' extension, minor tweaks
* Fix corlib types in 'IsConstructedGenericTypeVisitor'
* Gather constructed base interfaces
* Add two missing imports
* Emit 'NativeObject' for 'IReadOnlyList<T>'
* Remove unnecessary 'MemberReference'-s
* Rename discovery state type
* Add 'InteropGeneratorEmitState'
* Use fast lookup for type definitions
* Track missing 'IEnumerator<T>' types
* Emit stub 'Impl' type for 'IReadOnlyList<T>'
* Emit more 'IReadOnlyList<T>' types
* Fix reference signature of 'ConvertToUnmanaged'
* Fix type names for 'EventSource<...>' types
* Fix 'PropertySignature' declarations
* Emit 'InterfaceImpl' for 'IReadOnlyList<T>'
* Emit 'IList<T>' vtable types
* Minor code refactoring
* Emit stub 'IList<T>' vector types
* Simplify generic RCW-s infrastructure
* Emit 'IListMethods' types for 'IList<T>'
* Emit 'NativeObject' type for 'IList<T>', minor tweaks
* Refactor 'IID' properties to remove dependency cycles
* Share 'NativeObject' generation logic
* Share 'ComWrappersCallback' generation logic
* Share 'ComWrappersMarshallerAttribute' generation logic
* Share 'Marshaller' generation logic
* Emit proxy type for 'IList<T>'
* Emit missing 'RemoveAt' method
* Add 'GetMethods' extension method
* Emit 'InterfaceImpl' type for 'IList<T>'
* Add and use 'AddMethodImplementation' extension
* Share 'Impl' generation logic
* Emit 'IID' and 'Vftbl' types for 'IReadOnlyDictionary<,>'
* Add 'SignatureComparer.MakeValueTupleComparer'
* Emit 'IID' and 'Vftbl' types for 'IDictionary<,>'
* Emit 'IMapViewMethods' types for 'IReadOnlyDictionary<,>'
* Emit 'IReadOnlyDictionaryMethods' types
* Emit more types for 'IReadOnlyDictionary<,>'
* Add 'MakeTypeSignatureExtensions'
* Update code to use new extensions
* Minor code tweaks to interop references
* Emit 'InterfaceImpl' for 'IReadOnlyDictionary<,>'
* Add and use 'PropertySignatureExtensions'
* Add and use 'WellKnownMethodAttributesFactory'
* Add 'CreateLdloc' extensions
* Add 'WellKnownCilMethodBodyFactory'
* Adopt new IDIC implementation factory
* Minor tweaks
* Emit remaining types for 'IReadOnlyDictionary<,>'
* Update 'IDictionaryMethods<TKey, TValue>'
* Emit 'IMapMethods' types
* Emit 'IDictionaryMethods' types
* Use '[StructLayout]' to suppress 'CS0649' warnings
* Fix codegen for 'IDictionary<,>.CopyTo'
* Emit more 'IDictionary<,>' types
* Emit 'InterfaceImpl' type for 'IDictionary<,>'
* Fix 'ldarg' opcodes in DIMs
* Emit 'ICollection<T>.IsReadOnly' DIMs
* Use parameterless 'CilMethodBody' constructor
* Use UTF8 literals in 'InteropReferences'
* Add 'MethodDefinitionExtensions'
* Refactor 'IDictionary2' builder logic
* Emit stub 'Impl' type for 'IDictionary<,>'
* Add empty 'WinRT.Interop.Tasks'
* Add draft of 'CsWinRTGenerator' task
* Switch 'cswinrtgen' to using a response file
* Add support to save repro file
* Update WinRT.Interop.Tasks.csproj
* Save original file paths to JSON file
* Add message when saving debug repro
* Fix 'WinRT.Interop.dll' module name
* Rework runtime class name lookup methods
* Update the task namespace
* Remove leftover attributes
* Update 'WindowsRuntimeTypeHierarchy' forward classes
* Fix a typo
* Remove codegen for 'ComputeReadOnlySpanHash'
* Implement 'TryGetBaseRuntimeClassName' in C#
* Implement 'TryGetNextBaseRuntimeClassName' in C#
* Fix codegen and calls for next parent lookups
* Update to .NET 10, remove polyfills
* Add bindings for 'IInspectableVftbl'
* Remove 'CWT<,>' closures
* Remove 'CreateValueCallback' uses
* Remove unnecessary 'HSTRING' casts
* Minor tweaks
* Rename Windows runtime type map group
* Add partial logic for 'ComWrappers', fix XML docs
* Add logic to emit type map attributes
* Emit type map attributes for existing types
* Fix assembly for type map attributes
* Implement 'CreateObject'
* Add 'WindowsRuntimeObjectMarshaller.TryUnwrap'
* Implement 'ReleaseObjects'
* Fix vtable pointer casts
* Unwrap CCW pointers when marshalling
* Remove unnecessary 'Unsafe.AsRef' calls
* Centralize 'WindowsRuntimeComWrappers' logic
* Cache derived marshalling info, minor refactoring
* Simplify 'ComWrappers', fix some derived cases
* Simplify two 'Unsafe' calls
* Tweak some 'WindowsRuntimeObjectReference' factories
* Add 'WindowsRuntimeMarshal'
* 'WindowsRuntimeMarshal' API tweaks
* Use 'CreateObjectReferenceUnsafe' internally
* Add and use 'GetOrCreateObjectForComInstanceUnsafe'
* Fix 'CreatedWrapperFlags' for 'Uri'
* Tweak 'WindowsRuntimeComWrappersMarshallerAttribute'
* Use 'WindowsRuntimeMarshal' in generator
* Remove unnecessary 'ComputeVtables' method
* Add and use 'CilOutParameterIndices' extension
* Minor code refactoring
* Rename some APIs
* Fix 'IReferenceVftbl.get_ValueUnsafe'
* Tweak 'CsWinRTGenerator'
* Add 'InteropGeneratorTest'
* Tweak target and make messages visible
* Fix formatting in response file
* Escape the path to response files
* Minor code refactoring
* Add option to validate assembly versions
* Add new property to MSBuild task, update target
* Fix some 'IReference<HString>' stubs
* Update 'WinRT.Interop.dll' metadata in target
* Tweak target to copy to output and clean
* Trim arguments in 'cswinrtgen'
* Add support for additional arguments
* Minor tweaks to 'WindowsRuntimeComWrappers'
* Add 'TreatWarningsAsErrors' option
* Use UTF8 overload
* Implement more 'IDIC' logic
* Implement 'GetObjectReferenceForInterface'
* Implement more 'WindowsRuntimeObject' methods
* Tweak 'DynamicInterfaceCastableImplementationForwarderAttribute'
* Generalize type signature visitor logic
* Add discovery logic for SZ array types
* Add 'WindowsRuntimeArrayMarshaller' APIs
* Add and use 'HRESULTExtensions' internally
* Use '[UnsafeAccessorType]' from BLC, remove polyfill
* Handle arrays of arrays in visitor
* Emit 'IReferenceArrayVftbl' type
* Emit stub array marshaller types
* Emit 'IWindowsRuntimeArrayComWrappersCallback' types
* Emit 'Impl' types for SZ array types
* Emit 'IReferenceArrayInterfaceEntries' type
* Emit 'ArrayComWrappersMarshallerAttribute' types
* Emit proxy types and type map for array types
* Fix name mangling for SZ array types
* Optimize 'InteropUtf8NameFactory'
* Update AsmResolver, fix runtime context
* Simplify member accesses
* Fix 'CreatedWrapperFlags' parameter
* Fix 'Invoke' signature for delegate types
* Escape backtick characters
* Add `WinRT.Interop.dll` public API spec (#2002)
* Create winrt-interop-dll-spec.md
* Fix formatting
* Add spec for name mangling for arrays
* Add notes on build infrastructure
* Add technical docs on generic interfaces codegen (#1989)
* Add 'generic-interfaces-infrastructure.md'
* Tweaks and mention stateless adapters
* Rename docs file
* Create marshalling-arrays.md
* Fix typo
* Fix another typo
* Fix typo
Co-authored-by: Jeremy Koritzinsky <jekoritz@microsoft.com>
---------
Co-authored-by: Jeremy Koritzinsky <jekoritz@microsoft.com>
* Replace backticks with apostrophes in mangled names
* Add error for referencing CsWinRT 2.x
* Add 'ValidateWinRTRuntimeDllVersion2References'
* Fix XML doc
* Add 'EnableIncrementalGeneration' parameter
* Add 'WindowsRuntimeObjectMarshaller.ConvertToManaged' overload
* Move 'WindowsRuntimeTypeHierarchy'
* Update 'cswinrtgen' dependencies
* Add 'WindowsRuntimeArrayHelpers'
* Tweak runtime class name for reference arrays
* Add validation methods to 'WindowsRuntimeArrayHelpers'
* Partially implement 'Free' for array types
* Fix two build warnings
* Add shared stub for 'Type'
* Add 'DerivedComposed' and 'Sealed' types
* Remove temporary test projects
* Add new projects to .sln file
* Update an incorrect comment
* Fix build errors in cswinrtgen
* Fix 'WindowsRuntimeObject' constructors (WIP)
* Fix 'InitializeFromManagedTypeUnsafe'
* Incremental 'WindowsRuntimeObject' changes
* Remove asmresolver-nightly source from nuget.config
Deleted the asmresolver-nightly package source from nuget.config to streamline package sources and possibly resolve conflicts or redundancy.
* Add exception for missing type hierarchy entries
Introduces a sanity check in WindowsRuntimeTypeHierarchyBuilder to throw a specific exception when no type hierarchy key-value pairs are discovered. Adds TypeHierarchyNoDiscoveredKeyValuePairs to WellKnownInteropExceptions for clearer error reporting in this scenario.
* Remove duplicate method declarations in IDL file
Eliminated repeated static method declarations for unboxing types in TestComponentCSharp.idl to improve clarity and maintainability.
* Add new projects to solution file
Added WinRT.Interop.Generator and WinRT.Runtime2 projects to cswinrt.slnx to include them in the solution.
* Suppress analyzer warnings in project files
Added NoWarn for AD0001 to both csproj files to work around exceptions from ILLink.RoslynAnalyzer.DynamicallyAccessedMembersAnalyzer. Also suppressed IDE0060 in WinRT.Interop.Generator for unimplemented methods.
* Rename IWindowsRuntimeComWrappersCallback references
Updated references from IWindowsRuntimeComWrappersCallback to IWindowsRuntimeObjectComWrappersCallback in InteropTypeDefinitionBuilder.Delegate.cs and InteropReferences.cs to reflect API changes and improve clarity.
* Update comments and method signature in delegate builder
Clarified comments regarding local variable declarations and updated the 'ComputeVtables' method comment to reflect its override status in InteropTypeDefinitionBuilder.Delegate.
* Clarify constructor definition in EventSource builder
Added comments to explain the constructor implementation for EventSource types, noting that initialization logic resides in the base 'EventSource<T>' type. This improves code readability and developer understanding.
* Refactor method body assignment for iterator methods
Replaces 'Instructions' with 'CilInstructions' when assigning method bodies for 'HasCurrent' and 'MoveNext' methods in InteropTypeDefinitionBuilder.IEnumerator1.cs. This change improves consistency and clarity in method body construction.
* Fix comment to correctly reference 'MoveNext' method
Updated a comment to refer to the 'MoveNext' method instead of 'Reset' in InteropTypeDefinitionBuilder.IEnumerator1.cs for clarity and accuracy.
* Tweak error message for CsWinRT 2.x
Co-authored-by: Manodasan Wignarajah <mawign@microsoft.com>
* Fix a typo
Co-authored-by: Manodasan Wignarajah <mawign@microsoft.com>
* Fix marshaller usage in event args wrappers
Replaces incorrect 'value' parameter with 'result' in calls to ConvertToManaged for NotifyCollectionChangedEventArgs and DataErrorsChangedEventArgs marshallers, ensuring correct object conversion.
* Fix IID selection for INotifyPropertyChanged
Corrects the interface ID assignment to use INotifyPropertyChanged instead of INotifyCollectionChanged based on the WindowsRuntimeFeatureSwitches setting.
* Fix incorrect value being marshalled
Co-authored-by: Manodasan Wignarajah <mawign@microsoft.com>
* Fix more incorrect marshalled values
* Fix a few typos
* Update IID to IPropertyValue in IPropertyValueImpl
Changed the IID property in IPropertyValueImpl to reference WellKnownInterfaceIds.IID_IPropertyValue instead of IID_IInspectable to ensure correct interface identification.
* Fix incorrect release of activation factory pointer
Changed the ReleaseUnsafe call to release activationFactoryUnknown instead of activationFactory, ensuring the correct COM pointer is released after QueryInterface.
* Fix parameter name in array marshaller call
Replaces 'value' with 'referencePtr' in the call to IReferenceArrayVftbl.get_ValueUnsafe to ensure the correct pointer is used for unboxing the underlying array.
* Add StructLayout to IUnknownVftbl struct
Applied [StructLayout(LayoutKind.Sequential)] to the IUnknownVftbl struct to ensure proper memory layout for interop scenarios. This change improves compatibility with native code expecting a sequential layout.
* Suppress CS0649 warning in IUnknownImpl.cs
Added #pragma warning disable CS0649 to prevent compiler warnings about unassigned fields in the IUnknownImpl.cs file.
* Remove unused System.Runtime.InteropServices imports
Cleaned up unnecessary using directives for System.Runtime.InteropServices in several files under InteropServices to improve code clarity and reduce clutter.
* Remove explicit type annotations from lambda parameters
Simplified lambda expressions in AddOrUpdate by removing explicit type annotations from parameters, relying on type inference for improved readability.
* Suppress additional compiler warnings in source files
Added #pragma warning disable directives for CS8618, IDE0059, and IDE0060 in WindowsRuntimeObject.cs and IDE0060 in RestrictedErrorInfo.cs to suppress specific compiler warnings. These are marked as TODO for future review.
* Suppress type map trim warnings
* Add IsWindowsRuntimeAssembly check to module filtering
Extended module filtering logic to include assemblies identified as Windows Runtime assemblies, not just those referencing Windows SDK projections. Introduced IsWindowsRuntimeAssembly property to WindowsRuntimeExtensions and updated relevant checks in IgnoreAccessChecksToBuilder and InteropGenerator.Discover.
* Swap parameterless and parameterized activation methods
Reordered and updated ActivateInstanceUnsafe overloads: the parameterless version now activates sealed Windows Runtime types with no constructor parameters, while the parameterized version supports an additional string parameter. XML documentation was updated to clarify usage and method signatures were adjusted accordingly.
* Improve interface marshalling for inspectable objects
Refactored WindowsRuntimeInterfaceMarshaller to handle anonymous inspectable objects by unwrapping native references when possible, avoiding unnecessary CCW creation. Enhanced exception handling for QueryInterface failures with more informative error messages.
* Correct DateTimeOffset ticks calculation in comments
Updated comments in SystemTypes.cs and DateTimeOffset.cs to use the correct second value (0 instead of 1) when calculating ticks for DateTimeOffset(1601, 1, 1, 0, 0, 0, TimeSpan.Zero). This ensures documentation matches the actual constant value.
* Fix typo in method name ConvertToManaged
Corrected the spelling of the method name from ConvertToMananaged to ConvertToManaged in INotifyDataErrorInfoMethods to ensure proper method invocation.
* Fix duplicated wording in XML documentation comments
Removed redundant phrasing ('The IID for') from XML doc comments in NotifyCollectionChangedEventHandlerReferenceImpl and PropertyChangedEventHandlerReferenceImpl to improve clarity.
* Release IReference pointer before asserting HRESULT
Updated marshalling logic to always release the temporary IReference<T> interface pointer before asserting the HRESULT from get_ValueUnsafe. This ensures proper resource cleanup even if get_Value fails.
* Remove unnecessary blank lines in ABI event handlers
Cleaned up formatting by removing extraneous blank lines before event handler methods in INotifyCollectionChanged, INotifyDataErrorInfo, and INotifyPropertyChanged implementations.
---------
Co-authored-by: Jeremy Koritzinsky <jekoritz@microsoft.com>
Co-authored-by: Manodasan Wignarajah <mawign@microsoft.com>
This PR adds docs explaining in detail all codegen to handle generic collection interfaces in CsWinRT 3.0.