| __`SYSLIB1059`__ | Marshaller type does not support allocating constructor |
| __`SYSLIB1060`__ | BufferSize should be set on CustomTypeMarshallerAttribute |
| __`SYSLIB1061`__ | Marshaller type has incompatible method signatures |
-| __`SYSLIB1062`__ | *_`SYSLIB1062`-`SYSLIB1064` reserved for Microsoft.Interop.LibraryImportGenerator._* |
-| __`SYSLIB1063`__ | *_`SYSLIB1062`-`SYSLIB1064` reserved for Microsoft.Interop.LibraryImportGenerator._* |
-| __`SYSLIB1064`__ | *_`SYSLIB1062`-`SYSLIB1064` reserved for Microsoft.Interop.LibraryImportGenerator._* |
+| __`SYSLIB1062`__ | Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>' |
+| __`SYSLIB1063`__ | *_`SYSLIB1063`-`SYSLIB1069` reserved for Microsoft.Interop.LibraryImportGenerator._* |
+| __`SYSLIB1064`__ | *_`SYSLIB1063`-`SYSLIB1069` reserved for Microsoft.Interop.LibraryImportGenerator._* |
+| __`SYSLIB1065`__ | *_`SYSLIB1063`-`SYSLIB1069` reserved for Microsoft.Interop.LibraryImportGenerator._* |
+| __`SYSLIB1066`__ | *_`SYSLIB1063`-`SYSLIB1069` reserved for Microsoft.Interop.LibraryImportGenerator._* |
+| __`SYSLIB1067`__ | *_`SYSLIB1063`-`SYSLIB1069` reserved for Microsoft.Interop.LibraryImportGenerator._* |
+| __`SYSLIB1068`__ | *_`SYSLIB1063`-`SYSLIB1069` reserved for Microsoft.Interop.LibraryImportGenerator._* |
+| __`SYSLIB1069`__ | *_`SYSLIB1063`-`SYSLIB1069` reserved for Microsoft.Interop.LibraryImportGenerator._* |
### Diagnostic Suppressions (`SYSLIBSUPPRESS****`)
{
public class Ids
{
- // SYSLIB1050-SYSLIB1059 are reserved for LibraryImportGenerator
+ // SYSLIB1050-SYSLIB1069 are reserved for LibraryImportGenerator
public const string Prefix = "SYSLIB";
public const string InvalidLibraryImportAttributeUsage = Prefix + "1050";
public const string TypeNotSupported = Prefix + "1051";
public const string ConfigurationNotSupported = Prefix + "1052";
public const string CannotForwardToDllImport = Prefix + "1053";
+
+ public const string RequiresAllowUnsafeBlocks = Prefix + "1062";
}
private const string Category = "LibraryImportGenerator";
isEnabledByDefault: true,
description: GetResourceString(nameof(SR.CannotForwardToDllImportDescription)));
+ public static readonly DiagnosticDescriptor RequiresAllowUnsafeBlocks =
+ new DiagnosticDescriptor(
+ Ids.RequiresAllowUnsafeBlocks,
+ GetResourceString(nameof(SR.RequiresAllowUnsafeBlocksTitle)),
+ GetResourceString(nameof(SR.RequiresAllowUnsafeBlocksMessage)),
+ Category,
+ DiagnosticSeverity.Error,
+ isEnabledByDefault: true,
+ description: GetResourceString(nameof(SR.RequiresAllowUnsafeBlocksDescription)));
+
private readonly List<Diagnostic> _diagnostics = new List<Diagnostic>();
public IEnumerable<Diagnostic> Diagnostics => _diagnostics;
public void Initialize(IncrementalGeneratorInitializationContext context)
{
+ // Collect all methods adorned with LibraryImportAttribute
var attributedMethods = context.SyntaxProvider
.ForAttributeWithMetadataName(
context,
.Where(
static modelData => modelData is not null);
+ // Validate if attributed methods can have source generated
var methodsWithDiagnostics = attributedMethods.Select(static (data, ct) =>
{
Diagnostic? diagnostic = GetDiagnosticIfInvalidMethodForGeneration(data.Syntax, data.Symbol);
var methodsToGenerate = methodsWithDiagnostics.Where(static data => data.Diagnostic is null);
var invalidMethodDiagnostics = methodsWithDiagnostics.Where(static data => data.Diagnostic is not null);
+ // Report diagnostics for invalid methods
context.RegisterSourceOutput(invalidMethodDiagnostics, static (context, invalidMethod) =>
{
context.ReportDiagnostic(invalidMethod.Diagnostic);
});
+ // Compute generator options
IncrementalValueProvider<LibraryImportGeneratorOptions> stubOptions = context.AnalyzerConfigOptionsProvider
.Select(static (options, ct) => new LibraryImportGeneratorOptions(options.GlobalOptions));
+ IncrementalValueProvider<StubEnvironment> stubEnvironment = context.CreateStubEnvironmentProvider();
+
+ // Validate environment that is being used to generate stubs.
+ context.RegisterDiagnostics(stubEnvironment.Combine(attributedMethods.Collect()).SelectMany((data, ct) =>
+ {
+ if (data.Right.IsEmpty // no attributed methods
+ || data.Left.Compilation.Options is CSharpCompilationOptions { AllowUnsafe: true } // Unsafe code enabled
+ || data.Left.TargetFramework != TargetFramework.Net) // Non-.NET 5 scenarios use forwarders and don't need unsafe code
+ {
+ return ImmutableArray<Diagnostic>.Empty;
+ }
+
+ return ImmutableArray.Create(Diagnostic.Create(GeneratorDiagnostics.RequiresAllowUnsafeBlocks, null));
+ }));
+
IncrementalValuesProvider<(MemberDeclarationSyntax, ImmutableArray<Diagnostic>)> generateSingleStub = methodsToGenerate
- .Combine(context.CreateStubEnvironmentProvider())
+ .Combine(stubEnvironment)
.Combine(stubOptions)
.Select(static (data, ct) => new
{
<data name="MarshallerTypeMustBeNonNullMessage" xml:space="preserve">
<value>The 'marshallerType' parameter in the 'System.Runtime.InteropServices.Marshalling.CustomMarshallerAttribute' cannot be 'null'</value>
</data>
+ <data name="RequiresAllowUnsafeBlocksDescription" xml:space="preserve">
+ <value>LibraryImportAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</value>
+ </data>
+ <data name="RequiresAllowUnsafeBlocksMessage" xml:space="preserve">
+ <value>LibraryImportAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</value>
+ </data>
+ <data name="RequiresAllowUnsafeBlocksTitle" xml:space="preserve">
+ <value>LibraryImportAttribute requires unsafe code.</value>
+ </data>
</root>
\ No newline at end of file
<target state="new">The marshaller type '{0}' for managed type '{1}' must be a closed generic type, have the same arity as the managed type if it is a value marshaller, or have one additional generic parameter if it is a collection marshaller.</target>
<note />
</trans-unit>
+ <trans-unit id="RequiresAllowUnsafeBlocksDescription">
+ <source>LibraryImportAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</source>
+ <target state="new">LibraryImportAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="RequiresAllowUnsafeBlocksMessage">
+ <source>LibraryImportAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</source>
+ <target state="new">LibraryImportAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="RequiresAllowUnsafeBlocksTitle">
+ <source>LibraryImportAttribute requires unsafe code.</source>
+ <target state="new">LibraryImportAttribute requires unsafe code.</target>
+ <note />
+ </trans-unit>
<trans-unit id="ToUnmanagedFromManagedTypesMustMatchDescription">
<source>The return type of 'ConvertToUnmanaged' and the parameter type of 'ConvertToManaged' must be the same.</source>
<target state="new">The return type of 'ConvertToUnmanaged' and the parameter type of 'ConvertToManaged' must be the same.</target>
<target state="new">The marshaller type '{0}' for managed type '{1}' must be a closed generic type, have the same arity as the managed type if it is a value marshaller, or have one additional generic parameter if it is a collection marshaller.</target>
<note />
</trans-unit>
+ <trans-unit id="RequiresAllowUnsafeBlocksDescription">
+ <source>LibraryImportAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</source>
+ <target state="new">LibraryImportAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="RequiresAllowUnsafeBlocksMessage">
+ <source>LibraryImportAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</source>
+ <target state="new">LibraryImportAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="RequiresAllowUnsafeBlocksTitle">
+ <source>LibraryImportAttribute requires unsafe code.</source>
+ <target state="new">LibraryImportAttribute requires unsafe code.</target>
+ <note />
+ </trans-unit>
<trans-unit id="ToUnmanagedFromManagedTypesMustMatchDescription">
<source>The return type of 'ConvertToUnmanaged' and the parameter type of 'ConvertToManaged' must be the same.</source>
<target state="new">The return type of 'ConvertToUnmanaged' and the parameter type of 'ConvertToManaged' must be the same.</target>
<target state="new">The marshaller type '{0}' for managed type '{1}' must be a closed generic type, have the same arity as the managed type if it is a value marshaller, or have one additional generic parameter if it is a collection marshaller.</target>
<note />
</trans-unit>
+ <trans-unit id="RequiresAllowUnsafeBlocksDescription">
+ <source>LibraryImportAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</source>
+ <target state="new">LibraryImportAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="RequiresAllowUnsafeBlocksMessage">
+ <source>LibraryImportAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</source>
+ <target state="new">LibraryImportAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="RequiresAllowUnsafeBlocksTitle">
+ <source>LibraryImportAttribute requires unsafe code.</source>
+ <target state="new">LibraryImportAttribute requires unsafe code.</target>
+ <note />
+ </trans-unit>
<trans-unit id="ToUnmanagedFromManagedTypesMustMatchDescription">
<source>The return type of 'ConvertToUnmanaged' and the parameter type of 'ConvertToManaged' must be the same.</source>
<target state="new">The return type of 'ConvertToUnmanaged' and the parameter type of 'ConvertToManaged' must be the same.</target>
<target state="new">The marshaller type '{0}' for managed type '{1}' must be a closed generic type, have the same arity as the managed type if it is a value marshaller, or have one additional generic parameter if it is a collection marshaller.</target>
<note />
</trans-unit>
+ <trans-unit id="RequiresAllowUnsafeBlocksDescription">
+ <source>LibraryImportAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</source>
+ <target state="new">LibraryImportAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="RequiresAllowUnsafeBlocksMessage">
+ <source>LibraryImportAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</source>
+ <target state="new">LibraryImportAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="RequiresAllowUnsafeBlocksTitle">
+ <source>LibraryImportAttribute requires unsafe code.</source>
+ <target state="new">LibraryImportAttribute requires unsafe code.</target>
+ <note />
+ </trans-unit>
<trans-unit id="ToUnmanagedFromManagedTypesMustMatchDescription">
<source>The return type of 'ConvertToUnmanaged' and the parameter type of 'ConvertToManaged' must be the same.</source>
<target state="new">The return type of 'ConvertToUnmanaged' and the parameter type of 'ConvertToManaged' must be the same.</target>
<target state="new">The marshaller type '{0}' for managed type '{1}' must be a closed generic type, have the same arity as the managed type if it is a value marshaller, or have one additional generic parameter if it is a collection marshaller.</target>
<note />
</trans-unit>
+ <trans-unit id="RequiresAllowUnsafeBlocksDescription">
+ <source>LibraryImportAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</source>
+ <target state="new">LibraryImportAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="RequiresAllowUnsafeBlocksMessage">
+ <source>LibraryImportAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</source>
+ <target state="new">LibraryImportAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="RequiresAllowUnsafeBlocksTitle">
+ <source>LibraryImportAttribute requires unsafe code.</source>
+ <target state="new">LibraryImportAttribute requires unsafe code.</target>
+ <note />
+ </trans-unit>
<trans-unit id="ToUnmanagedFromManagedTypesMustMatchDescription">
<source>The return type of 'ConvertToUnmanaged' and the parameter type of 'ConvertToManaged' must be the same.</source>
<target state="new">The return type of 'ConvertToUnmanaged' and the parameter type of 'ConvertToManaged' must be the same.</target>
<target state="new">The marshaller type '{0}' for managed type '{1}' must be a closed generic type, have the same arity as the managed type if it is a value marshaller, or have one additional generic parameter if it is a collection marshaller.</target>
<note />
</trans-unit>
+ <trans-unit id="RequiresAllowUnsafeBlocksDescription">
+ <source>LibraryImportAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</source>
+ <target state="new">LibraryImportAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="RequiresAllowUnsafeBlocksMessage">
+ <source>LibraryImportAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</source>
+ <target state="new">LibraryImportAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="RequiresAllowUnsafeBlocksTitle">
+ <source>LibraryImportAttribute requires unsafe code.</source>
+ <target state="new">LibraryImportAttribute requires unsafe code.</target>
+ <note />
+ </trans-unit>
<trans-unit id="ToUnmanagedFromManagedTypesMustMatchDescription">
<source>The return type of 'ConvertToUnmanaged' and the parameter type of 'ConvertToManaged' must be the same.</source>
<target state="new">The return type of 'ConvertToUnmanaged' and the parameter type of 'ConvertToManaged' must be the same.</target>
<target state="new">The marshaller type '{0}' for managed type '{1}' must be a closed generic type, have the same arity as the managed type if it is a value marshaller, or have one additional generic parameter if it is a collection marshaller.</target>
<note />
</trans-unit>
+ <trans-unit id="RequiresAllowUnsafeBlocksDescription">
+ <source>LibraryImportAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</source>
+ <target state="new">LibraryImportAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="RequiresAllowUnsafeBlocksMessage">
+ <source>LibraryImportAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</source>
+ <target state="new">LibraryImportAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="RequiresAllowUnsafeBlocksTitle">
+ <source>LibraryImportAttribute requires unsafe code.</source>
+ <target state="new">LibraryImportAttribute requires unsafe code.</target>
+ <note />
+ </trans-unit>
<trans-unit id="ToUnmanagedFromManagedTypesMustMatchDescription">
<source>The return type of 'ConvertToUnmanaged' and the parameter type of 'ConvertToManaged' must be the same.</source>
<target state="new">The return type of 'ConvertToUnmanaged' and the parameter type of 'ConvertToManaged' must be the same.</target>
<target state="new">The marshaller type '{0}' for managed type '{1}' must be a closed generic type, have the same arity as the managed type if it is a value marshaller, or have one additional generic parameter if it is a collection marshaller.</target>
<note />
</trans-unit>
+ <trans-unit id="RequiresAllowUnsafeBlocksDescription">
+ <source>LibraryImportAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</source>
+ <target state="new">LibraryImportAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="RequiresAllowUnsafeBlocksMessage">
+ <source>LibraryImportAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</source>
+ <target state="new">LibraryImportAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="RequiresAllowUnsafeBlocksTitle">
+ <source>LibraryImportAttribute requires unsafe code.</source>
+ <target state="new">LibraryImportAttribute requires unsafe code.</target>
+ <note />
+ </trans-unit>
<trans-unit id="ToUnmanagedFromManagedTypesMustMatchDescription">
<source>The return type of 'ConvertToUnmanaged' and the parameter type of 'ConvertToManaged' must be the same.</source>
<target state="new">The return type of 'ConvertToUnmanaged' and the parameter type of 'ConvertToManaged' must be the same.</target>
<target state="new">The marshaller type '{0}' for managed type '{1}' must be a closed generic type, have the same arity as the managed type if it is a value marshaller, or have one additional generic parameter if it is a collection marshaller.</target>
<note />
</trans-unit>
+ <trans-unit id="RequiresAllowUnsafeBlocksDescription">
+ <source>LibraryImportAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</source>
+ <target state="new">LibraryImportAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="RequiresAllowUnsafeBlocksMessage">
+ <source>LibraryImportAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</source>
+ <target state="new">LibraryImportAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="RequiresAllowUnsafeBlocksTitle">
+ <source>LibraryImportAttribute requires unsafe code.</source>
+ <target state="new">LibraryImportAttribute requires unsafe code.</target>
+ <note />
+ </trans-unit>
<trans-unit id="ToUnmanagedFromManagedTypesMustMatchDescription">
<source>The return type of 'ConvertToUnmanaged' and the parameter type of 'ConvertToManaged' must be the same.</source>
<target state="new">The return type of 'ConvertToUnmanaged' and the parameter type of 'ConvertToManaged' must be the same.</target>
<target state="new">The marshaller type '{0}' for managed type '{1}' must be a closed generic type, have the same arity as the managed type if it is a value marshaller, or have one additional generic parameter if it is a collection marshaller.</target>
<note />
</trans-unit>
+ <trans-unit id="RequiresAllowUnsafeBlocksDescription">
+ <source>LibraryImportAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</source>
+ <target state="new">LibraryImportAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="RequiresAllowUnsafeBlocksMessage">
+ <source>LibraryImportAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</source>
+ <target state="new">LibraryImportAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="RequiresAllowUnsafeBlocksTitle">
+ <source>LibraryImportAttribute requires unsafe code.</source>
+ <target state="new">LibraryImportAttribute requires unsafe code.</target>
+ <note />
+ </trans-unit>
<trans-unit id="ToUnmanagedFromManagedTypesMustMatchDescription">
<source>The return type of 'ConvertToUnmanaged' and the parameter type of 'ConvertToManaged' must be the same.</source>
<target state="new">The return type of 'ConvertToUnmanaged' and the parameter type of 'ConvertToManaged' must be the same.</target>
<target state="new">The marshaller type '{0}' for managed type '{1}' must be a closed generic type, have the same arity as the managed type if it is a value marshaller, or have one additional generic parameter if it is a collection marshaller.</target>
<note />
</trans-unit>
+ <trans-unit id="RequiresAllowUnsafeBlocksDescription">
+ <source>LibraryImportAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</source>
+ <target state="new">LibraryImportAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="RequiresAllowUnsafeBlocksMessage">
+ <source>LibraryImportAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</source>
+ <target state="new">LibraryImportAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="RequiresAllowUnsafeBlocksTitle">
+ <source>LibraryImportAttribute requires unsafe code.</source>
+ <target state="new">LibraryImportAttribute requires unsafe code.</target>
+ <note />
+ </trans-unit>
<trans-unit id="ToUnmanagedFromManagedTypesMustMatchDescription">
<source>The return type of 'ConvertToUnmanaged' and the parameter type of 'ConvertToManaged' must be the same.</source>
<target state="new">The return type of 'ConvertToUnmanaged' and the parameter type of 'ConvertToManaged' must be the same.</target>
<target state="new">The marshaller type '{0}' for managed type '{1}' must be a closed generic type, have the same arity as the managed type if it is a value marshaller, or have one additional generic parameter if it is a collection marshaller.</target>
<note />
</trans-unit>
+ <trans-unit id="RequiresAllowUnsafeBlocksDescription">
+ <source>LibraryImportAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</source>
+ <target state="new">LibraryImportAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="RequiresAllowUnsafeBlocksMessage">
+ <source>LibraryImportAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</source>
+ <target state="new">LibraryImportAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="RequiresAllowUnsafeBlocksTitle">
+ <source>LibraryImportAttribute requires unsafe code.</source>
+ <target state="new">LibraryImportAttribute requires unsafe code.</target>
+ <note />
+ </trans-unit>
<trans-unit id="ToUnmanagedFromManagedTypesMustMatchDescription">
<source>The return type of 'ConvertToUnmanaged' and the parameter type of 'ConvertToManaged' must be the same.</source>
<target state="new">The return type of 'ConvertToUnmanaged' and the parameter type of 'ConvertToManaged' must be the same.</target>
<target state="new">The marshaller type '{0}' for managed type '{1}' must be a closed generic type, have the same arity as the managed type if it is a value marshaller, or have one additional generic parameter if it is a collection marshaller.</target>
<note />
</trans-unit>
+ <trans-unit id="RequiresAllowUnsafeBlocksDescription">
+ <source>LibraryImportAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</source>
+ <target state="new">LibraryImportAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="RequiresAllowUnsafeBlocksMessage">
+ <source>LibraryImportAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</source>
+ <target state="new">LibraryImportAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="RequiresAllowUnsafeBlocksTitle">
+ <source>LibraryImportAttribute requires unsafe code.</source>
+ <target state="new">LibraryImportAttribute requires unsafe code.</target>
+ <note />
+ </trans-unit>
<trans-unit id="ToUnmanagedFromManagedTypesMustMatchDescription">
<source>The return type of 'ConvertToUnmanaged' and the parameter type of 'ConvertToManaged' must be the same.</source>
<target state="new">The return type of 'ConvertToUnmanaged' and the parameter type of 'ConvertToManaged' must be the same.</target>
TestUtils.AssertPostSourceGeneratorCompilation(newComp);
}
+
+ [Fact]
+ public async Task ValidateRequireAllowUnsafeBlocksDiagnostic()
+ {
+ string source = CodeSnippets.TrivialClassDeclarations;
+ Compilation comp = await TestUtils.CreateCompilation(new[] { source }, allowUnsafe: false);
+ TestUtils.AssertPreSourceGeneratorCompilation(comp);
+
+ var newComp = TestUtils.RunGenerators(comp, out var generatorDiags, new Microsoft.Interop.LibraryImportGenerator());
+
+ // The errors should indicate the AllowUnsafeBlocks is required.
+ Assert.True(generatorDiags.All(d => d.Id == "SYSLIB1062"));
+
+ // There should only be one SYSLIB1062, even if there are multiple LibraryImportAttribute uses.
+ Assert.Equal(1, generatorDiags.Count());
+ }
}
}
TestUtils.AssertPostSourceGeneratorCompilation(newComp);
}
+
+ public static IEnumerable<object[]> CodeSnippetsToCompileToValidateAllowUnsafeBlocks()
+ {
+ yield return new object[] { ID(), CodeSnippets.TrivialClassDeclarations, TestTargetFramework.Net, true };
+
+ {
+ string source = @"
+using System.Runtime.InteropServices;
+public class Basic { }
+";
+ yield return new object[] { ID(), source, TestTargetFramework.Standard, false };
+ yield return new object[] { ID(), source, TestTargetFramework.Framework, false };
+ yield return new object[] { ID(), source, TestTargetFramework.Net, false };
+ }
+ }
+
+ [Theory]
+ [MemberData(nameof(CodeSnippetsToCompileToValidateAllowUnsafeBlocks))]
+ public async Task ValidateRequireAllowUnsafeBlocksDiagnosticNoTrigger(string id, string source, TestTargetFramework framework, bool allowUnsafe)
+ {
+ TestUtils.Use(id);
+ Compilation comp = await TestUtils.CreateCompilation(source, framework, allowUnsafe: allowUnsafe);
+ TestUtils.AssertPreSourceGeneratorCompilation(comp);
+
+ var newComp = TestUtils.RunGenerators(comp, out var generatorDiags, new Microsoft.Interop.LibraryImportGenerator());
+ Assert.Empty(generatorDiags);
+
+ TestUtils.AssertPostSourceGeneratorCompilation(newComp);
+ }
}
}
/// <param name="outputKind">Output type</param>
/// <param name="refs">Addtional metadata references</param>
/// <param name="preprocessorSymbols">Prepocessor symbols</param>
+ /// <param name="allowUnsafe">Indicate if the compilation should allow unsafe code blocks</param>
/// <returns>The resulting compilation</returns>
- public static Task<Compilation> CreateCompilation(string source, TestTargetFramework targetFramework = TestTargetFramework.Net, OutputKind outputKind = OutputKind.DynamicallyLinkedLibrary, IEnumerable<MetadataReference>? refs = null, IEnumerable<string>? preprocessorSymbols = null)
+ public static Task<Compilation> CreateCompilation(string source, TestTargetFramework targetFramework = TestTargetFramework.Net, OutputKind outputKind = OutputKind.DynamicallyLinkedLibrary, IEnumerable<MetadataReference>? refs = null, IEnumerable<string>? preprocessorSymbols = null, bool allowUnsafe = true)
{
- return CreateCompilation(new[] { source }, targetFramework, outputKind, refs, preprocessorSymbols);
+ return CreateCompilation(new[] { source }, targetFramework, outputKind, refs, preprocessorSymbols, allowUnsafe);
}
/// <summary>
/// <param name="outputKind">Output type</param>
/// <param name="refs">Addtional metadata references</param>
/// <param name="preprocessorSymbols">Prepocessor symbols</param>
+ /// <param name="allowUnsafe">Indicate if the compilation should allow unsafe code blocks</param>
/// <returns>The resulting compilation</returns>
- public static Task<Compilation> CreateCompilation(string[] sources, TestTargetFramework targetFramework = TestTargetFramework.Net, OutputKind outputKind = OutputKind.DynamicallyLinkedLibrary, IEnumerable<MetadataReference>? refs = null, IEnumerable<string>? preprocessorSymbols = null)
+ public static Task<Compilation> CreateCompilation(string[] sources, TestTargetFramework targetFramework = TestTargetFramework.Net, OutputKind outputKind = OutputKind.DynamicallyLinkedLibrary, IEnumerable<MetadataReference>? refs = null, IEnumerable<string>? preprocessorSymbols = null, bool allowUnsafe = true)
{
return CreateCompilation(
sources.Select(source =>
CSharpSyntaxTree.ParseText(source, new CSharpParseOptions(LanguageVersion.Preview, preprocessorSymbols: preprocessorSymbols))).ToArray(),
targetFramework,
outputKind,
- refs);
+ refs,
+ allowUnsafe);
}
/// <summary>
/// <param name="targetFramework">Target framework of the compilation</param>
/// <param name="outputKind">Output type</param>
/// <param name="refs">Addtional metadata references</param>
+ /// <param name="allowUnsafe">Indicate if the compilation should allow unsafe code blocks</param>
/// <returns>The resulting compilation</returns>
- public static async Task<Compilation> CreateCompilation(SyntaxTree[] sources, TestTargetFramework targetFramework = TestTargetFramework.Net, OutputKind outputKind = OutputKind.DynamicallyLinkedLibrary, IEnumerable<MetadataReference>? refs = null)
+ public static async Task<Compilation> CreateCompilation(SyntaxTree[] sources, TestTargetFramework targetFramework = TestTargetFramework.Net, OutputKind outputKind = OutputKind.DynamicallyLinkedLibrary, IEnumerable<MetadataReference>? refs = null, bool allowUnsafe = true)
{
var referenceAssemblies = await GetReferenceAssemblies(targetFramework);
return CSharpCompilation.Create("compilation",
sources,
referenceAssemblies,
- new CSharpCompilationOptions(outputKind, allowUnsafe: true, specificDiagnosticOptions: BindingRedirectWarnings));
+ new CSharpCompilationOptions(outputKind, allowUnsafe: allowUnsafe, specificDiagnosticOptions: BindingRedirectWarnings));
}
/// <summary>
int c = NativeExportsNE.Sum(a, b);
Console.WriteLine($"{a} + {b} = {c}");
- c = 0;
NativeExportsNE.Sum(a, b, out c);
Console.WriteLine($"{a} + {b} = {c}");