Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2577,4 +2577,4 @@
<Compile Include="$(MSBuildThisFileDirectory)System\Numerics\IUnaryPlusOperators.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Numerics\IUnsignedNumber.cs" />
</ItemGroup>
</Project>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,6 @@ public IEnumerable<StatementSyntax> GenerateMarshalStatements(TypePositionInfo i
{
var rewriter = new PointerNativeTypeAssignmentRewriter(assignment.Right.ToString(), (PointerTypeSyntax)pointer.Syntax);
assignment = (AssignmentExpressionSyntax)rewriter.Visit(assignment);

}
yield return ExpressionStatement(assignment);
}
Expand Down Expand Up @@ -534,7 +533,7 @@ public StatelessLinearCollectionNonBlittableElementsMarshalling(
IMarshallingGenerator elementMarshaller,
TypePositionInfo elementInfo,
ExpressionSyntax numElementsExpression)
: base (unmanagedElementType, elementMarshaller, elementInfo)
: base(unmanagedElementType, elementMarshaller, elementInfo)
{
_marshallerTypeSyntax = marshallerTypeSyntax;
_unmanagedType = unmanagedType;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,54 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using Microsoft.Interop;
using Microsoft.Interop.UnitTests;
using System;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.Marshalling;

namespace ComInterfaceGenerator.Unit.Tests
{
internal partial class CodeSnippets
internal partial class CodeSnippets : IComInterfaceAttributeProvider
{
private readonly GeneratorKind _generator;
GeneratorKind IComInterfaceAttributeProvider.Generator => _generator;

private string VirtualMethodIndex(
int index,
bool? ImplicitThisParameter = null,
MarshalDirection? Direction = null,
StringMarshalling? StringMarshalling = null,
Type? StringMarshallingCustomType = null,
bool? SetLastError = null,
ExceptionMarshalling? ExceptionMarshalling = null,
Type? ExceptionMarshallingType = null)
=> ((IComInterfaceAttributeProvider)this).VirtualMethodIndex(
index,
ImplicitThisParameter,
Direction,
StringMarshalling,
StringMarshallingCustomType,
SetLastError,
ExceptionMarshalling,
ExceptionMarshallingType);

private string UnmanagedObjectUnwrapper(Type t) => ((IComInterfaceAttributeProvider)this).UnmanagedObjectUnwrapper(t);

private string GeneratedComInterface => ((IComInterfaceAttributeProvider)this).GeneratedComInterface;

public CodeSnippets(GeneratorKind generator)
{
this._generator = generator;
}

private string UnmanagedCallConv(Type[]? CallConvs = null)
{
var arguments = CallConvs?.Length is 0 or null ? "" : "(CallConvs = new[] {" + string.Join(", ", CallConvs!.Select(t => $"typeof({t.FullName})")) + "})";
return "[global::System.Runtime.InteropServices.UnmanagedCallConvAttribute"
+ arguments + "]";
}

public static readonly string DisableRuntimeMarshalling = "[assembly:System.Runtime.CompilerServices.DisableRuntimeMarshalling]";
public static readonly string UsingSystemRuntimeInteropServicesMarshalling = "using System.Runtime.InteropServices.Marshalling;";
public const string INativeAPI_IUnmanagedInterfaceTypeImpl = $$"""
Expand All @@ -29,125 +70,137 @@ sealed class NativeAPI : IUnmanagedVirtualMethodTableProvider, INativeAPI.Native
}
";

public static readonly string SpecifiedMethodIndexNoExplicitParameters = @"
public string SpecifiedMethodIndexNoExplicitParameters => $@"
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.Marshalling;

[UnmanagedObjectUnwrapper<UnmanagedObjectUnwrapper.TestUnwrapper>]
{UnmanagedObjectUnwrapper(typeof(UnmanagedObjectUnwrapper.TestUnwrapper))}
{GeneratedComInterface}
partial interface INativeAPI : IUnmanagedInterfaceType
{
[VirtualMethodIndex(0)]
{{
{VirtualMethodIndex(0)}
void Method();
}" + NativeInterfaceUsage() + INativeAPI_IUnmanagedInterfaceTypeImpl;
}}" + NativeInterfaceUsage() + INativeAPI_IUnmanagedInterfaceTypeImpl;

public static readonly string SpecifiedMethodIndexNoExplicitParametersNoImplicitThis = @"
public string SpecifiedMethodIndexNoExplicitParametersNoImplicitThis => $@"
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.Marshalling;

[UnmanagedObjectUnwrapper<UnmanagedObjectUnwrapper.TestUnwrapper>]
{UnmanagedObjectUnwrapper(typeof(UnmanagedObjectUnwrapper.TestUnwrapper))}
{GeneratedComInterface}
partial interface INativeAPI : IUnmanagedInterfaceType
{
[VirtualMethodIndex(0, ImplicitThisParameter = false)]
{{
{VirtualMethodIndex(0, ImplicitThisParameter: false)}
void Method();
}" + NativeInterfaceUsage() + INativeAPI_IUnmanagedInterfaceTypeImpl;

public static readonly string SpecifiedMethodIndexNoExplicitParametersCallConvWithCallingConventions = @"
}}" + NativeInterfaceUsage() + INativeAPI_IUnmanagedInterfaceTypeImpl;

public string SpecifiedMethodIndexNoExplicitParametersCallConvWithCallingConventions => $@"
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.Marshalling;

[UnmanagedObjectUnwrapper<UnmanagedObjectUnwrapper.TestUnwrapper>]
{UnmanagedObjectUnwrapper(typeof(UnmanagedObjectUnwrapper.TestUnwrapper))}
{GeneratedComInterface}
partial interface INativeAPI : IUnmanagedInterfaceType
{
{{

[UnmanagedCallConv(CallConvs = new[] { typeof(CallConvCdecl) })]
[VirtualMethodIndex(0)]
{UnmanagedCallConv(CallConvs: new[] { typeof(CallConvCdecl) })}
{VirtualMethodIndex(0)}
void Method();
[UnmanagedCallConv(CallConvs = new[] { typeof(CallConvCdecl), typeof(CallConvMemberFunction) })]
[VirtualMethodIndex(1)]
{UnmanagedCallConv(CallConvs: new[] { typeof(CallConvCdecl), typeof(CallConvMemberFunction) })}
{VirtualMethodIndex(1)}
void Method1();

[SuppressGCTransition]
[UnmanagedCallConv(CallConvs = new[] { typeof(CallConvCdecl), typeof(CallConvMemberFunction) })]
[VirtualMethodIndex(2)]
{UnmanagedCallConv(CallConvs: new[] { typeof(CallConvCdecl), typeof(CallConvMemberFunction) })}
{VirtualMethodIndex(2)}
void Method2();

[SuppressGCTransition]
[UnmanagedCallConv]
[VirtualMethodIndex(3)]
{UnmanagedCallConv()}
{VirtualMethodIndex(3)}
void Method3();

[SuppressGCTransition]
[VirtualMethodIndex(4)]
{VirtualMethodIndex(4)}
void Method4();
}" + NativeInterfaceUsage() + INativeAPI_IUnmanagedInterfaceTypeImpl;
public static string BasicParametersAndModifiers(string typeName, string preDeclaration = "") => $@"
}}" + NativeInterfaceUsage() + INativeAPI_IUnmanagedInterfaceTypeImpl;

public string BasicParametersAndModifiers(string typeName, string preDeclaration = "") => $@"
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.Marshalling;
{preDeclaration}

[assembly:DisableRuntimeMarshalling]

[UnmanagedObjectUnwrapper<UnmanagedObjectUnwrapper.TestUnwrapper>]
{UnmanagedObjectUnwrapper(typeof(UnmanagedObjectUnwrapper.TestUnwrapper))}
{GeneratedComInterface}
partial interface INativeAPI : IUnmanagedInterfaceType
{{
[VirtualMethodIndex(0)]
{VirtualMethodIndex(0)}
{typeName} Method({typeName} value, in {typeName} inValue, ref {typeName} refValue, out {typeName} outValue);
}}" + NativeInterfaceUsage() + INativeAPI_IUnmanagedInterfaceTypeImpl;
public static string BasicParametersAndModifiersManagedToUnmanaged(string typeName, string preDeclaration = "") => $@"

public string BasicParametersAndModifiersManagedToUnmanaged(string typeName, string preDeclaration = "") => $@"
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.Marshalling;
{preDeclaration}

[assembly:DisableRuntimeMarshalling]

[UnmanagedObjectUnwrapper<UnmanagedObjectUnwrapper.TestUnwrapper>]
{UnmanagedObjectUnwrapper(typeof(UnmanagedObjectUnwrapper.TestUnwrapper))}
{GeneratedComInterface}
partial interface INativeAPI : IUnmanagedInterfaceType
{{
[VirtualMethodIndex(0, Direction = MarshalDirection.ManagedToUnmanaged)]
{VirtualMethodIndex(0, Direction: MarshalDirection.ManagedToUnmanaged)}
{typeName} Method({typeName} value, in {typeName} inValue, ref {typeName} refValue, out {typeName} outValue);
}}" + NativeInterfaceUsage() + INativeAPI_IUnmanagedInterfaceTypeImpl;
public static string BasicParametersAndModifiers<T>() => BasicParametersAndModifiers(typeof(T).FullName!);
public static string BasicParametersAndModifiersNoRef(string typeName, string preDeclaration = "") => $@"
public string BasicParametersAndModifiers<T>() => BasicParametersAndModifiers(typeof(T).FullName!);
public string BasicParametersAndModifiersNoRef(string typeName, string preDeclaration = "") => $@"
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.Marshalling;
{preDeclaration}

[assembly:DisableRuntimeMarshalling]

[UnmanagedObjectUnwrapper<UnmanagedObjectUnwrapper.TestUnwrapper>]
{UnmanagedObjectUnwrapper(typeof(UnmanagedObjectUnwrapper.TestUnwrapper))}
{GeneratedComInterface}
partial interface INativeAPI : IUnmanagedInterfaceType
{{
[VirtualMethodIndex(0)]
{VirtualMethodIndex(0)}
{typeName} Method({typeName} value, in {typeName} inValue, out {typeName} outValue);
}}" + NativeInterfaceUsage() + INativeAPI_IUnmanagedInterfaceTypeImpl;
public static string BasicParametersAndModifiersNoImplicitThis(string typeName) => $@"

public string BasicParametersAndModifiersNoImplicitThis(string typeName) => $@"
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.Marshalling;

[UnmanagedObjectUnwrapper<UnmanagedObjectUnwrapper.TestUnwrapper>]
{UnmanagedObjectUnwrapper(typeof(UnmanagedObjectUnwrapper.TestUnwrapper))}
{GeneratedComInterface}
partial interface INativeAPI : IUnmanagedInterfaceType
{{
[VirtualMethodIndex(0, ImplicitThisParameter = false)]
{VirtualMethodIndex(0, ImplicitThisParameter: false)}
{typeName} Method({typeName} value, in {typeName} inValue, ref {typeName} refValue, out {typeName} outValue);
}}" + NativeInterfaceUsage() + INativeAPI_IUnmanagedInterfaceTypeImpl;

public static string BasicParametersAndModifiersNoImplicitThis<T>() => BasicParametersAndModifiersNoImplicitThis(typeof(T).FullName!);
public static string MarshalUsingCollectionCountInfoParametersAndModifiers<T>() => MarshalUsingCollectionCountInfoParametersAndModifiers(typeof(T).ToString());
public static string MarshalUsingCollectionCountInfoParametersAndModifiers(string collectionType) => $@"
public string BasicParametersAndModifiersNoImplicitThis<T>() => BasicParametersAndModifiersNoImplicitThis(typeof(T).FullName!);
public string MarshalUsingCollectionCountInfoParametersAndModifiers<T>() => MarshalUsingCollectionCountInfoParametersAndModifiers(typeof(T).ToString());
public string MarshalUsingCollectionCountInfoParametersAndModifiers(string collectionType) => $@"
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.Marshalling;
[assembly:DisableRuntimeMarshalling]

[UnmanagedObjectUnwrapper<UnmanagedObjectUnwrapper.TestUnwrapper>]
{UnmanagedObjectUnwrapper(typeof(UnmanagedObjectUnwrapper.TestUnwrapper))}
{GeneratedComInterface}
partial interface INativeAPI : IUnmanagedInterfaceType
{{
[VirtualMethodIndex(0)]
{VirtualMethodIndex(0)}
[return:MarshalUsing(ConstantElementCount=10)]
{collectionType} Method(
{collectionType} p,
Expand All @@ -158,38 +211,43 @@ partial interface INativeAPI : IUnmanagedInterfaceType
out int pOutSize);
}}" + NativeInterfaceUsage() + INativeAPI_IUnmanagedInterfaceTypeImpl;

public static string BasicReturnTypeComExceptionHandling(string typeName, string preDeclaration = "") => $@"
public string BasicReturnTypeComExceptionHandling(string typeName, string preDeclaration = "") => $@"
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.Marshalling;
{preDeclaration}

[UnmanagedObjectUnwrapper<UnmanagedObjectUnwrapper.TestUnwrapper>]
{UnmanagedObjectUnwrapper(typeof(UnmanagedObjectUnwrapper.TestUnwrapper))}
{GeneratedComInterface}
partial interface INativeAPI : IUnmanagedInterfaceType
{{
[VirtualMethodIndex(0, ExceptionMarshalling = ExceptionMarshalling.Com)]
{VirtualMethodIndex(0, ExceptionMarshalling : ExceptionMarshalling.Com)}
{typeName} Method();
}}" + NativeInterfaceUsage() + INativeAPI_IUnmanagedInterfaceTypeImpl;

public static string BasicReturnTypeCustomExceptionHandling(string typeName, string customExceptionType, string preDeclaration = "") => $@"
public string BasicReturnTypeCustomExceptionHandling(string typeName, string customExceptionType, string preDeclaration = "") => $@"
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.Marshalling;
{preDeclaration}

[UnmanagedObjectUnwrapper<UnmanagedObjectUnwrapper.TestUnwrapper>]
{UnmanagedObjectUnwrapper(typeof(UnmanagedObjectUnwrapper.TestUnwrapper))}
{GeneratedComInterface}
partial interface INativeAPI : IUnmanagedInterfaceType
{{
[VirtualMethodIndex(0, CustomExceptionMarshallingType = typeof({customExceptionType}))]
{VirtualMethodIndex(0, ExceptionMarshallingType : Type.GetType(customExceptionType))}
{typeName} Method();
}}" + NativeInterfaceUsage() + INativeAPI_IUnmanagedInterfaceTypeImpl;

public class ManagedToUnmanaged : IVirtualMethodIndexSignatureProvider<ManagedToUnmanaged>
{
public ManagedToUnmanaged(GeneratorKind generator) => Generator = generator;
public static MarshalDirection Direction => MarshalDirection.ManagedToUnmanaged;

public static bool ImplicitThisParameter => true;

public GeneratorKind Generator { get; }

public static string NativeInterfaceUsage() => CodeSnippets.NativeInterfaceUsage();
}
public class ManagedToUnmanagedNoImplicitThis : IVirtualMethodIndexSignatureProvider<ManagedToUnmanagedNoImplicitThis>
Expand All @@ -198,6 +256,10 @@ public class ManagedToUnmanagedNoImplicitThis : IVirtualMethodIndexSignatureProv

public static bool ImplicitThisParameter => false;

public GeneratorKind Generator { get; }

public ManagedToUnmanagedNoImplicitThis(GeneratorKind generator) => Generator = generator;

public static string NativeInterfaceUsage() => CodeSnippets.NativeInterfaceUsage();
}
public class UnmanagedToManaged : IVirtualMethodIndexSignatureProvider<UnmanagedToManaged>
Expand All @@ -206,6 +268,10 @@ public class UnmanagedToManaged : IVirtualMethodIndexSignatureProvider<Unmanaged

public static bool ImplicitThisParameter => true;

public GeneratorKind Generator { get; }

public UnmanagedToManaged(GeneratorKind generator) => Generator = generator;

// Unmanaged-to-managed-only stubs don't provide implementations for the interface, so we don't want to try to use the generated nested interface
// since it won't have managed implementations for the methods
public static string NativeInterfaceUsage() => string.Empty;
Expand All @@ -215,6 +281,11 @@ public class Bidirectional : IVirtualMethodIndexSignatureProvider<Bidirectional>
public static MarshalDirection Direction => MarshalDirection.Bidirectional;

public static bool ImplicitThisParameter => true;

public GeneratorKind Generator { get; }

public Bidirectional(GeneratorKind generator) => Generator = generator;

public static string NativeInterfaceUsage() => CodeSnippets.NativeInterfaceUsage();
}
}
Expand Down
Loading