SharpGen/Generator/Marshallers/ArrayOfInterfaceMarshaller.cs (82 lines of code) (raw):

using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; using SharpGen.Model; using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory; namespace SharpGen.Generator.Marshallers { internal sealed class ArrayOfInterfaceMarshaller : ArrayMarshallerBase { public override bool CanMarshal(CsMarshalBase csElement) => csElement.IsArray && csElement.IsInterface; public override StatementSyntax GenerateManagedToNative(CsMarshalBase csElement, bool singleStackFrame) => GenerateNullCheckIfNeeded( csElement, ExpressionStatement( InvocationExpression( MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, GlobalNamespace.GetTypeNameSyntax(WellKnownName.MarshallingHelpers), GenericName(Identifier("ConvertToPointerArray")) .WithTypeArgumentList( TypeArgumentList( SingletonSeparatedList<TypeSyntax>( IdentifierName(csElement.PublicType.QualifiedName) ) ) ) ), ArgumentList( SeparatedList( new[] { // Span<IntPtr> pointers, ReadOnlySpan<TCallback> interfaces Argument(GetMarshalStorageLocation(csElement)), Argument(IdentifierName(csElement.Name)) } ) ) ) ) ); public override StatementSyntax GenerateNativeCleanup(CsMarshalBase csElement, bool singleStackFrame) => GenerateGCKeepAlive(csElement); public override StatementSyntax GenerateNativeToManaged(CsMarshalBase csElement, bool singleStackFrame) => csElement switch { CsParameter {IsFast: true, IsOut: true} => GenerateNullCheckIfNeeded( csElement, ExpressionStatement( InvocationExpression( MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, GlobalNamespace.GetTypeNameSyntax(WellKnownName.MarshallingHelpers), GenericName(Identifier("ConvertToInterfaceArrayFast")) .WithTypeArgumentList( TypeArgumentList( SingletonSeparatedList<TypeSyntax>( IdentifierName(csElement.PublicType.QualifiedName) ) ) ) ), ArgumentList( SeparatedList(new[] { // ReadOnlySpan<IntPtr> pointers, Span<TCallback> interfaces Argument(GetMarshalStorageLocation(csElement)), Argument(IdentifierName(csElement.Name)) } ) ) ) ) ), _ => LoopThroughArrayParameter( csElement, (publicElement, marshalElement) => MarshalInterfaceInstanceFromNative(csElement, publicElement, marshalElement) ) }; protected override TypeSyntax GetMarshalElementTypeSyntax(CsMarshalBase csElement) => IntPtrType; public ArrayOfInterfaceMarshaller(Ioc ioc) : base(ioc) { } } }