Remove unused usings and simplify access to CodeAnalysis.Location.
Cache the attributes searched for in incremental stub calculations.
Add warning if unsafe blocks are not allowed.
Removes assert in ComMethodInfo that was throwing when editing files in the test project.
Co-authored-by: Jeremy Koritzinsky <jkoritzinsky@gmail.com>
/// </summary>
internal sealed record ComInterfaceAndMethodsContext(ComInterfaceContext Interface, SequenceEqualImmutableArray<ComMethodContext> Methods)
{
- // Change Calc all methods to return an ordered list of all the methods and the data in comInterfaceandMethodsContext
- // Have a step that runs CalculateMethodStub on each of them.
- // Call GroupMethodsByInterfaceForGeneration
-
/// <summary>
/// COM methods that are declared on the attributed interface declaration.
/// </summary>
: null)
.Where(
static modelData => modelData is not null);
-
- var interfaceSymbolOrDiagnostics = attributedInterfaces.Select(static (data, ct) =>
+ var stubEnvironment = context.CreateStubEnvironmentProvider();
+ var interfaceSymbolOrDiagnostics = attributedInterfaces.Combine(stubEnvironment).Select(static (data, ct) =>
{
- return ComInterfaceInfo.From(data.Symbol, data.Syntax, ct);
+ return ComInterfaceInfo.From(data.Left.Symbol, data.Left.Syntax, data.Right, ct);
});
var interfaceSymbolsWithoutDiagnostics = context.FilterAndReportDiagnostics(interfaceSymbolOrDiagnostics);
var comMethodsAndSymbolsOrDiagnostics = interfaceSymbolsWithoutDiagnostics.Select(ComMethodInfo.GetMethodsFromInterface);
var methodInfoAndSymbolGroupedByInterface = context
- .FilterAndReportDiagnostics<(ComMethodInfo MethodInfo, IMethodSymbol Symbol)> (comMethodsAndSymbolsOrDiagnostics);
+ .FilterAndReportDiagnostics<(ComMethodInfo MethodInfo, IMethodSymbol Symbol)>(comMethodsAndSymbolsOrDiagnostics);
var methodInfosGroupedByInterface = methodInfoAndSymbolGroupedByInterface
.Select(static (methods, ct) =>
.Select((data, ct) => data.ToDictionary(static x => x.MethodInfo, static x => x.Symbol));
var comMethodContexts = comMethodContextBuilders
.Combine(methodInfoToSymbolMap)
- .Combine(context.CreateStubEnvironmentProvider())
+ .Combine(stubEnvironment)
.Select((param, ct) =>
{
var ((data, symbolMap), env) = param;
private static IncrementalMethodStubGenerationContext CalculateStubInformation(MethodDeclarationSyntax syntax, IMethodSymbol symbol, int index, StubEnvironment environment, ManagedTypeInfo owningInterface, CancellationToken ct)
{
ct.ThrowIfCancellationRequested();
- INamedTypeSymbol? lcidConversionAttrType = environment.Compilation.GetTypeByMetadataName(TypeNames.LCIDConversionAttribute);
- INamedTypeSymbol? suppressGCTransitionAttrType = environment.Compilation.GetTypeByMetadataName(TypeNames.SuppressGCTransitionAttribute);
- INamedTypeSymbol? unmanagedCallConvAttrType = environment.Compilation.GetTypeByMetadataName(TypeNames.UnmanagedCallConvAttribute);
+ INamedTypeSymbol? lcidConversionAttrType = environment.LcidConversionAttrType;
+ INamedTypeSymbol? suppressGCTransitionAttrType = environment.SuppressGCTransitionAttrType;
+ INamedTypeSymbol? unmanagedCallConvAttrType = environment.UnmanagedCallConvAttrType;
// Get any attributes of interest on the method
AttributeData? lcidConversionAttr = null;
AttributeData? suppressGCTransitionAttribute = null;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
-using Microsoft.Interop;
-using DiagnosticOrInterfaceInfo = Microsoft.Interop.DiagnosticOr<(Microsoft.Interop.ComInterfaceInfo InterfaceInfo, Microsoft.CodeAnalysis.INamedTypeSymbol Symbol) >;
+using DiagnosticOrInterfaceInfo = Microsoft.Interop.DiagnosticOr<(Microsoft.Interop.ComInterfaceInfo InterfaceInfo, Microsoft.CodeAnalysis.INamedTypeSymbol Symbol)>;
namespace Microsoft.Interop
{
Guid InterfaceId,
Location DiagnosticLocation)
{
- public static DiagnosticOrInterfaceInfo From(INamedTypeSymbol symbol, InterfaceDeclarationSyntax syntax, CancellationToken _)
+ public static DiagnosticOrInterfaceInfo From(INamedTypeSymbol symbol, InterfaceDeclarationSyntax syntax, StubEnvironment env, CancellationToken _)
{
+ if (env.Compilation.Options is not CSharpCompilationOptions { AllowUnsafe: true }) // Unsafe code enabled
+ return DiagnosticOrInterfaceInfo.From(DiagnosticInfo.Create(GeneratorDiagnostics.RequiresAllowUnsafeBlocks, syntax.Identifier.GetLocation()));
// Verify the method has no generic types or defined implementation
// and is not marked static or sealed
if (syntax.TypeParameterList is not null)
{
- // Verify the interface has no generic types or defined implementation
- // and is not marked static or sealed
- if (syntax.TypeParameterList is not null)
- {
- return DiagnosticOrInterfaceInfo.From(
- DiagnosticInfo.Create(
- GeneratorDiagnostics.InvalidAttributedInterfaceGenericNotSupported,
- syntax.Identifier.GetLocation(),
- symbol.Name));
- }
+ return DiagnosticOrInterfaceInfo.From(
+ DiagnosticInfo.Create(
+ GeneratorDiagnostics.InvalidAttributedInterfaceGenericNotSupported,
+ syntax.Identifier.GetLocation(),
+ symbol.Name));
}
- // Verify that the types the interface is declared in are marked partial.
- for (SyntaxNode? parentNode = syntax; parentNode is TypeDeclarationSyntax typeDecl; parentNode = parentNode.Parent)
- {
- if (!typeDecl.Modifiers.Any(SyntaxKind.PartialKeyword))
- {
- return DiagnosticOrInterfaceInfo.From(
- DiagnosticInfo.Create(
- GeneratorDiagnostics.InvalidAttributedInterfaceMissingPartialModifiers,
- syntax.Identifier.GetLocation(),
- symbol.Name,
- typeDecl.Identifier));
- }
- }
+ if (!IsInPartialContext(symbol, syntax, out DiagnosticInfo? partialContextDiagnostic))
+ return DiagnosticOrInterfaceInfo.From(partialContextDiagnostic);
if (!TryGetGuid(symbol, syntax, out Guid? guid, out DiagnosticInfo? guidDiagnostic))
return DiagnosticOrInterfaceInfo.From(guidDiagnostic);
new ContainingSyntaxContext(syntax),
new ContainingSyntax(syntax.Modifiers, syntax.Kind(), syntax.Identifier, syntax.TypeParameterList),
guid ?? Guid.Empty,
- symbol.Locations[0]),
+ syntax.Identifier.GetLocation()),
symbol));
}
+ private static bool IsInPartialContext(INamedTypeSymbol symbol, InterfaceDeclarationSyntax syntax, [NotNullWhen(false)] out DiagnosticInfo? diagnostic)
+ {
+ // Verify that the types the interface is declared in are marked partial.
+ for (SyntaxNode? parentNode = syntax; parentNode is TypeDeclarationSyntax typeDecl; parentNode = parentNode.Parent)
+ {
+ if (!typeDecl.Modifiers.Any(SyntaxKind.PartialKeyword))
+ {
+ diagnostic = DiagnosticInfo.Create(
+ GeneratorDiagnostics.InvalidAttributedInterfaceMissingPartialModifiers,
+ syntax.Identifier.GetLocation(),
+ symbol.Name,
+ typeDecl.Identifier);
+ return false;
+ }
+ }
+ diagnostic = null;
+ return true;
+ }
+
private static bool StringMarshallingIsValid(INamedTypeSymbol symbol, InterfaceDeclarationSyntax syntax, INamedTypeSymbol? baseSymbol, [NotNullWhen(false)] out DiagnosticInfo? stringMarshallingDiagnostic)
{
var attrInfo = GeneratedComInterfaceData.From(GeneratedComInterfaceCompilationData.GetAttributeDataFromInterfaceSymbol(symbol));
public const string InvalidLibraryImportAttributeUsage = Prefix + "1050";
public const string TypeNotSupported = Prefix + "1051";
public const string ConfigurationNotSupported = Prefix + "1052";
+ public const string RequiresAllowUnsafeBlocks = Prefix + "1062";
public const string InvalidGeneratedComInterfaceAttributeUsage = Prefix + "1090";
public const string MethodNotDeclaredInAttributedInterface = Prefix + "1091";
public const string MultipleComInterfaceBaseTypes = Prefix + "1092";
private const string Category = "ComInterfaceGenerator";
+ 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)));
+
/// <inheritdoc cref="SR.InvalidAttributedMethodSignatureMessage"/>
public static readonly DiagnosticDescriptor InvalidAttributedMethodSignature =
new DiagnosticDescriptor(
TypePositionInfo info,
string? notSupportedDetails)
{
- CodeAnalysis.Location diagnosticLocation = CodeAnalysis.Location.None;
+ Location diagnosticLocation = CodeAnalysis.Location.None;
string elementName = string.Empty;
if (info.IsManagedReturnPosition)
<data name="InvalidStringMarshallingConfigurationOnInterfaceMessage" xml:space="preserve">
<value>The configuration of 'StringMarshalling' and 'StringMarshallingCustomType' on interface '{0}' is invalid. {1}</value>
</data>
+ <data name="RequiresAllowUnsafeBlocksDescription" xml:space="preserve">
+ <value>GeneratedComInterfaceAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</value>
+ </data>
+ <data name="RequiresAllowUnsafeBlocksMessage" xml:space="preserve">
+ <value>GeneratedComInterfaceAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</value>
+ </data>
+ <data name="RequiresAllowUnsafeBlocksTitle" xml:space="preserve">
+ <value>GeneratedComInterfaceAttribute requires unsafe code.</value>
+ </data>
<data name="InvalidGeneratedComInterfaceUsageMissingPartialModifier" xml:space="preserve">
<value>The interface '{0}' or one of its containing types is missing the 'partial' keyword. Code will not be generated for '{0}'.</value>
</data>
<target state="translated">Zadané rozhraní je odvozeno ze dvou nebo více rozhraní s atributem GeneratedComInterfaceAttribute.</target>
<note />
</trans-unit>
+ <trans-unit id="RequiresAllowUnsafeBlocksDescription">
+ <source>GeneratedComInterfaceAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</source>
+ <target state="new">GeneratedComInterfaceAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="RequiresAllowUnsafeBlocksMessage">
+ <source>GeneratedComInterfaceAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</source>
+ <target state="new">GeneratedComInterfaceAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="RequiresAllowUnsafeBlocksTitle">
+ <source>GeneratedComInterfaceAttribute requires unsafe code.</source>
+ <target state="new">GeneratedComInterfaceAttribute requires unsafe code.</target>
+ <note />
+ </trans-unit>
<trans-unit id="RuntimeComApisDoNotSupportSourceGeneratedComDescription">
<source>COM Interop APIs on 'System.Runtime.InteropServices.Marshal' do not support source-generated COM and will fail at runtime</source>
<target state="new">COM Interop APIs on 'System.Runtime.InteropServices.Marshal' do not support source-generated COM and will fail at runtime</target>
<target state="translated">Die angegebene Schnittstelle wird von mindestens zwei Schnittstellen abgeleitet, die "GeneratedComInterfaceAttribute" zugeordnet sind.</target>
<note />
</trans-unit>
+ <trans-unit id="RequiresAllowUnsafeBlocksDescription">
+ <source>GeneratedComInterfaceAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</source>
+ <target state="new">GeneratedComInterfaceAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="RequiresAllowUnsafeBlocksMessage">
+ <source>GeneratedComInterfaceAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</source>
+ <target state="new">GeneratedComInterfaceAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="RequiresAllowUnsafeBlocksTitle">
+ <source>GeneratedComInterfaceAttribute requires unsafe code.</source>
+ <target state="new">GeneratedComInterfaceAttribute requires unsafe code.</target>
+ <note />
+ </trans-unit>
<trans-unit id="RuntimeComApisDoNotSupportSourceGeneratedComDescription">
<source>COM Interop APIs on 'System.Runtime.InteropServices.Marshal' do not support source-generated COM and will fail at runtime</source>
<target state="new">COM Interop APIs on 'System.Runtime.InteropServices.Marshal' do not support source-generated COM and will fail at runtime</target>
<target state="translated">La interfaz especificada deriva de dos o más interfaces con atributos "GeneratedComInterfaceAttribute".</target>
<note />
</trans-unit>
+ <trans-unit id="RequiresAllowUnsafeBlocksDescription">
+ <source>GeneratedComInterfaceAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</source>
+ <target state="new">GeneratedComInterfaceAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="RequiresAllowUnsafeBlocksMessage">
+ <source>GeneratedComInterfaceAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</source>
+ <target state="new">GeneratedComInterfaceAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="RequiresAllowUnsafeBlocksTitle">
+ <source>GeneratedComInterfaceAttribute requires unsafe code.</source>
+ <target state="new">GeneratedComInterfaceAttribute requires unsafe code.</target>
+ <note />
+ </trans-unit>
<trans-unit id="RuntimeComApisDoNotSupportSourceGeneratedComDescription">
<source>COM Interop APIs on 'System.Runtime.InteropServices.Marshal' do not support source-generated COM and will fail at runtime</source>
<target state="new">COM Interop APIs on 'System.Runtime.InteropServices.Marshal' do not support source-generated COM and will fail at runtime</target>
<target state="translated">L’interface spécifiée dérive de deux ou plusieurs interfaces avec attribut 'GeneratedComInterfaceAttribute'.</target>
<note />
</trans-unit>
+ <trans-unit id="RequiresAllowUnsafeBlocksDescription">
+ <source>GeneratedComInterfaceAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</source>
+ <target state="new">GeneratedComInterfaceAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="RequiresAllowUnsafeBlocksMessage">
+ <source>GeneratedComInterfaceAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</source>
+ <target state="new">GeneratedComInterfaceAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="RequiresAllowUnsafeBlocksTitle">
+ <source>GeneratedComInterfaceAttribute requires unsafe code.</source>
+ <target state="new">GeneratedComInterfaceAttribute requires unsafe code.</target>
+ <note />
+ </trans-unit>
<trans-unit id="RuntimeComApisDoNotSupportSourceGeneratedComDescription">
<source>COM Interop APIs on 'System.Runtime.InteropServices.Marshal' do not support source-generated COM and will fail at runtime</source>
<target state="new">COM Interop APIs on 'System.Runtime.InteropServices.Marshal' do not support source-generated COM and will fail at runtime</target>
<target state="translated">L'interfaccia specificata deriva da due o più interfacce con attributi 'GeneratedComInterfaceAttribute'.</target>
<note />
</trans-unit>
+ <trans-unit id="RequiresAllowUnsafeBlocksDescription">
+ <source>GeneratedComInterfaceAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</source>
+ <target state="new">GeneratedComInterfaceAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="RequiresAllowUnsafeBlocksMessage">
+ <source>GeneratedComInterfaceAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</source>
+ <target state="new">GeneratedComInterfaceAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="RequiresAllowUnsafeBlocksTitle">
+ <source>GeneratedComInterfaceAttribute requires unsafe code.</source>
+ <target state="new">GeneratedComInterfaceAttribute requires unsafe code.</target>
+ <note />
+ </trans-unit>
<trans-unit id="RuntimeComApisDoNotSupportSourceGeneratedComDescription">
<source>COM Interop APIs on 'System.Runtime.InteropServices.Marshal' do not support source-generated COM and will fail at runtime</source>
<target state="new">COM Interop APIs on 'System.Runtime.InteropServices.Marshal' do not support source-generated COM and will fail at runtime</target>
<target state="translated">指定されたインターフェイスは、2 つ以上の 'GeneratedComInterfaceAttribute' 属性インターフェイスから派生しています。</target>
<note />
</trans-unit>
+ <trans-unit id="RequiresAllowUnsafeBlocksDescription">
+ <source>GeneratedComInterfaceAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</source>
+ <target state="new">GeneratedComInterfaceAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="RequiresAllowUnsafeBlocksMessage">
+ <source>GeneratedComInterfaceAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</source>
+ <target state="new">GeneratedComInterfaceAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="RequiresAllowUnsafeBlocksTitle">
+ <source>GeneratedComInterfaceAttribute requires unsafe code.</source>
+ <target state="new">GeneratedComInterfaceAttribute requires unsafe code.</target>
+ <note />
+ </trans-unit>
<trans-unit id="RuntimeComApisDoNotSupportSourceGeneratedComDescription">
<source>COM Interop APIs on 'System.Runtime.InteropServices.Marshal' do not support source-generated COM and will fail at runtime</source>
<target state="new">COM Interop APIs on 'System.Runtime.InteropServices.Marshal' do not support source-generated COM and will fail at runtime</target>
<target state="translated">지정한 인터페이스는 두 개 이상의 'GeneratedComInterfaceAttribute' 특성 인터페이스에서 파생됩니다.</target>
<note />
</trans-unit>
+ <trans-unit id="RequiresAllowUnsafeBlocksDescription">
+ <source>GeneratedComInterfaceAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</source>
+ <target state="new">GeneratedComInterfaceAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="RequiresAllowUnsafeBlocksMessage">
+ <source>GeneratedComInterfaceAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</source>
+ <target state="new">GeneratedComInterfaceAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="RequiresAllowUnsafeBlocksTitle">
+ <source>GeneratedComInterfaceAttribute requires unsafe code.</source>
+ <target state="new">GeneratedComInterfaceAttribute requires unsafe code.</target>
+ <note />
+ </trans-unit>
<trans-unit id="RuntimeComApisDoNotSupportSourceGeneratedComDescription">
<source>COM Interop APIs on 'System.Runtime.InteropServices.Marshal' do not support source-generated COM and will fail at runtime</source>
<target state="new">COM Interop APIs on 'System.Runtime.InteropServices.Marshal' do not support source-generated COM and will fail at runtime</target>
<target state="translated">Określony interfejs pochodzi z co najmniej dwóch interfejsów z atrybutem „GeneratedComInterfaceAttribute”.</target>
<note />
</trans-unit>
+ <trans-unit id="RequiresAllowUnsafeBlocksDescription">
+ <source>GeneratedComInterfaceAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</source>
+ <target state="new">GeneratedComInterfaceAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="RequiresAllowUnsafeBlocksMessage">
+ <source>GeneratedComInterfaceAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</source>
+ <target state="new">GeneratedComInterfaceAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="RequiresAllowUnsafeBlocksTitle">
+ <source>GeneratedComInterfaceAttribute requires unsafe code.</source>
+ <target state="new">GeneratedComInterfaceAttribute requires unsafe code.</target>
+ <note />
+ </trans-unit>
<trans-unit id="RuntimeComApisDoNotSupportSourceGeneratedComDescription">
<source>COM Interop APIs on 'System.Runtime.InteropServices.Marshal' do not support source-generated COM and will fail at runtime</source>
<target state="new">COM Interop APIs on 'System.Runtime.InteropServices.Marshal' do not support source-generated COM and will fail at runtime</target>
<target state="translated">A interface especificada deriva de duas ou mais interfaces atribuídas a 'GeneratedComInterfaceAttribute'.</target>
<note />
</trans-unit>
+ <trans-unit id="RequiresAllowUnsafeBlocksDescription">
+ <source>GeneratedComInterfaceAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</source>
+ <target state="new">GeneratedComInterfaceAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="RequiresAllowUnsafeBlocksMessage">
+ <source>GeneratedComInterfaceAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</source>
+ <target state="new">GeneratedComInterfaceAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="RequiresAllowUnsafeBlocksTitle">
+ <source>GeneratedComInterfaceAttribute requires unsafe code.</source>
+ <target state="new">GeneratedComInterfaceAttribute requires unsafe code.</target>
+ <note />
+ </trans-unit>
<trans-unit id="RuntimeComApisDoNotSupportSourceGeneratedComDescription">
<source>COM Interop APIs on 'System.Runtime.InteropServices.Marshal' do not support source-generated COM and will fail at runtime</source>
<target state="new">COM Interop APIs on 'System.Runtime.InteropServices.Marshal' do not support source-generated COM and will fail at runtime</target>
<target state="translated">Указанный интерфейс является производным от двух или более интерфейсов с атрибутом "GeneratedComInterfaceAttribute".</target>
<note />
</trans-unit>
+ <trans-unit id="RequiresAllowUnsafeBlocksDescription">
+ <source>GeneratedComInterfaceAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</source>
+ <target state="new">GeneratedComInterfaceAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="RequiresAllowUnsafeBlocksMessage">
+ <source>GeneratedComInterfaceAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</source>
+ <target state="new">GeneratedComInterfaceAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="RequiresAllowUnsafeBlocksTitle">
+ <source>GeneratedComInterfaceAttribute requires unsafe code.</source>
+ <target state="new">GeneratedComInterfaceAttribute requires unsafe code.</target>
+ <note />
+ </trans-unit>
<trans-unit id="RuntimeComApisDoNotSupportSourceGeneratedComDescription">
<source>COM Interop APIs on 'System.Runtime.InteropServices.Marshal' do not support source-generated COM and will fail at runtime</source>
<target state="new">COM Interop APIs on 'System.Runtime.InteropServices.Marshal' do not support source-generated COM and will fail at runtime</target>
<target state="translated">Belirtilen arabirim 'GeneratedComInterfaceAttribute' özniteliğine sahip iki veya daha fazla arabirimden türetildi.</target>
<note />
</trans-unit>
+ <trans-unit id="RequiresAllowUnsafeBlocksDescription">
+ <source>GeneratedComInterfaceAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</source>
+ <target state="new">GeneratedComInterfaceAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="RequiresAllowUnsafeBlocksMessage">
+ <source>GeneratedComInterfaceAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</source>
+ <target state="new">GeneratedComInterfaceAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="RequiresAllowUnsafeBlocksTitle">
+ <source>GeneratedComInterfaceAttribute requires unsafe code.</source>
+ <target state="new">GeneratedComInterfaceAttribute requires unsafe code.</target>
+ <note />
+ </trans-unit>
<trans-unit id="RuntimeComApisDoNotSupportSourceGeneratedComDescription">
<source>COM Interop APIs on 'System.Runtime.InteropServices.Marshal' do not support source-generated COM and will fail at runtime</source>
<target state="new">COM Interop APIs on 'System.Runtime.InteropServices.Marshal' do not support source-generated COM and will fail at runtime</target>
<target state="translated">指定的接口派生自两个或更多“GeneratedComInterfaceAttribute”特性化接口。</target>
<note />
</trans-unit>
+ <trans-unit id="RequiresAllowUnsafeBlocksDescription">
+ <source>GeneratedComInterfaceAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</source>
+ <target state="new">GeneratedComInterfaceAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="RequiresAllowUnsafeBlocksMessage">
+ <source>GeneratedComInterfaceAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</source>
+ <target state="new">GeneratedComInterfaceAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="RequiresAllowUnsafeBlocksTitle">
+ <source>GeneratedComInterfaceAttribute requires unsafe code.</source>
+ <target state="new">GeneratedComInterfaceAttribute requires unsafe code.</target>
+ <note />
+ </trans-unit>
<trans-unit id="RuntimeComApisDoNotSupportSourceGeneratedComDescription">
<source>COM Interop APIs on 'System.Runtime.InteropServices.Marshal' do not support source-generated COM and will fail at runtime</source>
<target state="new">COM Interop APIs on 'System.Runtime.InteropServices.Marshal' do not support source-generated COM and will fail at runtime</target>
<target state="translated">指定的介面衍生自兩個或兩個以上的 'GeneratedComInterfaceAttribute'-屬性介面。</target>
<note />
</trans-unit>
+ <trans-unit id="RequiresAllowUnsafeBlocksDescription">
+ <source>GeneratedComInterfaceAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</source>
+ <target state="new">GeneratedComInterfaceAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="RequiresAllowUnsafeBlocksMessage">
+ <source>GeneratedComInterfaceAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</source>
+ <target state="new">GeneratedComInterfaceAttribute requires unsafe code. Project must be updated with '<AllowUnsafeBlocks>true</AllowUnsafeBlocks>'.</target>
+ <note />
+ </trans-unit>
+ <trans-unit id="RequiresAllowUnsafeBlocksTitle">
+ <source>GeneratedComInterfaceAttribute requires unsafe code.</source>
+ <target state="new">GeneratedComInterfaceAttribute requires unsafe code.</target>
+ <note />
+ </trans-unit>
<trans-unit id="RuntimeComApisDoNotSupportSourceGeneratedComDescription">
<source>COM Interop APIs on 'System.Runtime.InteropServices.Marshal' do not support source-generated COM and will fail at runtime</source>
<target state="new">COM Interop APIs on 'System.Runtime.InteropServices.Marshal' do not support source-generated COM and will fail at runtime</target>
using System.Collections.Immutable;
using System.Composition;
using System.Linq;
-using System.Runtime.InteropServices;
-using System.Text;
using System.Threading;
using System.Threading.Tasks;
-using System.Xml.Linq;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CodeActions;
using Microsoft.CodeAnalysis.CodeFixes;
-using Microsoft.CodeAnalysis.Differencing;
using Microsoft.CodeAnalysis.DotnetRuntime.Extensions;
using Microsoft.CodeAnalysis.Editing;
-using Microsoft.CodeAnalysis.Simplification;
-using Microsoft.CodeAnalysis.Text;
using static Microsoft.Interop.Analyzers.CustomMarshallerAttributeAnalyzer;
namespace Microsoft.Interop.Analyzers
// Get the managed type from the CustomMarshallerAttribute located at the provided location in source on the provided type.
// As we only get fixable diagnostics for types that have valid non-null managed types in the CustomMarshallerAttribute applications,
// we do not need to worry about the returned symbol being null.
- private static ITypeSymbol GetManagedTypeInAttributeSyntax(CodeAnalysis.Location locationInAttribute, INamedTypeSymbol attributedTypeSymbol)
+ private static ITypeSymbol GetManagedTypeInAttributeSyntax(Location locationInAttribute, INamedTypeSymbol attributedTypeSymbol)
=> (ITypeSymbol)attributedTypeSymbol.GetAttributes().First(attr =>
attr.ApplicationSyntaxReference.SyntaxTree == locationInAttribute.SourceTree
&& attr.ApplicationSyntaxReference.Span.Contains(locationInAttribute.SourceSpan)).ConstructorArguments[0].Value!;
_diagnosticFactory = createAndReportDiagnostic;
}
- public static DiagnosticReporter CreateForLocation(CodeAnalysis.Location location, Action<Diagnostic> reportDiagnostic) => new((descriptor, properties, args) => reportDiagnostic(location.CreateDiagnosticInfo(descriptor, properties, args).ToDiagnostic()));
+ public static DiagnosticReporter CreateForLocation(Location location, Action<Diagnostic> reportDiagnostic) => new((descriptor, properties, args) => reportDiagnostic(location.CreateDiagnosticInfo(descriptor, properties, args).ToDiagnostic()));
public void CreateAndReportDiagnostic(DiagnosticDescriptor descriptor, params object[] messageArgs) => _diagnosticFactory(descriptor, ImmutableDictionary<string, string>.Empty, messageArgs);
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
-using Microsoft.CodeAnalysis;
-using Microsoft.CodeAnalysis.CSharp.Syntax;
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
+using Microsoft.CodeAnalysis;
namespace Microsoft.Interop
{
string? notSupportedDetails,
ImmutableDictionary<string, string> diagnosticProperties)
{
- CodeAnalysis.Location diagnosticLocation = CodeAnalysis.Location.None;
+ Location diagnosticLocation = Location.None;
string elementName = string.Empty;
if (info.IsManagedReturnPosition)
// Validate if attributed methods can have source generated
var methodsWithDiagnostics = attributedMethods.Select(static (data, ct) =>
{
- Diagnostic? diagnostic = GetDiagnosticIfInvalidMethodForGeneration(data.Syntax, data.Symbol);
- return new { Syntax = data.Syntax, Symbol = data.Symbol, Diagnostic = diagnostic };
+ DiagnosticInfo? diagnostic = GetDiagnosticIfInvalidMethodForGeneration(data.Syntax, data.Symbol);
+ return diagnostic is not null
+ ? DiagnosticOr<(MethodDeclarationSyntax Syntax, IMethodSymbol Symbol)>.From(diagnostic)
+ : DiagnosticOr<(MethodDeclarationSyntax Syntax, IMethodSymbol Symbol)>.From((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);
- });
+ var methodsToGenerate = context.FilterAndReportDiagnostics(methodsWithDiagnostics);
// Compute generator options
IncrementalValueProvider<LibraryImportGeneratorOptions> stubOptions = context.AnalyzerConfigOptionsProvider
CancellationToken ct)
{
ct.ThrowIfCancellationRequested();
- INamedTypeSymbol? lcidConversionAttrType = environment.Compilation.GetTypeByMetadataName(TypeNames.LCIDConversionAttribute);
- INamedTypeSymbol? suppressGCTransitionAttrType = environment.Compilation.GetTypeByMetadataName(TypeNames.SuppressGCTransitionAttribute);
- INamedTypeSymbol? unmanagedCallConvAttrType = environment.Compilation.GetTypeByMetadataName(TypeNames.UnmanagedCallConvAttribute);
- INamedTypeSymbol? defaultDllImportSearchPathsAttrType = environment.Compilation.GetTypeByMetadataName(TypeNames.DefaultDllImportSearchPathsAttribute);
+ INamedTypeSymbol? lcidConversionAttrType = environment.LcidConversionAttrType;
+ INamedTypeSymbol? suppressGCTransitionAttrType = environment.SuppressGCTransitionAttrType;
+ INamedTypeSymbol? unmanagedCallConvAttrType = environment.UnmanagedCallConvAttrType;
+ INamedTypeSymbol? defaultDllImportSearchPathsAttrType = environment.DefaultDllImportSearchPathsAttrType;
// Get any attributes of interest on the method
AttributeData? generatedDllImportAttr = null;
AttributeData? lcidConversionAttr = null;
}
}
- private static Diagnostic? GetDiagnosticIfInvalidMethodForGeneration(MethodDeclarationSyntax methodSyntax, IMethodSymbol method)
+ private static DiagnosticInfo? GetDiagnosticIfInvalidMethodForGeneration(MethodDeclarationSyntax methodSyntax, IMethodSymbol method)
{
// Verify the method has no generic types or defined implementation
// and is marked static and partial.
|| !methodSyntax.Modifiers.Any(SyntaxKind.StaticKeyword)
|| !methodSyntax.Modifiers.Any(SyntaxKind.PartialKeyword))
{
- return Diagnostic.Create(GeneratorDiagnostics.InvalidAttributedMethodSignature, methodSyntax.Identifier.GetLocation(), method.Name);
+ return DiagnosticInfo.Create(GeneratorDiagnostics.InvalidAttributedMethodSignature, methodSyntax.Identifier.GetLocation(), method.Name);
}
// Verify that the types the method is declared in are marked partial.
{
if (!typeDecl.Modifiers.Any(SyntaxKind.PartialKeyword))
{
- return Diagnostic.Create(GeneratorDiagnostics.InvalidAttributedMethodContainingTypeMissingModifiers, methodSyntax.Identifier.GetLocation(), method.Name, typeDecl.Identifier);
+ return DiagnosticInfo.Create(GeneratorDiagnostics.InvalidAttributedMethodContainingTypeMissingModifiers, methodSyntax.Identifier.GetLocation(), method.Name, typeDecl.Identifier);
}
}
// Verify the method does not have a ref return
if (method.ReturnsByRef || method.ReturnsByRefReadonly)
{
- return Diagnostic.Create(GeneratorDiagnostics.ReturnConfigurationNotSupported, methodSyntax.Identifier.GetLocation(), "ref return", method.ToDisplayString());
+ return DiagnosticInfo.Create(GeneratorDiagnostics.ReturnConfigurationNotSupported, methodSyntax.Identifier.GetLocation(), "ref return", method.ToDisplayString());
}
return null;
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
-using System.Collections;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
properties: Properties?.Map,
messageArgs: MessageArgs.Array.ToArray());
- public static DiagnosticInfo Create(DiagnosticDescriptor descriptor, CodeAnalysis.Location location, params object?[] messageArgs)
+ public static DiagnosticInfo Create(DiagnosticDescriptor descriptor, Location location, params object?[] messageArgs)
{
return new DiagnosticInfo()
{
};
}
- public static DiagnosticInfo Create(DiagnosticDescriptor descriptor, CodeAnalysis.Location location, ImmutableDictionary<string, string>? properties, params object?[] messageArgs)
+ public static DiagnosticInfo Create(DiagnosticDescriptor descriptor, Location location, ImmutableDictionary<string, string>? properties, params object?[] messageArgs)
{
return new DiagnosticInfo()
{
};
}
- public static DiagnosticInfo Create(DiagnosticDescriptor descriptor, CodeAnalysis.Location location, IEnumerable<Location>? additionalLocations, ImmutableDictionary<string, string>? properties, params object?[] messageArgs)
+ public static DiagnosticInfo Create(DiagnosticDescriptor descriptor, Location location, IEnumerable<Location>? additionalLocations, ImmutableDictionary<string, string>? properties, params object?[] messageArgs)
{
return new DiagnosticInfo()
{
using System;
using System.Collections.Generic;
-using System.Collections.Immutable;
using System.Diagnostics;
-using System.Diagnostics.CodeAnalysis;
using System.Linq;
-using System.Runtime.InteropServices.ComTypes;
-using System.Text;
using Microsoft.CodeAnalysis;
-using Microsoft.CodeAnalysis.CSharp.Syntax;
namespace Microsoft.Interop
{
namespace Microsoft.Interop
{
- public sealed record MethodSignatureDiagnosticLocations(string MethodIdentifier, ImmutableArray<CodeAnalysis.Location> ManagedParameterLocations, CodeAnalysis.Location FallbackLocation)
+ public sealed record MethodSignatureDiagnosticLocations(string MethodIdentifier, ImmutableArray<Location> ManagedParameterLocations, Location FallbackLocation)
{
public MethodSignatureDiagnosticLocations(MethodDeclarationSyntax syntax)
: this(syntax.Identifier.Text, syntax.ParameterList.Parameters.Select(p => p.Identifier.GetLocation()).ToImmutableArray(), syntax.Identifier.GetLocation())
// The .NET Foundation licenses this file to you under the MIT license.
using System;
-
using Microsoft.CodeAnalysis;
namespace Microsoft.Interop
Compilation Compilation,
TargetFramework TargetFramework,
Version TargetFrameworkVersion,
- bool ModuleSkipLocalsInit);
+ bool ModuleSkipLocalsInit)
+ {
+ private Optional<INamedTypeSymbol?> _lcidConversionAttrType;
+ public INamedTypeSymbol? LcidConversionAttrType
+ {
+ get
+ {
+ if (_lcidConversionAttrType.HasValue)
+ {
+ return _lcidConversionAttrType.Value;
+ }
+ _lcidConversionAttrType = new Optional<INamedTypeSymbol?>(Compilation.GetTypeByMetadataName(TypeNames.LCIDConversionAttribute));
+ return _lcidConversionAttrType.Value;
+ }
+ }
+
+ private Optional<INamedTypeSymbol?> _suppressGCTransitionAttrType;
+ public INamedTypeSymbol? SuppressGCTransitionAttrType
+ {
+ get
+ {
+ if (_suppressGCTransitionAttrType.HasValue)
+ {
+ return _suppressGCTransitionAttrType.Value;
+ }
+ _suppressGCTransitionAttrType = new Optional<INamedTypeSymbol?>(Compilation.GetTypeByMetadataName(TypeNames.SuppressGCTransitionAttribute));
+ return _suppressGCTransitionAttrType.Value;
+ }
+ }
+
+ private Optional<INamedTypeSymbol?> _unmanagedCallConvAttrType;
+ public INamedTypeSymbol? UnmanagedCallConvAttrType
+ {
+ get
+ {
+ if (_unmanagedCallConvAttrType.HasValue)
+ {
+ return _unmanagedCallConvAttrType.Value;
+ }
+ _unmanagedCallConvAttrType = new Optional<INamedTypeSymbol?>(Compilation.GetTypeByMetadataName(TypeNames.UnmanagedCallConvAttribute));
+ return _unmanagedCallConvAttrType.Value;
+ }
+ }
+
+ private Optional<INamedTypeSymbol?> _defaultDllImportSearchPathsAttrType;
+ public INamedTypeSymbol? DefaultDllImportSearchPathsAttrType
+ {
+ get
+ {
+ if (_defaultDllImportSearchPathsAttrType.HasValue)
+ {
+ return _defaultDllImportSearchPathsAttrType.Value;
+ }
+ _defaultDllImportSearchPathsAttrType = new Optional<INamedTypeSymbol?>(Compilation.GetTypeByMetadataName(TypeNames.DefaultDllImportSearchPathsAttribute));
+ return _defaultDllImportSearchPathsAttrType.Value;
+ }
+ }
+ }
}
using System;
using System.Collections.Generic;
-using System.Collections.Immutable;
-using System.IO;
+using System.Diagnostics;
using System.Linq;
using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
+using System.Runtime.InteropServices.Marshalling;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.Testing;
using Microsoft.Interop;
using Microsoft.Interop.UnitTests;
using Xunit;
-using System.Diagnostics;
-
-using VerifyComInterfaceGenerator = Microsoft.Interop.UnitTests.Verifiers.CSharpSourceGeneratorVerifier<Microsoft.Interop.ComInterfaceGenerator>;
using StringMarshalling = System.Runtime.InteropServices.StringMarshalling;
-using System.Runtime.InteropServices.Marshalling;
-using Microsoft.CodeAnalysis.CSharp;
+using VerifyComInterfaceGenerator = Microsoft.Interop.UnitTests.Verifiers.CSharpSourceGeneratorVerifier<Microsoft.Interop.ComInterfaceGenerator>;
namespace ComInterfaceGenerator.Unit.Tests
{
await test.RunAsync();
}
+
+ [Fact]
+ public async Task VerifyDiagnosticIsOnAttributedSyntax()
+ {
+ string source = $$"""
+ using System.Runtime.InteropServices;
+ using System.Runtime.InteropServices.Marshalling;
+
+ partial interface J
+ {
+ }
+
+ [GeneratedComInterface]
+ partial interface {|#0:J|}
+ {
+ void Method();
+ }
+
+ partial interface J
+ {
+ }
+ """;
+ DiagnosticResult expectedDiagnostic = VerifyComInterfaceGenerator.Diagnostic(GeneratorDiagnostics.InvalidAttributedInterfaceMissingGuidAttribute)
+ .WithLocation(0).WithArguments("J");
+ await VerifyComInterfaceGenerator.VerifySourceGeneratorAsync(source, expectedDiagnostic);
+ }
+
+ internal class UnsafeBlocksNotAllowedTest : VerifyComInterfaceGenerator.Test
+ {
+ internal UnsafeBlocksNotAllowedTest(bool referenceAncillaryInterop) : base(referenceAncillaryInterop) { }
+ protected override CompilationOptions CreateCompilationOptions()
+ => new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary, allowUnsafe: false);
+ }
+
+ [Fact]
+ public async Task VerifyGeneratedComInterfaceWithoutAllowUnsafeBlocksWarns()
+ {
+ string source = $$"""
+ using System.Runtime.InteropServices;
+ using System.Runtime.InteropServices.Marshalling;
+
+ [GeneratedComInterface]
+ partial interface {|#0:J|}
+ {
+ void Method();
+ }
+ """;
+ DiagnosticResult expectedDiagnostic = VerifyComInterfaceGenerator.Diagnostic(GeneratorDiagnostics.RequiresAllowUnsafeBlocks)
+ .WithLocation(0);
+ var test = new UnsafeBlocksNotAllowedTest(false);
+ test.TestState.Sources.Add(source);
+ test.ExpectedDiagnostics.Add(expectedDiagnostic);
+ await test.RunAsync();
+ }
}
}