1
0
Fork 0
mirror of https://github.com/VSadov/Satori.git synced 2025-06-11 18:20:26 +09:00

Use more traditional interface implementation + delegation for generator unit tests (#83057)

This commit is contained in:
Jeremy Koritzinsky 2023-03-07 11:00:30 -08:00 committed by GitHub
parent 7018f03bba
commit 6512040d79
Signed by: github
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 276 additions and 226 deletions

View file

@ -26,7 +26,7 @@ namespace ComInterfaceGenerator.Unit.Tests
[UnmanagedObjectUnwrapper<UnmanagedObjectUnwrapper.TestUnwrapper>]
partial interface INativeAPI : IUnmanagedInterfaceType
{
{{CodeSnippets.INativeAPI_IUnmanagedInterfaceTypeMethodImpl}}
static unsafe void* IUnmanagedInterfaceType.VirtualMethodTableManagedImplementation => null;
[VirtualMethodIndex(0)]
void Method();
}
@ -53,7 +53,7 @@ namespace ComInterfaceGenerator.Unit.Tests
[UnmanagedObjectUnwrapper<UnmanagedObjectUnwrapper.TestUnwrapper>]
partial interface INativeAPI : IUnmanagedInterfaceType
{
{{CodeSnippets.INativeAPI_IUnmanagedInterfaceTypeMethodImpl}}
static unsafe void* IUnmanagedInterfaceType.VirtualMethodTableManagedImplementation => null;
[SuppressGCTransitionAttribute]
[VirtualMethodIndex(0)]
void Method();
@ -81,7 +81,7 @@ namespace ComInterfaceGenerator.Unit.Tests
[UnmanagedObjectUnwrapper<UnmanagedObjectUnwrapper.TestUnwrapper>]
partial interface INativeAPI : IUnmanagedInterfaceType
{
{{CodeSnippets.INativeAPI_IUnmanagedInterfaceTypeMethodImpl}}
static unsafe void* IUnmanagedInterfaceType.VirtualMethodTableManagedImplementation => null;
[UnmanagedCallConv]
[VirtualMethodIndex(0)]
void Method();
@ -109,7 +109,7 @@ namespace ComInterfaceGenerator.Unit.Tests
[UnmanagedObjectUnwrapper<UnmanagedObjectUnwrapper.TestUnwrapper>]
partial interface INativeAPI : IUnmanagedInterfaceType
{
{{CodeSnippets.INativeAPI_IUnmanagedInterfaceTypeMethodImpl}}
static unsafe void* IUnmanagedInterfaceType.VirtualMethodTableManagedImplementation => null;
[UnmanagedCallConv(CallConvs = new[] { typeof(CallConvCdecl) })]
[VirtualMethodIndex(0)]
void Method();
@ -137,7 +137,7 @@ namespace ComInterfaceGenerator.Unit.Tests
[UnmanagedObjectUnwrapper<UnmanagedObjectUnwrapper.TestUnwrapper>]
partial interface INativeAPI : IUnmanagedInterfaceType
{
{{CodeSnippets.INativeAPI_IUnmanagedInterfaceTypeMethodImpl}}
static unsafe void* IUnmanagedInterfaceType.VirtualMethodTableManagedImplementation => null;
[UnmanagedCallConv(CallConvs = new[] { typeof(CallConvCdecl), typeof(CallConvMemberFunction) })]
[VirtualMethodIndex(0)]
void Method();
@ -171,7 +171,7 @@ namespace ComInterfaceGenerator.Unit.Tests
[UnmanagedObjectUnwrapper<UnmanagedObjectUnwrapper.TestUnwrapper>]
partial interface INativeAPI : IUnmanagedInterfaceType
{
{{CodeSnippets.INativeAPI_IUnmanagedInterfaceTypeMethodImpl}}
static unsafe void* IUnmanagedInterfaceType.VirtualMethodTableManagedImplementation => null;
[SuppressGCTransition]
[UnmanagedCallConv(CallConvs = new[] { typeof(CallConvCdecl), typeof(CallConvMemberFunction) })]
[VirtualMethodIndex(0)]

View file

@ -9,10 +9,13 @@ using System.Runtime.InteropServices.Marshalling;
namespace ComInterfaceGenerator.Unit.Tests
{
internal partial class CodeSnippets : IComInterfaceAttributeProvider
internal partial class CodeSnippets
{
private readonly GeneratorKind _generator;
GeneratorKind IComInterfaceAttributeProvider.Generator => _generator;
private readonly IComInterfaceAttributeProvider _attributeProvider;
public CodeSnippets(IComInterfaceAttributeProvider attributeProvider)
{
_attributeProvider = attributeProvider;
}
private string VirtualMethodIndex(
int index,
@ -23,7 +26,7 @@ namespace ComInterfaceGenerator.Unit.Tests
bool? SetLastError = null,
ExceptionMarshalling? ExceptionMarshalling = null,
Type? ExceptionMarshallingType = null)
=> ((IComInterfaceAttributeProvider)this).VirtualMethodIndex(
=> _attributeProvider.VirtualMethodIndex(
index,
ImplicitThisParameter,
Direction,
@ -33,14 +36,9 @@ namespace ComInterfaceGenerator.Unit.Tests
ExceptionMarshalling,
ExceptionMarshallingType);
private string UnmanagedObjectUnwrapper(Type t) => ((IComInterfaceAttributeProvider)this).UnmanagedObjectUnwrapper(t);
private string UnmanagedObjectUnwrapper(Type t) => _attributeProvider.UnmanagedObjectUnwrapper(t);
private string GeneratedComInterface => ((IComInterfaceAttributeProvider)this).GeneratedComInterface;
public CodeSnippets(GeneratorKind generator)
{
this._generator = generator;
}
private string GeneratedComInterface => _attributeProvider.GeneratedComInterface;
private string UnmanagedCallConv(Type[]? CallConvs = null)
{
@ -51,16 +49,6 @@ namespace ComInterfaceGenerator.Unit.Tests
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 = $$"""
partial interface INativeAPI
{
{{INativeAPI_IUnmanagedInterfaceTypeMethodImpl}}
}
""";
public const string INativeAPI_IUnmanagedInterfaceTypeMethodImpl = """
static unsafe void* IUnmanagedInterfaceType.VirtualMethodTableManagedImplementation => null;
""";
public static string NativeInterfaceUsage() => @"
// Try using the generated native interface
@ -76,11 +64,11 @@ using System.Runtime.InteropServices.Marshalling;
{UnmanagedObjectUnwrapper(typeof(UnmanagedObjectUnwrapper.TestUnwrapper))}
{GeneratedComInterface}
partial interface INativeAPI : IUnmanagedInterfaceType
partial interface INativeAPI
{{
{VirtualMethodIndex(0)}
void Method();
}}" + NativeInterfaceUsage() + INativeAPI_IUnmanagedInterfaceTypeImpl;
}}" + NativeInterfaceUsage() + _attributeProvider.AdditionalUserRequiredInterfaces("INativeAPI");
public string SpecifiedMethodIndexNoExplicitParametersNoImplicitThis => $@"
using System.Runtime.InteropServices;
@ -88,12 +76,12 @@ using System.Runtime.InteropServices.Marshalling;
{UnmanagedObjectUnwrapper(typeof(UnmanagedObjectUnwrapper.TestUnwrapper))}
{GeneratedComInterface}
partial interface INativeAPI : IUnmanagedInterfaceType
partial interface INativeAPI
{{
{VirtualMethodIndex(0, ImplicitThisParameter: false)}
void Method();
}}" + NativeInterfaceUsage() + INativeAPI_IUnmanagedInterfaceTypeImpl;
}}" + NativeInterfaceUsage() + _attributeProvider.AdditionalUserRequiredInterfaces("INativeAPI");
public string SpecifiedMethodIndexNoExplicitParametersCallConvWithCallingConventions => $@"
using System.Runtime.CompilerServices;
@ -102,7 +90,7 @@ using System.Runtime.InteropServices.Marshalling;
{UnmanagedObjectUnwrapper(typeof(UnmanagedObjectUnwrapper.TestUnwrapper))}
{GeneratedComInterface}
partial interface INativeAPI : IUnmanagedInterfaceType
partial interface INativeAPI
{{
{UnmanagedCallConv(CallConvs: new[] { typeof(CallConvCdecl) })}
@ -125,7 +113,7 @@ partial interface INativeAPI : IUnmanagedInterfaceType
[SuppressGCTransition]
{VirtualMethodIndex(4)}
void Method4();
}}" + NativeInterfaceUsage() + INativeAPI_IUnmanagedInterfaceTypeImpl;
}}" + NativeInterfaceUsage() + _attributeProvider.AdditionalUserRequiredInterfaces("INativeAPI");
public string BasicParametersAndModifiers(string typeName, string preDeclaration = "") => $@"
using System.Runtime.CompilerServices;
@ -137,11 +125,11 @@ using System.Runtime.InteropServices.Marshalling;
{UnmanagedObjectUnwrapper(typeof(UnmanagedObjectUnwrapper.TestUnwrapper))}
{GeneratedComInterface}
partial interface INativeAPI : IUnmanagedInterfaceType
partial interface INativeAPI
{{
{VirtualMethodIndex(0)}
{typeName} Method({typeName} value, in {typeName} inValue, ref {typeName} refValue, out {typeName} outValue);
}}" + NativeInterfaceUsage() + INativeAPI_IUnmanagedInterfaceTypeImpl;
}}" + NativeInterfaceUsage() + _attributeProvider.AdditionalUserRequiredInterfaces("INativeAPI");
public string BasicParametersAndModifiersManagedToUnmanaged(string typeName, string preDeclaration = "") => $@"
using System.Runtime.CompilerServices;
@ -153,11 +141,11 @@ using System.Runtime.InteropServices.Marshalling;
{UnmanagedObjectUnwrapper(typeof(UnmanagedObjectUnwrapper.TestUnwrapper))}
{GeneratedComInterface}
partial interface INativeAPI : IUnmanagedInterfaceType
partial interface INativeAPI
{{
{VirtualMethodIndex(0, Direction: MarshalDirection.ManagedToUnmanaged)}
{typeName} Method({typeName} value, in {typeName} inValue, ref {typeName} refValue, out {typeName} outValue);
}}" + NativeInterfaceUsage() + INativeAPI_IUnmanagedInterfaceTypeImpl;
}}" + NativeInterfaceUsage() + _attributeProvider.AdditionalUserRequiredInterfaces("INativeAPI");
public string BasicParametersAndModifiers<T>() => BasicParametersAndModifiers(typeof(T).FullName!);
public string BasicParametersAndModifiersNoRef(string typeName, string preDeclaration = "") => $@"
using System.Runtime.CompilerServices;
@ -169,11 +157,11 @@ using System.Runtime.InteropServices.Marshalling;
{UnmanagedObjectUnwrapper(typeof(UnmanagedObjectUnwrapper.TestUnwrapper))}
{GeneratedComInterface}
partial interface INativeAPI : IUnmanagedInterfaceType
partial interface INativeAPI
{{
{VirtualMethodIndex(0)}
{typeName} Method({typeName} value, in {typeName} inValue, out {typeName} outValue);
}}" + NativeInterfaceUsage() + INativeAPI_IUnmanagedInterfaceTypeImpl;
}}" + NativeInterfaceUsage() + _attributeProvider.AdditionalUserRequiredInterfaces("INativeAPI");
public string BasicParametersAndModifiersNoImplicitThis(string typeName) => $@"
using System.Runtime.CompilerServices;
@ -182,11 +170,11 @@ using System.Runtime.InteropServices.Marshalling;
{UnmanagedObjectUnwrapper(typeof(UnmanagedObjectUnwrapper.TestUnwrapper))}
{GeneratedComInterface}
partial interface INativeAPI : IUnmanagedInterfaceType
partial interface INativeAPI
{{
{VirtualMethodIndex(0, ImplicitThisParameter: false)}
{typeName} Method({typeName} value, in {typeName} inValue, ref {typeName} refValue, out {typeName} outValue);
}}" + NativeInterfaceUsage() + INativeAPI_IUnmanagedInterfaceTypeImpl;
}}" + NativeInterfaceUsage() + _attributeProvider.AdditionalUserRequiredInterfaces("INativeAPI");
public string BasicParametersAndModifiersNoImplicitThis<T>() => BasicParametersAndModifiersNoImplicitThis(typeof(T).FullName!);
public string MarshalUsingCollectionCountInfoParametersAndModifiers<T>() => MarshalUsingCollectionCountInfoParametersAndModifiers(typeof(T).ToString());
@ -198,7 +186,7 @@ using System.Runtime.InteropServices.Marshalling;
{UnmanagedObjectUnwrapper(typeof(UnmanagedObjectUnwrapper.TestUnwrapper))}
{GeneratedComInterface}
partial interface INativeAPI : IUnmanagedInterfaceType
partial interface INativeAPI
{{
{VirtualMethodIndex(0)}
[return:MarshalUsing(ConstantElementCount=10)]
@ -209,7 +197,7 @@ partial interface INativeAPI : IUnmanagedInterfaceType
[MarshalUsing(CountElementName = ""pRefSize"")] ref {collectionType} pRef,
[MarshalUsing(CountElementName = ""pOutSize"")] out {collectionType} pOut,
out int pOutSize);
}}" + NativeInterfaceUsage() + INativeAPI_IUnmanagedInterfaceTypeImpl;
}}" + NativeInterfaceUsage() + _attributeProvider.AdditionalUserRequiredInterfaces("INativeAPI");
public string BasicReturnTypeComExceptionHandling(string typeName, string preDeclaration = "") => $@"
using System.Runtime.CompilerServices;
@ -219,11 +207,11 @@ using System.Runtime.InteropServices.Marshalling;
{UnmanagedObjectUnwrapper(typeof(UnmanagedObjectUnwrapper.TestUnwrapper))}
{GeneratedComInterface}
partial interface INativeAPI : IUnmanagedInterfaceType
partial interface INativeAPI
{{
{VirtualMethodIndex(0, ExceptionMarshalling : ExceptionMarshalling.Com)}
{typeName} Method();
}}" + NativeInterfaceUsage() + INativeAPI_IUnmanagedInterfaceTypeImpl;
}}" + NativeInterfaceUsage() + _attributeProvider.AdditionalUserRequiredInterfaces("INativeAPI");
public string BasicReturnTypeCustomExceptionHandling(string typeName, string customExceptionType, string preDeclaration = "") => $@"
using System.Runtime.CompilerServices;
@ -233,60 +221,73 @@ using System.Runtime.InteropServices.Marshalling;
{UnmanagedObjectUnwrapper(typeof(UnmanagedObjectUnwrapper.TestUnwrapper))}
{GeneratedComInterface}
partial interface INativeAPI : IUnmanagedInterfaceType
partial interface INativeAPI
{{
{VirtualMethodIndex(0, ExceptionMarshallingType : Type.GetType(customExceptionType))}
{typeName} Method();
}}" + NativeInterfaceUsage() + INativeAPI_IUnmanagedInterfaceTypeImpl;
}}" + NativeInterfaceUsage() + _attributeProvider.AdditionalUserRequiredInterfaces("INativeAPI");
public class ManagedToUnmanaged : IVirtualMethodIndexSignatureProvider<ManagedToUnmanaged>
public class ManagedToUnmanaged : IVirtualMethodIndexSignatureProvider
{
public ManagedToUnmanaged(GeneratorKind generator) => Generator = generator;
public static MarshalDirection Direction => MarshalDirection.ManagedToUnmanaged;
public MarshalDirection Direction => MarshalDirection.ManagedToUnmanaged;
public static bool ImplicitThisParameter => true;
public bool ImplicitThisParameter => true;
public GeneratorKind Generator { get; }
public string NativeInterfaceUsage() => CodeSnippets.NativeInterfaceUsage();
public static string NativeInterfaceUsage() => CodeSnippets.NativeInterfaceUsage();
public ManagedToUnmanaged(IComInterfaceAttributeProvider attributeProvider)
{
AttributeProvider = attributeProvider;
}
public IComInterfaceAttributeProvider AttributeProvider { get; }
}
public class ManagedToUnmanagedNoImplicitThis : IVirtualMethodIndexSignatureProvider<ManagedToUnmanagedNoImplicitThis>
public class ManagedToUnmanagedNoImplicitThis : IVirtualMethodIndexSignatureProvider
{
public static MarshalDirection Direction => MarshalDirection.ManagedToUnmanaged;
public MarshalDirection Direction => MarshalDirection.ManagedToUnmanaged;
public static bool ImplicitThisParameter => false;
public bool ImplicitThisParameter => false;
public GeneratorKind Generator { get; }
public string NativeInterfaceUsage() => CodeSnippets.NativeInterfaceUsage();
public ManagedToUnmanagedNoImplicitThis(GeneratorKind generator) => Generator = generator;
public ManagedToUnmanagedNoImplicitThis(IComInterfaceAttributeProvider attributeProvider)
{
AttributeProvider = attributeProvider;
}
public static string NativeInterfaceUsage() => CodeSnippets.NativeInterfaceUsage();
public IComInterfaceAttributeProvider AttributeProvider { get; }
}
public class UnmanagedToManaged : IVirtualMethodIndexSignatureProvider<UnmanagedToManaged>
public class UnmanagedToManaged : IVirtualMethodIndexSignatureProvider
{
public static MarshalDirection Direction => MarshalDirection.UnmanagedToManaged;
public MarshalDirection Direction => MarshalDirection.UnmanagedToManaged;
public static bool ImplicitThisParameter => true;
public GeneratorKind Generator { get; }
public UnmanagedToManaged(GeneratorKind generator) => Generator = generator;
public bool ImplicitThisParameter => true;
// 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;
public string NativeInterfaceUsage() => string.Empty;
public UnmanagedToManaged(IComInterfaceAttributeProvider attributeProvider)
{
AttributeProvider = attributeProvider;
}
public IComInterfaceAttributeProvider AttributeProvider { get; }
}
public class Bidirectional : IVirtualMethodIndexSignatureProvider<Bidirectional>
public class Bidirectional : IVirtualMethodIndexSignatureProvider
{
public static MarshalDirection Direction => MarshalDirection.Bidirectional;
public MarshalDirection Direction => MarshalDirection.Bidirectional;
public static bool ImplicitThisParameter => true;
public bool ImplicitThisParameter => true;
public GeneratorKind Generator { get; }
public string NativeInterfaceUsage() => CodeSnippets.NativeInterfaceUsage();
public Bidirectional(GeneratorKind generator) => Generator = generator;
public Bidirectional(IComInterfaceAttributeProvider attributeProvider)
{
AttributeProvider = attributeProvider;
}
public static string NativeInterfaceUsage() => CodeSnippets.NativeInterfaceUsage();
public IComInterfaceAttributeProvider AttributeProvider { get; }
}
}
}

