未验证 提交 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) ...@@ -588,7 +588,7 @@ public void AnalyzeMarshallerType(SymbolAnalysisContext context)
inConstructor = ctor; 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; callerAllocatedSpanConstructor = ctor;
} }
......
...@@ -354,10 +354,10 @@ ...@@ -354,10 +354,10 @@
<value>The specified custom marshaller direction for '{0}' is invalid</value> <value>The specified custom marshaller direction for '{0}' is invalid</value>
</data> </data>
<data name="ValueInCallerAllocatedBufferRequiresSpanConstructorDescription" xml:space="preserve"> <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>
<data name="ValueInCallerAllocatedBufferRequiresSpanConstructorMessage" xml:space="preserve"> <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>
<data name="ValueInRequiresOneParameterConstructorDescription" xml:space="preserve"> <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> <value>A 'Value'-kind native type must provide a one-parameter constructor taking the managed type as a parameter</value>
......
...@@ -505,13 +505,13 @@ ...@@ -505,13 +505,13 @@
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="ValueInCallerAllocatedBufferRequiresSpanConstructorDescription"> <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> <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&lt;byte&gt;' as parameters</target> <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 /> <note />
</trans-unit> </trans-unit>
<trans-unit id="ValueInCallerAllocatedBufferRequiresSpanConstructorMessage"> <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> <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&lt;byte&gt;' as parameters</target> <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 /> <note />
</trans-unit> </trans-unit>
<trans-unit id="ValueInRequiresOneParameterConstructorDescription"> <trans-unit id="ValueInRequiresOneParameterConstructorDescription">
......
...@@ -505,13 +505,13 @@ ...@@ -505,13 +505,13 @@
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="ValueInCallerAllocatedBufferRequiresSpanConstructorDescription"> <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> <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&lt;byte&gt;' as parameters</target> <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 /> <note />
</trans-unit> </trans-unit>
<trans-unit id="ValueInCallerAllocatedBufferRequiresSpanConstructorMessage"> <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> <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&lt;byte&gt;' as parameters</target> <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 /> <note />
</trans-unit> </trans-unit>
<trans-unit id="ValueInRequiresOneParameterConstructorDescription"> <trans-unit id="ValueInRequiresOneParameterConstructorDescription">
......
...@@ -505,13 +505,13 @@ ...@@ -505,13 +505,13 @@
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="ValueInCallerAllocatedBufferRequiresSpanConstructorDescription"> <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> <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&lt;byte&gt;' as parameters</target> <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 /> <note />
</trans-unit> </trans-unit>
<trans-unit id="ValueInCallerAllocatedBufferRequiresSpanConstructorMessage"> <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> <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&lt;byte&gt;' as parameters</target> <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 /> <note />
</trans-unit> </trans-unit>
<trans-unit id="ValueInRequiresOneParameterConstructorDescription"> <trans-unit id="ValueInRequiresOneParameterConstructorDescription">
......
...@@ -505,13 +505,13 @@ ...@@ -505,13 +505,13 @@
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="ValueInCallerAllocatedBufferRequiresSpanConstructorDescription"> <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> <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&lt;byte&gt;' as parameters</target> <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 /> <note />
</trans-unit> </trans-unit>
<trans-unit id="ValueInCallerAllocatedBufferRequiresSpanConstructorMessage"> <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> <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&lt;byte&gt;' as parameters</target> <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 /> <note />
</trans-unit> </trans-unit>
<trans-unit id="ValueInRequiresOneParameterConstructorDescription"> <trans-unit id="ValueInRequiresOneParameterConstructorDescription">
......
...@@ -505,13 +505,13 @@ ...@@ -505,13 +505,13 @@
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="ValueInCallerAllocatedBufferRequiresSpanConstructorDescription"> <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> <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&lt;byte&gt;' as parameters</target> <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 /> <note />
</trans-unit> </trans-unit>
<trans-unit id="ValueInCallerAllocatedBufferRequiresSpanConstructorMessage"> <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> <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&lt;byte&gt;' as parameters</target> <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 /> <note />
</trans-unit> </trans-unit>
<trans-unit id="ValueInRequiresOneParameterConstructorDescription"> <trans-unit id="ValueInRequiresOneParameterConstructorDescription">
......
...@@ -505,13 +505,13 @@ ...@@ -505,13 +505,13 @@
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="ValueInCallerAllocatedBufferRequiresSpanConstructorDescription"> <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> <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&lt;byte&gt;' as parameters</target> <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 /> <note />
</trans-unit> </trans-unit>
<trans-unit id="ValueInCallerAllocatedBufferRequiresSpanConstructorMessage"> <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> <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&lt;byte&gt;' as parameters</target> <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 /> <note />
</trans-unit> </trans-unit>
<trans-unit id="ValueInRequiresOneParameterConstructorDescription"> <trans-unit id="ValueInRequiresOneParameterConstructorDescription">
......
...@@ -505,13 +505,13 @@ ...@@ -505,13 +505,13 @@
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="ValueInCallerAllocatedBufferRequiresSpanConstructorDescription"> <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> <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&lt;byte&gt;' as parameters</target> <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 /> <note />
</trans-unit> </trans-unit>
<trans-unit id="ValueInCallerAllocatedBufferRequiresSpanConstructorMessage"> <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> <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&lt;byte&gt;' as parameters</target> <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 /> <note />
</trans-unit> </trans-unit>
<trans-unit id="ValueInRequiresOneParameterConstructorDescription"> <trans-unit id="ValueInRequiresOneParameterConstructorDescription">
......
...@@ -505,13 +505,13 @@ ...@@ -505,13 +505,13 @@
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="ValueInCallerAllocatedBufferRequiresSpanConstructorDescription"> <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> <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&lt;byte&gt;' as parameters</target> <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 /> <note />
</trans-unit> </trans-unit>
<trans-unit id="ValueInCallerAllocatedBufferRequiresSpanConstructorMessage"> <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> <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&lt;byte&gt;' as parameters</target> <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 /> <note />
</trans-unit> </trans-unit>
<trans-unit id="ValueInRequiresOneParameterConstructorDescription"> <trans-unit id="ValueInRequiresOneParameterConstructorDescription">
......
...@@ -505,13 +505,13 @@ ...@@ -505,13 +505,13 @@
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="ValueInCallerAllocatedBufferRequiresSpanConstructorDescription"> <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> <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&lt;byte&gt;' as parameters</target> <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 /> <note />
</trans-unit> </trans-unit>
<trans-unit id="ValueInCallerAllocatedBufferRequiresSpanConstructorMessage"> <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> <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&lt;byte&gt;' as parameters</target> <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 /> <note />
</trans-unit> </trans-unit>
<trans-unit id="ValueInRequiresOneParameterConstructorDescription"> <trans-unit id="ValueInRequiresOneParameterConstructorDescription">
......
...@@ -505,13 +505,13 @@ ...@@ -505,13 +505,13 @@
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="ValueInCallerAllocatedBufferRequiresSpanConstructorDescription"> <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> <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&lt;byte&gt;' as parameters</target> <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 /> <note />
</trans-unit> </trans-unit>
<trans-unit id="ValueInCallerAllocatedBufferRequiresSpanConstructorMessage"> <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> <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&lt;byte&gt;' as parameters</target> <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 /> <note />
</trans-unit> </trans-unit>
<trans-unit id="ValueInRequiresOneParameterConstructorDescription"> <trans-unit id="ValueInRequiresOneParameterConstructorDescription">
......
...@@ -505,13 +505,13 @@ ...@@ -505,13 +505,13 @@
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="ValueInCallerAllocatedBufferRequiresSpanConstructorDescription"> <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> <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&lt;byte&gt;' as parameters</target> <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 /> <note />
</trans-unit> </trans-unit>
<trans-unit id="ValueInCallerAllocatedBufferRequiresSpanConstructorMessage"> <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> <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&lt;byte&gt;' as parameters</target> <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 /> <note />
</trans-unit> </trans-unit>
<trans-unit id="ValueInRequiresOneParameterConstructorDescription"> <trans-unit id="ValueInRequiresOneParameterConstructorDescription">
......
...@@ -505,13 +505,13 @@ ...@@ -505,13 +505,13 @@
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="ValueInCallerAllocatedBufferRequiresSpanConstructorDescription"> <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> <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&lt;byte&gt;' as parameters</target> <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 /> <note />
</trans-unit> </trans-unit>
<trans-unit id="ValueInCallerAllocatedBufferRequiresSpanConstructorMessage"> <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> <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&lt;byte&gt;' as parameters</target> <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 /> <note />
</trans-unit> </trans-unit>
<trans-unit id="ValueInRequiresOneParameterConstructorDescription"> <trans-unit id="ValueInRequiresOneParameterConstructorDescription">
......
...@@ -505,13 +505,13 @@ ...@@ -505,13 +505,13 @@
<note /> <note />
</trans-unit> </trans-unit>
<trans-unit id="ValueInCallerAllocatedBufferRequiresSpanConstructorDescription"> <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> <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&lt;byte&gt;' as parameters</target> <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 /> <note />
</trans-unit> </trans-unit>
<trans-unit id="ValueInCallerAllocatedBufferRequiresSpanConstructorMessage"> <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> <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&lt;byte&gt;' as parameters</target> <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 /> <note />
</trans-unit> </trans-unit>
<trans-unit id="ValueInRequiresOneParameterConstructorDescription"> <trans-unit id="ValueInRequiresOneParameterConstructorDescription">
......
...@@ -51,6 +51,7 @@ public static ManagedTypeInfo CreateTypeInfoForTypeSymbol(ITypeSymbol type) ...@@ -51,6 +51,7 @@ public static ManagedTypeInfo CreateTypeInfoForTypeSymbol(ITypeSymbol type)
public sealed record SpecialTypeInfo(string FullTypeName, string DiagnosticFormattedName, SpecialType SpecialType) : ManagedTypeInfo(FullTypeName, DiagnosticFormattedName) 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 Int32 = new("int", "int", SpecialType.System_Int32);
public static readonly SpecialTypeInfo Void = new("void", "void", SpecialType.System_Void); public static readonly SpecialTypeInfo Void = new("void", "void", SpecialType.System_Void);
......
...@@ -194,19 +194,37 @@ public static bool HasToManagedMethod(ITypeSymbol nativeType, ITypeSymbol manage ...@@ -194,19 +194,37 @@ public static bool HasToManagedMethod(ITypeSymbol nativeType, ITypeSymbol manage
public static bool IsCallerAllocatedSpanConstructor( public static bool IsCallerAllocatedSpanConstructor(
IMethodSymbol ctor, IMethodSymbol ctor,
ITypeSymbol managedType, ITypeSymbol managedType,
ITypeSymbol spanOfByte, ITypeSymbol spanOfT,
CustomTypeMarshallerKind variant) CustomTypeMarshallerKind variant,
out ITypeSymbol? spanElementType)
{ {
spanElementType = null;
if (variant == CustomTypeMarshallerKind.LinearCollection) if (variant == CustomTypeMarshallerKind.LinearCollection)
{ {
return ctor.Parameters.Length == 3 return ctor.Parameters.Length == 3
&& SymbolEqualityComparer.Default.Equals(managedType, ctor.Parameters[0].Type) && SymbolEqualityComparer.Default.Equals(managedType, ctor.Parameters[0].Type)
&& SymbolEqualityComparer.Default.Equals(spanOfByte, ctor.Parameters[1].Type) && IsSpanOfUnmanagedType(ctor.Parameters[1].Type, spanOfT, out spanElementType)
&& ctor.Parameters[2].Type.SpecialType == SpecialType.System_Int32; && spanElementType.SpecialType == SpecialType.System_Byte
&& ctor.Parameters[2].Type.SpecialType == SpecialType.System_Int32;
} }
return ctor.Parameters.Length == 2 return ctor.Parameters.Length == 2
&& SymbolEqualityComparer.Default.Equals(managedType, ctor.Parameters[0].Type) && 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) public static IMethodSymbol? FindGetPinnableReference(ITypeSymbol type)
......
...@@ -165,7 +165,7 @@ private IMarshallingGenerator CreateCustomNativeTypeMarshaller(TypePositionInfo ...@@ -165,7 +165,7 @@ private IMarshallingGenerator CreateCustomNativeTypeMarshaller(TypePositionInfo
{ {
throw new MarshallingNotSupportedException(info, context); 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) if ((marshalInfo.MarshallingFeatures & CustomTypeMarshallerFeatures.UnmanagedResources) != 0)
......
...@@ -252,11 +252,13 @@ public IEnumerable<StatementSyntax> GeneratePinStatements(TypePositionInfo info, ...@@ -252,11 +252,13 @@ public IEnumerable<StatementSyntax> GeneratePinStatements(TypePositionInfo info,
internal sealed class StackallocOptimizationMarshalling : ICustomNativeTypeMarshallingStrategy internal sealed class StackallocOptimizationMarshalling : ICustomNativeTypeMarshallingStrategy
{ {
private readonly ICustomNativeTypeMarshallingStrategy _innerMarshaller; private readonly ICustomNativeTypeMarshallingStrategy _innerMarshaller;
private readonly TypeSyntax _bufferElementType;
private readonly int _bufferSize; private readonly int _bufferSize;
public StackallocOptimizationMarshalling(ICustomNativeTypeMarshallingStrategy innerMarshaller, int bufferSize) public StackallocOptimizationMarshalling(ICustomNativeTypeMarshallingStrategy innerMarshaller, TypeSyntax bufferElementType, int bufferSize)
{ {
_innerMarshaller = innerMarshaller; _innerMarshaller = innerMarshaller;
_bufferElementType = bufferElementType;
_bufferSize = bufferSize; _bufferSize = bufferSize;
} }
...@@ -274,16 +276,16 @@ public IEnumerable<StatementSyntax> GenerateMarshalStatements(TypePositionInfo i ...@@ -274,16 +276,16 @@ public IEnumerable<StatementSyntax> GenerateMarshalStatements(TypePositionInfo i
{ {
if (StackAllocOptimizationValid(info, context)) if (StackAllocOptimizationValid(info, context))
{ {
// byte* <managedIdentifier>__stackptr = stackalloc byte[<_bufferSize>]; // <bufferElementType>* <managedIdentifier>__stackptr = stackalloc <bufferElementType>[<_bufferSize>];
yield return LocalDeclarationStatement( yield return LocalDeclarationStatement(
VariableDeclaration( VariableDeclaration(
PointerType(PredefinedType(Token(SyntaxKind.ByteKeyword))), PointerType(_bufferElementType),
SingletonSeparatedList( SingletonSeparatedList(
VariableDeclarator(GetStackAllocPointerIdentifier(info, context)) VariableDeclarator(GetStackAllocPointerIdentifier(info, context))
.WithInitializer(EqualsValueClause( .WithInitializer(EqualsValueClause(
StackAllocArrayCreationExpression( StackAllocArrayCreationExpression(
ArrayType( ArrayType(
PredefinedType(Token(SyntaxKind.ByteKeyword)), _bufferElementType,
SingletonList(ArrayRankSpecifier(SingletonSeparatedList<ExpressionSyntax>( SingletonList(ArrayRankSpecifier(SingletonSeparatedList<ExpressionSyntax>(
LiteralExpression(SyntaxKind.NumericLiteralExpression, Literal(_bufferSize)) LiteralExpression(SyntaxKind.NumericLiteralExpression, Literal(_bufferSize))
)))))))))); ))))))))));
...@@ -332,7 +334,7 @@ public IEnumerable<ArgumentSyntax> GetNativeTypeConstructorArguments(TypePositio ...@@ -332,7 +334,7 @@ public IEnumerable<ArgumentSyntax> GetNativeTypeConstructorArguments(TypePositio
ObjectCreationExpression( ObjectCreationExpression(
GenericName(Identifier(TypeNames.System_Span), GenericName(Identifier(TypeNames.System_Span),
TypeArgumentList(SingletonSeparatedList<TypeSyntax>( TypeArgumentList(SingletonSeparatedList<TypeSyntax>(
PredefinedType(Token(SyntaxKind.ByteKeyword)))))) _bufferElementType))))
.WithArgumentList( .WithArgumentList(
ArgumentList(SeparatedList(new ArgumentSyntax[] ArgumentList(SeparatedList(new ArgumentSyntax[]
{ {
......
...@@ -143,6 +143,7 @@ public enum CustomTypeMarshallerPinning ...@@ -143,6 +143,7 @@ public enum CustomTypeMarshallerPinning
CustomTypeMarshallerFeatures MarshallingFeatures, CustomTypeMarshallerFeatures MarshallingFeatures,
CustomTypeMarshallerPinning PinningFeatures, CustomTypeMarshallerPinning PinningFeatures,
bool UseDefaultMarshalling, bool UseDefaultMarshalling,
ManagedTypeInfo? BufferElementType,
int? BufferSize) : MarshallingInfo; int? BufferSize) : MarshallingInfo;
/// <summary> /// <summary>
...@@ -178,6 +179,7 @@ public enum CustomTypeMarshallerPinning ...@@ -178,6 +179,7 @@ public enum CustomTypeMarshallerPinning
MarshallingFeatures, MarshallingFeatures,
PinningFeatures, PinningFeatures,
UseDefaultMarshalling, UseDefaultMarshalling,
SpecialTypeInfo.Byte,
BufferSize BufferSize
); );
...@@ -672,6 +674,26 @@ private CountInfo CreateCountInfo(AttributeData marshalUsingData, ImmutableHashS ...@@ -672,6 +674,26 @@ private CountInfo CreateCountInfo(AttributeData marshalUsingData, ImmutableHashS
GetMarshallingInfo(elementType, useSiteAttributes, indirectionLevel + 1, inspectedElements, ref maxIndirectionDepthUsed)); 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( return new NativeMarshallingAttributeInfo(
ManagedTypeInfo.CreateTypeInfoForTypeSymbol(nativeType), ManagedTypeInfo.CreateTypeInfoForTypeSymbol(nativeType),
toNativeValueMethod is not null ? ManagedTypeInfo.CreateTypeInfoForTypeSymbol(toNativeValueMethod.ReturnType) : null, toNativeValueMethod is not null ? ManagedTypeInfo.CreateTypeInfoForTypeSymbol(toNativeValueMethod.ReturnType) : null,
...@@ -679,6 +701,7 @@ private CountInfo CreateCountInfo(AttributeData marshalUsingData, ImmutableHashS ...@@ -679,6 +701,7 @@ private CountInfo CreateCountInfo(AttributeData marshalUsingData, ImmutableHashS
customTypeMarshallerData.Value.Features, customTypeMarshallerData.Value.Features,
pinning, pinning,
UseDefaultMarshalling: !isMarshalUsingAttribute, UseDefaultMarshalling: !isMarshalUsingAttribute,
bufferElementTypeInfo,
customTypeMarshallerData.Value.BufferSize); customTypeMarshallerData.Value.BufferSize);
} }
......
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<root> <root>
<!-- <!--
Microsoft ResX Schema Microsoft ResX Schema
Version 2.0 Version 2.0
The primary goals of this format is to allow a simple XML format The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes various data types are done through the TypeConverter classes
associated with the data types. associated with the data types.
Example: Example:
... ado.net/XML headers & schema ... ... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader> <resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader> <resheader name="version">2.0</resheader>
...@@ -26,36 +26,36 @@ ...@@ -26,36 +26,36 @@
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment> <comment>This is a comment</comment>
</data> </data>
There are any number of "resheader" rows that contain simple There are any number of "resheader" rows that contain simple
name/value pairs. name/value pairs.
Each data row contains a name, and value. The row also contains a Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture. text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the Classes that don't support this are serialized and stored with the
mimetype set. mimetype set.
The mimetype is used for serialized objects, and tells the The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly: extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below. read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64 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 : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding. : and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64 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 : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding. : and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64 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 : using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding. : and then encoded with base64 encoding.
--> -->
...@@ -198,4 +198,7 @@ ...@@ -198,4 +198,7 @@
<data name="RuntimeMarshallingMustBeDisabled" xml:space="preserve"> <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> <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>
<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> </root>
\ No newline at end of file
...@@ -137,6 +137,11 @@ ...@@ -137,6 +137,11 @@
<target state="new">Specified type is not supported by source-generated P/Invokes</target> <target state="new">Specified type is not supported by source-generated P/Invokes</target>
<note /> <note />
</trans-unit> </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> </body>
</file> </file>
</xliff> </xliff>
\ No newline at end of file
...@@ -137,6 +137,11 @@ ...@@ -137,6 +137,11 @@
<target state="new">Specified type is not supported by source-generated P/Invokes</target> <target state="new">Specified type is not supported by source-generated P/Invokes</target>
<note /> <note />
</trans-unit> </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> </body>
</file> </file>
</xliff> </xliff>
\ No newline at end of file
...@@ -137,6 +137,11 @@ ...@@ -137,6 +137,11 @@
<target state="new">Specified type is not supported by source-generated P/Invokes</target> <target state="new">Specified type is not supported by source-generated P/Invokes</target>
<note /> <note />
</trans-unit> </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> </body>
</file> </file>
</xliff> </xliff>
\ No newline at end of file
...@@ -137,6 +137,11 @@ ...@@ -137,6 +137,11 @@
<target state="new">Specified type is not supported by source-generated P/Invokes</target> <target state="new">Specified type is not supported by source-generated P/Invokes</target>
<note /> <note />
</trans-unit> </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> </body>
</file> </file>
</xliff> </xliff>
\ No newline at end of file
...@@ -137,6 +137,11 @@ ...@@ -137,6 +137,11 @@
<target state="new">Specified type is not supported by source-generated P/Invokes</target> <target state="new">Specified type is not supported by source-generated P/Invokes</target>
<note /> <note />
</trans-unit> </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> </body>
</file> </file>
</xliff> </xliff>
\ No newline at end of file
...@@ -137,6 +137,11 @@ ...@@ -137,6 +137,11 @@
<target state="new">Specified type is not supported by source-generated P/Invokes</target> <target state="new">Specified type is not supported by source-generated P/Invokes</target>
<note /> <note />
</trans-unit> </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> </body>
</file> </file>
</xliff> </xliff>
\ No newline at end of file
...@@ -137,6 +137,11 @@ ...@@ -137,6 +137,11 @@
<target state="new">Specified type is not supported by source-generated P/Invokes</target> <target state="new">Specified type is not supported by source-generated P/Invokes</target>
<note /> <note />
</trans-unit> </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> </body>
</file> </file>
</xliff> </xliff>
\ No newline at end of file
...@@ -137,6 +137,11 @@ ...@@ -137,6 +137,11 @@
<target state="new">Specified type is not supported by source-generated P/Invokes</target> <target state="new">Specified type is not supported by source-generated P/Invokes</target>
<note /> <note />
</trans-unit> </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> </body>
</file> </file>
</xliff> </xliff>
\ No newline at end of file
...@@ -137,6 +137,11 @@ ...@@ -137,6 +137,11 @@
<target state="new">Specified type is not supported by source-generated P/Invokes</target> <target state="new">Specified type is not supported by source-generated P/Invokes</target>
<note /> <note />
</trans-unit> </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> </body>
</file> </file>
</xliff> </xliff>
\ No newline at end of file
...@@ -137,6 +137,11 @@ ...@@ -137,6 +137,11 @@
<target state="new">Specified type is not supported by source-generated P/Invokes</target> <target state="new">Specified type is not supported by source-generated P/Invokes</target>
<note /> <note />
</trans-unit> </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> </body>
</file> </file>
</xliff> </xliff>
\ No newline at end of file
...@@ -137,6 +137,11 @@ ...@@ -137,6 +137,11 @@
<target state="new">Specified type is not supported by source-generated P/Invokes</target> <target state="new">Specified type is not supported by source-generated P/Invokes</target>
<note /> <note />
</trans-unit> </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> </body>
</file> </file>
</xliff> </xliff>
\ No newline at end of file
...@@ -137,6 +137,11 @@ ...@@ -137,6 +137,11 @@
<target state="new">Specified type is not supported by source-generated P/Invokes</target> <target state="new">Specified type is not supported by source-generated P/Invokes</target>
<note /> <note />
</trans-unit> </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> </body>
</file> </file>
</xliff> </xliff>
\ No newline at end of file
...@@ -137,6 +137,11 @@ ...@@ -137,6 +137,11 @@
<target state="new">Specified type is not supported by source-generated P/Invokes</target> <target state="new">Specified type is not supported by source-generated P/Invokes</target>
<note /> <note />
</trans-unit> </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> </body>
</file> </file>
</xliff> </xliff>
\ No newline at end of file
...@@ -983,6 +983,53 @@ struct Native ...@@ -983,6 +983,53 @@ struct Native
await VerifyCS.VerifyCodeFixAsync(source, source); 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] [Fact]
public async Task NativeTypeWithOnlyStackallocConstructor_ReportsDiagnostic() public async Task NativeTypeWithOnlyStackallocConstructor_ReportsDiagnostic()
{ {
......
...@@ -132,11 +132,11 @@ public void FreeNative() ...@@ -132,11 +132,11 @@ public void FreeNative()
private bool isNullString; private bool isNullString;
public Utf16StringMarshaller(string str) 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; isNullString = false;
if (str is null) if (str is null)
...@@ -147,8 +147,8 @@ public Utf16StringMarshaller(string str, Span<byte> buffer) ...@@ -147,8 +147,8 @@ public Utf16StringMarshaller(string str, Span<byte> buffer)
} }
else if ((str.Length + 1) < buffer.Length) else if ((str.Length + 1) < buffer.Length)
{ {
span = MemoryMarshal.Cast<byte, ushort>(buffer); span = buffer;
str.AsSpan().CopyTo(MemoryMarshal.Cast<byte, char>(buffer)); str.AsSpan().CopyTo(MemoryMarshal.Cast<ushort, char>(buffer));
// Supplied memory is in an undefined state so ensure // Supplied memory is in an undefined state so ensure
// there is a trailing null in the buffer. // there is a trailing null in the buffer.
span[str.Length] = '\0'; span[str.Length] = '\0';
...@@ -192,7 +192,7 @@ public void FreeNative() ...@@ -192,7 +192,7 @@ public void FreeNative()
Marshal.FreeCoTaskMem((IntPtr)allocated); Marshal.FreeCoTaskMem((IntPtr)allocated);
} }
} }
[CustomTypeMarshaller(typeof(string), Features = CustomTypeMarshallerFeatures.UnmanagedResources | CustomTypeMarshallerFeatures.TwoStageMarshalling | CustomTypeMarshallerFeatures.CallerAllocatedBuffer, BufferSize = 0x100)] [CustomTypeMarshaller(typeof(string), Features = CustomTypeMarshallerFeatures.UnmanagedResources | CustomTypeMarshallerFeatures.TwoStageMarshalling | CustomTypeMarshallerFeatures.CallerAllocatedBuffer, BufferSize = 0x100)]
public unsafe ref struct Utf8StringMarshaller public unsafe ref struct Utf8StringMarshaller
{ {
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<LangVersion>preview</LangVersion> <LangVersion>preview</LangVersion>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
<!-- Indicate to the compiler to output generated files to disk. Source addded <!-- Indicate to the compiler to output generated files to disk. Source addded
by the LibraryImportGenerator can be found in the intermediate directory. --> 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.
先完成此消息的编辑!
想要评论请 注册