| File: Marshalling\ByValueMarshalKindSupportDescriptor.cs | Web Access |
| Project: src\runtime\src\libraries\System.Runtime.InteropServices\gen\Microsoft.Interop.SourceGeneration\Microsoft.Interop.SourceGeneration.csproj (Microsoft.Interop.SourceGeneration) |
// 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.Diagnostics; namespace Microsoft.Interop { public record struct ByValueMarshalKindSupportInfo(ByValueMarshalKindSupport Support, string? details) { public ByValueMarshalKindSupport GetSupport(TypePositionInfo info, out GeneratorDiagnostic? diagnostic) { diagnostic = Support switch { ByValueMarshalKindSupport.Supported => null, ByValueMarshalKindSupport.NotRecommended => new GeneratorDiagnostic.NotRecommended(info) { Details = details }, ByValueMarshalKindSupport.NotSupported => new GeneratorDiagnostic.NotSupported(info) { NotSupportedDetails = details }, _ => throw new UnreachableException() }; return Support; } } /// <summary> /// Provides an implementation of <see cref="IUnboundMarshallingGenerator.SupportsByValueMarshalKind(ByValueContentsMarshalKind, TypePositionInfo, out GeneratorDiagnostic?)"/> through <see cref="GetSupport(ByValueContentsMarshalKind, TypePositionInfo, out GeneratorDiagnostic?)"/> /// </summary> public record ByValueMarshalKindSupportDescriptor( ByValueMarshalKindSupportInfo DefaultSupport, ByValueMarshalKindSupportInfo InSupport, ByValueMarshalKindSupportInfo OutSupport, ByValueMarshalKindSupportInfo InOutSupport) { /// <summary> /// A default <see cref="ByValueMarshalKindSupportDescriptor"/> for by value parameters. [In] and [Out] are not allowed. /// </summary> public static readonly ByValueMarshalKindSupportDescriptor Default = new ByValueMarshalKindSupportDescriptor( DefaultSupport: new(ByValueMarshalKindSupport.Supported, null), InSupport: new(ByValueMarshalKindSupport.NotSupported, SR.InAttributeNotSupportedOnByValueParameters), OutSupport: new(ByValueMarshalKindSupport.NotSupported, SR.OutAttributeNotSupportedOnByValueParameters), InOutSupport: new(ByValueMarshalKindSupport.NotSupported, SR.InOutAttributeNotSupportedOnByValueParameters)); /// <summary> /// A default <see cref="ByValueMarshalKindSupportDescriptor"/> for by value array parameters. Default is allowed, but Not Recommended. [In], [Out], and [In, Out] are allowed /// </summary> public static readonly ByValueMarshalKindSupportDescriptor ArrayParameter = new ByValueMarshalKindSupportDescriptor( DefaultSupport: new(ByValueMarshalKindSupport.NotRecommended, SR.PreferExplicitInOutAttributesOnArrays), InSupport: new(ByValueMarshalKindSupport.Supported, null), OutSupport: new(ByValueMarshalKindSupport.Supported, null), InOutSupport: new(ByValueMarshalKindSupport.Supported, null)); /// <summary> /// Returns the support for the ByValueContentsMarshalKind, and if it is not <see cref="ByValueMarshalKindSupport.Supported"/>, diagnostic is not null /// </summary> public ByValueMarshalKindSupport GetSupport(ByValueContentsMarshalKind marshalKind, TypePositionInfo info, out GeneratorDiagnostic? diagnostic) { if (info.IsByRef) { // ByRef with ByValue attributes is not allowed if (marshalKind != ByValueContentsMarshalKind.Default) { diagnostic = new GeneratorDiagnostic.NotSupported(info) { NotSupportedDetails = SR.InOutAttributeByRefNotSupported }; return ByValueMarshalKindSupport.NotSupported; } // ByRef with no ByValue attributes is supported diagnostic = null; return ByValueMarshalKindSupport.Supported; } // Return can never have In or Out attributes, so can assume valid ByValue attributes if (info.ManagedIndex < 0) { Debug.Assert(marshalKind is ByValueContentsMarshalKind.Default); diagnostic = null; return ByValueMarshalKindSupport.Supported; } return marshalKind switch { ByValueContentsMarshalKind.Default => DefaultSupport.GetSupport(info, out diagnostic), ByValueContentsMarshalKind.In => InSupport.GetSupport(info, out diagnostic), ByValueContentsMarshalKind.Out => OutSupport.GetSupport(info, out diagnostic), ByValueContentsMarshalKind.InOut => InOutSupport.GetSupport(info, out diagnostic), _ => throw new UnreachableException() }; } } }