View file

@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
@ -19,9 +20,17 @@ namespace ComInterfaceGenerator.Unit.Tests
[CallerFilePath] string? filePath = null)
=> TestUtils.GetFileLineName(lineNumber, filePath);
private static IComInterfaceAttributeProvider GetAttributeProvider(GeneratorKind generator)
=> generator switch
{
GeneratorKind.VTableIndexStubGenerator => new VirtualMethodIndexAttributeProvider(),
GeneratorKind.ComInterfaceGenerator => new GeneratedComInterfaceAttributeProvider(),
_ => throw new UnreachableException(),
};
public static IEnumerable<object[]> CodeSnippetsToCompile(GeneratorKind generator)
{
CodeSnippets codeSnippets = new(generator);
CodeSnippets codeSnippets = new(GetAttributeProvider(generator));
yield return new[] { ID(), codeSnippets.SpecifiedMethodIndexNoExplicitParameters };
yield return new[] { ID(), codeSnippets.SpecifiedMethodIndexNoExplicitParametersNoImplicitThis };
yield return new[] { ID(), codeSnippets.SpecifiedMethodIndexNoExplicitParametersCallConvWithCallingConventions };
@ -53,7 +62,7 @@ namespace ComInterfaceGenerator.Unit.Tests
yield return new[] { ID(), codeSnippets.BasicParametersAndModifiersNoImplicitThis<UIntPtr>() };
// Custom type marshalling managed-to-unmanaged
CustomStructMarshallingCodeSnippets<CodeSnippets.ManagedToUnmanaged> customStructMarshallingCodeSnippetsManagedToUnmanaged = new(new(generator));
CustomStructMarshallingCodeSnippets customStructMarshallingCodeSnippetsManagedToUnmanaged = new(new CodeSnippets.ManagedToUnmanaged(GetAttributeProvider(generator)));
yield return new[] { ID(), customStructMarshallingCodeSnippetsManagedToUnmanaged.Stateless.ParametersAndModifiers };
yield return new[] { ID(), customStructMarshallingCodeSnippetsManagedToUnmanaged.Stateless.MarshalUsingParametersAndModifiers };
yield return new[] { ID(), customStructMarshallingCodeSnippetsManagedToUnmanaged.Stateless.NativeToManagedOnlyOutParameter };
@ -87,7 +96,7 @@ namespace ComInterfaceGenerator.Unit.Tests
yield return new[] { ID(), customStructMarshallingCodeSnippetsManagedToUnmanaged.Stateful.DefaultModeReturnValue };
// Custom type marshalling unmanaged-to-managed
CustomStructMarshallingCodeSnippets<CodeSnippets.UnmanagedToManaged> customStructMarshallingCodeSnippetsUnmanagedToManaged = new(new(generator));
CustomStructMarshallingCodeSnippets customStructMarshallingCodeSnippetsUnmanagedToManaged = new(new CodeSnippets.UnmanagedToManaged(GetAttributeProvider(generator)));
yield return new[] { ID(), customStructMarshallingCodeSnippetsUnmanagedToManaged.Stateless.ParametersAndModifiers };
yield return new[] { ID(), customStructMarshallingCodeSnippetsUnmanagedToManaged.Stateless.MarshalUsingParametersAndModifiers };
yield return new[] { ID(), customStructMarshallingCodeSnippetsUnmanagedToManaged.Stateless.NativeToManagedOnlyInParameter };
@ -106,7 +115,7 @@ namespace ComInterfaceGenerator.Unit.Tests
yield return new[] { ID(), customStructMarshallingCodeSnippetsUnmanagedToManaged.Stateful.OptionalStackallocParametersAndModifiers };
// Custom type marshalling bidirectional
CustomStructMarshallingCodeSnippets<CodeSnippets.Bidirectional> customStructMarshallingCodeSnippetsBidirectional = new(new(generator));
CustomStructMarshallingCodeSnippets customStructMarshallingCodeSnippetsBidirectional = new(new CodeSnippets.Bidirectional(GetAttributeProvider(generator)));
yield return new[] { ID(), customStructMarshallingCodeSnippetsBidirectional.Stateless.ParametersAndModifiers };
yield return new[] { ID(), customStructMarshallingCodeSnippetsBidirectional.Stateless.MarshalUsingParametersAndModifiers };
yield return new[] { ID(), customStructMarshallingCodeSnippetsBidirectional.Stateless.RefParameter };
@ -137,7 +146,7 @@ namespace ComInterfaceGenerator.Unit.Tests
public static IEnumerable<object[]> CustomCollections(GeneratorKind generator)
{
// Custom collection marshalling
CustomCollectionMarshallingCodeSnippets<CodeSnippets.ManagedToUnmanaged> customCollectionMarshallingCodeSnippetsManagedToUnmanaged = new(new(generator));
CustomCollectionMarshallingCodeSnippets customCollectionMarshallingCodeSnippetsManagedToUnmanaged = new(new CodeSnippets.ManagedToUnmanaged(GetAttributeProvider(generator)));
yield return new[] { ID(), customCollectionMarshallingCodeSnippetsManagedToUnmanaged.Stateless.ByValue<byte>() };
yield return new[] { ID(), customCollectionMarshallingCodeSnippetsManagedToUnmanaged.Stateless.ByValue<sbyte>() };
yield return new[] { ID(), customCollectionMarshallingCodeSnippetsManagedToUnmanaged.Stateless.ByValue<short>() };
@ -221,7 +230,7 @@ namespace ComInterfaceGenerator.Unit.Tests
yield return new[] { ID(), customCollectionMarshallingCodeSnippetsManagedToUnmanaged.Stateful.NonBlittableElementNativeToManagedOnlyOutParameter };
yield return new[] { ID(), customCollectionMarshallingCodeSnippetsManagedToUnmanaged.Stateful.NonBlittableElementNativeToManagedOnlyReturnValue };
CodeSnippets codeSnippets = new(generator);
CodeSnippets codeSnippets = new(GetAttributeProvider(generator));
yield return new[] { ID(), codeSnippets.MarshalUsingCollectionCountInfoParametersAndModifiers<byte[]>() };
yield return new[] { ID(), codeSnippets.MarshalUsingCollectionCountInfoParametersAndModifiers<sbyte[]>() };
yield return new[] { ID(), codeSnippets.MarshalUsingCollectionCountInfoParametersAndModifiers<short[]>() };
@ -235,7 +244,7 @@ namespace ComInterfaceGenerator.Unit.Tests
yield return new[] { ID(), codeSnippets.MarshalUsingCollectionCountInfoParametersAndModifiers<IntPtr[]>() };
yield return new[] { ID(), codeSnippets.MarshalUsingCollectionCountInfoParametersAndModifiers<UIntPtr[]>() };
CustomCollectionMarshallingCodeSnippets<CodeSnippets.Bidirectional> customCollectionMarshallingCodeSnippetsBidirectional = new(new(generator));
CustomCollectionMarshallingCodeSnippets customCollectionMarshallingCodeSnippetsBidirectional = new(new CodeSnippets.Bidirectional(GetAttributeProvider(generator)));
yield return new[] { ID(), customCollectionMarshallingCodeSnippetsBidirectional.Stateless.DefaultMarshallerParametersAndModifiers<byte>() };
yield return new[] { ID(), customCollectionMarshallingCodeSnippetsBidirectional.Stateless.DefaultMarshallerParametersAndModifiers<sbyte>() };
yield return new[] { ID(), customCollectionMarshallingCodeSnippetsBidirectional.Stateless.DefaultMarshallerParametersAndModifiers<short>() };

View file

@ -0,0 +1,29 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.Marshalling;
namespace ComInterfaceGenerator.Unit.Tests
{
internal class GeneratedComInterfaceAttributeProvider : IComInterfaceAttributeProvider
{
public 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)
=> "";
public string UnmanagedObjectUnwrapper(Type t) => "";
public string GeneratedComInterface => "[global::System.Runtime.InteropServices.Marshalling.GeneratedComInterfaceAttribute]";
public string AdditionalUserRequiredInterfaces(string userDefinedInterfaceName) => "";
}
}

View file

@ -8,16 +8,14 @@ using System.Runtime.InteropServices.Marshalling;
namespace ComInterfaceGenerator.Unit.Tests
{
/// <summary>
/// Provides methods for adding attributes in a snippet if the generator requires them, or leaving them out if the generator doesn't require them.
/// Provides methods for adding attributes in a snippet.
/// </summary>
internal interface IComInterfaceAttributeProvider
{
public GeneratorKind Generator { get; }
/// <summary>
/// Returns the [VirtualMethodIndexAttribute] to be put into a snippet if Generator is <see cref="GeneratorKind.VTableIndexStubGenerator"/>, or an empty string if Generator is <see cref="GeneratorKind.ComInterfaceGenerator"/>.
/// Returns the [VirtualMethodIndexAttribute] to be put into a snippet if desired. Otherwise, returns <see cref="string.Empty" />.
/// </summary>
public string VirtualMethodIndex(
string VirtualMethodIndex(
int index,
bool? ImplicitThisParameter = null,
MarshalDirection? Direction = null,
@ -25,42 +23,22 @@ namespace ComInterfaceGenerator.Unit.Tests
Type? StringMarshallingCustomType = null,
bool? SetLastError = null,
ExceptionMarshalling? ExceptionMarshalling = null,
Type? ExceptionMarshallingType = null)
=> Generator switch
{
GeneratorKind.ComInterfaceGenerator => "",
GeneratorKind.VTableIndexStubGenerator =>
"[global::System.Runtime.InteropServices.Marshalling.VirtualMethodIndexAttribute("
+ index.ToString()
+ (ImplicitThisParameter.HasValue ? $", ImplicitThisParameter = {ImplicitThisParameter.Value.ToString().ToLower()}" : "")
+ (Direction is not null ? $", Direction = {typeof(MarshalDirection).FullName}.{Direction.Value}" : "")
+ (StringMarshalling is not null ? $", StringMarshalling = {typeof(StringMarshalling).FullName}.{StringMarshalling!.Value}" : "")
+ (StringMarshallingCustomType is not null ? $", StringMarshallingCustomType = {StringMarshallingCustomType!.FullName}" : "")
+ (SetLastError is not null ? $", SetLastError = {SetLastError.Value.ToString().ToLower()}" : "")
+ (ExceptionMarshalling is not null ? $", ExceptionMarshalling = {typeof(ExceptionMarshalling).FullName}.{ExceptionMarshalling.Value}" : "")
+ (ExceptionMarshallingType is not null ? $", ExceptionMarshallingCustomType = {ExceptionMarshallingType!.FullName}" : "")
+ ")]",
_ => throw new NotImplementedException()
};
Type? ExceptionMarshallingType = null);
/// <summary>
/// Returns the [UnmanagedObjectUnwrapper] to be put into a snippet if Generator is <see cref="GeneratorKind.VTableIndexStubGenerator"/>, or an empty string if Generator is <see cref="GeneratorKind.ComInterfaceGenerator"/>.
/// Returns the [UnmanagedObjectUnwrapper] to be put into a snippet if desired. Otherwise, returns <see cref="string.Empty" />.
/// </summary>
public string UnmanagedObjectUnwrapper(Type t) => Generator switch
{
GeneratorKind.VTableIndexStubGenerator => $"[global::System.Runtime.InteropServices.Marshalling.UnmanagedObjectUnwrapperAttribute<{t.FullName!.Replace('+', '.')}>]",
GeneratorKind.ComInterfaceGenerator => "",
_ => throw new NotImplementedException(),
};
string UnmanagedObjectUnwrapper(Type t);
/// <summary>
/// Returns the [ComInterfaceTypeAttribute] to be put into a snippet if Generator is <see cref="GeneratorKind.ComInterfaceGenerator"/>, or an empty string if Generator is <see cref="GeneratorKind.VTableIndexStubGenerator"/>.
/// Returns the [GeneratedComInterface] to be put into a snippet, if desired. Otherwise, returns <see cref="string.Empty" />.
/// </summary>
public string GeneratedComInterface => Generator switch
{
GeneratorKind.VTableIndexStubGenerator => "",
GeneratorKind.ComInterfaceGenerator => $"[global::System.Runtime.InteropServices.Marshalling.GeneratedComInterfaceAttribute]",
_ => throw new NotImplementedException(),
};
string GeneratedComInterface { get; }
/// <summary>
/// Returns any additional code to be appended to the snippet that provides any additional interfaces the user must implement
/// for the generator to function correctly.
/// </summary>
string AdditionalUserRequiredInterfaces(string userDefinedInterfaceName);
}
}

View file

@ -11,26 +11,18 @@ using Microsoft.Interop.UnitTests;
namespace ComInterfaceGenerator.Unit.Tests
{
internal interface IVirtualMethodIndexSignatureProvider<TProvider> : ICustomMarshallingSignatureTestProvider, IComInterfaceAttributeProvider
where TProvider : IVirtualMethodIndexSignatureProvider<TProvider>
internal interface IVirtualMethodIndexSignatureProvider : ICustomMarshallingSignatureTestProvider
{
public static abstract MarshalDirection Direction { get; }
public static abstract bool ImplicitThisParameter { get; }
MarshalDirection Direction { get; }
bool ImplicitThisParameter { get; }
IComInterfaceAttributeProvider AttributeProvider { get; }
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 = $$"""
partial interface INativeAPI
{
{{INativeAPI_IUnmanagedInterfaceTypeMethodImpl}}
}
""";
public const string INativeAPI_IUnmanagedInterfaceTypeMethodImpl = """
static unsafe void* IUnmanagedInterfaceType.VirtualMethodTableManagedImplementation => null;
""";
string NativeInterfaceUsage();
public static abstract string NativeInterfaceUsage();
string ICustomMarshallingSignatureTestProvider.BasicParametersAndModifiers(string typeName, string preDeclaration) => $@"
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
@ -39,13 +31,13 @@ using System.Runtime.InteropServices.Marshalling;
[assembly:DisableRuntimeMarshalling]
{UnmanagedObjectUnwrapper(typeof(UnmanagedObjectUnwrapper.TestUnwrapper))}
{GeneratedComInterface}
partial interface INativeAPI : IUnmanagedInterfaceType
{AttributeProvider.UnmanagedObjectUnwrapper(typeof(UnmanagedObjectUnwrapper.TestUnwrapper))}
{AttributeProvider.GeneratedComInterface}
partial interface INativeAPI
{{
{VirtualMethodIndex(0, ImplicitThisParameter: TProvider.ImplicitThisParameter, Direction: TProvider.Direction)}
{AttributeProvider.VirtualMethodIndex(0, ImplicitThisParameter: ImplicitThisParameter, Direction: Direction)}
{typeName} Method({typeName} value, in {typeName} inValue, ref {typeName} refValue, out {typeName} outValue);
}}" + TProvider.NativeInterfaceUsage() + INativeAPI_IUnmanagedInterfaceTypeImpl;
}}" + NativeInterfaceUsage() + AttributeProvider.AdditionalUserRequiredInterfaces("INativeAPI");
string ICustomMarshallingSignatureTestProvider.BasicParametersAndModifiersNoRef(string typeName, string preDeclaration) => $@"
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
@ -54,13 +46,13 @@ using System.Runtime.InteropServices.Marshalling;
[assembly:DisableRuntimeMarshalling]
{UnmanagedObjectUnwrapper(typeof(UnmanagedObjectUnwrapper.TestUnwrapper))}
{GeneratedComInterface}
partial interface INativeAPI : IUnmanagedInterfaceType
{AttributeProvider.UnmanagedObjectUnwrapper(typeof(UnmanagedObjectUnwrapper.TestUnwrapper))}
{AttributeProvider.GeneratedComInterface}
partial interface INativeAPI
{{
{VirtualMethodIndex(0, ImplicitThisParameter: TProvider.ImplicitThisParameter, Direction: TProvider.Direction)}
{AttributeProvider.VirtualMethodIndex(0, ImplicitThisParameter: ImplicitThisParameter, Direction: Direction)}
{typeName} Method({typeName} value, in {typeName} inValue, out {typeName} outValue);
}}" + TProvider.NativeInterfaceUsage() + INativeAPI_IUnmanagedInterfaceTypeImpl;
}}" + NativeInterfaceUsage() + AttributeProvider.AdditionalUserRequiredInterfaces("INativeAPI");
string ICustomMarshallingSignatureTestProvider.BasicParameterByValue(string typeName, string preDeclaration) => $@"
using System.Runtime.CompilerServices;
@ -68,13 +60,13 @@ using System.Runtime.InteropServices;
using System.Runtime.InteropServices.Marshalling;
{preDeclaration}
{UnmanagedObjectUnwrapper(typeof(UnmanagedObjectUnwrapper.TestUnwrapper))}
{GeneratedComInterface}
partial interface INativeAPI : IUnmanagedInterfaceType
{AttributeProvider.UnmanagedObjectUnwrapper(typeof(UnmanagedObjectUnwrapper.TestUnwrapper))}
{AttributeProvider.GeneratedComInterface}
partial interface INativeAPI
{{
{VirtualMethodIndex(0, ImplicitThisParameter: TProvider.ImplicitThisParameter, Direction: TProvider.Direction)}
{AttributeProvider.VirtualMethodIndex(0, ImplicitThisParameter: ImplicitThisParameter, Direction: Direction)}
void Method({typeName} value);
}}" + TProvider.NativeInterfaceUsage() + INativeAPI_IUnmanagedInterfaceTypeImpl;
}}" + NativeInterfaceUsage() + AttributeProvider.AdditionalUserRequiredInterfaces("INativeAPI");
string ICustomMarshallingSignatureTestProvider.BasicParameterWithByRefModifier(string modifier, string typeName, string preDeclaration) => $@"
using System.Runtime.CompilerServices;
@ -84,55 +76,55 @@ using System.Runtime.InteropServices.Marshalling;
[assembly:DisableRuntimeMarshalling]
{UnmanagedObjectUnwrapper(typeof(UnmanagedObjectUnwrapper.TestUnwrapper))}
{GeneratedComInterface}
partial interface INativeAPI : IUnmanagedInterfaceType
{AttributeProvider.UnmanagedObjectUnwrapper(typeof(UnmanagedObjectUnwrapper.TestUnwrapper))}
{AttributeProvider.GeneratedComInterface}
partial interface INativeAPI
{{
{VirtualMethodIndex(0, ImplicitThisParameter: TProvider.ImplicitThisParameter, Direction: TProvider.Direction)}
{AttributeProvider.VirtualMethodIndex(0, ImplicitThisParameter: ImplicitThisParameter, Direction: Direction)}
void Method({modifier} {typeName} value);
}}" + TProvider.NativeInterfaceUsage() + INativeAPI_IUnmanagedInterfaceTypeImpl;
}}" + NativeInterfaceUsage() + AttributeProvider.AdditionalUserRequiredInterfaces("INativeAPI");
string ICustomMarshallingSignatureTestProvider.BasicReturnType(string typeName, string preDeclaration) => $@"
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.Marshalling;
{preDeclaration}
{UnmanagedObjectUnwrapper(typeof(UnmanagedObjectUnwrapper.TestUnwrapper))}
{GeneratedComInterface}
partial interface INativeAPI : IUnmanagedInterfaceType
{AttributeProvider.UnmanagedObjectUnwrapper(typeof(UnmanagedObjectUnwrapper.TestUnwrapper))}
{AttributeProvider.GeneratedComInterface}
partial interface INativeAPI
{{
{VirtualMethodIndex(0, ImplicitThisParameter: TProvider.ImplicitThisParameter, Direction: TProvider.Direction)}
{AttributeProvider.VirtualMethodIndex(0, ImplicitThisParameter: ImplicitThisParameter, Direction: Direction)}
{typeName} Method();
}}" + TProvider.NativeInterfaceUsage() + INativeAPI_IUnmanagedInterfaceTypeImpl;
}}" + NativeInterfaceUsage() + AttributeProvider.AdditionalUserRequiredInterfaces("INativeAPI");
string ICustomMarshallingSignatureTestProvider.MarshalUsingParametersAndModifiers(string typeName, string marshallerTypeName, string preDeclaration) => $@"
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.Marshalling;
{preDeclaration}
{UnmanagedObjectUnwrapper(typeof(UnmanagedObjectUnwrapper.TestUnwrapper))}
{GeneratedComInterface}
partial interface INativeAPI : IUnmanagedInterfaceType
{AttributeProvider.UnmanagedObjectUnwrapper(typeof(UnmanagedObjectUnwrapper.TestUnwrapper))}
{AttributeProvider.GeneratedComInterface}
partial interface INativeAPI
{{
{VirtualMethodIndex(0, ImplicitThisParameter: TProvider.ImplicitThisParameter, Direction: TProvider.Direction)}
{AttributeProvider.VirtualMethodIndex(0, ImplicitThisParameter: ImplicitThisParameter, Direction: Direction)}
[return: MarshalUsing(typeof({marshallerTypeName}))]
{typeName} Method(
[MarshalUsing(typeof({marshallerTypeName}))] {typeName} p,
[MarshalUsing(typeof({marshallerTypeName}))] in {typeName} pIn,
[MarshalUsing(typeof({marshallerTypeName}))] ref {typeName} pRef,
[MarshalUsing(typeof({marshallerTypeName}))] out {typeName} pOut);
}}" + TProvider.NativeInterfaceUsage() + INativeAPI_IUnmanagedInterfaceTypeImpl;
}}" + NativeInterfaceUsage() + AttributeProvider.AdditionalUserRequiredInterfaces("INativeAPI");
string ICustomMarshallingSignatureTestProvider.MarshalUsingCollectionCountInfoParametersAndModifiers(string collectionType) => $@"
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.Marshalling;
[assembly:DisableRuntimeMarshalling]
{UnmanagedObjectUnwrapper(typeof(UnmanagedObjectUnwrapper.TestUnwrapper))}
{GeneratedComInterface}
partial interface INativeAPI : IUnmanagedInterfaceType
{AttributeProvider.UnmanagedObjectUnwrapper(typeof(UnmanagedObjectUnwrapper.TestUnwrapper))}
{AttributeProvider.GeneratedComInterface}
partial interface INativeAPI
{{
{VirtualMethodIndex(0, ImplicitThisParameter: TProvider.ImplicitThisParameter, Direction: TProvider.Direction)}
{AttributeProvider.VirtualMethodIndex(0, ImplicitThisParameter: ImplicitThisParameter, Direction: Direction)}
[return:MarshalUsing(ConstantElementCount=10)]
{collectionType} Method(
{collectionType} p,
@ -141,7 +133,7 @@ partial interface INativeAPI : IUnmanagedInterfaceType
[MarshalUsing(CountElementName = ""pRefSize"")] ref {collectionType} pRef,
[MarshalUsing(CountElementName = ""pOutSize"")] out {collectionType} pOut,
out int pOutSize);
}}" + TProvider.NativeInterfaceUsage() + INativeAPI_IUnmanagedInterfaceTypeImpl;
}}" + NativeInterfaceUsage() + AttributeProvider.AdditionalUserRequiredInterfaces("INativeAPI");
string ICustomMarshallingSignatureTestProvider.MarshalUsingCollectionParametersAndModifiers(string collectionType, string marshallerType) => $@"
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
@ -149,11 +141,11 @@ using System.Runtime.InteropServices.Marshalling;
[assembly:DisableRuntimeMarshalling]
{UnmanagedObjectUnwrapper(typeof(UnmanagedObjectUnwrapper.TestUnwrapper))}
{GeneratedComInterface}
partial interface INativeAPI : IUnmanagedInterfaceType
{AttributeProvider.UnmanagedObjectUnwrapper(typeof(UnmanagedObjectUnwrapper.TestUnwrapper))}
{AttributeProvider.GeneratedComInterface}
partial interface INativeAPI
{{
{VirtualMethodIndex(0, ImplicitThisParameter: TProvider.ImplicitThisParameter, Direction: TProvider.Direction)}
{AttributeProvider.VirtualMethodIndex(0, ImplicitThisParameter: ImplicitThisParameter, Direction: Direction)}
[return:MarshalUsing(typeof({marshallerType}), ConstantElementCount=10)]
{collectionType} Method(
[MarshalUsing(typeof({marshallerType}))] {collectionType} p,
@ -163,7 +155,7 @@ partial interface INativeAPI : IUnmanagedInterfaceType
[MarshalUsing(typeof({marshallerType}), CountElementName = ""pOutSize"")] out {collectionType} pOut,
out int pOutSize
);
}}" + TProvider.NativeInterfaceUsage() + INativeAPI_IUnmanagedInterfaceTypeImpl;
}}" + NativeInterfaceUsage() + AttributeProvider.AdditionalUserRequiredInterfaces("INativeAPI");
string ICustomMarshallingSignatureTestProvider.MarshalUsingCollectionReturnValueLength(string collectionType, string marshallerType) => $@"
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
@ -171,15 +163,15 @@ using System.Runtime.InteropServices.Marshalling;
[assembly:DisableRuntimeMarshalling]
{UnmanagedObjectUnwrapper(typeof(UnmanagedObjectUnwrapper.TestUnwrapper))}
{GeneratedComInterface}
partial interface INativeAPI : IUnmanagedInterfaceType
{AttributeProvider.UnmanagedObjectUnwrapper(typeof(UnmanagedObjectUnwrapper.TestUnwrapper))}
{AttributeProvider.GeneratedComInterface}
partial interface INativeAPI
{{
{VirtualMethodIndex(0, ImplicitThisParameter: TProvider.ImplicitThisParameter, Direction: TProvider.Direction)}
{AttributeProvider.VirtualMethodIndex(0, ImplicitThisParameter: ImplicitThisParameter, Direction: Direction)}
int Method(
[MarshalUsing(typeof({marshallerType}), CountElementName = MarshalUsingAttribute.ReturnsCountValue)] out {collectionType} pOut
);
}}" + TProvider.NativeInterfaceUsage() + INativeAPI_IUnmanagedInterfaceTypeImpl;
}}" + NativeInterfaceUsage() + AttributeProvider.AdditionalUserRequiredInterfaces("INativeAPI");
string ICustomMarshallingSignatureTestProvider.MarshalUsingCollectionOutConstantLength(string collectionType, string predeclaration) => $@"
using System.Runtime.CompilerServices;
@ -189,16 +181,16 @@ using System.Runtime.InteropServices.Marshalling;
[assembly:DisableRuntimeMarshalling]
{UnmanagedObjectUnwrapper(typeof(UnmanagedObjectUnwrapper.TestUnwrapper))}
{GeneratedComInterface}
partial interface INativeAPI : IUnmanagedInterfaceType
{AttributeProvider.UnmanagedObjectUnwrapper(typeof(UnmanagedObjectUnwrapper.TestUnwrapper))}
{AttributeProvider.GeneratedComInterface}
partial interface INativeAPI
{{
{VirtualMethodIndex(0, ImplicitThisParameter: TProvider.ImplicitThisParameter, Direction: TProvider.Direction)}
{AttributeProvider.VirtualMethodIndex(0, ImplicitThisParameter: ImplicitThisParameter, Direction: Direction)}
int Method(
[MarshalUsing(ConstantElementCount = 10)] out {collectionType} pOut
);
}}
" + TProvider.NativeInterfaceUsage() + INativeAPI_IUnmanagedInterfaceTypeImpl;
" + NativeInterfaceUsage() + AttributeProvider.AdditionalUserRequiredInterfaces("INativeAPI");
string ICustomMarshallingSignatureTestProvider.MarshalUsingCollectionReturnConstantLength(string collectionType, string predeclaration) => $@"
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
@ -207,15 +199,15 @@ using System.Runtime.InteropServices.Marshalling;
[assembly:DisableRuntimeMarshalling]
{UnmanagedObjectUnwrapper(typeof(UnmanagedObjectUnwrapper.TestUnwrapper))}
{GeneratedComInterface}
partial interface INativeAPI : IUnmanagedInterfaceType
{AttributeProvider.UnmanagedObjectUnwrapper(typeof(UnmanagedObjectUnwrapper.TestUnwrapper))}
{AttributeProvider.GeneratedComInterface}
partial interface INativeAPI
{{
{VirtualMethodIndex(0, ImplicitThisParameter: TProvider.ImplicitThisParameter, Direction: TProvider.Direction)}
{AttributeProvider.VirtualMethodIndex(0, ImplicitThisParameter: ImplicitThisParameter, Direction: Direction)}
[return:MarshalUsing(ConstantElementCount = 10)]
{collectionType} Method();
}}
" + TProvider.NativeInterfaceUsage() + INativeAPI_IUnmanagedInterfaceTypeImpl;
" + NativeInterfaceUsage() + AttributeProvider.AdditionalUserRequiredInterfaces("INativeAPI");
string ICustomMarshallingSignatureTestProvider.CustomElementMarshalling(string collectionType, string elementMarshaller, string predeclaration) => $@"
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
@ -224,11 +216,11 @@ using System.Runtime.InteropServices.Marshalling;
[assembly:DisableRuntimeMarshalling]
{UnmanagedObjectUnwrapper(typeof(UnmanagedObjectUnwrapper.TestUnwrapper))}
{GeneratedComInterface}
partial interface INativeAPI : IUnmanagedInterfaceType
{AttributeProvider.UnmanagedObjectUnwrapper(typeof(UnmanagedObjectUnwrapper.TestUnwrapper))}
{AttributeProvider.GeneratedComInterface}
partial interface INativeAPI
{{
{VirtualMethodIndex(0, ImplicitThisParameter: TProvider.ImplicitThisParameter, Direction: TProvider.Direction)}
{AttributeProvider.VirtualMethodIndex(0, ImplicitThisParameter: ImplicitThisParameter, Direction: Direction)}
[return:MarshalUsing(ConstantElementCount=10)]
[return:MarshalUsing(typeof({elementMarshaller}), ElementIndirectionDepth = 1)]
TestCollection<int> Method(
@ -240,6 +232,6 @@ partial interface INativeAPI : IUnmanagedInterfaceType
out int pOutSize
);
}}
" + TProvider.NativeInterfaceUsage() + INativeAPI_IUnmanagedInterfaceTypeImpl;
" + NativeInterfaceUsage() + AttributeProvider.AdditionalUserRequiredInterfaces("INativeAPI");
}
}

