Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ensure that we don't root the compilation when using a custom exception marshalling type. #80147

Merged
merged 2 commits into from
Jan 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,36 @@
namespace Microsoft.Interop
{
/// <summary>
/// VirtualMethodIndexAttribute data
/// Contains the data related to a VirtualMethodIndexAttribute, without references to Roslyn symbols.
/// See <seealso cref="VirtualMethodIndexCompilationData"/> for a type with a reference to the StringMarshallingCustomType
/// </summary>
internal sealed record VirtualMethodIndexData(int Index) : InteropAttributeCompilationData
internal sealed record VirtualMethodIndexData(
int Index,
bool ImplicitThisParameter,
MarshalDirection Direction,
bool ExceptionMarshallingDefined,
ExceptionMarshalling ExceptionMarshalling) : InteropAttributeData
{

public static VirtualMethodIndexData From(VirtualMethodIndexCompilationData virtualMethodIndex)
=> new VirtualMethodIndexData(
virtualMethodIndex.Index,
virtualMethodIndex.ImplicitThisParameter,
virtualMethodIndex.Direction,
virtualMethodIndex.ExceptionMarshallingDefined,
virtualMethodIndex.ExceptionMarshalling)
{
IsUserDefined = virtualMethodIndex.IsUserDefined,
SetLastError = virtualMethodIndex.SetLastError,
StringMarshalling = virtualMethodIndex.StringMarshalling
};
}

/// <summary>
/// Contains the data related to a VirtualMethodIndexAttribute, with references to Roslyn symbols.
/// Use <seealso cref="VirtualMethodIndexData"/> instead when using for incremental compilation state to avoid keeping a compilation alive
/// </summary>
internal sealed record VirtualMethodIndexCompilationData(int Index) : InteropAttributeCompilationData
{
public bool ImplicitThisParameter { get; init; }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ private static MethodDeclarationSyntax PrintGeneratedSource(
.WithBody(stubCode);
}

private static VirtualMethodIndexData? ProcessVirtualMethodIndexAttribute(AttributeData attrData)
private static VirtualMethodIndexCompilationData? ProcessVirtualMethodIndexAttribute(AttributeData attrData)
{
// Found the attribute, but it has an error so report the error.
// This is most likely an issue with targeting an incorrect TFM.
Expand All @@ -214,7 +214,7 @@ private static MethodDeclarationSyntax PrintGeneratedSource(
bool exceptionMarshallingDefined = false;
ExceptionMarshalling exceptionMarshalling = ExceptionMarshalling.Custom;
INamedTypeSymbol? exceptionMarshallingCustomType = null;
if (namedArguments.TryGetValue(nameof(VirtualMethodIndexData.Direction), out TypedConstant directionValue))
if (namedArguments.TryGetValue(nameof(VirtualMethodIndexCompilationData.Direction), out TypedConstant directionValue))
{
// TypedConstant's Value property only contains primitive values.
if (directionValue.Value is not int)
Expand All @@ -224,15 +224,15 @@ private static MethodDeclarationSyntax PrintGeneratedSource(
// A boxed primitive can be unboxed to an enum with the same underlying type.
direction = (MarshalDirection)directionValue.Value!;
}
if (namedArguments.TryGetValue(nameof(VirtualMethodIndexData.ImplicitThisParameter), out TypedConstant implicitThisValue))
if (namedArguments.TryGetValue(nameof(VirtualMethodIndexCompilationData.ImplicitThisParameter), out TypedConstant implicitThisValue))
{
if (implicitThisValue.Value is not bool)
{
return null;
}
implicitThis = (bool)implicitThisValue.Value!;
}
if (namedArguments.TryGetValue(nameof(VirtualMethodIndexData.ExceptionMarshalling), out TypedConstant exceptionMarshallingValue))
if (namedArguments.TryGetValue(nameof(VirtualMethodIndexCompilationData.ExceptionMarshalling), out TypedConstant exceptionMarshallingValue))
{
exceptionMarshallingDefined = true;
// TypedConstant's Value property only contains primitive values.
Expand All @@ -243,7 +243,7 @@ private static MethodDeclarationSyntax PrintGeneratedSource(
// A boxed primitive can be unboxed to an enum with the same underlying type.
exceptionMarshalling = (ExceptionMarshalling)exceptionMarshallingValue.Value!;
}
if (namedArguments.TryGetValue(nameof(VirtualMethodIndexData.ExceptionMarshallingCustomType), out TypedConstant exceptionMarshallingCustomTypeValue))
if (namedArguments.TryGetValue(nameof(VirtualMethodIndexCompilationData.ExceptionMarshallingCustomType), out TypedConstant exceptionMarshallingCustomTypeValue))
{
if (exceptionMarshallingCustomTypeValue.Value is not INamedTypeSymbol)
{
Expand All @@ -252,7 +252,7 @@ private static MethodDeclarationSyntax PrintGeneratedSource(
exceptionMarshallingCustomType = (INamedTypeSymbol)exceptionMarshallingCustomTypeValue.Value;
}

return new VirtualMethodIndexData((int)attrData.ConstructorArguments[0].Value).WithValuesFromNamedArguments(namedArguments) with
return new VirtualMethodIndexCompilationData((int)attrData.ConstructorArguments[0].Value).WithValuesFromNamedArguments(namedArguments) with
{
Direction = direction,
ImplicitThisParameter = implicitThis,
Expand Down Expand Up @@ -300,11 +300,11 @@ private static IncrementalStubGenerationContext CalculateStubInformation(MethodD
var generatorDiagnostics = new GeneratorDiagnostics();

// Process the LibraryImport attribute
VirtualMethodIndexData? virtualMethodIndexData = ProcessVirtualMethodIndexAttribute(virtualMethodIndexAttr!);
VirtualMethodIndexCompilationData? virtualMethodIndexData = ProcessVirtualMethodIndexAttribute(virtualMethodIndexAttr!);

if (virtualMethodIndexData is null)
{
virtualMethodIndexData = new VirtualMethodIndexData(-1);
virtualMethodIndexData = new VirtualMethodIndexCompilationData(-1);
}
else if (virtualMethodIndexData.Index < 0)
{
Expand Down Expand Up @@ -371,7 +371,7 @@ private static IncrementalStubGenerationContext CalculateStubInformation(MethodD
methodSyntaxTemplate,
new MethodSignatureDiagnosticLocations(syntax),
new SequenceEqualImmutableArray<FunctionPointerUnmanagedCallingConventionSyntax>(callConv, SyntaxEquivalentComparer.Instance),
virtualMethodIndexData,
VirtualMethodIndexData.From(virtualMethodIndexData),
exceptionMarshallingInfo,
ComInterfaceGeneratorHelpers.CreateGeneratorFactory(environment, MarshalDirection.ManagedToUnmanaged),
ComInterfaceGeneratorHelpers.CreateGeneratorFactory(environment, MarshalDirection.UnmanagedToManaged),
Expand All @@ -380,7 +380,7 @@ private static IncrementalStubGenerationContext CalculateStubInformation(MethodD
new SequenceEqualImmutableArray<Diagnostic>(generatorDiagnostics.Diagnostics.ToImmutableArray()));
}

private static MarshallingInfo CreateExceptionMarshallingInfo(AttributeData virtualMethodIndexAttr, ISymbol symbol, Compilation compilation, GeneratorDiagnostics diagnostics, VirtualMethodIndexData virtualMethodIndexData)
private static MarshallingInfo CreateExceptionMarshallingInfo(AttributeData virtualMethodIndexAttr, ISymbol symbol, Compilation compilation, GeneratorDiagnostics diagnostics, VirtualMethodIndexCompilationData virtualMethodIndexData)
{
if (virtualMethodIndexData.ExceptionMarshallingDefined)
{
Expand Down