From afc175f3a9d0e1eeaf9017bf4c946667a86ed2e6 Mon Sep 17 00:00:00 2001 From: Elinor Fung Date: Mon, 28 Mar 2022 08:52:43 -0700 Subject: [PATCH] Let CustomTypeMarshaller implementation use Span of unmanaged type for Value marshalling (#67172) --- .../Analyzers/CustomTypeMarshallerAnalyzer.cs | 2 +- .../Resources/Strings.resx | 4 +- .../Resources/xlf/Strings.cs.xlf | 8 +-- .../Resources/xlf/Strings.de.xlf | 8 +-- .../Resources/xlf/Strings.es.xlf | 8 +-- .../Resources/xlf/Strings.fr.xlf | 8 +-- .../Resources/xlf/Strings.it.xlf | 8 +-- .../Resources/xlf/Strings.ja.xlf | 8 +-- .../Resources/xlf/Strings.ko.xlf | 8 +-- .../Resources/xlf/Strings.pl.xlf | 8 +-- .../Resources/xlf/Strings.pt-BR.xlf | 8 +-- .../Resources/xlf/Strings.ru.xlf | 8 +-- .../Resources/xlf/Strings.tr.xlf | 8 +-- .../Resources/xlf/Strings.zh-Hans.xlf | 8 +-- .../Resources/xlf/Strings.zh-Hant.xlf | 8 +-- .../ManagedTypeInfo.cs | 1 + .../ManualTypeMarshallingHelper.cs | 30 ++++++++-- ...ributedMarshallingModelGeneratorFactory.cs | 2 +- .../ICustomNativeTypeMarshallingStrategy.cs | 12 ++-- .../MarshallingAttributeInfo.cs | 23 ++++++++ .../Resources/Strings.resx | 57 ++++++++++--------- .../Resources/xlf/Strings.cs.xlf | 5 ++ .../Resources/xlf/Strings.de.xlf | 5 ++ .../Resources/xlf/Strings.es.xlf | 5 ++ .../Resources/xlf/Strings.fr.xlf | 5 ++ .../Resources/xlf/Strings.it.xlf | 5 ++ .../Resources/xlf/Strings.ja.xlf | 5 ++ .../Resources/xlf/Strings.ko.xlf | 5 ++ .../Resources/xlf/Strings.pl.xlf | 5 ++ .../Resources/xlf/Strings.pt-BR.xlf | 5 ++ .../Resources/xlf/Strings.ru.xlf | 5 ++ .../Resources/xlf/Strings.tr.xlf | 5 ++ .../Resources/xlf/Strings.zh-Hans.xlf | 5 ++ .../Resources/xlf/Strings.zh-Hant.xlf | 5 ++ .../CustomTypeMarshallerFixerTests.cs | 47 +++++++++++++++ .../TestAssets/SharedTypes/NonBlittable.cs | 10 ++-- .../LibraryImportGeneratorSample.csproj | 1 + 37 files changed, 259 insertions(+), 99 deletions(-) diff --git a/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Analyzers/CustomTypeMarshallerAnalyzer.cs b/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Analyzers/CustomTypeMarshallerAnalyzer.cs index 98fe06058f0..ff5056f4e40 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Analyzers/CustomTypeMarshallerAnalyzer.cs +++ b/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Analyzers/CustomTypeMarshallerAnalyzer.cs @@ -588,7 +588,7 @@ public void AnalyzeMarshallerType(SymbolAnalysisContext context) inConstructor = ctor; } - if (callerAllocatedSpanConstructor is null && ManualTypeMarshallingHelper.IsCallerAllocatedSpanConstructor(ctor, type, _spanOfByte, marshallerData.Kind)) + if (callerAllocatedSpanConstructor is null && ManualTypeMarshallingHelper.IsCallerAllocatedSpanConstructor(ctor, type, _spanOfT, marshallerData.Kind, out _)) { callerAllocatedSpanConstructor = ctor; } diff --git a/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Resources/Strings.resx b/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Resources/Strings.resx index cb1b973807d..f722840d097 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Resources/Strings.resx +++ b/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Resources/Strings.resx @@ -354,10 +354,10 @@ The specified custom marshaller direction for '{0}' is invalid - A 'Value'-kind native type that supports the 'CallerAllocatedBuffer' feature must provide a two-parameter constructor taking the managed type and a 'Span<byte>' as parameters + A 'Value'-kind native type that supports the 'CallerAllocatedBuffer' feature must provide a two-parameter constructor taking the managed type and a 'Span' of an 'unmanaged' type as parameters - The type '{0}' specifies that it supports 'In' marshalling with the 'CallerAllocatedBuffer' feature for '{1}' but does not provide a one-parameter constructor that takes a '{1}' and 'Span<byte>' as parameters + The type '{0}' specifies that it supports 'In' marshalling with the 'CallerAllocatedBuffer' feature for '{1}' but does not provide a one-parameter constructor that takes a '{1}' and 'Span' of an 'unmanaged' type as parameters A 'Value'-kind native type must provide a one-parameter constructor taking the managed type as a parameter diff --git a/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Resources/xlf/Strings.cs.xlf b/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Resources/xlf/Strings.cs.xlf index 661675de7c4..f5fa45a1233 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Resources/xlf/Strings.cs.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Resources/xlf/Strings.cs.xlf @@ -505,13 +505,13 @@ - A 'Value'-kind native type that supports the 'CallerAllocatedBuffer' feature must provide a two-parameter constructor taking the managed type and a 'Span<byte>' as parameters - A 'Value'-kind native type that supports the 'CallerAllocatedBuffer' feature must provide a two-parameter constructor taking the managed type and a 'Span<byte>' as parameters + A 'Value'-kind native type that supports the 'CallerAllocatedBuffer' feature must provide a two-parameter constructor taking the managed type and a 'Span' of an 'unmanaged' type as parameters + A 'Value'-kind native type that supports the 'CallerAllocatedBuffer' feature must provide a two-parameter constructor taking the managed type and a 'Span' of an 'unmanaged' type as parameters - The type '{0}' specifies that it supports 'In' marshalling with the 'CallerAllocatedBuffer' feature for '{1}' but does not provide a one-parameter constructor that takes a '{1}' and 'Span<byte>' as parameters - The type '{0}' specifies that it supports 'In' marshalling with the 'CallerAllocatedBuffer' feature for '{1}' but does not provide a one-parameter constructor that takes a '{1}' and 'Span<byte>' as parameters + The type '{0}' specifies that it supports 'In' marshalling with the 'CallerAllocatedBuffer' feature for '{1}' but does not provide a one-parameter constructor that takes a '{1}' and 'Span' of an 'unmanaged' type as parameters + The type '{0}' specifies that it supports 'In' marshalling with the 'CallerAllocatedBuffer' feature for '{1}' but does not provide a one-parameter constructor that takes a '{1}' and 'Span' of an 'unmanaged' type as parameters diff --git a/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Resources/xlf/Strings.de.xlf b/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Resources/xlf/Strings.de.xlf index 67dbab7b156..984a0641f70 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Resources/xlf/Strings.de.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Resources/xlf/Strings.de.xlf @@ -505,13 +505,13 @@ - A 'Value'-kind native type that supports the 'CallerAllocatedBuffer' feature must provide a two-parameter constructor taking the managed type and a 'Span<byte>' as parameters - A 'Value'-kind native type that supports the 'CallerAllocatedBuffer' feature must provide a two-parameter constructor taking the managed type and a 'Span<byte>' as parameters + A 'Value'-kind native type that supports the 'CallerAllocatedBuffer' feature must provide a two-parameter constructor taking the managed type and a 'Span' of an 'unmanaged' type as parameters + A 'Value'-kind native type that supports the 'CallerAllocatedBuffer' feature must provide a two-parameter constructor taking the managed type and a 'Span' of an 'unmanaged' type as parameters - The type '{0}' specifies that it supports 'In' marshalling with the 'CallerAllocatedBuffer' feature for '{1}' but does not provide a one-parameter constructor that takes a '{1}' and 'Span<byte>' as parameters - The type '{0}' specifies that it supports 'In' marshalling with the 'CallerAllocatedBuffer' feature for '{1}' but does not provide a one-parameter constructor that takes a '{1}' and 'Span<byte>' as parameters + The type '{0}' specifies that it supports 'In' marshalling with the 'CallerAllocatedBuffer' feature for '{1}' but does not provide a one-parameter constructor that takes a '{1}' and 'Span' of an 'unmanaged' type as parameters + The type '{0}' specifies that it supports 'In' marshalling with the 'CallerAllocatedBuffer' feature for '{1}' but does not provide a one-parameter constructor that takes a '{1}' and 'Span' of an 'unmanaged' type as parameters diff --git a/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Resources/xlf/Strings.es.xlf b/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Resources/xlf/Strings.es.xlf index b9e8c6e50e3..72aa666bf89 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Resources/xlf/Strings.es.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Resources/xlf/Strings.es.xlf @@ -505,13 +505,13 @@ - A 'Value'-kind native type that supports the 'CallerAllocatedBuffer' feature must provide a two-parameter constructor taking the managed type and a 'Span<byte>' as parameters - A 'Value'-kind native type that supports the 'CallerAllocatedBuffer' feature must provide a two-parameter constructor taking the managed type and a 'Span<byte>' as parameters + A 'Value'-kind native type that supports the 'CallerAllocatedBuffer' feature must provide a two-parameter constructor taking the managed type and a 'Span' of an 'unmanaged' type as parameters + A 'Value'-kind native type that supports the 'CallerAllocatedBuffer' feature must provide a two-parameter constructor taking the managed type and a 'Span' of an 'unmanaged' type as parameters - The type '{0}' specifies that it supports 'In' marshalling with the 'CallerAllocatedBuffer' feature for '{1}' but does not provide a one-parameter constructor that takes a '{1}' and 'Span<byte>' as parameters - The type '{0}' specifies that it supports 'In' marshalling with the 'CallerAllocatedBuffer' feature for '{1}' but does not provide a one-parameter constructor that takes a '{1}' and 'Span<byte>' as parameters + The type '{0}' specifies that it supports 'In' marshalling with the 'CallerAllocatedBuffer' feature for '{1}' but does not provide a one-parameter constructor that takes a '{1}' and 'Span' of an 'unmanaged' type as parameters + The type '{0}' specifies that it supports 'In' marshalling with the 'CallerAllocatedBuffer' feature for '{1}' but does not provide a one-parameter constructor that takes a '{1}' and 'Span' of an 'unmanaged' type as parameters diff --git a/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Resources/xlf/Strings.fr.xlf b/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Resources/xlf/Strings.fr.xlf index c61bde6083f..367d391814f 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Resources/xlf/Strings.fr.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Resources/xlf/Strings.fr.xlf @@ -505,13 +505,13 @@ - A 'Value'-kind native type that supports the 'CallerAllocatedBuffer' feature must provide a two-parameter constructor taking the managed type and a 'Span<byte>' as parameters - A 'Value'-kind native type that supports the 'CallerAllocatedBuffer' feature must provide a two-parameter constructor taking the managed type and a 'Span<byte>' as parameters + A 'Value'-kind native type that supports the 'CallerAllocatedBuffer' feature must provide a two-parameter constructor taking the managed type and a 'Span' of an 'unmanaged' type as parameters + A 'Value'-kind native type that supports the 'CallerAllocatedBuffer' feature must provide a two-parameter constructor taking the managed type and a 'Span' of an 'unmanaged' type as parameters - The type '{0}' specifies that it supports 'In' marshalling with the 'CallerAllocatedBuffer' feature for '{1}' but does not provide a one-parameter constructor that takes a '{1}' and 'Span<byte>' as parameters - The type '{0}' specifies that it supports 'In' marshalling with the 'CallerAllocatedBuffer' feature for '{1}' but does not provide a one-parameter constructor that takes a '{1}' and 'Span<byte>' as parameters + The type '{0}' specifies that it supports 'In' marshalling with the 'CallerAllocatedBuffer' feature for '{1}' but does not provide a one-parameter constructor that takes a '{1}' and 'Span' of an 'unmanaged' type as parameters + The type '{0}' specifies that it supports 'In' marshalling with the 'CallerAllocatedBuffer' feature for '{1}' but does not provide a one-parameter constructor that takes a '{1}' and 'Span' of an 'unmanaged' type as parameters diff --git a/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Resources/xlf/Strings.it.xlf b/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Resources/xlf/Strings.it.xlf index 62f494b1491..b5fb9f58099 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Resources/xlf/Strings.it.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Resources/xlf/Strings.it.xlf @@ -505,13 +505,13 @@ - A 'Value'-kind native type that supports the 'CallerAllocatedBuffer' feature must provide a two-parameter constructor taking the managed type and a 'Span<byte>' as parameters - A 'Value'-kind native type that supports the 'CallerAllocatedBuffer' feature must provide a two-parameter constructor taking the managed type and a 'Span<byte>' as parameters + A 'Value'-kind native type that supports the 'CallerAllocatedBuffer' feature must provide a two-parameter constructor taking the managed type and a 'Span' of an 'unmanaged' type as parameters + A 'Value'-kind native type that supports the 'CallerAllocatedBuffer' feature must provide a two-parameter constructor taking the managed type and a 'Span' of an 'unmanaged' type as parameters - The type '{0}' specifies that it supports 'In' marshalling with the 'CallerAllocatedBuffer' feature for '{1}' but does not provide a one-parameter constructor that takes a '{1}' and 'Span<byte>' as parameters - The type '{0}' specifies that it supports 'In' marshalling with the 'CallerAllocatedBuffer' feature for '{1}' but does not provide a one-parameter constructor that takes a '{1}' and 'Span<byte>' as parameters + The type '{0}' specifies that it supports 'In' marshalling with the 'CallerAllocatedBuffer' feature for '{1}' but does not provide a one-parameter constructor that takes a '{1}' and 'Span' of an 'unmanaged' type as parameters + The type '{0}' specifies that it supports 'In' marshalling with the 'CallerAllocatedBuffer' feature for '{1}' but does not provide a one-parameter constructor that takes a '{1}' and 'Span' of an 'unmanaged' type as parameters diff --git a/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Resources/xlf/Strings.ja.xlf b/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Resources/xlf/Strings.ja.xlf index 62c9f095b3a..9d8fb27cbf9 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Resources/xlf/Strings.ja.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Resources/xlf/Strings.ja.xlf @@ -505,13 +505,13 @@ - A 'Value'-kind native type that supports the 'CallerAllocatedBuffer' feature must provide a two-parameter constructor taking the managed type and a 'Span<byte>' as parameters - A 'Value'-kind native type that supports the 'CallerAllocatedBuffer' feature must provide a two-parameter constructor taking the managed type and a 'Span<byte>' as parameters + A 'Value'-kind native type that supports the 'CallerAllocatedBuffer' feature must provide a two-parameter constructor taking the managed type and a 'Span' of an 'unmanaged' type as parameters + A 'Value'-kind native type that supports the 'CallerAllocatedBuffer' feature must provide a two-parameter constructor taking the managed type and a 'Span' of an 'unmanaged' type as parameters - The type '{0}' specifies that it supports 'In' marshalling with the 'CallerAllocatedBuffer' feature for '{1}' but does not provide a one-parameter constructor that takes a '{1}' and 'Span<byte>' as parameters - The type '{0}' specifies that it supports 'In' marshalling with the 'CallerAllocatedBuffer' feature for '{1}' but does not provide a one-parameter constructor that takes a '{1}' and 'Span<byte>' as parameters + The type '{0}' specifies that it supports 'In' marshalling with the 'CallerAllocatedBuffer' feature for '{1}' but does not provide a one-parameter constructor that takes a '{1}' and 'Span' of an 'unmanaged' type as parameters + The type '{0}' specifies that it supports 'In' marshalling with the 'CallerAllocatedBuffer' feature for '{1}' but does not provide a one-parameter constructor that takes a '{1}' and 'Span' of an 'unmanaged' type as parameters diff --git a/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Resources/xlf/Strings.ko.xlf b/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Resources/xlf/Strings.ko.xlf index adba6124afc..ea7da22607c 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Resources/xlf/Strings.ko.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Resources/xlf/Strings.ko.xlf @@ -505,13 +505,13 @@ - A 'Value'-kind native type that supports the 'CallerAllocatedBuffer' feature must provide a two-parameter constructor taking the managed type and a 'Span<byte>' as parameters - A 'Value'-kind native type that supports the 'CallerAllocatedBuffer' feature must provide a two-parameter constructor taking the managed type and a 'Span<byte>' as parameters + A 'Value'-kind native type that supports the 'CallerAllocatedBuffer' feature must provide a two-parameter constructor taking the managed type and a 'Span' of an 'unmanaged' type as parameters + A 'Value'-kind native type that supports the 'CallerAllocatedBuffer' feature must provide a two-parameter constructor taking the managed type and a 'Span' of an 'unmanaged' type as parameters - The type '{0}' specifies that it supports 'In' marshalling with the 'CallerAllocatedBuffer' feature for '{1}' but does not provide a one-parameter constructor that takes a '{1}' and 'Span<byte>' as parameters - The type '{0}' specifies that it supports 'In' marshalling with the 'CallerAllocatedBuffer' feature for '{1}' but does not provide a one-parameter constructor that takes a '{1}' and 'Span<byte>' as parameters + The type '{0}' specifies that it supports 'In' marshalling with the 'CallerAllocatedBuffer' feature for '{1}' but does not provide a one-parameter constructor that takes a '{1}' and 'Span' of an 'unmanaged' type as parameters + The type '{0}' specifies that it supports 'In' marshalling with the 'CallerAllocatedBuffer' feature for '{1}' but does not provide a one-parameter constructor that takes a '{1}' and 'Span' of an 'unmanaged' type as parameters diff --git a/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Resources/xlf/Strings.pl.xlf b/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Resources/xlf/Strings.pl.xlf index cc87c74accc..b36c9c56df7 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Resources/xlf/Strings.pl.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Resources/xlf/Strings.pl.xlf @@ -505,13 +505,13 @@ - A 'Value'-kind native type that supports the 'CallerAllocatedBuffer' feature must provide a two-parameter constructor taking the managed type and a 'Span<byte>' as parameters - A 'Value'-kind native type that supports the 'CallerAllocatedBuffer' feature must provide a two-parameter constructor taking the managed type and a 'Span<byte>' as parameters + A 'Value'-kind native type that supports the 'CallerAllocatedBuffer' feature must provide a two-parameter constructor taking the managed type and a 'Span' of an 'unmanaged' type as parameters + A 'Value'-kind native type that supports the 'CallerAllocatedBuffer' feature must provide a two-parameter constructor taking the managed type and a 'Span' of an 'unmanaged' type as parameters - The type '{0}' specifies that it supports 'In' marshalling with the 'CallerAllocatedBuffer' feature for '{1}' but does not provide a one-parameter constructor that takes a '{1}' and 'Span<byte>' as parameters - The type '{0}' specifies that it supports 'In' marshalling with the 'CallerAllocatedBuffer' feature for '{1}' but does not provide a one-parameter constructor that takes a '{1}' and 'Span<byte>' as parameters + The type '{0}' specifies that it supports 'In' marshalling with the 'CallerAllocatedBuffer' feature for '{1}' but does not provide a one-parameter constructor that takes a '{1}' and 'Span' of an 'unmanaged' type as parameters + The type '{0}' specifies that it supports 'In' marshalling with the 'CallerAllocatedBuffer' feature for '{1}' but does not provide a one-parameter constructor that takes a '{1}' and 'Span' of an 'unmanaged' type as parameters diff --git a/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Resources/xlf/Strings.pt-BR.xlf b/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Resources/xlf/Strings.pt-BR.xlf index a355eb968cb..c6f9dbe8881 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Resources/xlf/Strings.pt-BR.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Resources/xlf/Strings.pt-BR.xlf @@ -505,13 +505,13 @@ - A 'Value'-kind native type that supports the 'CallerAllocatedBuffer' feature must provide a two-parameter constructor taking the managed type and a 'Span<byte>' as parameters - A 'Value'-kind native type that supports the 'CallerAllocatedBuffer' feature must provide a two-parameter constructor taking the managed type and a 'Span<byte>' as parameters + A 'Value'-kind native type that supports the 'CallerAllocatedBuffer' feature must provide a two-parameter constructor taking the managed type and a 'Span' of an 'unmanaged' type as parameters + A 'Value'-kind native type that supports the 'CallerAllocatedBuffer' feature must provide a two-parameter constructor taking the managed type and a 'Span' of an 'unmanaged' type as parameters - The type '{0}' specifies that it supports 'In' marshalling with the 'CallerAllocatedBuffer' feature for '{1}' but does not provide a one-parameter constructor that takes a '{1}' and 'Span<byte>' as parameters - The type '{0}' specifies that it supports 'In' marshalling with the 'CallerAllocatedBuffer' feature for '{1}' but does not provide a one-parameter constructor that takes a '{1}' and 'Span<byte>' as parameters + The type '{0}' specifies that it supports 'In' marshalling with the 'CallerAllocatedBuffer' feature for '{1}' but does not provide a one-parameter constructor that takes a '{1}' and 'Span' of an 'unmanaged' type as parameters + The type '{0}' specifies that it supports 'In' marshalling with the 'CallerAllocatedBuffer' feature for '{1}' but does not provide a one-parameter constructor that takes a '{1}' and 'Span' of an 'unmanaged' type as parameters diff --git a/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Resources/xlf/Strings.ru.xlf b/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Resources/xlf/Strings.ru.xlf index 9fed260cc5f..f074e7239a5 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Resources/xlf/Strings.ru.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Resources/xlf/Strings.ru.xlf @@ -505,13 +505,13 @@ - A 'Value'-kind native type that supports the 'CallerAllocatedBuffer' feature must provide a two-parameter constructor taking the managed type and a 'Span<byte>' as parameters - A 'Value'-kind native type that supports the 'CallerAllocatedBuffer' feature must provide a two-parameter constructor taking the managed type and a 'Span<byte>' as parameters + A 'Value'-kind native type that supports the 'CallerAllocatedBuffer' feature must provide a two-parameter constructor taking the managed type and a 'Span' of an 'unmanaged' type as parameters + A 'Value'-kind native type that supports the 'CallerAllocatedBuffer' feature must provide a two-parameter constructor taking the managed type and a 'Span' of an 'unmanaged' type as parameters - The type '{0}' specifies that it supports 'In' marshalling with the 'CallerAllocatedBuffer' feature for '{1}' but does not provide a one-parameter constructor that takes a '{1}' and 'Span<byte>' as parameters - The type '{0}' specifies that it supports 'In' marshalling with the 'CallerAllocatedBuffer' feature for '{1}' but does not provide a one-parameter constructor that takes a '{1}' and 'Span<byte>' as parameters + The type '{0}' specifies that it supports 'In' marshalling with the 'CallerAllocatedBuffer' feature for '{1}' but does not provide a one-parameter constructor that takes a '{1}' and 'Span' of an 'unmanaged' type as parameters + The type '{0}' specifies that it supports 'In' marshalling with the 'CallerAllocatedBuffer' feature for '{1}' but does not provide a one-parameter constructor that takes a '{1}' and 'Span' of an 'unmanaged' type as parameters diff --git a/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Resources/xlf/Strings.tr.xlf b/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Resources/xlf/Strings.tr.xlf index 6598f924458..9b870faecab 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Resources/xlf/Strings.tr.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Resources/xlf/Strings.tr.xlf @@ -505,13 +505,13 @@ - A 'Value'-kind native type that supports the 'CallerAllocatedBuffer' feature must provide a two-parameter constructor taking the managed type and a 'Span<byte>' as parameters - A 'Value'-kind native type that supports the 'CallerAllocatedBuffer' feature must provide a two-parameter constructor taking the managed type and a 'Span<byte>' as parameters + A 'Value'-kind native type that supports the 'CallerAllocatedBuffer' feature must provide a two-parameter constructor taking the managed type and a 'Span' of an 'unmanaged' type as parameters + A 'Value'-kind native type that supports the 'CallerAllocatedBuffer' feature must provide a two-parameter constructor taking the managed type and a 'Span' of an 'unmanaged' type as parameters - The type '{0}' specifies that it supports 'In' marshalling with the 'CallerAllocatedBuffer' feature for '{1}' but does not provide a one-parameter constructor that takes a '{1}' and 'Span<byte>' as parameters - The type '{0}' specifies that it supports 'In' marshalling with the 'CallerAllocatedBuffer' feature for '{1}' but does not provide a one-parameter constructor that takes a '{1}' and 'Span<byte>' as parameters + The type '{0}' specifies that it supports 'In' marshalling with the 'CallerAllocatedBuffer' feature for '{1}' but does not provide a one-parameter constructor that takes a '{1}' and 'Span' of an 'unmanaged' type as parameters + The type '{0}' specifies that it supports 'In' marshalling with the 'CallerAllocatedBuffer' feature for '{1}' but does not provide a one-parameter constructor that takes a '{1}' and 'Span' of an 'unmanaged' type as parameters diff --git a/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Resources/xlf/Strings.zh-Hans.xlf b/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Resources/xlf/Strings.zh-Hans.xlf index d84e6dc034b..8c44fff953d 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Resources/xlf/Strings.zh-Hans.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Resources/xlf/Strings.zh-Hans.xlf @@ -505,13 +505,13 @@ - A 'Value'-kind native type that supports the 'CallerAllocatedBuffer' feature must provide a two-parameter constructor taking the managed type and a 'Span<byte>' as parameters - A 'Value'-kind native type that supports the 'CallerAllocatedBuffer' feature must provide a two-parameter constructor taking the managed type and a 'Span<byte>' as parameters + A 'Value'-kind native type that supports the 'CallerAllocatedBuffer' feature must provide a two-parameter constructor taking the managed type and a 'Span' of an 'unmanaged' type as parameters + A 'Value'-kind native type that supports the 'CallerAllocatedBuffer' feature must provide a two-parameter constructor taking the managed type and a 'Span' of an 'unmanaged' type as parameters - The type '{0}' specifies that it supports 'In' marshalling with the 'CallerAllocatedBuffer' feature for '{1}' but does not provide a one-parameter constructor that takes a '{1}' and 'Span<byte>' as parameters - The type '{0}' specifies that it supports 'In' marshalling with the 'CallerAllocatedBuffer' feature for '{1}' but does not provide a one-parameter constructor that takes a '{1}' and 'Span<byte>' as parameters + The type '{0}' specifies that it supports 'In' marshalling with the 'CallerAllocatedBuffer' feature for '{1}' but does not provide a one-parameter constructor that takes a '{1}' and 'Span' of an 'unmanaged' type as parameters + The type '{0}' specifies that it supports 'In' marshalling with the 'CallerAllocatedBuffer' feature for '{1}' but does not provide a one-parameter constructor that takes a '{1}' and 'Span' of an 'unmanaged' type as parameters diff --git a/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Resources/xlf/Strings.zh-Hant.xlf b/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Resources/xlf/Strings.zh-Hant.xlf index 835e269137a..fcbb1000254 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Resources/xlf/Strings.zh-Hant.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/LibraryImportGenerator/Resources/xlf/Strings.zh-Hant.xlf @@ -505,13 +505,13 @@ - A 'Value'-kind native type that supports the 'CallerAllocatedBuffer' feature must provide a two-parameter constructor taking the managed type and a 'Span<byte>' as parameters - A 'Value'-kind native type that supports the 'CallerAllocatedBuffer' feature must provide a two-parameter constructor taking the managed type and a 'Span<byte>' as parameters + A 'Value'-kind native type that supports the 'CallerAllocatedBuffer' feature must provide a two-parameter constructor taking the managed type and a 'Span' of an 'unmanaged' type as parameters + A 'Value'-kind native type that supports the 'CallerAllocatedBuffer' feature must provide a two-parameter constructor taking the managed type and a 'Span' of an 'unmanaged' type as parameters - The type '{0}' specifies that it supports 'In' marshalling with the 'CallerAllocatedBuffer' feature for '{1}' but does not provide a one-parameter constructor that takes a '{1}' and 'Span<byte>' as parameters - The type '{0}' specifies that it supports 'In' marshalling with the 'CallerAllocatedBuffer' feature for '{1}' but does not provide a one-parameter constructor that takes a '{1}' and 'Span<byte>' as parameters + The type '{0}' specifies that it supports 'In' marshalling with the 'CallerAllocatedBuffer' feature for '{1}' but does not provide a one-parameter constructor that takes a '{1}' and 'Span' of an 'unmanaged' type as parameters + The type '{0}' specifies that it supports 'In' marshalling with the 'CallerAllocatedBuffer' feature for '{1}' but does not provide a one-parameter constructor that takes a '{1}' and 'Span' of an 'unmanaged' type as parameters diff --git a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/ManagedTypeInfo.cs b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/ManagedTypeInfo.cs index 2151a1a0dc4..57d4617eccd 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/ManagedTypeInfo.cs +++ b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/ManagedTypeInfo.cs @@ -51,6 +51,7 @@ public static ManagedTypeInfo CreateTypeInfoForTypeSymbol(ITypeSymbol type) public sealed record SpecialTypeInfo(string FullTypeName, string DiagnosticFormattedName, SpecialType SpecialType) : ManagedTypeInfo(FullTypeName, DiagnosticFormattedName) { + public static readonly SpecialTypeInfo Byte = new("byte", "byte", SpecialType.System_Void); public static readonly SpecialTypeInfo Int32 = new("int", "int", SpecialType.System_Int32); public static readonly SpecialTypeInfo Void = new("void", "void", SpecialType.System_Void); diff --git a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/ManualTypeMarshallingHelper.cs b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/ManualTypeMarshallingHelper.cs index 3b190b6ad04..f636f96d9fa 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/ManualTypeMarshallingHelper.cs +++ b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/ManualTypeMarshallingHelper.cs @@ -194,19 +194,37 @@ public static bool HasToManagedMethod(ITypeSymbol nativeType, ITypeSymbol manage public static bool IsCallerAllocatedSpanConstructor( IMethodSymbol ctor, ITypeSymbol managedType, - ITypeSymbol spanOfByte, - CustomTypeMarshallerKind variant) + ITypeSymbol spanOfT, + CustomTypeMarshallerKind variant, + out ITypeSymbol? spanElementType) { + spanElementType = null; if (variant == CustomTypeMarshallerKind.LinearCollection) { return ctor.Parameters.Length == 3 - && SymbolEqualityComparer.Default.Equals(managedType, ctor.Parameters[0].Type) - && SymbolEqualityComparer.Default.Equals(spanOfByte, ctor.Parameters[1].Type) - && ctor.Parameters[2].Type.SpecialType == SpecialType.System_Int32; + && SymbolEqualityComparer.Default.Equals(managedType, ctor.Parameters[0].Type) + && IsSpanOfUnmanagedType(ctor.Parameters[1].Type, spanOfT, out spanElementType) + && spanElementType.SpecialType == SpecialType.System_Byte + && ctor.Parameters[2].Type.SpecialType == SpecialType.System_Int32; } return ctor.Parameters.Length == 2 && SymbolEqualityComparer.Default.Equals(managedType, ctor.Parameters[0].Type) - && SymbolEqualityComparer.Default.Equals(spanOfByte, ctor.Parameters[1].Type); + && IsSpanOfUnmanagedType(ctor.Parameters[1].Type, spanOfT, out spanElementType); + + static bool IsSpanOfUnmanagedType(ITypeSymbol typeToCheck, ITypeSymbol spanOfT, out ITypeSymbol? typeArgument) + { + typeArgument = null; + if (typeToCheck is INamedTypeSymbol namedType + && SymbolEqualityComparer.Default.Equals(spanOfT, namedType.ConstructedFrom) + && namedType.TypeArguments.Length == 1 + && namedType.TypeArguments[0].IsUnmanagedType) + { + typeArgument = namedType.TypeArguments[0]; + return true; + } + + return false; + } } public static IMethodSymbol? FindGetPinnableReference(ITypeSymbol type) diff --git a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/AttributedMarshallingModelGeneratorFactory.cs b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/AttributedMarshallingModelGeneratorFactory.cs index 9243a2ed0ec..95bf75c7a5b 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/AttributedMarshallingModelGeneratorFactory.cs +++ b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/AttributedMarshallingModelGeneratorFactory.cs @@ -165,7 +165,7 @@ private IMarshallingGenerator CreateCustomNativeTypeMarshaller(TypePositionInfo { throw new MarshallingNotSupportedException(info, context); } - marshallingStrategy = new StackallocOptimizationMarshalling(marshallingStrategy, marshalInfo.BufferSize.Value); + marshallingStrategy = new StackallocOptimizationMarshalling(marshallingStrategy, marshalInfo.BufferElementType.Syntax, marshalInfo.BufferSize.Value); } if ((marshalInfo.MarshallingFeatures & CustomTypeMarshallerFeatures.UnmanagedResources) != 0) diff --git a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/ICustomNativeTypeMarshallingStrategy.cs b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/ICustomNativeTypeMarshallingStrategy.cs index 41fb36247c9..355ff6cdb09 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/ICustomNativeTypeMarshallingStrategy.cs +++ b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/ICustomNativeTypeMarshallingStrategy.cs @@ -252,11 +252,13 @@ public IEnumerable GeneratePinStatements(TypePositionInfo info, internal sealed class StackallocOptimizationMarshalling : ICustomNativeTypeMarshallingStrategy { private readonly ICustomNativeTypeMarshallingStrategy _innerMarshaller; + private readonly TypeSyntax _bufferElementType; private readonly int _bufferSize; - public StackallocOptimizationMarshalling(ICustomNativeTypeMarshallingStrategy innerMarshaller, int bufferSize) + public StackallocOptimizationMarshalling(ICustomNativeTypeMarshallingStrategy innerMarshaller, TypeSyntax bufferElementType, int bufferSize) { _innerMarshaller = innerMarshaller; + _bufferElementType = bufferElementType; _bufferSize = bufferSize; } @@ -274,16 +276,16 @@ public IEnumerable GenerateMarshalStatements(TypePositionInfo i { if (StackAllocOptimizationValid(info, context)) { - // byte* __stackptr = stackalloc byte[<_bufferSize>]; + // * __stackptr = stackalloc [<_bufferSize>]; yield return LocalDeclarationStatement( VariableDeclaration( - PointerType(PredefinedType(Token(SyntaxKind.ByteKeyword))), + PointerType(_bufferElementType), SingletonSeparatedList( VariableDeclarator(GetStackAllocPointerIdentifier(info, context)) .WithInitializer(EqualsValueClause( StackAllocArrayCreationExpression( ArrayType( - PredefinedType(Token(SyntaxKind.ByteKeyword)), + _bufferElementType, SingletonList(ArrayRankSpecifier(SingletonSeparatedList( LiteralExpression(SyntaxKind.NumericLiteralExpression, Literal(_bufferSize)) )))))))))); @@ -332,7 +334,7 @@ public IEnumerable GetNativeTypeConstructorArguments(TypePositio ObjectCreationExpression( GenericName(Identifier(TypeNames.System_Span), TypeArgumentList(SingletonSeparatedList( - PredefinedType(Token(SyntaxKind.ByteKeyword)))))) + _bufferElementType)))) .WithArgumentList( ArgumentList(SeparatedList(new ArgumentSyntax[] { diff --git a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/MarshallingAttributeInfo.cs b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/MarshallingAttributeInfo.cs index e78ae6d0f95..3e3e79b6c5a 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/MarshallingAttributeInfo.cs +++ b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/MarshallingAttributeInfo.cs @@ -143,6 +143,7 @@ public enum CustomTypeMarshallerPinning CustomTypeMarshallerFeatures MarshallingFeatures, CustomTypeMarshallerPinning PinningFeatures, bool UseDefaultMarshalling, + ManagedTypeInfo? BufferElementType, int? BufferSize) : MarshallingInfo; /// @@ -178,6 +179,7 @@ public enum CustomTypeMarshallerPinning MarshallingFeatures, PinningFeatures, UseDefaultMarshalling, + SpecialTypeInfo.Byte, BufferSize ); @@ -672,6 +674,26 @@ private CountInfo CreateCountInfo(AttributeData marshalUsingData, ImmutableHashS GetMarshallingInfo(elementType, useSiteAttributes, indirectionLevel + 1, inspectedElements, ref maxIndirectionDepthUsed)); } + ManagedTypeInfo? bufferElementTypeInfo = null; + if (customTypeMarshallerData.Value.Features.HasFlag(CustomTypeMarshallerFeatures.CallerAllocatedBuffer)) + { + ITypeSymbol? bufferElementType = null; + INamedTypeSymbol spanOfT = _compilation.GetTypeByMetadataName(TypeNames.System_Span_Metadata)!; + foreach (IMethodSymbol ctor in nativeType.Constructors) + { + if (ManualTypeMarshallingHelper.IsCallerAllocatedSpanConstructor(ctor, type, spanOfT, customTypeMarshallerData.Value.Kind, out bufferElementType)) + break; + } + + if (bufferElementType is null) + { + _diagnostics.ReportInvalidMarshallingAttributeInfo(attrData, nameof(SR.ValueInCallerAllocatedBufferRequiresSpanConstructorMessage), nativeType.ToDisplayString(), type.ToDisplayString()); + return NoMarshallingInfo.Instance; + } + + bufferElementTypeInfo = ManagedTypeInfo.CreateTypeInfoForTypeSymbol(bufferElementType); + } + return new NativeMarshallingAttributeInfo( ManagedTypeInfo.CreateTypeInfoForTypeSymbol(nativeType), toNativeValueMethod is not null ? ManagedTypeInfo.CreateTypeInfoForTypeSymbol(toNativeValueMethod.ReturnType) : null, @@ -679,6 +701,7 @@ private CountInfo CreateCountInfo(AttributeData marshalUsingData, ImmutableHashS customTypeMarshallerData.Value.Features, pinning, UseDefaultMarshalling: !isMarshalUsingAttribute, + bufferElementTypeInfo, customTypeMarshallerData.Value.BufferSize); } diff --git a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Resources/Strings.resx b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Resources/Strings.resx index 2097f8a82ec..d2af81aae71 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Resources/Strings.resx +++ b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Resources/Strings.resx @@ -1,17 +1,17 @@  - @@ -198,4 +198,7 @@ Runtime marshalling must be disabled in this project by applying the 'System.Runtime.InteropServices.DisableRuntimeMarshallingAttribute' to the assembly to enable marshalling this type. + + The type '{0}' specifies that it supports 'In' marshalling with the 'CallerAllocatedBuffer' feature for '{1}' but does not provide a one-parameter constructor that takes a '{1}' and 'Span' of an 'unmanaged' type as parameters + \ No newline at end of file diff --git a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Resources/xlf/Strings.cs.xlf b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Resources/xlf/Strings.cs.xlf index a61cc27f811..91db3ad3cc3 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Resources/xlf/Strings.cs.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Resources/xlf/Strings.cs.xlf @@ -137,6 +137,11 @@ Specified type is not supported by source-generated P/Invokes + + The type '{0}' specifies that it supports 'In' marshalling with the 'CallerAllocatedBuffer' feature for '{1}' but does not provide a one-parameter constructor that takes a '{1}' and 'Span' of an 'unmanaged' type as parameters + The type '{0}' specifies that it supports 'In' marshalling with the 'CallerAllocatedBuffer' feature for '{1}' but does not provide a one-parameter constructor that takes a '{1}' and 'Span' of an 'unmanaged' type as parameters + + \ No newline at end of file diff --git a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Resources/xlf/Strings.de.xlf b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Resources/xlf/Strings.de.xlf index e2e8d52edae..8a5b48adaec 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Resources/xlf/Strings.de.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Resources/xlf/Strings.de.xlf @@ -137,6 +137,11 @@ Specified type is not supported by source-generated P/Invokes + + The type '{0}' specifies that it supports 'In' marshalling with the 'CallerAllocatedBuffer' feature for '{1}' but does not provide a one-parameter constructor that takes a '{1}' and 'Span' of an 'unmanaged' type as parameters + The type '{0}' specifies that it supports 'In' marshalling with the 'CallerAllocatedBuffer' feature for '{1}' but does not provide a one-parameter constructor that takes a '{1}' and 'Span' of an 'unmanaged' type as parameters + + \ No newline at end of file diff --git a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Resources/xlf/Strings.es.xlf b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Resources/xlf/Strings.es.xlf index 13798c5a101..68e8bba5deb 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Resources/xlf/Strings.es.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Resources/xlf/Strings.es.xlf @@ -137,6 +137,11 @@ Specified type is not supported by source-generated P/Invokes + + The type '{0}' specifies that it supports 'In' marshalling with the 'CallerAllocatedBuffer' feature for '{1}' but does not provide a one-parameter constructor that takes a '{1}' and 'Span' of an 'unmanaged' type as parameters + The type '{0}' specifies that it supports 'In' marshalling with the 'CallerAllocatedBuffer' feature for '{1}' but does not provide a one-parameter constructor that takes a '{1}' and 'Span' of an 'unmanaged' type as parameters + + \ No newline at end of file diff --git a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Resources/xlf/Strings.fr.xlf b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Resources/xlf/Strings.fr.xlf index 44b14b340fb..2843754d999 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Resources/xlf/Strings.fr.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Resources/xlf/Strings.fr.xlf @@ -137,6 +137,11 @@ Specified type is not supported by source-generated P/Invokes + + The type '{0}' specifies that it supports 'In' marshalling with the 'CallerAllocatedBuffer' feature for '{1}' but does not provide a one-parameter constructor that takes a '{1}' and 'Span' of an 'unmanaged' type as parameters + The type '{0}' specifies that it supports 'In' marshalling with the 'CallerAllocatedBuffer' feature for '{1}' but does not provide a one-parameter constructor that takes a '{1}' and 'Span' of an 'unmanaged' type as parameters + + \ No newline at end of file diff --git a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Resources/xlf/Strings.it.xlf b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Resources/xlf/Strings.it.xlf index 3464fd95557..e78cd51dd5b 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Resources/xlf/Strings.it.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Resources/xlf/Strings.it.xlf @@ -137,6 +137,11 @@ Specified type is not supported by source-generated P/Invokes + + The type '{0}' specifies that it supports 'In' marshalling with the 'CallerAllocatedBuffer' feature for '{1}' but does not provide a one-parameter constructor that takes a '{1}' and 'Span' of an 'unmanaged' type as parameters + The type '{0}' specifies that it supports 'In' marshalling with the 'CallerAllocatedBuffer' feature for '{1}' but does not provide a one-parameter constructor that takes a '{1}' and 'Span' of an 'unmanaged' type as parameters + + \ No newline at end of file diff --git a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Resources/xlf/Strings.ja.xlf b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Resources/xlf/Strings.ja.xlf index a955b300859..8e306237aaa 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Resources/xlf/Strings.ja.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Resources/xlf/Strings.ja.xlf @@ -137,6 +137,11 @@ Specified type is not supported by source-generated P/Invokes + + The type '{0}' specifies that it supports 'In' marshalling with the 'CallerAllocatedBuffer' feature for '{1}' but does not provide a one-parameter constructor that takes a '{1}' and 'Span' of an 'unmanaged' type as parameters + The type '{0}' specifies that it supports 'In' marshalling with the 'CallerAllocatedBuffer' feature for '{1}' but does not provide a one-parameter constructor that takes a '{1}' and 'Span' of an 'unmanaged' type as parameters + + \ No newline at end of file diff --git a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Resources/xlf/Strings.ko.xlf b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Resources/xlf/Strings.ko.xlf index db30b860d51..94c3d202315 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Resources/xlf/Strings.ko.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Resources/xlf/Strings.ko.xlf @@ -137,6 +137,11 @@ Specified type is not supported by source-generated P/Invokes + + The type '{0}' specifies that it supports 'In' marshalling with the 'CallerAllocatedBuffer' feature for '{1}' but does not provide a one-parameter constructor that takes a '{1}' and 'Span' of an 'unmanaged' type as parameters + The type '{0}' specifies that it supports 'In' marshalling with the 'CallerAllocatedBuffer' feature for '{1}' but does not provide a one-parameter constructor that takes a '{1}' and 'Span' of an 'unmanaged' type as parameters + + \ No newline at end of file diff --git a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Resources/xlf/Strings.pl.xlf b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Resources/xlf/Strings.pl.xlf index fdb876b0ff8..babb0c5af3a 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Resources/xlf/Strings.pl.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Resources/xlf/Strings.pl.xlf @@ -137,6 +137,11 @@ Specified type is not supported by source-generated P/Invokes + + The type '{0}' specifies that it supports 'In' marshalling with the 'CallerAllocatedBuffer' feature for '{1}' but does not provide a one-parameter constructor that takes a '{1}' and 'Span' of an 'unmanaged' type as parameters + The type '{0}' specifies that it supports 'In' marshalling with the 'CallerAllocatedBuffer' feature for '{1}' but does not provide a one-parameter constructor that takes a '{1}' and 'Span' of an 'unmanaged' type as parameters + + \ No newline at end of file diff --git a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Resources/xlf/Strings.pt-BR.xlf b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Resources/xlf/Strings.pt-BR.xlf index 7b8bcf88be0..72ddb089d98 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Resources/xlf/Strings.pt-BR.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Resources/xlf/Strings.pt-BR.xlf @@ -137,6 +137,11 @@ Specified type is not supported by source-generated P/Invokes + + The type '{0}' specifies that it supports 'In' marshalling with the 'CallerAllocatedBuffer' feature for '{1}' but does not provide a one-parameter constructor that takes a '{1}' and 'Span' of an 'unmanaged' type as parameters + The type '{0}' specifies that it supports 'In' marshalling with the 'CallerAllocatedBuffer' feature for '{1}' but does not provide a one-parameter constructor that takes a '{1}' and 'Span' of an 'unmanaged' type as parameters + + \ No newline at end of file diff --git a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Resources/xlf/Strings.ru.xlf b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Resources/xlf/Strings.ru.xlf index e43fc3c65fb..7e61c42c73a 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Resources/xlf/Strings.ru.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Resources/xlf/Strings.ru.xlf @@ -137,6 +137,11 @@ Specified type is not supported by source-generated P/Invokes + + The type '{0}' specifies that it supports 'In' marshalling with the 'CallerAllocatedBuffer' feature for '{1}' but does not provide a one-parameter constructor that takes a '{1}' and 'Span' of an 'unmanaged' type as parameters + The type '{0}' specifies that it supports 'In' marshalling with the 'CallerAllocatedBuffer' feature for '{1}' but does not provide a one-parameter constructor that takes a '{1}' and 'Span' of an 'unmanaged' type as parameters + + \ No newline at end of file diff --git a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Resources/xlf/Strings.tr.xlf b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Resources/xlf/Strings.tr.xlf index 423b980c258..762c2a8df4b 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Resources/xlf/Strings.tr.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Resources/xlf/Strings.tr.xlf @@ -137,6 +137,11 @@ Specified type is not supported by source-generated P/Invokes + + The type '{0}' specifies that it supports 'In' marshalling with the 'CallerAllocatedBuffer' feature for '{1}' but does not provide a one-parameter constructor that takes a '{1}' and 'Span' of an 'unmanaged' type as parameters + The type '{0}' specifies that it supports 'In' marshalling with the 'CallerAllocatedBuffer' feature for '{1}' but does not provide a one-parameter constructor that takes a '{1}' and 'Span' of an 'unmanaged' type as parameters + + \ No newline at end of file diff --git a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Resources/xlf/Strings.zh-Hans.xlf b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Resources/xlf/Strings.zh-Hans.xlf index 47cbe134d44..424869bf951 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Resources/xlf/Strings.zh-Hans.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Resources/xlf/Strings.zh-Hans.xlf @@ -137,6 +137,11 @@ Specified type is not supported by source-generated P/Invokes + + The type '{0}' specifies that it supports 'In' marshalling with the 'CallerAllocatedBuffer' feature for '{1}' but does not provide a one-parameter constructor that takes a '{1}' and 'Span' of an 'unmanaged' type as parameters + The type '{0}' specifies that it supports 'In' marshalling with the 'CallerAllocatedBuffer' feature for '{1}' but does not provide a one-parameter constructor that takes a '{1}' and 'Span' of an 'unmanaged' type as parameters + + \ No newline at end of file diff --git a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Resources/xlf/Strings.zh-Hant.xlf b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Resources/xlf/Strings.zh-Hant.xlf index 62c4bcd5172..c113ba504de 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Resources/xlf/Strings.zh-Hant.xlf +++ b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Resources/xlf/Strings.zh-Hant.xlf @@ -137,6 +137,11 @@ Specified type is not supported by source-generated P/Invokes + + The type '{0}' specifies that it supports 'In' marshalling with the 'CallerAllocatedBuffer' feature for '{1}' but does not provide a one-parameter constructor that takes a '{1}' and 'Span' of an 'unmanaged' type as parameters + The type '{0}' specifies that it supports 'In' marshalling with the 'CallerAllocatedBuffer' feature for '{1}' but does not provide a one-parameter constructor that takes a '{1}' and 'Span' of an 'unmanaged' type as parameters + + \ No newline at end of file diff --git a/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/CustomTypeMarshallerFixerTests.cs b/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/CustomTypeMarshallerFixerTests.cs index 9707345179c..800a60ff48c 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/CustomTypeMarshallerFixerTests.cs +++ b/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/CustomTypeMarshallerFixerTests.cs @@ -983,6 +983,53 @@ struct Native await VerifyCS.VerifyCodeFixAsync(source, source); } + [Fact] + public async Task NativeTypeWithIncorrectStackallocConstructor_ReportsDiagnostic() + { + string source = @" +using System; +using System.Runtime.InteropServices; + +[NativeMarshalling(typeof(Native))] +class S +{ + public byte c; +} + +[CustomTypeMarshaller(typeof(S), Direction = CustomTypeMarshallerDirection.In, Features = CustomTypeMarshallerFeatures.CallerAllocatedBuffer, BufferSize = 0x100)] +struct {|#0:Native|} +{ + public Native(S managed) {} + public Native(S s, int i) {} + public Native(S s, Span buffer) {} +}"; + string fixedSource = @" +using System; +using System.Runtime.InteropServices; + +[NativeMarshalling(typeof(Native))] +class S +{ + public byte c; +} + +[CustomTypeMarshaller(typeof(S), Direction = CustomTypeMarshallerDirection.In, Features = CustomTypeMarshallerFeatures.CallerAllocatedBuffer, BufferSize = 0x100)] +struct Native +{ + public Native(S managed) {} + public Native(S s, int i) {} + public Native(S s, Span buffer) {} + + public Native(S managed, Span buffer) + { + throw new NotImplementedException(); + } +}"; + await VerifyCS.VerifyCodeFixAsync(source, + fixedSource, + VerifyCS.Diagnostic(ValueInCallerAllocatedBufferRequiresSpanConstructorRule).WithLocation(0).WithArguments("Native", "S")); + } + [Fact] public async Task NativeTypeWithOnlyStackallocConstructor_ReportsDiagnostic() { diff --git a/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/NonBlittable.cs b/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/NonBlittable.cs index 155edea1bc9..5697e7ad921 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/NonBlittable.cs +++ b/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/NonBlittable.cs @@ -132,11 +132,11 @@ public void FreeNative() private bool isNullString; public Utf16StringMarshaller(string str) - : this(str, default(Span)) + : this(str, default(Span)) { } - public Utf16StringMarshaller(string str, Span buffer) + public Utf16StringMarshaller(string str, Span buffer) { isNullString = false; if (str is null) @@ -147,8 +147,8 @@ public Utf16StringMarshaller(string str, Span buffer) } else if ((str.Length + 1) < buffer.Length) { - span = MemoryMarshal.Cast(buffer); - str.AsSpan().CopyTo(MemoryMarshal.Cast(buffer)); + span = buffer; + str.AsSpan().CopyTo(MemoryMarshal.Cast(buffer)); // Supplied memory is in an undefined state so ensure // there is a trailing null in the buffer. span[str.Length] = '\0'; @@ -192,7 +192,7 @@ public void FreeNative() Marshal.FreeCoTaskMem((IntPtr)allocated); } } - + [CustomTypeMarshaller(typeof(string), Features = CustomTypeMarshallerFeatures.UnmanagedResources | CustomTypeMarshallerFeatures.TwoStageMarshalling | CustomTypeMarshallerFeatures.CallerAllocatedBuffer, BufferSize = 0x100)] public unsafe ref struct Utf8StringMarshaller { diff --git a/src/samples/LibraryImportGeneratorSample/LibraryImportGeneratorSample.csproj b/src/samples/LibraryImportGeneratorSample/LibraryImportGeneratorSample.csproj index 146275ae0a2..47b102d4d34 100644 --- a/src/samples/LibraryImportGeneratorSample/LibraryImportGeneratorSample.csproj +++ b/src/samples/LibraryImportGeneratorSample/LibraryImportGeneratorSample.csproj @@ -6,6 +6,7 @@ true preview enable + false -- GitLab