|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.Collections.Generic;
namespace Microsoft.Interop
{
/// <summary>
/// Default resolver for marshalling generators.
/// </summary>
public static class DefaultMarshallingGeneratorResolver
{
/// <summary>
/// Creates a marshalling generator resolver with support for all marshalling information generated by <see cref="DefaultMarshallingInfoParser"/>.
/// </summary>
/// <param name="env">Flags about the compilation environment for emitted code.</param>
/// <param name="direction">The direction of marshalling.</param>
/// <param name="stringMarshallingAttribute">The name of the attribute type where the <see cref="T:System.Runtime.InteropServices.Marshalling.StringMarshalling"/> marshalling data is specified by the user.</param>
/// <param name="additionalResolvers">Additional resolvers for resolving generators for any custom marshalling information.</param>
/// <returns>A marshalling generator with support for marshalling types supported by <see cref="DefaultMarshallingInfoParser"/> as well as any types supported by the additional resolvers.</returns>
public static IMarshallingGeneratorResolver Create(
EnvironmentFlags env,
MarshalDirection direction,
string stringMarshallingAttribute,
IEnumerable<IMarshallingGeneratorResolver> additionalResolvers)
{
IMarshallingGeneratorResolver fallbackResolver = new NotSupportedResolver();
List<IMarshallingGeneratorResolver> coreResolvers = [
.. additionalResolvers,
new BlittableMarshallerResolver(env.HasFlag(EnvironmentFlags.DisableRuntimeMarshalling)),
new MarshalAsMarshallingGeneratorResolver(new InteropGenerationOptions(UseMarshalType: true)),
new NoMarshallingInfoErrorResolver(stringMarshallingAttribute),
];
// Since the char type in an array will not be part of the P/Invoke signature, we can
// use the regular blittable marshaller in all cases.
var charElementMarshaller = new CharMarshallingGeneratorResolver(useBlittableMarshallerForUtf16: true, stringMarshallingAttribute);
IMarshallingGeneratorResolver elementFactory = new AttributedMarshallingModelGeneratorResolver(
new CompositeMarshallingGeneratorResolver([
.. coreResolvers,
// Since the char type in an array will not be part of the P/Invoke signature, we can
// use the regular blittable marshaller in all cases.
charElementMarshaller,
fallbackResolver,
]),
new AttributedMarshallingModelOptions(
env.HasFlag(EnvironmentFlags.DisableRuntimeMarshalling),
MarshalMode.ElementIn,
MarshalMode.ElementRef,
MarshalMode.ElementOut,
ResolveElementsFromSelf: true));
IMarshallingGeneratorResolver generatorResolver = new ByValueContentsMarshalKindValidator(
new CompositeMarshallingGeneratorResolver(
[
.. coreResolvers,
new AttributedMarshallingModelGeneratorResolver(
new CompositeMarshallingGeneratorResolver(
[elementFactory, .. coreResolvers, charElementMarshaller, fallbackResolver]),
new AttributedMarshallingModelOptions(
env.HasFlag(EnvironmentFlags.DisableRuntimeMarshalling),
direction == MarshalDirection.ManagedToUnmanaged
? MarshalMode.ManagedToUnmanagedIn
: MarshalMode.UnmanagedToManagedOut,
direction == MarshalDirection.ManagedToUnmanaged
? MarshalMode.ManagedToUnmanagedRef
: MarshalMode.UnmanagedToManagedRef,
direction == MarshalDirection.ManagedToUnmanaged
? MarshalMode.ManagedToUnmanagedOut
: MarshalMode.UnmanagedToManagedIn,
ResolveElementsFromSelf: false)),
// Since the char type can go into the P/Invoke signature here, we can only use it when
// runtime marshalling is disabled.
new CharMarshallingGeneratorResolver(useBlittableMarshallerForUtf16: env.HasFlag(EnvironmentFlags.DisableRuntimeMarshalling), stringMarshallingAttribute),
fallbackResolver
]));
generatorResolver = new BreakingChangeDetector(generatorResolver);
return generatorResolver;
}
}
}
|