From 678967bf2518fc4bcca1a98248e2997bc3ae151c Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Tue, 3 Jan 2023 13:24:54 -0800 Subject: [PATCH 1/2] Ensure that we don't root the compilation when using a custom exception marshalling type. --- .../VirtualMethodIndexData.cs | 32 +++++++++++++++++-- .../VtableIndexStubGenerator.cs | 20 ++++++------ 2 files changed, 40 insertions(+), 12 deletions(-) diff --git a/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/VirtualMethodIndexData.cs b/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/VirtualMethodIndexData.cs index c5a7b93f492ed..bc582854d1013 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/VirtualMethodIndexData.cs +++ b/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/VirtualMethodIndexData.cs @@ -6,9 +6,37 @@ namespace Microsoft.Interop { /// - /// VirtualMethodIndexAttribute data + /// Contains the data related to a VirtualMethodIndexAttribute, without references to Roslyn symbols. + /// See for a type with a reference to the StringMarshallingCustomType /// - internal sealed record VirtualMethodIndexData(int Index) : InteropAttributeCompilationData + internal sealed record VirtualMethodIndexData(int Index) : InteropAttributeData + { + public bool ImplicitThisParameter { get; init; } + + public MarshalDirection Direction { get; init; } + + public bool ExceptionMarshallingDefined { get; init; } + + public ExceptionMarshalling ExceptionMarshalling { get; init; } + + public static VirtualMethodIndexData From(VirtualMethodIndexCompilationData virtualMethodIndex) + => new VirtualMethodIndexData(virtualMethodIndex.Index) with + { + ImplicitThisParameter = virtualMethodIndex.ImplicitThisParameter, + Direction = virtualMethodIndex.Direction, + ExceptionMarshallingDefined = virtualMethodIndex.ExceptionMarshallingDefined, + ExceptionMarshalling = virtualMethodIndex.ExceptionMarshalling, + IsUserDefined = virtualMethodIndex.IsUserDefined, + SetLastError = virtualMethodIndex.SetLastError, + StringMarshalling = virtualMethodIndex.StringMarshalling + }; + } + + /// + /// Contains the data related to a VirtualMethodIndexAttribute, with references to Roslyn symbols. + /// Use instead when using for incremental compilation state to avoid keeping a compilation alive + /// + internal sealed record VirtualMethodIndexCompilationData(int Index) : InteropAttributeCompilationData { public bool ImplicitThisParameter { get; init; } diff --git a/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/VtableIndexStubGenerator.cs b/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/VtableIndexStubGenerator.cs index 669db87f806ed..c92244da6c50f 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/VtableIndexStubGenerator.cs +++ b/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/VtableIndexStubGenerator.cs @@ -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. @@ -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) @@ -224,7 +224,7 @@ 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) { @@ -232,7 +232,7 @@ private static MethodDeclarationSyntax PrintGeneratedSource( } 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. @@ -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) { @@ -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, @@ -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) { @@ -371,7 +371,7 @@ private static IncrementalStubGenerationContext CalculateStubInformation(MethodD methodSyntaxTemplate, new MethodSignatureDiagnosticLocations(syntax), new SequenceEqualImmutableArray(callConv, SyntaxEquivalentComparer.Instance), - virtualMethodIndexData, + VirtualMethodIndexData.From(virtualMethodIndexData), exceptionMarshallingInfo, ComInterfaceGeneratorHelpers.CreateGeneratorFactory(environment, MarshalDirection.ManagedToUnmanaged), ComInterfaceGeneratorHelpers.CreateGeneratorFactory(environment, MarshalDirection.UnmanagedToManaged), @@ -380,7 +380,7 @@ private static IncrementalStubGenerationContext CalculateStubInformation(MethodD new SequenceEqualImmutableArray(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) { From 77febaba9a14ee62af791f4fe4e34d33e9ba2deb Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Tue, 3 Jan 2023 14:18:27 -0800 Subject: [PATCH 2/2] Use constructor parameters instead of manual properties --- .../VirtualMethodIndexData.cs | 25 +++++++++---------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/VirtualMethodIndexData.cs b/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/VirtualMethodIndexData.cs index bc582854d1013..350413a10ab71 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/VirtualMethodIndexData.cs +++ b/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/VirtualMethodIndexData.cs @@ -9,23 +9,22 @@ namespace Microsoft.Interop /// Contains the data related to a VirtualMethodIndexAttribute, without references to Roslyn symbols. /// See for a type with a reference to the StringMarshallingCustomType /// - internal sealed record VirtualMethodIndexData(int Index) : InteropAttributeData + internal sealed record VirtualMethodIndexData( + int Index, + bool ImplicitThisParameter, + MarshalDirection Direction, + bool ExceptionMarshallingDefined, + ExceptionMarshalling ExceptionMarshalling) : InteropAttributeData { - public bool ImplicitThisParameter { get; init; } - - public MarshalDirection Direction { get; init; } - - public bool ExceptionMarshallingDefined { get; init; } - - public ExceptionMarshalling ExceptionMarshalling { get; init; } public static VirtualMethodIndexData From(VirtualMethodIndexCompilationData virtualMethodIndex) - => new VirtualMethodIndexData(virtualMethodIndex.Index) with + => new VirtualMethodIndexData( + virtualMethodIndex.Index, + virtualMethodIndex.ImplicitThisParameter, + virtualMethodIndex.Direction, + virtualMethodIndex.ExceptionMarshallingDefined, + virtualMethodIndex.ExceptionMarshalling) { - ImplicitThisParameter = virtualMethodIndex.ImplicitThisParameter, - Direction = virtualMethodIndex.Direction, - ExceptionMarshallingDefined = virtualMethodIndex.ExceptionMarshallingDefined, - ExceptionMarshalling = virtualMethodIndex.ExceptionMarshalling, IsUserDefined = virtualMethodIndex.IsUserDefined, SetLastError = virtualMethodIndex.SetLastError, StringMarshalling = virtualMethodIndex.StringMarshalling