View file

@ -26,7 +26,7 @@ namespace ComInterfaceGenerator.Unit.Tests
[UnmanagedObjectUnwrapper<UnmanagedObjectUnwrapper.TestUnwrapper>]
partial interface INativeAPI : IUnmanagedInterfaceType
{
{{CodeSnippets.INativeAPI_IUnmanagedInterfaceTypeMethodImpl}}
static unsafe void* IUnmanagedInterfaceType.VirtualMethodTableManagedImplementation => null;
[VirtualMethodIndex(0)]
void Method();
}
@ -53,7 +53,7 @@ namespace ComInterfaceGenerator.Unit.Tests
[UnmanagedObjectUnwrapper<UnmanagedObjectUnwrapper.TestUnwrapper>]
partial interface INativeAPI : IUnmanagedInterfaceType
{
{{CodeSnippets.INativeAPI_IUnmanagedInterfaceTypeMethodImpl}}
static unsafe void* IUnmanagedInterfaceType.VirtualMethodTableManagedImplementation => null;
[VirtualMethodIndex(0)]
void Method();
}
@ -80,7 +80,7 @@ namespace ComInterfaceGenerator.Unit.Tests
[UnmanagedObjectUnwrapper<UnmanagedObjectUnwrapper.TestUnwrapper>]
partial interface INativeAPI : IUnmanagedInterfaceType
{
{{CodeSnippets.INativeAPI_IUnmanagedInterfaceTypeMethodImpl}}
static unsafe void* IUnmanagedInterfaceType.VirtualMethodTableManagedImplementation => null;
[VirtualMethodIndex(0)]
void Method();
}
@ -112,7 +112,7 @@ namespace ComInterfaceGenerator.Unit.Tests
[UnmanagedObjectUnwrapper<UnmanagedObjectUnwrapper.TestUnwrapper>]
partial interface INativeAPI : IUnmanagedInterfaceType
{
{{CodeSnippets.INativeAPI_IUnmanagedInterfaceTypeMethodImpl}}
static unsafe void* IUnmanagedInterfaceType.VirtualMethodTableManagedImplementation => null;
[VirtualMethodIndex(0)]
void Method();
}

