diff --git a/eng/Versions.props b/eng/Versions.props
index 81158b426779d..437f0ceaf5f82 100644
--- a/eng/Versions.props
+++ b/eng/Versions.props
@@ -164,7 +164,7 @@
2.14.3
- 1.1.2-beta1.22205.2
+ 1.1.2-beta1.22403.2
7.0.0-preview-20220721.1
diff --git a/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Analyzers/CustomMarshallerAttributeAnalyzer.cs b/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Analyzers/CustomMarshallerAttributeAnalyzer.cs
index 9603ec32cbc2c..d9b513cc1769a 100644
--- a/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Analyzers/CustomMarshallerAttributeAnalyzer.cs
+++ b/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Analyzers/CustomMarshallerAttributeAnalyzer.cs
@@ -468,7 +468,7 @@ public static class DefaultMarshalModeDiagnostics
description: GetResourceString(nameof(SR.StatelessLinearCollectionRequiresTwoParameterAllocateContainerForManagedElementsDescription)));
///
- public static readonly DiagnosticDescriptor StatefulMarshallerRequiresFromManagedRule =
+ private static readonly DiagnosticDescriptor StatefulMarshallerRequiresFromManagedRule =
new DiagnosticDescriptor(
Ids.CustomMarshallerTypeMustHaveRequiredShape,
GetResourceString(nameof(SR.CustomMarshallerTypeMustHaveRequiredShapeTitle)),
@@ -479,7 +479,7 @@ public static class DefaultMarshalModeDiagnostics
description: GetResourceString(nameof(SR.StatefulMarshallerRequiresFromManagedDescription)));
///
- public static readonly DiagnosticDescriptor StatefulMarshallerRequiresToUnmanagedRule =
+ private static readonly DiagnosticDescriptor StatefulMarshallerRequiresToUnmanagedRule =
new DiagnosticDescriptor(
Ids.CustomMarshallerTypeMustHaveRequiredShape,
GetResourceString(nameof(SR.CustomMarshallerTypeMustHaveRequiredShapeTitle)),
@@ -490,7 +490,7 @@ public static class DefaultMarshalModeDiagnostics
description: GetResourceString(nameof(SR.StatefulMarshallerRequiresToUnmanagedDescription)));
///
- public static readonly DiagnosticDescriptor StatefulMarshallerRequiresToManagedRule =
+ private static readonly DiagnosticDescriptor StatefulMarshallerRequiresToManagedRule =
new DiagnosticDescriptor(
Ids.CustomMarshallerTypeMustHaveRequiredShape,
GetResourceString(nameof(SR.CustomMarshallerTypeMustHaveRequiredShapeTitle)),
@@ -501,7 +501,7 @@ public static class DefaultMarshalModeDiagnostics
description: GetResourceString(nameof(SR.StatefulMarshallerRequiresToManagedDescription)));
///
- public static readonly DiagnosticDescriptor StatefulMarshallerRequiresFromUnmanagedRule =
+ private static readonly DiagnosticDescriptor StatefulMarshallerRequiresFromUnmanagedRule =
new DiagnosticDescriptor(
Ids.CustomMarshallerTypeMustHaveRequiredShape,
GetResourceString(nameof(SR.CustomMarshallerTypeMustHaveRequiredShapeTitle)),
@@ -511,7 +511,7 @@ public static class DefaultMarshalModeDiagnostics
isEnabledByDefault: true,
description: GetResourceString(nameof(SR.StatefulMarshallerRequiresFromUnmanagedDescription)));
- internal static DiagnosticDescriptor GetDefaultMarshalModeDiagnostic(DiagnosticDescriptor errorDescriptor)
+ public static DiagnosticDescriptor GetDefaultMarshalModeDiagnostic(DiagnosticDescriptor errorDescriptor)
{
if (ReferenceEquals(errorDescriptor, CustomMarshallerAttributeAnalyzer.StatelessValueInRequiresConvertToUnmanagedRule))
{
diff --git a/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Analyzers/CustomMarshallerAttributeFixer.cs b/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Analyzers/CustomMarshallerAttributeFixer.cs
index 74413228d4dab..22d34aa852c66 100644
--- a/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Analyzers/CustomMarshallerAttributeFixer.cs
+++ b/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Analyzers/CustomMarshallerAttributeFixer.cs
@@ -200,6 +200,10 @@ private static void AddMissingMembers(
{
AddMissingMembersToStatelessMarshaller(editor, declaringSyntax, marshallerType, managedType, missingMemberNames, isLinearCollectionMarshaller);
}
+ if (marshallerType.IsValueType)
+ {
+ AddMissingMembersToStatefulMarshaller(editor, declaringSyntax, marshallerType, managedType, missingMemberNames, isLinearCollectionMarshaller);
+ }
}
private static void AddMissingMembersToStatelessMarshaller(DocumentEditor editor, SyntaxNode declaringSyntax, INamedTypeSymbol marshallerType, ITypeSymbol managedType, HashSet missingMemberNames, bool isLinearCollectionMarshaller)
@@ -398,6 +402,173 @@ ITypeSymbol CreateManagedElementTypeSymbol()
}
}
+ private static void AddMissingMembersToStatefulMarshaller(DocumentEditor editor, SyntaxNode declaringSyntax, INamedTypeSymbol marshallerType, ITypeSymbol managedType, HashSet missingMemberNames, bool isLinearCollectionMarshaller)
+ {
+ SyntaxGenerator gen = editor.Generator;
+ // Get the methods of the shape so we can use them to determine what types to use in signatures that are not obvious.
+ var (_, methods) = StatefulMarshallerShapeHelper.GetShapeForType(marshallerType, managedType, isLinearCollectionMarshaller, editor.SemanticModel.Compilation);
+ INamedTypeSymbol spanOfT = editor.SemanticModel.Compilation.GetBestTypeByMetadataName(TypeNames.System_Span_Metadata)!;
+ INamedTypeSymbol readOnlySpanOfT = editor.SemanticModel.Compilation.GetBestTypeByMetadataName(TypeNames.System_ReadOnlySpan_Metadata)!;
+ var (typeParameters, _) = marshallerType.GetAllTypeArgumentsIncludingInContainingTypes();
+
+ // Use a lazy factory for the type syntaxes to avoid re-checking the various methods and reconstructing the syntax.
+ Lazy unmanagedTypeSyntax = new(CreateUnmanagedTypeSyntax, isThreadSafe: false);
+ Lazy managedElementTypeSymbol = new(CreateManagedElementTypeSymbol, isThreadSafe: false);
+
+ List newMembers = new();
+
+ if (missingMemberNames.Contains(ShapeMemberNames.Value.Stateful.FromManaged))
+ {
+ newMembers.Add(
+ gen.MethodDeclaration(
+ ShapeMemberNames.Value.Stateful.FromManaged,
+ parameters: new[] { gen.ParameterDeclaration("managed", gen.TypeExpression(managedType)) },
+ accessibility: Accessibility.Public,
+ statements: new[] { DefaultMethodStatement(gen, editor.SemanticModel.Compilation) }));
+ }
+
+ if (missingMemberNames.Contains(ShapeMemberNames.Value.Stateful.ToUnmanaged))
+ {
+ newMembers.Add(
+ gen.MethodDeclaration(
+ ShapeMemberNames.Value.Stateful.ToUnmanaged,
+ returnType: unmanagedTypeSyntax.Value,
+ accessibility: Accessibility.Public,
+ statements: new[] { DefaultMethodStatement(gen, editor.SemanticModel.Compilation) }));
+ }
+
+ if (missingMemberNames.Contains(ShapeMemberNames.Value.Stateful.FromUnmanaged))
+ {
+ newMembers.Add(
+ gen.MethodDeclaration(
+ ShapeMemberNames.Value.Stateful.FromUnmanaged,
+ parameters: new[] { gen.ParameterDeclaration("unmanaged", unmanagedTypeSyntax.Value) },
+ accessibility: Accessibility.Public,
+ statements: new[] { DefaultMethodStatement(gen, editor.SemanticModel.Compilation) }));
+ }
+
+ if (missingMemberNames.Contains(ShapeMemberNames.Value.Stateful.ToManaged))
+ {
+ newMembers.Add(
+ gen.MethodDeclaration(
+ ShapeMemberNames.Value.Stateful.ToManaged,
+ returnType: gen.TypeExpression(managedType),
+ accessibility: Accessibility.Public,
+ statements: new[] { DefaultMethodStatement(gen, editor.SemanticModel.Compilation) }));
+ }
+
+ if (missingMemberNames.Contains(ShapeMemberNames.BufferSize))
+ {
+ newMembers.Add(
+ gen.WithAccessorDeclarations(
+ gen.PropertyDeclaration(ShapeMemberNames.BufferSize,
+ gen.TypeExpression(editor.SemanticModel.Compilation.GetSpecialType(SpecialType.System_Int32)),
+ Accessibility.Public,
+ DeclarationModifiers.Static),
+ gen.GetAccessorDeclaration(statements: new[] { DefaultMethodStatement(gen, editor.SemanticModel.Compilation) })));
+ }
+
+ if (missingMemberNames.Contains(ShapeMemberNames.LinearCollection.Stateful.GetManagedValuesSource))
+ {
+ newMembers.Add(
+ gen.MethodDeclaration(
+ ShapeMemberNames.LinearCollection.Stateful.GetManagedValuesSource,
+ returnType: gen.TypeExpression(readOnlySpanOfT.Construct(managedElementTypeSymbol.Value)),
+ accessibility: Accessibility.Public,
+ statements: new[] { DefaultMethodStatement(gen, editor.SemanticModel.Compilation) }));
+ }
+
+ if (missingMemberNames.Contains(ShapeMemberNames.LinearCollection.Stateful.GetUnmanagedValuesDestination))
+ {
+ newMembers.Add(
+ gen.MethodDeclaration(
+ ShapeMemberNames.LinearCollection.Stateful.GetUnmanagedValuesDestination,
+ returnType: gen.TypeExpression(spanOfT.Construct(typeParameters[typeParameters.Length - 1])),
+ accessibility: Accessibility.Public,
+ statements: new[] { DefaultMethodStatement(gen, editor.SemanticModel.Compilation) }));
+ }
+
+ if (missingMemberNames.Contains(ShapeMemberNames.LinearCollection.Stateful.GetUnmanagedValuesSource))
+ {
+ newMembers.Add(
+ gen.MethodDeclaration(
+ ShapeMemberNames.LinearCollection.Stateful.GetUnmanagedValuesSource,
+ parameters: new[]
+ {
+ gen.ParameterDeclaration("numElements", gen.TypeExpression(SpecialType.System_Int32))
+ },
+ returnType: gen.TypeExpression(readOnlySpanOfT.Construct(typeParameters[typeParameters.Length - 1])),
+ accessibility: Accessibility.Public,
+ statements: new[] { DefaultMethodStatement(gen, editor.SemanticModel.Compilation) }));
+ }
+
+ if (missingMemberNames.Contains(ShapeMemberNames.LinearCollection.Stateful.GetManagedValuesDestination))
+ {
+ newMembers.Add(
+ gen.MethodDeclaration(
+ ShapeMemberNames.LinearCollection.Stateful.GetManagedValuesDestination,
+ parameters: new[]
+ {
+ gen.ParameterDeclaration("numElements", gen.TypeExpression(SpecialType.System_Int32))
+ },
+ returnType: gen.TypeExpression(spanOfT.Construct(managedElementTypeSymbol.Value)),
+ accessibility: Accessibility.Public,
+ statements: new[] { DefaultMethodStatement(gen, editor.SemanticModel.Compilation) }));
+ }
+
+ if (missingMemberNames.Contains(ShapeMemberNames.Free))
+ {
+ newMembers.Add(
+ gen.MethodDeclaration(
+ ShapeMemberNames.Value.Stateful.Free,
+ accessibility: Accessibility.Public,
+ statements: new[] { DefaultMethodStatement(gen, editor.SemanticModel.Compilation) }));
+ }
+
+ editor.ReplaceNode(declaringSyntax, (declaringSyntax, gen) => gen.AddMembers(declaringSyntax, newMembers));
+
+ SyntaxNode CreateUnmanagedTypeSyntax()
+ {
+ ITypeSymbol? unmanagedType = null;
+ if (methods.ToUnmanaged is not null)
+ {
+ unmanagedType = methods.ToUnmanaged.ReturnType;
+ }
+ else if (methods.FromUnmanaged is not null)
+ {
+ unmanagedType = methods.FromUnmanaged.Parameters[0].Type;
+ }
+ else if (methods.UnmanagedValuesSource is not null)
+ {
+ unmanagedType = methods.UnmanagedValuesSource.Parameters[0].Type;
+ }
+ else if (methods.UnmanagedValuesDestination is not null)
+ {
+ unmanagedType = methods.UnmanagedValuesDestination.Parameters[0].Type;
+ }
+
+ if (unmanagedType is not null)
+ {
+ return gen.TypeExpression(unmanagedType);
+ }
+ return gen.TypeExpression(editor.SemanticModel.Compilation.GetSpecialType(SpecialType.System_IntPtr));
+ }
+
+ ITypeSymbol CreateManagedElementTypeSymbol()
+ {
+ if (methods.ManagedValuesSource is not null)
+ {
+ return ((INamedTypeSymbol)methods.ManagedValuesSource.ReturnType).TypeArguments[0];
+ }
+ if (methods.ManagedValuesDestination is not null)
+ {
+ return ((INamedTypeSymbol)methods.ManagedValuesDestination.ReturnType).TypeArguments[0];
+ }
+
+ return editor.SemanticModel.Compilation.GetSpecialType(SpecialType.System_IntPtr);
+ }
+ }
+
private static SyntaxNode DefaultMethodStatement(SyntaxGenerator generator, Compilation compilation)
{
return generator.ThrowStatement(generator.ObjectCreationExpression(
diff --git a/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/CustomMarshallerAttributeFixerTest.cs b/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/CustomMarshallerAttributeFixerTest.cs
new file mode 100644
index 0000000000000..c56b8aa792f21
--- /dev/null
+++ b/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/CustomMarshallerAttributeFixerTest.cs
@@ -0,0 +1,143 @@
+// 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.Collections.Generic;
+using System.Collections.Immutable;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Text;
+using System.Threading.Tasks;
+using LibraryImportGenerator.UnitTests.Verifiers;
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.Testing;
+using Microsoft.Interop.Analyzers;
+using static Microsoft.Interop.Analyzers.CustomMarshallerAttributeAnalyzer;
+
+namespace LibraryImportGenerator.UnitTests
+{
+ internal class CustomMarshallerAttributeFixerTest : CSharpCodeFixVerifier.Test
+ {
+ // Sort the diagnostics in a deterministic order even when they only differ by diagnostic message.
+ // In particular, sort the equivalent subgroups by their diagnostic descriptor in the order that the fixer's fix-all provider
+ // will add the methods.
+ // This ensures that the iterative code-fix test will produce the same (deterministic) output as the fix-all tests.
+ protected override ImmutableArray<(Project project, Diagnostic diagnostic)> SortDistinctDiagnostics(IEnumerable<(Project project, Diagnostic diagnostic)> diagnostics)
+ => diagnostics.OrderBy(d => d.diagnostic.Location.GetLineSpan().Path, StringComparer.Ordinal)
+ .ThenBy(d => d.diagnostic.Location.SourceSpan.Start)
+ .ThenBy(d => d.diagnostic.Location.SourceSpan.End)
+ .ThenBy(d => d.diagnostic.Id)
+ .ThenBy(d => d.diagnostic.Descriptor, Comparer.Instance)
+ .ToImmutableArray();
+
+ private class Comparer : IComparer
+ {
+ public static readonly Comparer Instance = new();
+
+ ///
+ /// Checks if the provided descriptor matches the expected descriptor or the default marshal mode equivalent of the expected descriptor.
+ ///
+ ///
+ ///
+ ///
+ private static bool IsEquivalentDescriptor(DiagnosticDescriptor descriptor, DiagnosticDescriptor expected)
+ {
+ return descriptor.Equals(expected) || descriptor.Equals(DefaultMarshalModeDiagnostics.GetDefaultMarshalModeDiagnostic(expected));
+ }
+
+ private static int GetOrderIndexFromDescriptor(DiagnosticDescriptor descriptor)
+ {
+ // We'll order the descriptors in the following order for testing:
+ // - FromManaged/ConvertToUnmanaged
+ // - ToUnmanaged
+ // - FromUnmanaged/ConvertToManaged
+ // - ToManaged
+ // - BufferSize
+ // - AllocateContainerForUnmanagedElements
+ // - AllocateContainerForManagedElements
+ // - GetManagedValuesSource/GetUnmanagedValuesDestination
+ // - GetUnmanagedValuesSource/GetManagedValuesDestination
+ // - Free
+ // This order corresponds to the order that the fix-all provider will add the methods.
+
+ if (IsEquivalentDescriptor(descriptor, StatefulMarshallerRequiresFromManagedRule)
+ || IsEquivalentDescriptor(descriptor, StatelessValueInRequiresConvertToUnmanagedRule)
+ || IsEquivalentDescriptor(descriptor, StatelessLinearCollectionRequiresTwoParameterAllocateContainerForUnmanagedElementsRule))
+ {
+ return 0;
+ }
+ if (IsEquivalentDescriptor(descriptor, StatefulMarshallerRequiresToUnmanagedRule))
+ {
+ return 1;
+ }
+ if (IsEquivalentDescriptor(descriptor, StatefulMarshallerRequiresFromUnmanagedRule)
+ || IsEquivalentDescriptor(descriptor, StatelessRequiresConvertToManagedRule)
+ || IsEquivalentDescriptor(descriptor, StatelessLinearCollectionRequiresTwoParameterAllocateContainerForManagedElementsRule))
+ {
+ return 2;
+ }
+ if (IsEquivalentDescriptor(descriptor, StatefulMarshallerRequiresToManagedRule))
+ {
+ return 3;
+ }
+ if (IsEquivalentDescriptor(descriptor, CallerAllocFromManagedMustHaveBufferSizeRule)
+ || IsEquivalentDescriptor(descriptor, StatelessLinearCollectionCallerAllocFromManagedMustHaveBufferSizeRule))
+ {
+ return 4;
+ }
+ if (IsEquivalentDescriptor(descriptor, StatelessLinearCollectionRequiresTwoParameterAllocateContainerForUnmanagedElementsRule))
+ {
+ return 5;
+ }
+ if (IsEquivalentDescriptor(descriptor, StatelessLinearCollectionRequiresTwoParameterAllocateContainerForManagedElementsRule))
+ {
+ return 6;
+ }
+ if (IsEquivalentDescriptor(descriptor, LinearCollectionInRequiresCollectionMethodsRule)
+ || IsEquivalentDescriptor(descriptor, StatelessLinearCollectionInRequiresCollectionMethodsRule))
+ {
+ return 7;
+ }
+ if (IsEquivalentDescriptor(descriptor, LinearCollectionOutRequiresCollectionMethodsRule)
+ || IsEquivalentDescriptor(descriptor, StatelessLinearCollectionOutRequiresCollectionMethodsRule))
+ {
+ return 8;
+ }
+ if (IsEquivalentDescriptor(descriptor, StatefulMarshallerRequiresFreeRule))
+ {
+ return 9;
+ }
+ // Sort all unknown diagnostic descriptors later.
+ return 10;
+ }
+
+ public int Compare(DiagnosticDescriptor? x, DiagnosticDescriptor? y)
+ {
+ // Sort null as less than non-null.
+ if (x is null)
+ {
+ return y is null ? 0 : -1;
+ }
+ if (y is null)
+ {
+ return 1;
+ }
+
+ return GetOrderIndexFromDescriptor(x) - GetOrderIndexFromDescriptor(y);
+ }
+ }
+
+ public static async Task VerifyCodeFixAsync(string source, string fixedSource, params DiagnosticResult[] diagnostics)
+ {
+ CustomMarshallerAttributeFixerTest test = new()
+ {
+ TestCode = source,
+ FixedCode = fixedSource,
+ };
+
+ test.ExpectedDiagnostics.AddRange(diagnostics);
+
+ await test.RunAsync();
+ }
+ }
+}
diff --git a/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/CustomMarshallerAttributeFixerTests_StatefulLinearCollectionShapeValidation.cs b/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/CustomMarshallerAttributeFixerTests_StatefulLinearCollectionShapeValidation.cs
index 13f79c7e2f293..62d599fea5494 100644
--- a/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/CustomMarshallerAttributeFixerTests_StatefulLinearCollectionShapeValidation.cs
+++ b/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/CustomMarshallerAttributeFixerTests_StatefulLinearCollectionShapeValidation.cs
@@ -34,8 +34,46 @@ struct MarshallerType
}
""";
- await VerifyCS.VerifyAnalyzerAsync(
+ string fixedSource = """
+ using System.Runtime.InteropServices.Marshalling;
+
+ class ManagedType {}
+
+ [CustomMarshaller(typeof(ManagedType), MarshalMode.ManagedToUnmanagedIn, typeof(MarshallerType<>))]
+ [CustomMarshaller(typeof(ManagedType), MarshalMode.UnmanagedToManagedOut, typeof(MarshallerType<>))]
+ [ContiguousCollectionMarshaller]
+ struct MarshallerType
+ {
+ public void FromManaged(ManagedType managed)
+ {
+ throw new System.NotImplementedException();
+ }
+
+ public nint ToUnmanaged()
+ {
+ throw new System.NotImplementedException();
+ }
+
+ public System.ReadOnlySpan GetManagedValuesSource()
+ {
+ throw new System.NotImplementedException();
+ }
+
+ public System.Span GetUnmanagedValuesDestination()
+ {
+ throw new System.NotImplementedException();
+ }
+
+ public void Free()
+ {
+ throw new System.NotImplementedException();
+ }
+ }
+ """;
+
+ await CustomMarshallerAttributeFixerTest.VerifyCodeFixAsync(
source,
+ fixedSource,
VerifyCS.DiagnosticWithArguments(StatefulMarshallerRequiresFreeRule, "MarshallerType").WithLocation(0),
VerifyCS.DiagnosticWithArguments(StatefulMarshallerRequiresFromManagedRule, "MarshallerType", MarshalMode.ManagedToUnmanagedIn, "ManagedType").WithLocation(0),
VerifyCS.DiagnosticWithArguments(StatefulMarshallerRequiresFromManagedRule, "MarshallerType", MarshalMode.UnmanagedToManagedOut, "ManagedType").WithLocation(1),
@@ -65,8 +103,35 @@ public void Free() {}
}
""";
- await VerifyCS.VerifyAnalyzerAsync(
+ string fixedSource = """
+ using System.Runtime.InteropServices.Marshalling;
+
+ class ManagedType {}
+
+ [CustomMarshaller(typeof(ManagedType), MarshalMode.ManagedToUnmanagedIn, typeof(MarshallerType<>))]
+ [CustomMarshaller(typeof(ManagedType), MarshalMode.UnmanagedToManagedOut, typeof(MarshallerType<>))]
+ [ContiguousCollectionMarshaller]
+ struct MarshallerType
+ {
+ public void FromManaged(ManagedType m) {}
+ public nint ToUnmanaged() => default;
+ public void Free() {}
+
+ public System.ReadOnlySpan GetManagedValuesSource()
+ {
+ throw new System.NotImplementedException();
+ }
+
+ public System.Span GetUnmanagedValuesDestination()
+ {
+ throw new System.NotImplementedException();
+ }
+ }
+ """;
+
+ await CustomMarshallerAttributeFixerTest.VerifyCodeFixAsync(
source,
+ fixedSource,
VerifyCS.Diagnostic(LinearCollectionInRequiresCollectionMethodsRule).WithLocation(0).WithArguments("MarshallerType", MarshalMode.ManagedToUnmanagedIn, "ManagedType"),
VerifyCS.Diagnostic(LinearCollectionInRequiresCollectionMethodsRule).WithLocation(1).WithArguments("MarshallerType", MarshalMode.UnmanagedToManagedOut, "ManagedType"));
}
@@ -92,8 +157,32 @@ public void Free() {}
}
""";
- await VerifyCS.VerifyAnalyzerAsync(
+ string fixedSource = """
+ using System;
+ using System.Runtime.InteropServices.Marshalling;
+
+ class ManagedType {}
+
+ [CustomMarshaller(typeof(ManagedType), MarshalMode.ManagedToUnmanagedIn, typeof(MarshallerType<>))]
+ [CustomMarshaller(typeof(ManagedType), MarshalMode.UnmanagedToManagedOut, typeof(MarshallerType<>))]
+ [ContiguousCollectionMarshaller]
+ struct MarshallerType
+ {
+ public void FromManaged(ManagedType m) {}
+ public nint ToUnmanaged() => default;
+ public void Free() {}
+ public Span GetUnmanagedValuesDestination() => default;
+
+ public ReadOnlySpan GetManagedValuesSource()
+ {
+ throw new NotImplementedException();
+ }
+ }
+ """;
+
+ await CustomMarshallerAttributeFixerTest.VerifyCodeFixAsync(
source,
+ fixedSource,
VerifyCS.Diagnostic(LinearCollectionInRequiresCollectionMethodsRule).WithLocation(0).WithArguments("MarshallerType", MarshalMode.ManagedToUnmanagedIn, "ManagedType"),
VerifyCS.Diagnostic(LinearCollectionInRequiresCollectionMethodsRule).WithLocation(1).WithArguments("MarshallerType", MarshalMode.UnmanagedToManagedOut, "ManagedType"));
}
@@ -119,8 +208,32 @@ public void Free() {}
}
""";
- await VerifyCS.VerifyAnalyzerAsync(
+ string fixedSource = """
+ using System;
+ using System.Runtime.InteropServices.Marshalling;
+
+ class ManagedType {}
+
+ [CustomMarshaller(typeof(ManagedType), MarshalMode.ManagedToUnmanagedIn, typeof(MarshallerType<>))]
+ [CustomMarshaller(typeof(ManagedType), MarshalMode.UnmanagedToManagedOut, typeof(MarshallerType<>))]
+ [ContiguousCollectionMarshaller]
+ struct MarshallerType
+ {
+ public void FromManaged(ManagedType m) {}
+ public nint ToUnmanaged() => default;
+ public void Free() {}
+ public ReadOnlySpan GetManagedValuesSource() => default;
+
+ public Span GetUnmanagedValuesDestination()
+ {
+ throw new NotImplementedException();
+ }
+ }
+ """;
+
+ await CustomMarshallerAttributeFixerTest.VerifyCodeFixAsync(
source,
+ fixedSource,
VerifyCS.Diagnostic(LinearCollectionInRequiresCollectionMethodsRule).WithLocation(1).WithArguments("MarshallerType", MarshalMode.UnmanagedToManagedOut, "ManagedType"),
VerifyCS.Diagnostic(LinearCollectionInRequiresCollectionMethodsRule).WithLocation(0).WithArguments("MarshallerType", MarshalMode.ManagedToUnmanagedIn, "ManagedType"));
}
@@ -196,8 +309,46 @@ struct MarshallerType
}
""";
- await VerifyCS.VerifyAnalyzerAsync(
+ string fixedSource = """
+ using System.Runtime.InteropServices.Marshalling;
+
+ class ManagedType {}
+
+ [CustomMarshaller(typeof(ManagedType), MarshalMode.ManagedToUnmanagedOut, typeof(MarshallerType<>))]
+ [CustomMarshaller(typeof(ManagedType), MarshalMode.UnmanagedToManagedIn, typeof(MarshallerType<>))]
+ [ContiguousCollectionMarshaller]
+ struct MarshallerType
+ {
+ public void FromUnmanaged(nint unmanaged)
+ {
+ throw new System.NotImplementedException();
+ }
+
+ public ManagedType ToManaged()
+ {
+ throw new System.NotImplementedException();
+ }
+
+ public System.ReadOnlySpan GetUnmanagedValuesSource(int numElements)
+ {
+ throw new System.NotImplementedException();
+ }
+
+ public System.Span GetManagedValuesDestination(int numElements)
+ {
+ throw new System.NotImplementedException();
+ }
+
+ public void Free()
+ {
+ throw new System.NotImplementedException();
+ }
+ }
+ """;
+
+ await CustomMarshallerAttributeFixerTest.VerifyCodeFixAsync(
source,
+ fixedSource,
VerifyCS.DiagnosticWithArguments(StatefulMarshallerRequiresFreeRule, "MarshallerType").WithLocation(0),
VerifyCS.DiagnosticWithArguments(StatefulMarshallerRequiresToManagedRule, "MarshallerType", MarshalMode.ManagedToUnmanagedOut, "ManagedType").WithLocation(0),
VerifyCS.DiagnosticWithArguments(StatefulMarshallerRequiresToManagedRule, "MarshallerType", MarshalMode.UnmanagedToManagedIn, "ManagedType").WithLocation(1),
@@ -227,8 +378,35 @@ public void Free() {}
}
""";
- await VerifyCS.VerifyAnalyzerAsync(
+ string fixedSource = """
+ using System.Runtime.InteropServices.Marshalling;
+
+ class ManagedType {}
+
+ [CustomMarshaller(typeof(ManagedType), MarshalMode.ManagedToUnmanagedOut, typeof(MarshallerType<>))]
+ [CustomMarshaller(typeof(ManagedType), MarshalMode.UnmanagedToManagedIn, typeof(MarshallerType<>))]
+ [ContiguousCollectionMarshaller]
+ struct MarshallerType
+ {
+ public void FromUnmanaged(int f) {}
+ public ManagedType ToManaged() => default;
+ public void Free() {}
+
+ public System.ReadOnlySpan GetUnmanagedValuesSource(int numElements)
+ {
+ throw new System.NotImplementedException();
+ }
+
+ public System.Span GetManagedValuesDestination(int numElements)
+ {
+ throw new System.NotImplementedException();
+ }
+ }
+ """;
+
+ await CustomMarshallerAttributeFixerTest.VerifyCodeFixAsync(
source,
+ fixedSource,
VerifyCS.Diagnostic(LinearCollectionOutRequiresCollectionMethodsRule).WithLocation(0).WithArguments("MarshallerType", MarshalMode.ManagedToUnmanagedOut, "ManagedType"),
VerifyCS.Diagnostic(LinearCollectionOutRequiresCollectionMethodsRule).WithLocation(1).WithArguments("MarshallerType", MarshalMode.UnmanagedToManagedIn, "ManagedType"));
}
@@ -254,8 +432,32 @@ public void Free() {}
}
""";
- await VerifyCS.VerifyAnalyzerAsync(
+ string fixedSource = """
+ using System;
+ using System.Runtime.InteropServices.Marshalling;
+
+ class ManagedType {}
+
+ [CustomMarshaller(typeof(ManagedType), MarshalMode.ManagedToUnmanagedOut, typeof(MarshallerType<>))]
+ [CustomMarshaller(typeof(ManagedType), MarshalMode.UnmanagedToManagedIn, typeof(MarshallerType<>))]
+ [ContiguousCollectionMarshaller]
+ struct MarshallerType
+ {
+ public void FromUnmanaged(int f) {}
+ public ManagedType ToManaged() => default;
+ public void Free() {}
+ public Span GetManagedValuesDestination(int numElements) => default;
+
+ public ReadOnlySpan GetUnmanagedValuesSource(int numElements)
+ {
+ throw new NotImplementedException();
+ }
+ }
+ """;
+
+ await CustomMarshallerAttributeFixerTest.VerifyCodeFixAsync(
source,
+ fixedSource,
VerifyCS.Diagnostic(LinearCollectionOutRequiresCollectionMethodsRule).WithLocation(0).WithArguments("MarshallerType", MarshalMode.ManagedToUnmanagedOut, "ManagedType"),
VerifyCS.Diagnostic(LinearCollectionOutRequiresCollectionMethodsRule).WithLocation(1).WithArguments("MarshallerType", MarshalMode.UnmanagedToManagedIn, "ManagedType"));
}
@@ -281,8 +483,32 @@ public void Free() {}
}
""";
- await VerifyCS.VerifyAnalyzerAsync(
+ string fixedSource = """
+ using System;
+ using System.Runtime.InteropServices.Marshalling;
+
+ class ManagedType {}
+
+ [CustomMarshaller(typeof(ManagedType), MarshalMode.ManagedToUnmanagedOut, typeof(MarshallerType<>))]
+ [CustomMarshaller(typeof(ManagedType), MarshalMode.UnmanagedToManagedIn, typeof(MarshallerType<>))]
+ [ContiguousCollectionMarshaller]
+ struct MarshallerType
+ {
+ public void FromUnmanaged(int f) {}
+ public ManagedType ToManaged() => default;
+ public void Free() {}
+ public ReadOnlySpan GetUnmanagedValuesSource(int numElements) => default;
+
+ public Span GetManagedValuesDestination(int numElements)
+ {
+ throw new NotImplementedException();
+ }
+ }
+ """;
+
+ await CustomMarshallerAttributeFixerTest.VerifyCodeFixAsync(
source,
+ fixedSource,
VerifyCS.Diagnostic(LinearCollectionOutRequiresCollectionMethodsRule).WithLocation(1).WithArguments("MarshallerType", MarshalMode.UnmanagedToManagedIn, "ManagedType"),
VerifyCS.Diagnostic(LinearCollectionOutRequiresCollectionMethodsRule).WithLocation(0).WithArguments("MarshallerType", MarshalMode.ManagedToUnmanagedOut, "ManagedType"));
}
@@ -362,8 +588,35 @@ public void Free() {}
}
""";
- await VerifyCS.VerifyAnalyzerAsync(
+ string fixedSource = """
+ using System;
+ using System.Runtime.InteropServices.Marshalling;
+
+ class ManagedType {}
+
+ [CustomMarshaller(typeof(ManagedType), MarshalMode.ManagedToUnmanagedIn, typeof(MarshallerType<>))]
+ [ContiguousCollectionMarshaller]
+ struct MarshallerType
+ {
+ public void FromManaged(ManagedType m, Span buffer) {}
+ public nint ToUnmanaged() => default;
+ public void Free() {}
+ public ReadOnlySpan GetManagedValuesSource() => default;
+ public Span GetUnmanagedValuesDestination() => default;
+
+ public static int BufferSize
+ {
+ get
+ {
+ throw new NotImplementedException();
+ }
+ }
+ }
+ """;
+
+ await CustomMarshallerAttributeFixerTest.VerifyCodeFixAsync(
source,
+ fixedSource,
VerifyCS.Diagnostic(CallerAllocFromManagedMustHaveBufferSizeRule).WithLocation(0).WithArguments("MarshallerType", "byte"));
}
diff --git a/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/CustomMarshallerAttributeFixerTests_StatefulValueShapeValidation.cs b/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/CustomMarshallerAttributeFixerTests_StatefulValueShapeValidation.cs
index 1fa6fbca1b383..6cf2b96e61912 100644
--- a/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/CustomMarshallerAttributeFixerTests_StatefulValueShapeValidation.cs
+++ b/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/CustomMarshallerAttributeFixerTests_StatefulValueShapeValidation.cs
@@ -5,6 +5,7 @@
using Microsoft.CodeAnalysis.Testing;
using Microsoft.Interop;
using System.Collections.Generic;
+using System.Threading;
using System.Threading.Tasks;
using Xunit;
using static Microsoft.Interop.Analyzers.CustomMarshallerAttributeAnalyzer;
@@ -33,8 +34,35 @@ struct MarshallerType
}
""";
- await VerifyCS.VerifyAnalyzerAsync(
+ string fixedSource = """
+ using System.Runtime.InteropServices.Marshalling;
+
+ class ManagedType {}
+
+ [CustomMarshaller(typeof(ManagedType), MarshalMode.ManagedToUnmanagedIn, typeof(MarshallerType))]
+ [CustomMarshaller(typeof(ManagedType), MarshalMode.UnmanagedToManagedOut, typeof(MarshallerType))]
+ struct MarshallerType
+ {
+ public void FromManaged(ManagedType managed)
+ {
+ throw new System.NotImplementedException();
+ }
+
+ public nint ToUnmanaged()
+ {
+ throw new System.NotImplementedException();
+ }
+
+ public void Free()
+ {
+ throw new System.NotImplementedException();
+ }
+ }
+ """;
+
+ await CustomMarshallerAttributeFixerTest.VerifyCodeFixAsync(
source,
+ fixedSource,
VerifyCS.DiagnosticWithArguments(StatefulMarshallerRequiresFromManagedRule, "MarshallerType", MarshalMode.ManagedToUnmanagedIn, "ManagedType").WithLocation(0),
VerifyCS.DiagnosticWithArguments(StatefulMarshallerRequiresFromManagedRule, "MarshallerType", MarshalMode.UnmanagedToManagedOut, "ManagedType").WithLocation(1),
VerifyCS.DiagnosticWithArguments(StatefulMarshallerRequiresToUnmanagedRule, "MarshallerType", MarshalMode.ManagedToUnmanagedIn, "ManagedType").WithLocation(0),
@@ -58,8 +86,35 @@ struct MarshallerType
}
""";
- await VerifyCS.VerifyAnalyzerAsync(
+ string fixedSource = """
+ using System.Runtime.InteropServices.Marshalling;
+
+ class ManagedType {}
+
+ [CustomMarshaller(typeof(ManagedType), MarshalMode.ManagedToUnmanagedOut, typeof(MarshallerType))]
+ [CustomMarshaller(typeof(ManagedType), MarshalMode.UnmanagedToManagedIn, typeof(MarshallerType))]
+ struct MarshallerType
+ {
+ public void FromUnmanaged(nint unmanaged)
+ {
+ throw new System.NotImplementedException();
+ }
+
+ public ManagedType ToManaged()
+ {
+ throw new System.NotImplementedException();
+ }
+
+ public void Free()
+ {
+ throw new System.NotImplementedException();
+ }
+ }
+ """;
+
+ await CustomMarshallerAttributeFixerTest.VerifyCodeFixAsync(
source,
+ fixedSource,
VerifyCS.DiagnosticWithArguments(StatefulMarshallerRequiresFromUnmanagedRule, "MarshallerType", MarshalMode.ManagedToUnmanagedOut, "ManagedType").WithLocation(0),
VerifyCS.DiagnosticWithArguments(StatefulMarshallerRequiresFromUnmanagedRule, "MarshallerType", MarshalMode.UnmanagedToManagedIn, "ManagedType").WithLocation(1),
VerifyCS.DiagnosticWithArguments(StatefulMarshallerRequiresToManagedRule, "MarshallerType", MarshalMode.ManagedToUnmanagedOut, "ManagedType").WithLocation(0),
@@ -106,8 +161,45 @@ struct MarshallerType
}
""";
- await VerifyCS.VerifyAnalyzerAsync(
+ string fixedSource = """
+ using System.Runtime.InteropServices.Marshalling;
+
+ class ManagedType {}
+
+ [CustomMarshaller(typeof(ManagedType), MarshalMode.ManagedToUnmanagedRef, typeof(MarshallerType))]
+ [CustomMarshaller(typeof(ManagedType), MarshalMode.UnmanagedToManagedRef, typeof(MarshallerType))]
+ struct MarshallerType
+ {
+ public void FromManaged(ManagedType managed)
+ {
+ throw new System.NotImplementedException();
+ }
+
+ public nint ToUnmanaged()
+ {
+ throw new System.NotImplementedException();
+ }
+
+ public void FromUnmanaged(nint unmanaged)
+ {
+ throw new System.NotImplementedException();
+ }
+
+ public ManagedType ToManaged()
+ {
+ throw new System.NotImplementedException();
+ }
+
+ public void Free()
+ {
+ throw new System.NotImplementedException();
+ }
+ }
+ """;
+
+ await CustomMarshallerAttributeFixerTest.VerifyCodeFixAsync(
source,
+ fixedSource,
VerifyCS.DiagnosticWithArguments(StatefulMarshallerRequiresFreeRule, "MarshallerType").WithLocation(0),
VerifyCS.DiagnosticWithArguments(StatefulMarshallerRequiresFromManagedRule, "MarshallerType", MarshalMode.ManagedToUnmanagedRef, "ManagedType").WithLocation(0),
VerifyCS.DiagnosticWithArguments(StatefulMarshallerRequiresFromManagedRule, "MarshallerType", MarshalMode.UnmanagedToManagedRef, "ManagedType").WithLocation(1),
@@ -212,8 +304,44 @@ struct MarshallerType
}
""";
- await VerifyCS.VerifyAnalyzerAsync(
+ string fixedSource = """
+ using System.Runtime.InteropServices.Marshalling;
+
+ class ManagedType {}
+
+ [CustomMarshaller(typeof(ManagedType), MarshalMode.Default, typeof(MarshallerType))]
+ struct MarshallerType
+ {
+ public void FromManaged(ManagedType managed)
+ {
+ throw new System.NotImplementedException();
+ }
+
+ public nint ToUnmanaged()
+ {
+ throw new System.NotImplementedException();
+ }
+
+ public void FromUnmanaged(nint unmanaged)
+ {
+ throw new System.NotImplementedException();
+ }
+
+ public ManagedType ToManaged()
+ {
+ throw new System.NotImplementedException();
+ }
+
+ public void Free()
+ {
+ throw new System.NotImplementedException();
+ }
+ }
+ """;
+
+ await CustomMarshallerAttributeFixerTest.VerifyCodeFixAsync(
source,
+ fixedSource,
VerifyCS.Diagnostic(StatefulMarshallerRequiresFreeRule).WithLocation(0).WithArguments("MarshallerType"),
VerifyCS.DiagnosticWithArguments(StatefulMarshallerRequiresFromManagedRule, "MarshallerType", MarshalMode.Default, "ManagedType").WithSeverity(DiagnosticSeverity.Info).WithLocation(0),
VerifyCS.DiagnosticWithArguments(StatefulMarshallerRequiresToUnmanagedRule, "MarshallerType", MarshalMode.Default, "ManagedType").WithSeverity(DiagnosticSeverity.Info).WithLocation(0),
@@ -241,8 +369,34 @@ public void Free() {}
}
""";
- await VerifyCS.VerifyAnalyzerAsync(
+ string fixedSource = """
+ using System;
+ using System.Runtime.InteropServices.Marshalling;
+
+ class ManagedType {}
+
+ [CustomMarshaller(typeof(ManagedType), MarshalMode.ManagedToUnmanagedIn, typeof({|#0:MarshallerType|}))]
+ struct MarshallerType
+ {
+ public void FromManaged(ManagedType m, Span b) {}
+
+ public int ToUnmanaged() => default;
+
+ public void Free() {}
+
+ public static int BufferSize
+ {
+ get
+ {
+ throw new NotImplementedException();
+ }
+ }
+ }
+ """;
+
+ await CustomMarshallerAttributeFixerTest.VerifyCodeFixAsync(
source,
+ fixedSource,
VerifyCS.Diagnostic(CallerAllocFromManagedMustHaveBufferSizeRule).WithLocation(0).WithArguments("MarshallerType", "byte"));
}
}
diff --git a/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/CustomMarshallerAttributeFixerTests_StatelessLinearCollectionShapeValidation.cs b/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/CustomMarshallerAttributeFixerTests_StatelessLinearCollectionShapeValidation.cs
index 65ecd60049f42..28149a0f7864e 100644
--- a/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/CustomMarshallerAttributeFixerTests_StatelessLinearCollectionShapeValidation.cs
+++ b/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/CustomMarshallerAttributeFixerTests_StatelessLinearCollectionShapeValidation.cs
@@ -63,7 +63,7 @@ public static System.Span GetUnmanagedValuesDestination(nint unmanaged, int n
}
""";
- await VerifyCS.VerifyCodeFixAsync(
+ await CustomMarshallerAttributeFixerTest.VerifyCodeFixAsync(
source,
fixedSource,
VerifyCS.DiagnosticWithArguments(StatelessLinearCollectionRequiresTwoParameterAllocateContainerForUnmanagedElementsRule, "MarshallerType", MarshalMode.ManagedToUnmanagedIn, "ManagedType").WithLocation(0),
@@ -117,7 +117,7 @@ public static System.Span GetUnmanagedValuesDestination(nint unmanaged, int n
}
""";
- await VerifyCS.VerifyCodeFixAsync(
+ await CustomMarshallerAttributeFixerTest.VerifyCodeFixAsync(
source,
fixedSource,
VerifyCS.Diagnostic(StatelessLinearCollectionInRequiresCollectionMethodsRule).WithLocation(0).WithArguments("MarshallerType", MarshalMode.ManagedToUnmanagedIn, "ManagedType"),
@@ -169,7 +169,7 @@ public static ReadOnlySpan GetManagedValuesSource(ManagedType managed)
}
""";
- await VerifyCS.VerifyCodeFixAsync(
+ await CustomMarshallerAttributeFixerTest.VerifyCodeFixAsync(
source,
fixedSource,
VerifyCS.Diagnostic(StatelessLinearCollectionInRequiresCollectionMethodsRule).WithLocation(0).WithArguments("MarshallerType", MarshalMode.ManagedToUnmanagedIn, "ManagedType"),
@@ -221,7 +221,7 @@ public static Span GetUnmanagedValuesDestination(nint unmanaged, int numEleme
}
""";
- await VerifyCS.VerifyCodeFixAsync(
+ await CustomMarshallerAttributeFixerTest.VerifyCodeFixAsync(
source,
fixedSource,
VerifyCS.Diagnostic(StatelessLinearCollectionInRequiresCollectionMethodsRule).WithLocation(0).WithArguments("MarshallerType", MarshalMode.ManagedToUnmanagedIn, "ManagedType"),
@@ -362,7 +362,7 @@ public static System.Span GetManagedValuesDestination(ManagedType managed)
}
""";
- await VerifyCS.VerifyCodeFixAsync(
+ await CustomMarshallerAttributeFixerTest.VerifyCodeFixAsync(
source,
fixedSource,
VerifyCS.DiagnosticWithArguments(StatelessLinearCollectionRequiresTwoParameterAllocateContainerForManagedElementsRule, "MarshallerType", MarshalMode.ManagedToUnmanagedOut, "ManagedType").WithLocation(0),
@@ -416,7 +416,7 @@ public static System.Span GetManagedValuesDestination(ManagedType managed)
}
""";
- await VerifyCS.VerifyCodeFixAsync(
+ await CustomMarshallerAttributeFixerTest.VerifyCodeFixAsync(
source,
fixedSource,
VerifyCS.Diagnostic(StatelessLinearCollectionOutRequiresCollectionMethodsRule).WithLocation(0).WithArguments("MarshallerType", MarshalMode.ManagedToUnmanagedOut, "ManagedType"),
@@ -468,7 +468,7 @@ public static ReadOnlySpan GetUnmanagedValuesSource(nint unmanaged, int numEl
}
""";
- await VerifyCS.VerifyCodeFixAsync(
+ await CustomMarshallerAttributeFixerTest.VerifyCodeFixAsync(
source,
fixedSource,
VerifyCS.Diagnostic(StatelessLinearCollectionOutRequiresCollectionMethodsRule).WithLocation(0).WithArguments("MarshallerType", MarshalMode.ManagedToUnmanagedOut, "ManagedType"),
@@ -520,7 +520,7 @@ public static Span GetManagedValuesDestination(ManagedType managed)
}
""";
- await VerifyCS.VerifyCodeFixAsync(
+ await CustomMarshallerAttributeFixerTest.VerifyCodeFixAsync(
source,
fixedSource,
VerifyCS.Diagnostic(StatelessLinearCollectionOutRequiresCollectionMethodsRule).WithLocation(0).WithArguments("MarshallerType", MarshalMode.ManagedToUnmanagedOut, "ManagedType"),
@@ -662,7 +662,7 @@ public static int BufferSize
}
""";
- await VerifyCS.VerifyCodeFixAsync(
+ await CustomMarshallerAttributeFixerTest.VerifyCodeFixAsync(
source,
fixedSource,
VerifyCS.Diagnostic(StatelessLinearCollectionCallerAllocFromManagedMustHaveBufferSizeRule).WithLocation(0).WithArguments("MarshallerType", "byte"));
diff --git a/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/CustomMarshallerAttributeFixerTests_StatelessValueShapeValidation.cs b/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/CustomMarshallerAttributeFixerTests_StatelessValueShapeValidation.cs
index 273982f374ded..b855690efc2b3 100644
--- a/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/CustomMarshallerAttributeFixerTests_StatelessValueShapeValidation.cs
+++ b/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/CustomMarshallerAttributeFixerTests_StatelessValueShapeValidation.cs
@@ -51,7 +51,7 @@ public static nint ConvertToUnmanaged(ManagedType managed)
}
""";
- await VerifyCS.VerifyCodeFixAsync(
+ await CustomMarshallerAttributeFixerTest.VerifyCodeFixAsync(
source,
fixedSource,
VerifyCS.Diagnostic(StatelessValueInRequiresConvertToUnmanagedRule).WithLocation(0).WithArguments("MarshallerType", MarshalMode.ManagedToUnmanagedIn, "ManagedType"),
@@ -113,7 +113,7 @@ public static ManagedType ConvertToManaged(nint unmanaged)
}
""";
- await VerifyCS.VerifyCodeFixAsync(
+ await CustomMarshallerAttributeFixerTest.VerifyCodeFixAsync(
source,
fixedSource,
VerifyCS.Diagnostic(StatelessRequiresConvertToManagedRule).WithLocation(0).WithArguments("MarshallerType", MarshalMode.ManagedToUnmanagedOut, "ManagedType"),
@@ -159,7 +159,7 @@ public static ManagedType ConvertToManaged(nint unmanaged)
}
""";
- await VerifyCS.VerifyCodeFixAsync(
+ await CustomMarshallerAttributeFixerTest.VerifyCodeFixAsync(
source,
fixedSource,
VerifyCS.DiagnosticWithArguments(StatelessValueInRequiresConvertToUnmanagedRule, "MarshallerType", MarshalMode.ManagedToUnmanagedRef, "ManagedType").WithLocation(0),
@@ -212,7 +212,7 @@ public static float ConvertToUnmanaged(ManagedType managed)
}
""";
- await VerifyCS.VerifyCodeFixAsync(
+ await CustomMarshallerAttributeFixerTest.VerifyCodeFixAsync(
source,
fixedSource,
VerifyCS.Diagnostic(StatelessValueInRequiresConvertToUnmanagedRule).WithLocation(0).WithArguments("MarshallerType", MarshalMode.ManagedToUnmanagedRef, "ManagedType"),
@@ -262,7 +262,7 @@ public static ManagedType ConvertToManaged(float unmanaged)
}
""";
- await VerifyCS.VerifyCodeFixAsync(
+ await CustomMarshallerAttributeFixerTest.VerifyCodeFixAsync(
source,
fixedSource,
VerifyCS.Diagnostic(StatelessRequiresConvertToManagedRule).WithLocation(0).WithArguments("MarshallerType", MarshalMode.ManagedToUnmanagedRef, "ManagedType"),
@@ -329,7 +329,7 @@ public static ManagedType ConvertToManaged(nint unmanaged)
}
""";
- await VerifyCS.VerifyCodeFixAsync(
+ await CustomMarshallerAttributeFixerTest.VerifyCodeFixAsync(
source,
fixedSource,
VerifyCS.Diagnostic(StatelessValueInRequiresConvertToUnmanagedRule).WithSeverity(DiagnosticSeverity.Info).WithLocation(0).WithArguments("MarshallerType", MarshalMode.Default, "ManagedType"),
@@ -373,7 +373,7 @@ public static int BufferSize
}
""";
- await VerifyCS.VerifyCodeFixAsync(
+ await CustomMarshallerAttributeFixerTest.VerifyCodeFixAsync(
source,
fixedSource,
VerifyCS.Diagnostic(CallerAllocFromManagedMustHaveBufferSizeRule).WithLocation(0).WithArguments("MarshallerType", "byte"));
@@ -422,14 +422,11 @@ public static nint ConvertToUnmanaged(ManagedType managed)
}
[Fact]
- [ActiveIssue("https://github.com/dotnet/roslyn-sdk/issues/1000")]
public async Task ModeThatUsesManagedToUnmanagedShape_Missing_ConvertToUnmanagedMethod_Marshaller_DifferentProject_ReportsDiagnostic()
{
string entryPointTypeSource = """
using System.Runtime.InteropServices.Marshalling;
- class ManagedType {}
-
[CustomMarshaller(typeof(ManagedType), MarshalMode.ManagedToUnmanagedIn, typeof({|SYSLIB1057:OtherMarshallerType|}))]
[CustomMarshaller(typeof(ManagedType), MarshalMode.UnmanagedToManagedOut, typeof({|SYSLIB1057:OtherMarshallerType|}))]
[CustomMarshaller(typeof(ManagedType), MarshalMode.ElementIn, typeof({|SYSLIB1057:OtherMarshallerType|}))]
@@ -439,12 +436,14 @@ static class MarshallerType
""";
string otherMarshallerTypeOriginalSource = """
+ public class ManagedType {}
public static class OtherMarshallerType
{
}
""";
string otherMarshallerTypeFixedSource = """
+ public class ManagedType {}
public static class OtherMarshallerType
{
public static nint ConvertToUnmanaged(ManagedType managed)
@@ -472,8 +471,10 @@ public static nint ConvertToUnmanaged(ManagedType managed)
test.FixedState.Sources.Add(entryPointTypeSource);
test.FixedState.AdditionalProjects.Add(otherProjectName, otherProjectFixedState);
test.FixedState.AdditionalProjectReferences.Add(otherProjectName);
- test.MarkupOptions = MarkupOptions.UseFirstDescriptor;
test.FixedState.MarkupHandling = MarkupMode.IgnoreFixable;
+
+ test.NumberOfFixAllIterations = 1;
+ test.MarkupOptions = MarkupOptions.UseFirstDescriptor;
await test.RunAsync();
}
@@ -515,7 +516,7 @@ public static nint ConvertToUnmanaged(ManagedType2 managed)
}
""";
- await VerifyCS.VerifyCodeFixAsync(
+ await CustomMarshallerAttributeFixerTest.VerifyCodeFixAsync(
source,
fixedSource,
VerifyCS.Diagnostic(StatelessValueInRequiresConvertToUnmanagedRule).WithLocation(0).WithArguments("MarshallerType", MarshalMode.ManagedToUnmanagedIn, "ManagedType"),