diff --git a/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/VirtualMethodIndexData.cs b/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/VirtualMethodIndexData.cs index c5a7b93f492ed..350413a10ab71 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/VirtualMethodIndexData.cs +++ b/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/VirtualMethodIndexData.cs @@ -6,9 +6,36 @@ 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, + 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 + }; + } + + /// + /// 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 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. @@ -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) @@ -224,7 +224,7 @@ 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) { @@ -232,7 +232,7 @@ private static SyntaxTokenList StripTriviaFromModifiers(SyntaxTokenList tokenLis } 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 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) { @@ -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, @@ -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) {