View file

@ -0,0 +1,43 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.Marshalling;
namespace ComInterfaceGenerator.Unit.Tests
{
internal class VirtualMethodIndexAttributeProvider : IComInterfaceAttributeProvider
{
public 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)
=> "[global::System.Runtime.InteropServices.Marshalling.VirtualMethodIndexAttribute("
+ index.ToString()
+ (ImplicitThisParameter.HasValue ? $", ImplicitThisParameter = {ImplicitThisParameter.Value.ToString().ToLower()}" : "")
+ (Direction is not null ? $", Direction = {typeof(MarshalDirection).FullName}.{Direction.Value}" : "")
+ (StringMarshalling is not null ? $", StringMarshalling = {typeof(StringMarshalling).FullName}.{StringMarshalling!.Value}" : "")
+ (StringMarshallingCustomType is not null ? $", StringMarshallingCustomType = {StringMarshallingCustomType!.FullName}" : "")
+ (SetLastError is not null ? $", SetLastError = {SetLastError.Value.ToString().ToLower()}" : "")
+ (ExceptionMarshalling is not null ? $", ExceptionMarshalling = {typeof(ExceptionMarshalling).FullName}.{ExceptionMarshalling.Value}" : "")
+ (ExceptionMarshallingType is not null ? $", ExceptionMarshallingCustomType = {ExceptionMarshallingType!.FullName}" : "")
+ ")]";
public string UnmanagedObjectUnwrapper(Type t) => $"[global::System.Runtime.InteropServices.Marshalling.UnmanagedObjectUnwrapperAttribute<{t.FullName!.Replace('+', '.')}>]";
public string GeneratedComInterface => "";
public string AdditionalUserRequiredInterfaces(string userDefinedInterfaceName) => """
partial interface INativeAPI : IUnmanagedInterfaceType
{
static unsafe void* IUnmanagedInterfaceType.VirtualMethodTableManagedImplementation => null;
}
""";
}
}

