未验证 提交 afc175f3 编写于 作者: E Elinor Fung 提交者: GitHub

Let CustomTypeMarshaller implementation use Span of unmanaged type for Value marshalling (#67172)

上级 bdbdaa8e
......@@ -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;
}
......
......@@ -354,10 +354,10 @@
<value>The specified custom marshaller direction for '{0}' is invalid</value>
</data>
<data name="ValueInCallerAllocatedBufferRequiresSpanConstructorDescription" xml:space="preserve">
<value>A 'Value'-kind native type that supports the 'CallerAllocatedBuffer' feature must provide a two-parameter constructor taking the managed type and a 'Span&lt;byte&gt;' as parameters</value>
<value>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</value>
</data>
<data name="ValueInCallerAllocatedBufferRequiresSpanConstructorMessage" xml:space="preserve">
<value>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&lt;byte&gt;' as parameters</value>
<value>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</value>
</data>
<data name="ValueInRequiresOneParameterConstructorDescription" xml:space="preserve">
<value>A 'Value'-kind native type must provide a one-parameter constructor taking the managed type as a parameter</value>
......
......@@ -505,13 +505,13 @@
<note />
</trans-unit>
<trans-unit id="ValueInCallerAllocatedBufferRequiresSpanConstructorDescription">
<source>A 'Value'-kind native type that supports the 'CallerAllocatedBuffer' feature must provide a two-parameter constructor taking the managed type and a 'Span&lt;byte&gt;' as parameters</source>
<target state="new">A 'Value'-kind native type that supports the 'CallerAllocatedBuffer' feature must provide a two-parameter constructor taking the managed type and a 'Span&lt;byte&gt;' as parameters</target>
<source>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</source>
<target state="new">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</target>
<note />
</trans-unit>
<trans-unit id="ValueInCallerAllocatedBufferRequiresSpanConstructorMessage">
<source>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&lt;byte&gt;' as parameters</source>
<target state="new">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&lt;byte&gt;' as parameters</target>
<source>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</source>
<target state="new">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</target>
<note />
</trans-unit>
<trans-unit id="ValueInRequiresOneParameterConstructorDescription">
......
......@@ -505,13 +505,13 @@
<note />
</trans-unit>
<trans-unit id="ValueInCallerAllocatedBufferRequiresSpanConstructorDescription">
<source>A 'Value'-kind native type that supports the 'CallerAllocatedBuffer' feature must provide a two-parameter constructor taking the managed type and a 'Span&lt;byte&gt;' as parameters</source>
<target state="new">A 'Value'-kind native type that supports the 'CallerAllocatedBuffer' feature must provide a two-parameter constructor taking the managed type and a 'Span&lt;byte&gt;' as parameters</target>
<source>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</source>
<target state="new">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</target>
<note />
</trans-unit>
<trans-unit id="ValueInCallerAllocatedBufferRequiresSpanConstructorMessage">
<source>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&lt;byte&gt;' as parameters</source>
<target state="new">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&lt;byte&gt;' as parameters</target>
<source>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</source>
<target state="new">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</target>
<note />
</trans-unit>
<trans-unit id="ValueInRequiresOneParameterConstructorDescription">
......
......@@ -505,13 +505,13 @@
<note />
</trans-unit>
<trans-unit id="ValueInCallerAllocatedBufferRequiresSpanConstructorDescription">
<source>A 'Value'-kind native type that supports the 'CallerAllocatedBuffer' feature must provide a two-parameter constructor taking the managed type and a 'Span&lt;byte&gt;' as parameters</source>
<target state="new">A 'Value'-kind native type that supports the 'CallerAllocatedBuffer' feature must provide a two-parameter constructor taking the managed type and a 'Span&lt;byte&gt;' as parameters</target>
<source>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</source>
<target state="new">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</target>
<note />
</trans-unit>
<trans-unit id="ValueInCallerAllocatedBufferRequiresSpanConstructorMessage">
<source>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&lt;byte&gt;' as parameters</source>
<target state="new">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&lt;byte&gt;' as parameters</target>
<source>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</source>
<target state="new">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</target>
<note />
</trans-unit>
<trans-unit id="ValueInRequiresOneParameterConstructorDescription">
......
......@@ -505,13 +505,13 @@
<note />
</trans-unit>
<trans-unit id="ValueInCallerAllocatedBufferRequiresSpanConstructorDescription">
<source>A 'Value'-kind native type that supports the 'CallerAllocatedBuffer' feature must provide a two-parameter constructor taking the managed type and a 'Span&lt;byte&gt;' as parameters</source>
<target state="new">A 'Value'-kind native type that supports the 'CallerAllocatedBuffer' feature must provide a two-parameter constructor taking the managed type and a 'Span&lt;byte&gt;' as parameters</target>
<source>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</source>
<target state="new">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</target>
<note />
</trans-unit>
<trans-unit id="ValueInCallerAllocatedBufferRequiresSpanConstructorMessage">
<source>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&lt;byte&gt;' as parameters</source>
<target state="new">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&lt;byte&gt;' as parameters</target>
<source>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</source>
<target state="new">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</target>
<note />
</trans-unit>
<trans-unit id="ValueInRequiresOneParameterConstructorDescription">
......
......@@ -505,13 +505,13 @@
<note />
</trans-unit>
<trans-unit id="ValueInCallerAllocatedBufferRequiresSpanConstructorDescription">
<source>A 'Value'-kind native type that supports the 'CallerAllocatedBuffer' feature must provide a two-parameter constructor taking the managed type and a 'Span&lt;byte&gt;' as parameters</source>
<target state="new">A 'Value'-kind native type that supports the 'CallerAllocatedBuffer' feature must provide a two-parameter constructor taking the managed type and a 'Span&lt;byte&gt;' as parameters</target>
<source>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</source>
<target state="new">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</target>
<note />
</trans-unit>
<trans-unit id="ValueInCallerAllocatedBufferRequiresSpanConstructorMessage">
<source>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&lt;byte&gt;' as parameters</source>
<target state="new">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&lt;byte&gt;' as parameters</target>
<source>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</source>
<target state="new">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</target>
<note />
</trans-unit>
<trans-unit id="ValueInRequiresOneParameterConstructorDescription">
......
......@@ -505,13 +505,13 @@
<note />
</trans-unit>
<trans-unit id="ValueInCallerAllocatedBufferRequiresSpanConstructorDescription">
<source>A 'Value'-kind native type that supports the 'CallerAllocatedBuffer' feature must provide a two-parameter constructor taking the managed type and a 'Span&lt;byte&gt;' as parameters</source>
<target state="new">A 'Value'-kind native type that supports the 'CallerAllocatedBuffer' feature must provide a two-parameter constructor taking the managed type and a 'Span&lt;byte&gt;' as parameters</target>
<source>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</source>
<target state="new">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</target>
<note />
</trans-unit>
<trans-unit id="ValueInCallerAllocatedBufferRequiresSpanConstructorMessage">
<source>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&lt;byte&gt;' as parameters</source>
<target state="new">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&lt;byte&gt;' as parameters</target>
<source>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</source>
<target state="new">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</target>
<note />
</trans-unit>
<trans-unit id="ValueInRequiresOneParameterConstructorDescription">
......
......@@ -505,13 +505,13 @@
<note />
</trans-unit>
<trans-unit id="ValueInCallerAllocatedBufferRequiresSpanConstructorDescription">
<source>A 'Value'-kind native type that supports the 'CallerAllocatedBuffer' feature must provide a two-parameter constructor taking the managed type and a 'Span&lt;byte&gt;' as parameters</source>
<target state="new">A 'Value'-kind native type that supports the 'CallerAllocatedBuffer' feature must provide a two-parameter constructor taking the managed type and a 'Span&lt;byte&gt;' as parameters</target>
<source>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</source>
<target state="new">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</target>
<note />
</trans-unit>
<trans-unit id="ValueInCallerAllocatedBufferRequiresSpanConstructorMessage">
<source>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&lt;byte&gt;' as parameters</source>
<target state="new">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&lt;byte&gt;' as parameters</target>
<source>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</source>
<target state="new">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</target>
<note />
</trans-unit>
<trans-unit id="ValueInRequiresOneParameterConstructorDescription">
......
......@@ -505,13 +505,13 @@
<note />
</trans-unit>
<trans-unit id="ValueInCallerAllocatedBufferRequiresSpanConstructorDescription">
<source>A 'Value'-kind native type that supports the 'CallerAllocatedBuffer' feature must provide a two-parameter constructor taking the managed type and a 'Span&lt;byte&gt;' as parameters</source>
<target state="new">A 'Value'-kind native type that supports the 'CallerAllocatedBuffer' feature must provide a two-parameter constructor taking the managed type and a 'Span&lt;byte&gt;' as parameters</target>
<source>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</source>
<target state="new">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</target>
<note />
</trans-unit>
<trans-unit id="ValueInCallerAllocatedBufferRequiresSpanConstructorMessage">
<source>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&lt;byte&gt;' as parameters</source>
<target state="new">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&lt;byte&gt;' as parameters</target>
<source>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</source>
<target state="new">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</target>
<note />
</trans-unit>
<trans-unit id="ValueInRequiresOneParameterConstructorDescription">
......
......@@ -505,13 +505,13 @@
<note />
</trans-unit>
<trans-unit id="ValueInCallerAllocatedBufferRequiresSpanConstructorDescription">
<source>A 'Value'-kind native type that supports the 'CallerAllocatedBuffer' feature must provide a two-parameter constructor taking the managed type and a 'Span&lt;byte&gt;' as parameters</source>
<target state="new">A 'Value'-kind native type that supports the 'CallerAllocatedBuffer' feature must provide a two-parameter constructor taking the managed type and a 'Span&lt;byte&gt;' as parameters</target>
<source>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</source>
<target state="new">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</target>
<note />
</trans-unit>
<trans-unit id="ValueInCallerAllocatedBufferRequiresSpanConstructorMessage">
<source>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&lt;byte&gt;' as parameters</source>
<target state="new">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&lt;byte&gt;' as parameters</target>
<source>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</source>
<target state="new">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</target>
<note />
</trans-unit>
<trans-unit id="ValueInRequiresOneParameterConstructorDescription">
......
......@@ -505,13 +505,13 @@
<note />
</trans-unit>
<trans-unit id="ValueInCallerAllocatedBufferRequiresSpanConstructorDescription">
<source>A 'Value'-kind native type that supports the 'CallerAllocatedBuffer' feature must provide a two-parameter constructor taking the managed type and a 'Span&lt;byte&gt;' as parameters</source>
<target state="new">A 'Value'-kind native type that supports the 'CallerAllocatedBuffer' feature must provide a two-parameter constructor taking the managed type and a 'Span&lt;byte&gt;' as parameters</target>
<source>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</source>
<target state="new">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</target>
<note />
</trans-unit>
<trans-unit id="ValueInCallerAllocatedBufferRequiresSpanConstructorMessage">
<source>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&lt;byte&gt;' as parameters</source>
<target state="new">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&lt;byte&gt;' as parameters</target>
<source>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</source>
<target state="new">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</target>
<note />
</trans-unit>
<trans-unit id="ValueInRequiresOneParameterConstructorDescription">
......
......@@ -505,13 +505,13 @@
<note />
</trans-unit>
<trans-unit id="ValueInCallerAllocatedBufferRequiresSpanConstructorDescription">
<source>A 'Value'-kind native type that supports the 'CallerAllocatedBuffer' feature must provide a two-parameter constructor taking the managed type and a 'Span&lt;byte&gt;' as parameters</source>
<target state="new">A 'Value'-kind native type that supports the 'CallerAllocatedBuffer' feature must provide a two-parameter constructor taking the managed type and a 'Span&lt;byte&gt;' as parameters</target>
<source>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</source>
<target state="new">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</target>
<note />
</trans-unit>
<trans-unit id="ValueInCallerAllocatedBufferRequiresSpanConstructorMessage">
<source>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&lt;byte&gt;' as parameters</source>
<target state="new">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&lt;byte&gt;' as parameters</target>
<source>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</source>
<target state="new">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</target>
<note />
</trans-unit>
<trans-unit id="ValueInRequiresOneParameterConstructorDescription">
......
......@@ -505,13 +505,13 @@
<note />
</trans-unit>
<trans-unit id="ValueInCallerAllocatedBufferRequiresSpanConstructorDescription">
<source>A 'Value'-kind native type that supports the 'CallerAllocatedBuffer' feature must provide a two-parameter constructor taking the managed type and a 'Span&lt;byte&gt;' as parameters</source>
<target state="new">A 'Value'-kind native type that supports the 'CallerAllocatedBuffer' feature must provide a two-parameter constructor taking the managed type and a 'Span&lt;byte&gt;' as parameters</target>
<source>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</source>
<target state="new">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</target>
<note />
</trans-unit>
<trans-unit id="ValueInCallerAllocatedBufferRequiresSpanConstructorMessage">
<source>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&lt;byte&gt;' as parameters</source>
<target state="new">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&lt;byte&gt;' as parameters</target>
<source>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</source>
<target state="new">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</target>
<note />
</trans-unit>
<trans-unit id="ValueInRequiresOneParameterConstructorDescription">
......
......@@ -505,13 +505,13 @@
<note />
</trans-unit>
<trans-unit id="ValueInCallerAllocatedBufferRequiresSpanConstructorDescription">
<source>A 'Value'-kind native type that supports the 'CallerAllocatedBuffer' feature must provide a two-parameter constructor taking the managed type and a 'Span&lt;byte&gt;' as parameters</source>
<target state="new">A 'Value'-kind native type that supports the 'CallerAllocatedBuffer' feature must provide a two-parameter constructor taking the managed type and a 'Span&lt;byte&gt;' as parameters</target>
<source>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</source>
<target state="new">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</target>
<note />
</trans-unit>
<trans-unit id="ValueInCallerAllocatedBufferRequiresSpanConstructorMessage">
<source>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&lt;byte&gt;' as parameters</source>
<target state="new">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&lt;byte&gt;' as parameters</target>
<source>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</source>
<target state="new">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</target>
<note />
</trans-unit>
<trans-unit id="ValueInRequiresOneParameterConstructorDescription">
......
......@@ -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);
......
......@@ -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)
......
......@@ -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)
......
......@@ -252,11 +252,13 @@ public IEnumerable<StatementSyntax> 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<StatementSyntax> GenerateMarshalStatements(TypePositionInfo i
{
if (StackAllocOptimizationValid(info, context))
{
// byte* <managedIdentifier>__stackptr = stackalloc byte[<_bufferSize>];
// <bufferElementType>* <managedIdentifier>__stackptr = stackalloc <bufferElementType>[<_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<ExpressionSyntax>(
LiteralExpression(SyntaxKind.NumericLiteralExpression, Literal(_bufferSize))
))))))))));
......@@ -332,7 +334,7 @@ public IEnumerable<ArgumentSyntax> GetNativeTypeConstructorArguments(TypePositio
ObjectCreationExpression(
GenericName(Identifier(TypeNames.System_Span),
TypeArgumentList(SingletonSeparatedList<TypeSyntax>(
PredefinedType(Token(SyntaxKind.ByteKeyword))))))
_bufferElementType))))
.WithArgumentList(
ArgumentList(SeparatedList(new ArgumentSyntax[]
{
......
......@@ -143,6 +143,7 @@ public enum CustomTypeMarshallerPinning
CustomTypeMarshallerFeatures MarshallingFeatures,
CustomTypeMarshallerPinning PinningFeatures,
bool UseDefaultMarshalling,
ManagedTypeInfo? BufferElementType,
int? BufferSize) : MarshallingInfo;
/// <summary>
......@@ -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);
}
......
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
......@@ -26,36 +26,36 @@
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
......@@ -198,4 +198,7 @@
<data name="RuntimeMarshallingMustBeDisabled" xml:space="preserve">
<value>Runtime marshalling must be disabled in this project by applying the 'System.Runtime.InteropServices.DisableRuntimeMarshallingAttribute' to the assembly to enable marshalling this type.</value>
</data>
<data name="ValueInCallerAllocatedBufferRequiresSpanConstructorMessage" xml:space="preserve">
<value>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</value>
</data>
</root>
\ No newline at end of file
......@@ -137,6 +137,11 @@
<target state="new">Specified type is not supported by source-generated P/Invokes</target>
<note />
</trans-unit>
<trans-unit id="ValueInCallerAllocatedBufferRequiresSpanConstructorMessage">
<source>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</source>
<target state="new">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</target>
<note />
</trans-unit>
</body>
</file>
</xliff>
\ No newline at end of file
......@@ -137,6 +137,11 @@
<target state="new">Specified type is not supported by source-generated P/Invokes</target>
<note />
</trans-unit>
<trans-unit id="ValueInCallerAllocatedBufferRequiresSpanConstructorMessage">
<source>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</source>
<target state="new">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</target>
<note />
</trans-unit>
</body>
</file>
</xliff>
\ No newline at end of file
......@@ -137,6 +137,11 @@
<target state="new">Specified type is not supported by source-generated P/Invokes</target>
<note />
</trans-unit>
<trans-unit id="ValueInCallerAllocatedBufferRequiresSpanConstructorMessage">
<source>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</source>
<target state="new">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</target>
<note />
</trans-unit>
</body>
</file>
</xliff>
\ No newline at end of file
......@@ -137,6 +137,11 @@
<target state="new">Specified type is not supported by source-generated P/Invokes</target>
<note />
</trans-unit>
<trans-unit id="ValueInCallerAllocatedBufferRequiresSpanConstructorMessage">
<source>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</source>
<target state="new">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</target>
<note />
</trans-unit>
</body>
</file>
</xliff>
\ No newline at end of file
......@@ -137,6 +137,11 @@
<target state="new">Specified type is not supported by source-generated P/Invokes</target>
<note />
</trans-unit>
<trans-unit id="ValueInCallerAllocatedBufferRequiresSpanConstructorMessage">
<source>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</source>
<target state="new">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</target>
<note />
</trans-unit>
</body>
</file>
</xliff>
\ No newline at end of file
......@@ -137,6 +137,11 @@
<target state="new">Specified type is not supported by source-generated P/Invokes</target>
<note />
</trans-unit>
<trans-unit id="ValueInCallerAllocatedBufferRequiresSpanConstructorMessage">
<source>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</source>
<target state="new">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</target>
<note />
</trans-unit>
</body>
</file>
</xliff>
\ No newline at end of file
......@@ -137,6 +137,11 @@
<target state="new">Specified type is not supported by source-generated P/Invokes</target>
<note />
</trans-unit>
<trans-unit id="ValueInCallerAllocatedBufferRequiresSpanConstructorMessage">
<source>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</source>
<target state="new">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</target>
<note />
</trans-unit>
</body>
</file>
</xliff>
\ No newline at end of file
......@@ -137,6 +137,11 @@
<target state="new">Specified type is not supported by source-generated P/Invokes</target>
<note />
</trans-unit>
<trans-unit id="ValueInCallerAllocatedBufferRequiresSpanConstructorMessage">
<source>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</source>
<target state="new">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</target>
<note />
</trans-unit>
</body>
</file>
</xliff>
\ No newline at end of file
......@@ -137,6 +137,11 @@
<target state="new">Specified type is not supported by source-generated P/Invokes</target>
<note />
</trans-unit>
<trans-unit id="ValueInCallerAllocatedBufferRequiresSpanConstructorMessage">
<source>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</source>
<target state="new">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</target>
<note />
</trans-unit>
</body>
</file>
</xliff>
\ No newline at end of file
......@@ -137,6 +137,11 @@
<target state="new">Specified type is not supported by source-generated P/Invokes</target>
<note />
</trans-unit>
<trans-unit id="ValueInCallerAllocatedBufferRequiresSpanConstructorMessage">
<source>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</source>
<target state="new">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</target>
<note />
</trans-unit>
</body>
</file>
</xliff>
\ No newline at end of file
......@@ -137,6 +137,11 @@
<target state="new">Specified type is not supported by source-generated P/Invokes</target>
<note />
</trans-unit>
<trans-unit id="ValueInCallerAllocatedBufferRequiresSpanConstructorMessage">
<source>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</source>
<target state="new">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</target>
<note />
</trans-unit>
</body>
</file>
</xliff>
\ No newline at end of file
......@@ -137,6 +137,11 @@
<target state="new">Specified type is not supported by source-generated P/Invokes</target>
<note />
</trans-unit>
<trans-unit id="ValueInCallerAllocatedBufferRequiresSpanConstructorMessage">
<source>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</source>
<target state="new">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</target>
<note />
</trans-unit>
</body>
</file>
</xliff>
\ No newline at end of file
......@@ -137,6 +137,11 @@
<target state="new">Specified type is not supported by source-generated P/Invokes</target>
<note />
</trans-unit>
<trans-unit id="ValueInCallerAllocatedBufferRequiresSpanConstructorMessage">
<source>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</source>
<target state="new">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</target>
<note />
</trans-unit>
</body>
</file>
</xliff>
\ No newline at end of file
......@@ -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<object> 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<object> buffer) {}
public Native(S managed, Span<byte> buffer)
{
throw new NotImplementedException();
}
}";
await VerifyCS.VerifyCodeFixAsync(source,
fixedSource,
VerifyCS.Diagnostic(ValueInCallerAllocatedBufferRequiresSpanConstructorRule).WithLocation(0).WithArguments("Native", "S"));
}
[Fact]
public async Task NativeTypeWithOnlyStackallocConstructor_ReportsDiagnostic()
{
......
......@@ -132,11 +132,11 @@ public void FreeNative()
private bool isNullString;
public Utf16StringMarshaller(string str)
: this(str, default(Span<byte>))
: this(str, default(Span<ushort>))
{
}
public Utf16StringMarshaller(string str, Span<byte> buffer)
public Utf16StringMarshaller(string str, Span<ushort> buffer)
{
isNullString = false;
if (str is null)
......@@ -147,8 +147,8 @@ public Utf16StringMarshaller(string str, Span<byte> buffer)
}
else if ((str.Length + 1) < buffer.Length)
{
span = MemoryMarshal.Cast<byte, ushort>(buffer);
str.AsSpan().CopyTo(MemoryMarshal.Cast<byte, char>(buffer));
span = buffer;
str.AsSpan().CopyTo(MemoryMarshal.Cast<ushort, char>(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
{
......
......@@ -6,6 +6,7 @@
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<LangVersion>preview</LangVersion>
<Nullable>enable</Nullable>
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
<!-- Indicate to the compiler to output generated files to disk. Source addded
by the LibraryImportGenerator can be found in the intermediate directory. -->
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册