Skip to content

Commit

Permalink
Ensure that we don't root the compilation when using a custom excepti…
Browse files Browse the repository at this point in the history
…on marshalling type. (#80147)
  • Loading branch information
jkoritzinsky committed Jan 5, 2023
1 parent 02681cd commit 7952df7
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 12 deletions.
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 SyntaxTokenList StripTriviaFromModifiers(SyntaxTokenList tokenLis
.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 SyntaxTokenList StripTriviaFromModifiers(SyntaxTokenList tokenLis
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 SyntaxTokenList StripTriviaFromModifiers(SyntaxTokenList tokenLis
// 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 SyntaxTokenList StripTriviaFromModifiers(SyntaxTokenList tokenLis
// 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 SyntaxTokenList StripTriviaFromModifiers(SyntaxTokenList tokenLis
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

0 comments on commit 7952df7

Please sign in to comment.