View file

@ -3,13 +3,12 @@
namespace Microsoft.Interop.UnitTests
{
public class CustomCollectionMarshallingCodeSnippets<TSignatureTestProvider>
where TSignatureTestProvider : ICustomMarshallingSignatureTestProvider
public class CustomCollectionMarshallingCodeSnippets
{
TSignatureTestProvider _provider;
ICustomMarshallingSignatureTestProvider _provider;
public StatelessSnippets Stateless { get; }
public StatefulSnippets Stateful { get; }
public CustomCollectionMarshallingCodeSnippets(TSignatureTestProvider provider)
public CustomCollectionMarshallingCodeSnippets(ICustomMarshallingSignatureTestProvider provider)
{
_provider = provider;
Stateless = new StatelessSnippets(this, provider);
@ -77,9 +76,9 @@ static class CustomIntMarshaller
";
public class StatelessSnippets
{
TSignatureTestProvider _provider;
CustomCollectionMarshallingCodeSnippets<TSignatureTestProvider> _snippets;
public StatelessSnippets(CustomCollectionMarshallingCodeSnippets<TSignatureTestProvider> instance, TSignatureTestProvider provider)
ICustomMarshallingSignatureTestProvider _provider;
CustomCollectionMarshallingCodeSnippets _snippets;
public StatelessSnippets(CustomCollectionMarshallingCodeSnippets instance, ICustomMarshallingSignatureTestProvider provider)
{
_provider = provider;
_snippets = instance;
@ -304,9 +303,9 @@ static unsafe class Marshaller<T, U, TUnmanagedElement> where TUnmanagedElement
public class StatefulSnippets
{
private readonly TSignatureTestProvider _provider;
private readonly CustomCollectionMarshallingCodeSnippets<TSignatureTestProvider> _snippets;
public StatefulSnippets(CustomCollectionMarshallingCodeSnippets<TSignatureTestProvider> snippets, TSignatureTestProvider provider)
private readonly ICustomMarshallingSignatureTestProvider _provider;
private readonly CustomCollectionMarshallingCodeSnippets _snippets;
public StatefulSnippets(CustomCollectionMarshallingCodeSnippets snippets, ICustomMarshallingSignatureTestProvider provider)
{
_provider = provider;
_snippets = snippets;

View file

@ -3,13 +3,12 @@
namespace Microsoft.Interop.UnitTests
{
public class CustomStructMarshallingCodeSnippets<TSignatureTestProvider>
where TSignatureTestProvider : ICustomMarshallingSignatureTestProvider
public class CustomStructMarshallingCodeSnippets
{
readonly TSignatureTestProvider _provider;
readonly ICustomMarshallingSignatureTestProvider _provider;
public StatelessSnippets Stateless { get; }
public StatefulSnippets Stateful { get; }
public CustomStructMarshallingCodeSnippets(TSignatureTestProvider provider)
public CustomStructMarshallingCodeSnippets(ICustomMarshallingSignatureTestProvider provider)
{
_provider = provider;
Stateless = new StatelessSnippets(provider);
@ -57,8 +56,8 @@ public struct Marshaller
public class StatelessSnippets
{
public readonly TSignatureTestProvider _provider;
public StatelessSnippets(TSignatureTestProvider provider)
public readonly ICustomMarshallingSignatureTestProvider _provider;
public StatelessSnippets(ICustomMarshallingSignatureTestProvider provider)
{
this._provider = provider;
}
@ -260,8 +259,8 @@ public static class Marshaller
public class StatefulSnippets
{
private readonly TSignatureTestProvider _provider;
public StatefulSnippets (TSignatureTestProvider provider)
private readonly ICustomMarshallingSignatureTestProvider _provider;
public StatefulSnippets (ICustomMarshallingSignatureTestProvider provider)
{
_provider = provider;
}

View file

@ -982,9 +982,9 @@ partial class Test
[MarshalUsing(typeof(CustomIntMarshaller), ElementIndirectionDepth = 1)] [MarshalUsing(typeof(CustomIntMarshaller), ElementIndirectionDepth = 1)] TestCollection<int> p);
}}
"
+ CustomCollectionMarshallingCodeSnippets<CodeSnippets>.TestCollection()
+ CustomCollectionMarshallingCodeSnippets<CodeSnippets>.StatelessSnippets.In
+ CustomCollectionMarshallingCodeSnippets<CodeSnippets>.CustomIntMarshaller;
+ CustomCollectionMarshallingCodeSnippets.TestCollection()
+ CustomCollectionMarshallingCodeSnippets.StatelessSnippets.In
+ CustomCollectionMarshallingCodeSnippets.CustomIntMarshaller;
public static string CustomElementMarshallingUnusedElementIndirectionDepth => $@"
using System.Runtime.InteropServices;
@ -997,9 +997,9 @@ partial class Test
[MarshalUsing(typeof(CustomIntMarshaller), ElementIndirectionDepth = 2)] TestCollection<int> p);
}}
"
+ CustomCollectionMarshallingCodeSnippets<CodeSnippets>.TestCollection()
+ CustomCollectionMarshallingCodeSnippets<CodeSnippets>.StatelessSnippets.In
+ CustomCollectionMarshallingCodeSnippets<CodeSnippets>.CustomIntMarshaller;
+ CustomCollectionMarshallingCodeSnippets.TestCollection()
+ CustomCollectionMarshallingCodeSnippets.StatelessSnippets.In
+ CustomCollectionMarshallingCodeSnippets.CustomIntMarshaller;
public static string RecursiveCountElementNameOnReturnValue => $@"
using System.Runtime.InteropServices;

View file

@ -99,7 +99,7 @@ namespace LibraryImportGenerator.UnitTests
yield return new object[] { ID(), CodeSnippets.MarshalUsingArrayParameterWithSizeParam<bool>(isByRef: false), 2, 0 };
// Custom type marshalling with invalid members
CustomStructMarshallingCodeSnippets<CodeSnippets> customStructMarshallingCodeSnippets = new(new CodeSnippets());
CustomStructMarshallingCodeSnippets customStructMarshallingCodeSnippets = new(new CodeSnippets());
yield return new object[] { ID(), customStructMarshallingCodeSnippets.NonStaticMarshallerEntryPoint, 2, 0 };
yield return new object[] { ID(), customStructMarshallingCodeSnippets.Stateless.ManagedToNativeOnlyOutParameter, 1, 0 };
yield return new object[] { ID(), customStructMarshallingCodeSnippets.Stateless.ManagedToNativeOnlyReturnValue, 1, 0 };
@ -120,7 +120,7 @@ namespace LibraryImportGenerator.UnitTests
yield return new object[] { ID(), CodeSnippets.MarshalUsingCollectionWithNullElementName, 2, 0 };
// Generic collection marshaller has different arity than collection.
CustomCollectionMarshallingCodeSnippets<CodeSnippets> customCollectionMarshallingCodeSnippets = new(new CodeSnippets());
CustomCollectionMarshallingCodeSnippets customCollectionMarshallingCodeSnippets = new(new CodeSnippets());
yield return new object[] { ID(), customCollectionMarshallingCodeSnippets.Stateless.GenericCollectionMarshallingArityMismatch, 2, 0 };
yield return new object[] { ID(), CodeSnippets.MarshalAsAndMarshalUsingOnReturnValue, 1, 0 };

View file

@ -125,11 +125,11 @@ namespace LibraryImportGenerator.UnitTests
// [In, Out] attributes
// By value non-blittable array
yield return new[] { ID(), CodeSnippets.ByValueParameterWithModifier("S[]", "Out")
+ CustomStructMarshallingCodeSnippets<CodeSnippets>.NonBlittableUserDefinedType()
+ CustomStructMarshallingCodeSnippets<CodeSnippets>.StatelessSnippets.Default };
+ CustomStructMarshallingCodeSnippets.NonBlittableUserDefinedType()
+ CustomStructMarshallingCodeSnippets.StatelessSnippets.Default };
yield return new[] { ID(), CodeSnippets.ByValueParameterWithModifier("S[]", "In, Out")
+ CustomStructMarshallingCodeSnippets<CodeSnippets>.NonBlittableUserDefinedType()
+ CustomStructMarshallingCodeSnippets<CodeSnippets>.StatelessSnippets.Default };
+ CustomStructMarshallingCodeSnippets.NonBlittableUserDefinedType()
+ CustomStructMarshallingCodeSnippets.StatelessSnippets.Default };
// Enums
yield return new[] { ID(), CodeSnippets.EnumParameters };
@ -177,7 +177,7 @@ namespace LibraryImportGenerator.UnitTests
yield return new[] { ID(), CodeSnippets.SafeHandleWithCustomDefaultConstructorAccessibility(privateCtor: true) };
// Custom type marshalling
CustomStructMarshallingCodeSnippets<CodeSnippets> customStructMarshallingCodeSnippets = new(new CodeSnippets());
CustomStructMarshallingCodeSnippets customStructMarshallingCodeSnippets = new(new CodeSnippets());
yield return new[] { ID(), customStructMarshallingCodeSnippets.StructMarshallerEntryPoint };
yield return new[] { ID(), customStructMarshallingCodeSnippets.Stateless.ParametersAndModifiers };
yield return new[] { ID(), customStructMarshallingCodeSnippets.Stateless.MarshalUsingParametersAndModifiers };
@ -235,7 +235,7 @@ namespace LibraryImportGenerator.UnitTests
public static IEnumerable<object[]> CustomCollections()
{
// Custom collection marshalling
CustomCollectionMarshallingCodeSnippets<CodeSnippets> customCollectionMarshallingCodeSnippets = new(new CodeSnippets());
CustomCollectionMarshallingCodeSnippets customCollectionMarshallingCodeSnippets = new(new CodeSnippets());
yield return new[] { ID(), customCollectionMarshallingCodeSnippets.Stateless.ByValue<byte>() };
yield return new[] { ID(), customCollectionMarshallingCodeSnippets.Stateless.ByValue<sbyte>() };
yield return new[] { ID(), customCollectionMarshallingCodeSnippets.Stateless.ByValue<short>() };