diff --git a/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/AttributeInfo.cs b/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/AttributeInfo.cs index fed18f1eb50a6f..7f4b487ad976f6 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/AttributeInfo.cs +++ b/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/AttributeInfo.cs @@ -4,27 +4,17 @@ using System.Linq; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; -using Microsoft.CodeAnalysis.CSharp.Syntax; -using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory; namespace Microsoft.Interop { /// /// Provides the info necessary for copying an attribute from user code to generated code. /// - internal sealed record AttributeInfo(ManagedTypeInfo Type, SequenceEqualImmutableArray Arguments) + internal sealed record AttributeInfo(string Type, SequenceEqualImmutableArray Arguments) { - internal AttributeSyntax GenerateSyntax() - { - return Attribute((NameSyntax)Type.Syntax, AttributeArgumentList(SeparatedList(Arguments.Select(arg => AttributeArgument(ParseExpression(arg)))))); - } - internal AttributeListSyntax GenerateAttributeList() - { - return AttributeList(SingletonSeparatedList(GenerateSyntax())); - } internal static AttributeInfo From(AttributeData attribute) { - var type = ManagedTypeInfo.CreateTypeInfoForTypeSymbol(attribute.AttributeClass); + var type = attribute.AttributeClass.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat); var args = attribute.ConstructorArguments.Select(ca => ca.ToCSharpString()); return new(type, args.ToSequenceEqualImmutableArray()); } diff --git a/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/ComInterfaceGenerator.cs b/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/ComInterfaceGenerator.cs index 116ee786fb86cd..dad35781688f1a 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/ComInterfaceGenerator.cs +++ b/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/ComInterfaceGenerator.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; +using System.CodeDom.Compiler; using System.Collections.Generic; using System.Collections.Immutable; using System.IO; @@ -12,27 +13,12 @@ using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory; -using static Microsoft.Interop.SyntaxFactoryExtensions; namespace Microsoft.Interop { [Generator] public sealed partial class ComInterfaceGenerator : IIncrementalGenerator { - public static class StepNames - { - public const string CalculateStubInformation = nameof(CalculateStubInformation); - public const string GenerateManagedToNativeStub = nameof(GenerateManagedToNativeStub); - public const string GenerateNativeToManagedStub = nameof(GenerateNativeToManagedStub); - public const string GenerateManagedToNativeInterfaceImplementation = nameof(GenerateManagedToNativeInterfaceImplementation); - public const string GenerateNativeToManagedVTableMethods = nameof(GenerateNativeToManagedVTableMethods); - public const string GenerateNativeToManagedVTableStruct = nameof(GenerateNativeToManagedVTableStruct); - public const string GenerateNativeToManagedVTable = nameof(GenerateNativeToManagedVTable); - public const string GenerateInterfaceInformation = nameof(GenerateInterfaceInformation); - public const string GenerateIUnknownDerivedAttribute = nameof(GenerateIUnknownDerivedAttribute); - public const string GenerateShadowingMethods = nameof(GenerateShadowingMethods); - } - public void Initialize(IncrementalGeneratorInitializationContext context) { var stubEnvironment = context.CreateStubEnvironmentProvider(); @@ -143,99 +129,37 @@ public void Initialize(IncrementalGeneratorInitializationContext context) .SelectMany(static (data, ct) => GroupComContextsForInterfaceGeneration(data.Left.Array, data.Right, ct)); - // Generate the code for the managed-to-unmanaged stubs. - var syntaxes = interfaceAndMethodsContexts - .Select(static (x, ct) => new ItemAndSyntaxes(x, - [ - GenerateImplementationInterface(x, ct).NormalizeWhitespace(), - GenerateInterfaceImplementationVtable(x, ct).NormalizeWhitespace(), - GenerateImplementationVTableMethods(x, ct).NormalizeWhitespace(), - GenerateShadowingMethodsInterface(x), - GenerateImplementationVTable(x, ct).NormalizeWhitespace(), - GenerateInterfaceInformation(x.Interface.Info, ct).NormalizeWhitespace(), - GenerateIUnknownDerivedAttributeApplication(x.Interface.Info, ct).NormalizeWhitespace() - ])); - - var filesToGenerate = syntaxes - .Select(static (methodSyntaxes, ct) => + context.RegisterSourceOutput(interfaceAndMethodsContexts, static (context, data) => + { + ComInterfaceContext interfaceContext = data.Interface; + + using StringWriter sw = new(); + using IndentedTextWriter writer = new(sw); + writer.WriteLine("// "); + writer.WriteLine("#pragma warning disable CS0612, CS0618, CS0649, CS1591"); // Suppress warnings about [Obsolete], "lack of assignment", and missing XML documentation in generated code. + + // If the user has specified 'ManagedObjectWrapper', it means that the COM interface will never be used to marshal a native + // object as an RCW (eg. the IDIC vtable will also not be generated, nor any additional supporting code). To reduce binary + // size, we're not emitting the interface methods on the implementation interface that has '[DynamicInterfaceCastableImplementation]' + // on it. However, doing so will cause the CA2256 warning to be produced. We can't remove the attribute, as that would cause + // the wrong exception to be thrown when trying an IDIC cast with this interface (not 'InvalidCastException'). Because this is + // a niche scenario, and we don't want to regress perf or size, we can just disable the warning instead. + if (interfaceContext.Options is ComInterfaceOptions.ManagedObjectWrapper) { - var interfaceContext = methodSyntaxes.Context.Interface; - var managedToNativeInterfaceImplementations = (InterfaceDeclarationSyntax)methodSyntaxes[0]; - var nativeToManagedVtableStructs = (StructDeclarationSyntax)methodSyntaxes[1]; - var nativeToManagedStubs = (InterfaceDeclarationSyntax)methodSyntaxes[2]; - var shadowingMethod = (MemberDeclarationSyntax)methodSyntaxes[3]; - var nativeToManagedVtable = (InterfaceDeclarationSyntax)methodSyntaxes[4]; - var interfaceInfo = (ClassDeclarationSyntax)methodSyntaxes[5]; - var iUnknownDerivedAttribute = (MemberDeclarationSyntax)methodSyntaxes[6]; - - using StringWriter source = new(); - source.WriteLine("// "); - source.WriteLine("#pragma warning disable CS0612, CS0618, CS0649, CS1591"); // Suppress warnings about [Obsolete], "lack of assignment", and missing XML documentation in generated code. - - // If the user has specified 'ManagedObjectWrapper', it means that the COM interface will never be used to marshal a native - // object as an RCW (eg. the IDIC vtable will also not be generated, nor any additional supporting code). To reduce binary - // size, we're not emitting the interface methods on the implementation interface that has '[DynamicInterfaceCastableImplementation]' - // on it. However, doing so will cause the CA2256 warning to be produced. We can't remove the attribute, as that would cause - // the wrong exception to be thrown when trying an IDIC cast with this interface (not 'InvalidCastException'). Because this is - // a niche scenario, and we don't want to regress perf or size, we can just disable the warning instead. - if (interfaceContext.Options is ComInterfaceOptions.ManagedObjectWrapper) - { - source.WriteLine("#pragma warning disable CA2256"); - } + writer.WriteLine("#pragma warning disable CA2256"); + } - interfaceInfo.WriteTo(source); - // Two newlines looks cleaner than one - source.WriteLine(); - source.WriteLine(); - // TODO: Merge the three InterfaceImplementation partials? We have them all right here. - managedToNativeInterfaceImplementations.WriteTo(source); - source.WriteLine(); - source.WriteLine(); - nativeToManagedStubs.WriteTo(source); - source.WriteLine(); - source.WriteLine(); - nativeToManagedVtableStructs.WriteTo(source); - source.WriteLine(); - source.WriteLine(); - nativeToManagedVtable.WriteTo(source); - source.WriteLine(); - source.WriteLine(); - iUnknownDerivedAttribute.WriteTo(source); - source.WriteLine(); - source.WriteLine(); - shadowingMethod.WriteTo(source); - return new { TypeName = interfaceContext.Info.Type.FullTypeName, Source = source.ToString() }; - }); - - context.RegisterSourceOutput(filesToGenerate, static (context, data) => - { - context.AddSource(data.TypeName.Replace(TypeNames.GlobalAlias, ""), data.Source); - }); - } + sw.WriteLine(); + WriteImplementationVTableStruct(writer, data); + sw.WriteLine(); + WriteInterfaceInformation(writer, interfaceContext.Info); + sw.WriteLine(); + WriteInterfaceImplementation(writer, data); + sw.WriteLine(); + WriteIUnknownDerivedOriginalInterfacePart(writer, data); - private static readonly AttributeSyntax s_iUnknownDerivedAttributeTemplate = - Attribute( - GenericName(TypeNames.GlobalAlias + TypeNames.IUnknownDerivedAttribute) - .AddTypeArgumentListArguments( - IdentifierName("InterfaceInformation"), - IdentifierName("InterfaceImplementation"))); - - private static MemberDeclarationSyntax GenerateIUnknownDerivedAttributeApplication(ComInterfaceInfo context, CancellationToken _) - => context.TypeDefinitionContext.WrapMemberInContainingSyntaxWithUnsafeModifier( - TypeDeclaration(context.ContainingSyntax.TypeKind, context.ContainingSyntax.Identifier) - .WithModifiers(context.ContainingSyntax.Modifiers) - .WithTypeParameterList(context.ContainingSyntax.TypeParameters) - .AddAttributeLists(AttributeList(SingletonSeparatedList(s_iUnknownDerivedAttributeTemplate)))); - - private static MemberDeclarationSyntax GenerateShadowingMethodsInterface(ComInterfaceAndMethodsContext interfaceMethods) - { - var containingSyntax = interfaceMethods.Interface.Info.ContainingSyntax; - return interfaceMethods.Interface.Info.TypeDefinitionContext.WrapMemberInContainingSyntaxWithUnsafeModifier( - TypeDeclaration(containingSyntax.TypeKind, containingSyntax.Identifier) - .WithModifiers(containingSyntax.Modifiers.AddToModifiers(SyntaxKind.UnsafeKeyword)) - .WithTypeParameterList(containingSyntax.TypeParameters) - .WithMembers(List(interfaceMethods.ShadowingMethods.Select(m => m.Shadow)))) - .NormalizeWhitespace(); + context.AddSource(interfaceContext.Info.Type.FullTypeName.Replace(TypeNames.GlobalAlias, ""), sw.ToString()); + }); } private static bool IsHResultLikeType(ManagedTypeInfo type) @@ -542,108 +466,15 @@ static bool MethodEquals(ComMethodContext a, ComMethodContext b) } } - private static readonly InterfaceDeclarationSyntax ImplementationInterfaceTemplate = InterfaceDeclaration("InterfaceImplementation") - .WithModifiers(TokenList(Token(SyntaxKind.FileKeyword), Token(SyntaxKind.UnsafeKeyword), Token(SyntaxKind.PartialKeyword))); - - private static InterfaceDeclarationSyntax GenerateImplementationInterface(ComInterfaceAndMethodsContext interfaceGroup, CancellationToken _) - { - var definingType = interfaceGroup.Interface.Info.Type; - var shadowImplementations = interfaceGroup.InheritedMethods.Where(m => !m.IsExternallyDefined).Select(m => (Method: m, ManagedToUnmanagedStub: m.ManagedToUnmanagedStub)) - .Where(p => p.ManagedToUnmanagedStub is GeneratedStubCodeContext) - .Select(ctx => ((GeneratedStubCodeContext)ctx.ManagedToUnmanagedStub).Stub.Node - .WithExplicitInterfaceSpecifier( - ExplicitInterfaceSpecifier(ParseName(definingType.FullTypeName)))); - var inheritedStubs = interfaceGroup.InheritedMethods.Where(m => !m.IsExternallyDefined).Select(m => m.UnreachableExceptionStub); - return ImplementationInterfaceTemplate - .AddBaseListTypes(SimpleBaseType(definingType.Syntax)) - .WithMembers( - List( - interfaceGroup.DeclaredMethods - .Select(m => m.ManagedToUnmanagedStub) - .OfType() - .Select(ctx => ctx.Stub.Node) - .Concat(shadowImplementations) - .Concat(inheritedStubs))) - .AddAttributeLists(AttributeList(SingletonSeparatedList(Attribute(NameSyntaxes.System_Runtime_InteropServices_DynamicInterfaceCastableImplementationAttribute)))); - } - - private static InterfaceDeclarationSyntax GenerateImplementationVTableMethods(ComInterfaceAndMethodsContext comInterfaceAndMethods, CancellationToken _) + private static void WriteImplementationVTableStruct(IndentedTextWriter writer, ComInterfaceAndMethodsContext interfaceMethods) { - return ImplementationInterfaceTemplate - .WithMembers( - List( - comInterfaceAndMethods.DeclaredMethods - .Select(m => m.UnmanagedToManagedStub) - .OfType() - .Where(context => context.Diagnostics.All(diag => diag.Descriptor.DefaultSeverity != DiagnosticSeverity.Error)) - .Select(context => context.Stub.Node))); - } - - private static readonly StructDeclarationSyntax InterfaceImplementationVtableTemplate = StructDeclaration("InterfaceImplementationVtable") - .WithModifiers(TokenList(Token(SyntaxKind.FileKeyword), Token(SyntaxKind.UnsafeKeyword))); - - private static StructDeclarationSyntax GenerateInterfaceImplementationVtable(ComInterfaceAndMethodsContext interfaceMethods, CancellationToken _) - { - StructDeclarationSyntax vtableDeclaration = - InterfaceImplementationVtableTemplate - .AddMembers( - FieldDeclaration( - VariableDeclaration( - FunctionPointerType( - FunctionPointerCallingConvention( - Token(SyntaxKind.UnmanagedKeyword), - FunctionPointerUnmanagedCallingConventionList( - SingletonSeparatedList( - FunctionPointerUnmanagedCallingConvention(Identifier("MemberFunction"))))), - FunctionPointerParameterList( - SeparatedList([ - FunctionPointerParameter(TypeSyntaxes.VoidStar), - FunctionPointerParameter(PointerType(TypeSyntaxes.System_Guid)), - FunctionPointerParameter(TypeSyntaxes.VoidStarStar), - FunctionPointerParameter(ParseTypeName("int"))])))) - .AddVariables(VariableDeclarator("QueryInterface_0"))) - .WithModifiers(TokenList(Token(SyntaxKind.PublicKeyword))), - FieldDeclaration( - VariableDeclaration( - FunctionPointerType( - FunctionPointerCallingConvention( - Token(SyntaxKind.UnmanagedKeyword), - FunctionPointerUnmanagedCallingConventionList( - SingletonSeparatedList( - FunctionPointerUnmanagedCallingConvention(Identifier("MemberFunction"))))), - FunctionPointerParameterList( - SeparatedList([ - FunctionPointerParameter(TypeSyntaxes.VoidStar), - FunctionPointerParameter(ParseTypeName("uint"))])))) - .AddVariables(VariableDeclarator("AddRef_1"))) - .WithModifiers(TokenList(Token(SyntaxKind.PublicKeyword))), - FieldDeclaration( - VariableDeclaration( - FunctionPointerType( - FunctionPointerCallingConvention( - Token(SyntaxKind.UnmanagedKeyword), - FunctionPointerUnmanagedCallingConventionList( - SingletonSeparatedList( - FunctionPointerUnmanagedCallingConvention(Identifier("MemberFunction"))))), - FunctionPointerParameterList( - SeparatedList([ - FunctionPointerParameter(TypeSyntaxes.VoidStar), - FunctionPointerParameter(ParseTypeName("uint"))])))) - .AddVariables(VariableDeclarator("Release_2"))) - .WithModifiers(TokenList(Token(SyntaxKind.PublicKeyword)))) - .AddAttributeLists( - AttributeList( - SingletonSeparatedList( - Attribute( - NameSyntaxes.System_Runtime_InteropServices_StructLayoutAttribute, - AttributeArgumentList( - SingletonSeparatedList( - AttributeArgument( - MemberAccessExpression( - SyntaxKind.SimpleMemberAccessExpression, - TypeSyntaxes.System_Runtime_InteropServices_LayoutKind, - IdentifierName("Sequential"))))))))); - + writer.WriteLine("[global::System.Runtime.InteropServices.StructLayoutAttribute(global::System.Runtime.InteropServices.LayoutKind.Sequential)]"); + writer.WriteLine("file unsafe struct InterfaceImplementationVtable"); + writer.WriteLine('{'); + writer.Indent++; + writer.WriteLine("public delegate* unmanaged[MemberFunction] QueryInterface_0;"); + writer.WriteLine("public delegate* unmanaged[MemberFunction] AddRef_1;"); + writer.WriteLine("public delegate* unmanaged[MemberFunction] Release_2;"); if (interfaceMethods.Interface.Base is not null) { foreach (ComMethodContext inheritedMethod in interfaceMethods.InheritedMethods) @@ -652,239 +483,168 @@ private static StructDeclarationSyntax GenerateInterfaceImplementationVtable(Com inheritedMethod.GenerationContext, ComInterfaceGeneratorHelpers.GetGeneratorResolver); - vtableDeclaration = vtableDeclaration - .AddMembers( - FieldDeclaration( - VariableDeclaration(functionPointerType) - .AddVariables(VariableDeclarator($"{inheritedMethod.MethodInfo.MethodName}_{inheritedMethod.GenerationContext.VtableIndexData.Index}"))) - .WithModifiers(TokenList(Token(SyntaxKind.PublicKeyword)))); + writer.WriteLine($"public {functionPointerType.NormalizeWhitespace()} {inheritedMethod.MethodInfo.MethodName}_{inheritedMethod.GenerationContext.VtableIndexData.Index};"); } } foreach (ComMethodContext declaredMethod in interfaceMethods.DeclaredMethods - .Where(context => context.UnmanagedToManagedStub.Diagnostics.All(diag => diag.Descriptor.DefaultSeverity != DiagnosticSeverity.Error))) + .Where(context => context.UnmanagedToManagedStub.Diagnostics.All(diag => diag.Descriptor.DefaultSeverity != DiagnosticSeverity.Error))) { FunctionPointerTypeSyntax functionPointerType = VirtualMethodPointerStubGenerator.GenerateUnmanagedFunctionPointerTypeForMethod( - declaredMethod.GenerationContext, - ComInterfaceGeneratorHelpers.GetGeneratorResolver); + declaredMethod.GenerationContext, + ComInterfaceGeneratorHelpers.GetGeneratorResolver); - vtableDeclaration = vtableDeclaration - .AddMembers( - FieldDeclaration( - VariableDeclaration(functionPointerType) - .AddVariables(VariableDeclarator($"{declaredMethod.MethodInfo.MethodName}_{declaredMethod.GenerationContext.VtableIndexData.Index}"))) - .WithModifiers(TokenList(Token(SyntaxKind.PublicKeyword)))); + writer.WriteLine($"public {functionPointerType.NormalizeWhitespace()} {declaredMethod.MethodInfo.MethodName}_{declaredMethod.GenerationContext.VtableIndexData.Index};"); } - return vtableDeclaration; + writer.Indent--; + writer.WriteLine('}'); } - private static InterfaceDeclarationSyntax GenerateImplementationVTable(ComInterfaceAndMethodsContext interfaceMethods, CancellationToken _) + private static void WriteInterfaceInformation(IndentedTextWriter writer, ComInterfaceInfo interfaceInfo) { - if (!interfaceMethods.Interface.Options.HasFlag(ComInterfaceOptions.ManagedObjectWrapper)) - { - return ImplementationInterfaceTemplate; - } + writer.WriteLine("file unsafe sealed class InterfaceInformation : global::System.Runtime.InteropServices.Marshalling.IIUnknownInterfaceType"); + writer.WriteLine('{'); + writer.Indent++; + writer.WriteLine($"public static global::System.Guid Iid {{ get; }} = new([{string.Join(", ", interfaceInfo.InterfaceId.ToByteArray())}]);"); + writer.WriteLine($"public static void** ManagedVirtualMethodTable => {(interfaceInfo.Options.HasFlag(ComInterfaceOptions.ManagedObjectWrapper) ? "(void**)global::System.Runtime.CompilerServices.Unsafe.AsPointer(in InterfaceImplementation.Vtable)" : "null")};"); + writer.Indent--; + writer.WriteLine('}'); + } - BlockSyntax fillBaseInterfaceSlots; + private static void WriteInterfaceImplementation(IndentedTextWriter writer, ComInterfaceAndMethodsContext data) + { + writer.WriteLine("[global::System.Runtime.InteropServices.DynamicInterfaceCastableImplementationAttribute]"); + writer.WriteLine($"file unsafe interface InterfaceImplementation : {data.Interface.Info.Type.FullTypeName}"); + writer.WriteLine('{'); + writer.Indent++; - if (interfaceMethods.Interface.Base is null) + if (data.Interface.Options.HasFlag(ComInterfaceOptions.ManagedObjectWrapper)) { - // If we don't have a base interface, we need to manually fill in the base iUnknown slots. - fillBaseInterfaceSlots = Block() - .AddStatements( - // ComWrappers.GetIUnknownImpl( - // out *(nint*)&((InterfaceImplementationVtable*)Unsafe.AsPointer(ref Vtable))->QueryInterface_0, - // out *(nint*)&((InterfaceImplementationVtable*)Unsafe.AsPointer(ref Vtable))->AddRef_1, - // out *(nint*)&((InterfaceImplementationVtable*)Unsafe.AsPointer(ref Vtable))->Release_2); - MethodInvocationStatement( - TypeSyntaxes.System_Runtime_InteropServices_ComWrappers, - IdentifierName("GetIUnknownImpl"), - OutArgument( - PrefixUnaryExpression( - SyntaxKind.PointerIndirectionExpression, - CastExpression( - PointerType(ParseTypeName("nint")), - PrefixUnaryExpression( - SyntaxKind.AddressOfExpression, - MemberAccessExpression( - SyntaxKind.PointerMemberAccessExpression, - ParenthesizedExpression( - CastExpression( - PointerType(ParseTypeName("InterfaceImplementationVtable")), - InvocationExpression( - MemberAccessExpression( - SyntaxKind.SimpleMemberAccessExpression, - TypeSyntaxes.System_Runtime_CompilerServices_Unsafe, - IdentifierName("AsPointer"))) - .AddArgumentListArguments( - Argument( - RefExpression(IdentifierName("Vtable")))))), - IdentifierName("QueryInterface_0")))))), - OutArgument( - PrefixUnaryExpression( - SyntaxKind.PointerIndirectionExpression, - CastExpression( - PointerType(ParseTypeName("nint")), - PrefixUnaryExpression( - SyntaxKind.AddressOfExpression, - MemberAccessExpression( - SyntaxKind.PointerMemberAccessExpression, - ParenthesizedExpression( - CastExpression( - PointerType(ParseTypeName("InterfaceImplementationVtable")), - InvocationExpression( - MemberAccessExpression( - SyntaxKind.SimpleMemberAccessExpression, - TypeSyntaxes.System_Runtime_CompilerServices_Unsafe, - IdentifierName("AsPointer"))) - .AddArgumentListArguments( - Argument( - RefExpression(IdentifierName("Vtable")))))), - IdentifierName("AddRef_1")))))), - OutArgument( - PrefixUnaryExpression( - SyntaxKind.PointerIndirectionExpression, - CastExpression( - PointerType(ParseTypeName("nint")), - PrefixUnaryExpression( - SyntaxKind.AddressOfExpression, - MemberAccessExpression( - SyntaxKind.PointerMemberAccessExpression, - ParenthesizedExpression( - CastExpression( - PointerType(ParseTypeName("InterfaceImplementationVtable")), - InvocationExpression( - MemberAccessExpression( - SyntaxKind.SimpleMemberAccessExpression, - TypeSyntaxes.System_Runtime_CompilerServices_Unsafe, - IdentifierName("AsPointer"))) - .AddArgumentListArguments( - Argument( - RefExpression(IdentifierName("Vtable")))))), - IdentifierName("Release_2")))))))); + writer.WriteLine("[global::System.Runtime.CompilerServices.FixedAddressValueTypeAttribute]"); + writer.WriteLine("public static readonly InterfaceImplementationVtable Vtable;"); + writer.InnerWriter.WriteLine(); + writer.WriteLine("static InterfaceImplementation()"); + writer.WriteLine('{'); + writer.Indent++; + + if (data.Interface.Base is { } baseInterface) + { + writer.WriteLine("global::System.Runtime.InteropServices.NativeMemory.Copy("); + writer.Indent++; + writer.WriteLine($"global::System.Runtime.InteropServices.Marshalling.StrategyBasedComWrappers.DefaultIUnknownInterfaceDetailsStrategy.GetIUnknownDerivedDetails(typeof({baseInterface.Info.Type.FullTypeName}).TypeHandle).ManagedVirtualMethodTable,"); + writer.WriteLine("global::System.Runtime.CompilerServices.Unsafe.AsPointer(ref Vtable),"); + writer.WriteLine($"(nuint)(sizeof(void*) * {data.BaseVTableSize}));"); + writer.Indent--; + } + else + { + // If we don't have a base interface, we need to manually fill in the base IUnknown slots. + writer.WriteLine("global::System.Runtime.InteropServices.ComWrappers.GetIUnknownImpl("); + writer.Indent++; + writer.WriteLine("out *(nint*)&((InterfaceImplementationVtable*)global::System.Runtime.CompilerServices.Unsafe.AsPointer(ref Vtable))->QueryInterface_0,"); + writer.WriteLine("out *(nint*)&((InterfaceImplementationVtable*)global::System.Runtime.CompilerServices.Unsafe.AsPointer(ref Vtable))->AddRef_1,"); + writer.WriteLine("out *(nint*)&((InterfaceImplementationVtable*)global::System.Runtime.CompilerServices.Unsafe.AsPointer(ref Vtable))->Release_2);"); + writer.Indent--; + } + + writer.InnerWriter.WriteLine(); + + foreach (ComMethodContext declaredMethodContext in data.DeclaredMethods + .Where(context => context.UnmanagedToManagedStub.Diagnostics.All(diag => diag.Descriptor.DefaultSeverity != DiagnosticSeverity.Error))) + { + writer.WriteLine($"Vtable.{declaredMethodContext.MethodInfo.MethodName}_{declaredMethodContext.GenerationContext.VtableIndexData.Index} = &ABI_{((SourceAvailableIncrementalMethodStubGenerationContext)declaredMethodContext.GenerationContext).StubMethodSyntaxTemplate.Identifier};"); + } + + writer.Indent--; + writer.WriteLine('}'); } - else + + foreach (ComMethodContext declaredMethod in data.DeclaredMethods) { - // NativeMemory.Copy(StrategyBasedComWrappers.DefaultIUnknownInterfaceDetailsStrategy.GetIUnknownDerivedDetails(typeof().TypeHandle).ManagedVirtualMethodTable, vtable, (nuint)(sizeof(void*) * )); - fillBaseInterfaceSlots = Block( - MethodInvocationStatement( - TypeSyntaxes.System_Runtime_InteropServices_NativeMemory, - IdentifierName("Copy"), - Argument( - MethodInvocation( - TypeSyntaxes.StrategyBasedComWrappers - .Dot(IdentifierName("DefaultIUnknownInterfaceDetailsStrategy")), - IdentifierName("GetIUnknownDerivedDetails"), - Argument( - TypeOfExpression(ParseTypeName(interfaceMethods.Interface.Base.Info.Type.FullTypeName)) - .Dot(IdentifierName("TypeHandle")))) - .Dot(IdentifierName("ManagedVirtualMethodTable"))), - Argument( - InvocationExpression( - MemberAccessExpression( - SyntaxKind.SimpleMemberAccessExpression, - TypeSyntaxes.System_Runtime_CompilerServices_Unsafe, - IdentifierName("AsPointer"))) - .AddArgumentListArguments( - Argument( - RefExpression(IdentifierName("Vtable"))))), - Argument(CastExpression(IdentifierName("nuint"), - ParenthesizedExpression( - BinaryExpression(SyntaxKind.MultiplyExpression, - SizeOfExpression(PointerType(PredefinedType(Token(SyntaxKind.VoidKeyword)))), - LiteralExpression(SyntaxKind.NumericLiteralExpression, Literal(interfaceMethods.BaseVTableSize)))))))); + if (declaredMethod.ManagedToUnmanagedStub is GeneratedStubCodeContext managedToUnmanagedContext) + { + writer.InnerWriter.WriteLine(); + writer.WriteMultilineNode(managedToUnmanagedContext.Stub.Node.NormalizeWhitespace()); + } + + if (declaredMethod.UnmanagedToManagedStub is GeneratedStubCodeContext unmanagedToManagedContext && + unmanagedToManagedContext.Diagnostics.All(static d => d.Descriptor.DefaultSeverity != DiagnosticSeverity.Error)) + { + writer.InnerWriter.WriteLine(); + writer.WriteMultilineNode(unmanagedToManagedContext.Stub.Node.NormalizeWhitespace()); + } } - var validDeclaredMethods = interfaceMethods.DeclaredMethods - .Where(context => context.UnmanagedToManagedStub.Diagnostics.All(diag => diag.Descriptor.DefaultSeverity != DiagnosticSeverity.Error)); + foreach (ComMethodContext inheritedStub in data.InheritedMethods) + { + if (inheritedStub is not { IsExternallyDefined: false, ManagedToUnmanagedStub: GeneratedStubCodeContext shadowImplementationContextContext }) + { + continue; + } + + MethodDeclarationSyntax preparedNode = shadowImplementationContextContext.Stub.Node + .WithExplicitInterfaceSpecifier( + ExplicitInterfaceSpecifier(ParseName(data.Interface.Info.Type.FullTypeName))) + .NormalizeWhitespace(); - System.Collections.Generic.List statements = new(); + writer.InnerWriter.WriteLine(); + writer.WriteMultilineNode(preparedNode); + } - foreach (var declaredMethodContext in validDeclaredMethods) + foreach (ComMethodContext inheritedStub in data.InheritedMethods) { - statements.Add( - ExpressionStatement( - AssignmentExpression( - SyntaxKind.SimpleAssignmentExpression, - MemberAccessExpression( - SyntaxKind.SimpleMemberAccessExpression, - IdentifierName("Vtable"), - IdentifierName($"{declaredMethodContext.MethodInfo.MethodName}_{declaredMethodContext.GenerationContext.VtableIndexData.Index}")), - PrefixUnaryExpression( - SyntaxKind.AddressOfExpression, - IdentifierName($"ABI_{((SourceAvailableIncrementalMethodStubGenerationContext)declaredMethodContext.GenerationContext).StubMethodSyntaxTemplate.Identifier}"))))); + if (inheritedStub.IsExternallyDefined) + { + continue; + } + + writer.InnerWriter.WriteLine(); + writer.Write($"{inheritedStub.GenerationContext.SignatureContext.StubReturnType} {inheritedStub.OriginalDeclaringInterface.Info.Type.FullTypeName}.{inheritedStub.MethodInfo.MethodName}"); + writer.Write($"({string.Join(", ", inheritedStub.GenerationContext.SignatureContext.StubParameters.Select(p => p.NormalizeWhitespace().ToString()))})"); + writer.WriteLine(" => throw new global::System.Diagnostics.UnreachableException();"); } - return ImplementationInterfaceTemplate - .AddMembers( - FieldDeclaration( - VariableDeclaration(ParseTypeName("InterfaceImplementationVtable")) - .AddVariables(VariableDeclarator("Vtable"))) - .WithModifiers(TokenList(Token(SyntaxKind.PublicKeyword), Token(SyntaxKind.StaticKeyword), Token(SyntaxKind.ReadOnlyKeyword))) - .AddAttributeLists( - AttributeList( - SingletonSeparatedList( - Attribute(NameSyntaxes.System_Runtime_CompilerServices_FixedAddressValueTypeAttribute)))), - ConstructorDeclaration("InterfaceImplementation") - .AddModifiers(Token(SyntaxKind.StaticKeyword)) - .WithBody( - Block( - fillBaseInterfaceSlots, - Block(statements)))); + writer.Indent--; + writer.WriteLine('}'); } - private static readonly ClassDeclarationSyntax InterfaceInformationTypeTemplate = - ClassDeclaration("InterfaceInformation") - .AddModifiers(Token(SyntaxKind.FileKeyword), Token(SyntaxKind.UnsafeKeyword)) - .AddBaseListTypes(SimpleBaseType(TypeSyntaxes.IIUnknownInterfaceType)); - - private static ClassDeclarationSyntax GenerateInterfaceInformation(ComInterfaceInfo context, CancellationToken _) + private static void WriteIUnknownDerivedOriginalInterfacePart(IndentedTextWriter writer, ComInterfaceAndMethodsContext data) { - ClassDeclarationSyntax interfaceInformationType = InterfaceInformationTypeTemplate - .AddMembers( - // public static System.Guid Iid { get; } = new(); - PropertyDeclaration(TypeSyntaxes.System_Guid, "Iid") - .AddModifiers(Token(SyntaxKind.PublicKeyword), Token(SyntaxKind.StaticKeyword)) - .AddAccessorListAccessors( - AccessorDeclaration(SyntaxKind.GetAccessorDeclaration).WithSemicolonToken(Token(SyntaxKind.SemicolonToken))) - .WithInitializer( - EqualsValueClause( - ImplicitObjectCreationExpression() - .AddArgumentListArguments( - Argument(ComInterfaceGeneratorHelpers.CreateEmbeddedDataBlobCreationStatement(context.InterfaceId.ToByteArray()))))) - .WithSemicolonToken(Token(SyntaxKind.SemicolonToken))); - - if (context.Options.HasFlag(ComInterfaceOptions.ManagedObjectWrapper)) + data.Interface.Info.TypeDefinitionContext.WriteToWithUnsafeModifier(writer, (data.Interface.Info.ContainingSyntax, data.ShadowingMethods), static (writer, data) => { - return interfaceInformationType.AddMembers( - // public static void** VirtualMethodTableManagedImplementation => (void**)System.Runtime.CompilerServices.Unsafe.AsPointer(in InterfaceImplementation.Vtable); - PropertyDeclaration(TypeSyntaxes.VoidStarStar, "ManagedVirtualMethodTable") - .AddModifiers(Token(SyntaxKind.PublicKeyword), Token(SyntaxKind.StaticKeyword)) - .WithExpressionBody( - ArrowExpressionClause( - CastExpression( - PointerType(PointerType(ParseTypeName("void"))), - InvocationExpression( - MemberAccessExpression( - SyntaxKind.SimpleMemberAccessExpression, - TypeSyntaxes.System_Runtime_CompilerServices_Unsafe, - IdentifierName("AsPointer"))) - .AddArgumentListArguments( - InArgument( - MemberAccessExpression( - SyntaxKind.SimpleMemberAccessExpression, - IdentifierName("InterfaceImplementation"), - IdentifierName("Vtable"))))))) - .WithSemicolonToken(Token(SyntaxKind.SemicolonToken))); - } + (ContainingSyntax syntax, IEnumerable? shadowingMethods) = data; + + writer.WriteLine("[global::System.Runtime.InteropServices.Marshalling.IUnknownDerivedAttribute]"); + writer.WriteLine($"{string.Join(" ", syntax.Modifiers.AddToModifiers(SyntaxKind.UnsafeKeyword))} {syntax.TypeKind.GetDeclarationKeyword()} {syntax.Identifier}{syntax.TypeParameters}"); + writer.WriteLine('{'); + writer.Indent++; + + foreach (ComMethodContext shadow in shadowingMethods) + { + IncrementalMethodStubGenerationContext generationContext = shadow.GenerationContext; + SignatureContext sigContext = generationContext.SignatureContext; + + foreach (AttributeListSyntax additionalAttr in sigContext.AdditionalAttributes) + { + writer.WriteLine(additionalAttr.NormalizeWhitespace().ToString()); + } + + foreach (AttributeInfo attrInfo in shadow.MethodInfo.Attributes) + { + writer.WriteLine($"[{attrInfo.Type}({string.Join(", ", attrInfo.Arguments)})]"); + } + + writer.Write($"new {sigContext.StubReturnType} {shadow.MethodInfo.MethodName}"); + writer.Write($"({string.Join(", ", sigContext.StubParameters.Select(p => p.NormalizeWhitespace().ToString()))})"); + writer.Write($" => (({shadow.OriginalDeclaringInterface.Info.Type.FullTypeName})this).{shadow.MethodInfo.MethodName}"); + writer.WriteLine($"({string.Join(", ", sigContext.ManagedParameters.Select(mp => $"{(mp.IsByRef ? $"{MarshallerHelpers.GetManagedArgumentRefKindKeyword(mp)} " : "")}{mp.InstanceIdentifier}"))});"); + } - return interfaceInformationType.AddMembers( - PropertyDeclaration(TypeSyntaxes.VoidStarStar, "ManagedVirtualMethodTable") - .AddModifiers(Token(SyntaxKind.PublicKeyword), Token(SyntaxKind.StaticKeyword)) - .WithExpressionBody(ArrowExpressionClause(LiteralExpression(SyntaxKind.NullLiteralExpression))) - .WithSemicolonToken(Token(SyntaxKind.SemicolonToken))); + writer.Indent--; + writer.WriteLine('}'); + }); } } } diff --git a/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/ComMethodContext.cs b/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/ComMethodContext.cs index d2327e0cafdb34..a9d55aab0649e1 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/ComMethodContext.cs +++ b/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/ComMethodContext.cs @@ -6,10 +6,6 @@ using System.Collections.Immutable; using System.Linq; using System.Threading; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp; -using Microsoft.CodeAnalysis.CSharp.Syntax; -using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory; namespace Microsoft.Interop { @@ -113,57 +109,6 @@ private GeneratedMethodContextBase CreateUnmanagedToManagedStub() return new GeneratedStubCodeContext(sourceAvailableContext.OriginalDefiningType, sourceAvailableContext.ContainingSyntaxContext, new(methodStub), new(diagnostics)); } - private MethodDeclarationSyntax? _unreachableExceptionStub; - - public MethodDeclarationSyntax UnreachableExceptionStub => _unreachableExceptionStub ??= CreateUnreachableExceptionStub(); - - private MethodDeclarationSyntax CreateUnreachableExceptionStub() - { - // DeclarationCopiedFromBaseDeclaration() => throw new UnreachableException(); - return MethodInfo.Syntax - .WithReturnType(GenerationContext.SignatureContext.StubReturnType) - .WithModifiers(TokenList()) - .WithAttributeLists(List()) - .WithExplicitInterfaceSpecifier(ExplicitInterfaceSpecifier( - ParseName(OriginalDeclaringInterface.Info.Type.FullTypeName))) - .WithParameterList(ParameterList(SeparatedList(GenerationContext.SignatureContext.StubParameters))) - .WithExpressionBody(ArrowExpressionClause( - ThrowExpression( - ObjectCreationExpression( - TypeSyntaxes.UnreachableException) - .WithArgumentList(ArgumentList())))); - } - - private MethodDeclarationSyntax? _shadow; - - public MethodDeclarationSyntax Shadow => _shadow ??= GenerateShadow(); - - private MethodDeclarationSyntax GenerateShadow() - { - // DeclarationCopiedFromBaseDeclaration() - // => (()this).(); - return MethodDeclaration(GenerationContext.SignatureContext.StubReturnType, MethodInfo.MethodName) - .WithModifiers(TokenList(Token(SyntaxKind.NewKeyword))) - .WithAttributeLists(List(GenerationContext.SignatureContext.AdditionalAttributes.Concat(MethodInfo.Attributes.Select(a => a.GenerateAttributeList())))) - .WithParameterList(ParameterList(SeparatedList(GenerationContext.SignatureContext.StubParameters))) - .WithExpressionBody( - ArrowExpressionClause( - InvocationExpression( - MemberAccessExpression( - SyntaxKind.SimpleMemberAccessExpression, - ParenthesizedExpression( - CastExpression(OriginalDeclaringInterface.Info.Type.Syntax, IdentifierName("this"))), - IdentifierName(MethodInfo.MethodName)), - ArgumentList( - SeparatedList(GenerationContext.SignatureContext.ManagedParameters.Select(GenerateArgument)))))) - .WithSemicolonToken(Token(SyntaxKind.SemicolonToken)); - - static ArgumentSyntax GenerateArgument(TypePositionInfo info) - => info.IsByRef - ? Argument(IdentifierName(info.InstanceIdentifier)).WithRefKindKeyword(MarshallerHelpers.GetManagedArgumentRefKindKeyword(info)) - : Argument(IdentifierName(info.InstanceIdentifier)); - } - /// /// Returns a flat list of and its owning interface that represents all declared methods and inherited methods. /// Guarantees the output will be sorted by order of interface input order, then by vtable order. diff --git a/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/ItemAndSyntaxes.cs b/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/ItemAndSyntaxes.cs deleted file mode 100644 index c3cc57e84bd510..00000000000000 --- a/src/libraries/System.Runtime.InteropServices/gen/ComInterfaceGenerator/ItemAndSyntaxes.cs +++ /dev/null @@ -1,53 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Collections.Generic; -using System.Collections.Immutable; -using System.Text; -using Microsoft.CodeAnalysis; - -namespace Microsoft.Interop -{ - internal sealed class ItemAndSyntaxes : IEquatable> - { - private T _item; - private ImmutableArray _syntaxNodes; - public SyntaxNode this[int index] => _syntaxNodes[index]; - public ItemAndSyntaxes(T item, params ImmutableArray nodes) - { - _item = item; - _syntaxNodes = nodes; - } - - public T Context => _item; - - public bool Equals(ItemAndSyntaxes other) - { - if (other is null) return false; - if (!other._item.Equals(_item)) return false; - if (other._syntaxNodes.Length != _syntaxNodes.Length) return false; - for (int i = 0; i < _syntaxNodes.Length; i++) - { - var item = _syntaxNodes[i]; - var otherItem = other._syntaxNodes[i]; - - if (!SyntaxEquivalentComparer.Instance.Equals(item, otherItem)) - { - return false; - } - } - return true; - } - - public override bool Equals(object obj) - { - return Equals(obj as ItemAndSyntaxes); - } - - public override int GetHashCode() - { - return _item.GetHashCode(); - } - } -} diff --git a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/ContainingSyntaxContext.cs b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/ContainingSyntaxContext.cs index 832be0b79db305..5c8b8a6635be16 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/ContainingSyntaxContext.cs +++ b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/ContainingSyntaxContext.cs @@ -169,17 +169,7 @@ public void WriteToWithUnsafeModifier(IndentedTextWriter writer, TState { ContainingSyntax syntax = ContainingSyntax[i]; - string declarationKeyword = syntax.TypeKind switch - { - SyntaxKind.ClassDeclaration => "class", - SyntaxKind.StructDeclaration => "struct", - SyntaxKind.InterfaceDeclaration => "interface", - SyntaxKind.RecordDeclaration => "record", - SyntaxKind.RecordStructDeclaration => "record struct", - _ => throw new UnreachableException(), - }; - - writer.WriteLine($"{string.Join(" ", syntax.Modifiers.AddToModifiers(SyntaxKind.UnsafeKeyword))} {declarationKeyword} {syntax.Identifier}{syntax.TypeParameters}"); + writer.WriteLine($"{string.Join(" ", syntax.Modifiers.AddToModifiers(SyntaxKind.UnsafeKeyword))} {syntax.TypeKind.GetDeclarationKeyword()} {syntax.Identifier}{syntax.TypeParameters}"); writer.WriteLine('{'); writer.Indent++; } diff --git a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/IndentedTextWriterExtensions.cs b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/IndentedTextWriterExtensions.cs new file mode 100644 index 00000000000000..4a4af2ef394260 --- /dev/null +++ b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/IndentedTextWriterExtensions.cs @@ -0,0 +1,43 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.CodeDom.Compiler; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; + +namespace Microsoft.Interop; + +public static class IndentedTextWriterExtensions +{ + public static void WriteMultilineNode(this IndentedTextWriter writer, SyntaxNode node) + { + foreach (SyntaxToken token in node.DescendantTokens()) + { + foreach (SyntaxTrivia leadingTrivia in token.LeadingTrivia) + { + if (leadingTrivia.IsKind(SyntaxKind.EndOfLineTrivia)) + { + writer.WriteLine(); + continue; + } + + writer.Write(leadingTrivia.ToString()); + } + + writer.Write(token.Text); + + foreach (SyntaxTrivia trailingTrivia in token.TrailingTrivia) + { + if (trailingTrivia.IsKind(SyntaxKind.EndOfLineTrivia)) + { + writer.WriteLine(); + continue; + } + + writer.Write(trailingTrivia.ToString()); + } + } + + writer.WriteLine(); + } +} diff --git a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/SyntaxKindExtensions.cs b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/SyntaxKindExtensions.cs new file mode 100644 index 00000000000000..da80fd6089f7c8 --- /dev/null +++ b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/SyntaxKindExtensions.cs @@ -0,0 +1,19 @@ +// 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.CSharp; + +namespace Microsoft.Interop; + +public static class SyntaxKindExtensions +{ + public static string GetDeclarationKeyword(this SyntaxKind syntaxKind) => syntaxKind switch + { + SyntaxKind.ClassDeclaration => "class", + SyntaxKind.StructDeclaration => "struct", + SyntaxKind.InterfaceDeclaration => "interface", + SyntaxKind.RecordDeclaration => "record", + SyntaxKind.RecordStructDeclaration => "record struct", + _ => throw new UnreachableException(), + }; +} diff --git a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/TypeNames.cs b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/TypeNames.cs index f906e506bdec31..56be4847f6feee 100644 --- a/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/TypeNames.cs +++ b/src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/TypeNames.cs @@ -37,11 +37,6 @@ public static class NameSyntaxes private static NameSyntax? _WasmImportLinkageAttribute; public static NameSyntax WasmImportLinkageAttribute => _WasmImportLinkageAttribute ??= ParseName(TypeNames.GlobalAlias + TypeNames.WasmImportLinkageAttribute); - private static NameSyntax? _System_Runtime_CompilerServices_FixedAddressValueTypeAttribute; - public static NameSyntax System_Runtime_CompilerServices_FixedAddressValueTypeAttribute => _System_Runtime_CompilerServices_FixedAddressValueTypeAttribute ??= ParseName(TypeNames.GlobalAlias + TypeNames.System_Runtime_CompilerServices_FixedAddressValueTypeAttribute); - - private static NameSyntax? _System_Runtime_InteropServices_StructLayoutAttribute; - public static NameSyntax System_Runtime_InteropServices_StructLayoutAttribute => _System_Runtime_InteropServices_StructLayoutAttribute ??= ParseName(TypeNames.GlobalAlias + TypeNames.System_Runtime_InteropServices_StructLayoutAttribute); private static NameSyntax? _System_Diagnostics_StackTraceHiddenAttribute; public static NameSyntax System_Diagnostics_StackTraceHiddenAttribute => _System_Diagnostics_StackTraceHiddenAttribute ??= ParseName(TypeNames.GlobalAlias + TypeNames.System_Diagnostics_StackTraceHiddenAttribute); } @@ -50,35 +45,18 @@ public static class TypeSyntaxes { public static TypeSyntax VoidStar { get; } = PointerType(PredefinedType(Token(SyntaxKind.VoidKeyword))); - public static TypeSyntax VoidStarStar { get; } = PointerType(PointerType(PredefinedType(Token(SyntaxKind.VoidKeyword)))); - - private static TypeSyntax? _System_Runtime_InteropServices_NativeMemory; - public static TypeSyntax System_Runtime_InteropServices_NativeMemory => _System_Runtime_InteropServices_NativeMemory ??= ParseTypeName(TypeNames.GlobalAlias + TypeNames.System_Runtime_InteropServices_NativeMemory); - - private static TypeSyntax? _StrategyBasedComWrappers; - public static TypeSyntax StrategyBasedComWrappers => _StrategyBasedComWrappers ??= ParseTypeName(TypeNames.GlobalAlias + TypeNames.StrategyBasedComWrappers); - private static TypeSyntax? _IUnmanagedVirtualMethodTableProvider; public static TypeSyntax IUnmanagedVirtualMethodTableProvider => _IUnmanagedVirtualMethodTableProvider ??= ParseTypeName(TypeNames.GlobalAlias + TypeNames.IUnmanagedVirtualMethodTableProvider); - private static TypeSyntax? _IIUnknownInterfaceType; - public static TypeSyntax IIUnknownInterfaceType => _IIUnknownInterfaceType ??= ParseTypeName(TypeNames.GlobalAlias + TypeNames.IIUnknownInterfaceType); - private static TypeSyntax? _UnmanagedObjectUnwrapper; public static TypeSyntax UnmanagedObjectUnwrapper => _UnmanagedObjectUnwrapper ??= ParseTypeName(TypeNames.GlobalAlias + TypeNames.UnmanagedObjectUnwrapper); private static TypeSyntax? _UnreachableException; public static TypeSyntax UnreachableException => _UnreachableException ??= ParseTypeName(TypeNames.GlobalAlias + TypeNames.UnreachableException); - private static TypeSyntax? _System_Runtime_InteropServices_ComWrappers; - public static TypeSyntax System_Runtime_InteropServices_ComWrappers => _System_Runtime_InteropServices_ComWrappers ??= ParseTypeName(TypeNames.GlobalAlias + TypeNames.System_Runtime_InteropServices_ComWrappers); - private static TypeSyntax? _System_IntPtr; public static TypeSyntax System_IntPtr => _System_IntPtr ??= ParseTypeName(TypeNames.GlobalAlias + TypeNames.System_IntPtr); - private static TypeSyntax? _System_Guid; - public static TypeSyntax System_Guid => _System_Guid ??= ParseTypeName(TypeNames.GlobalAlias + TypeNames.System_Guid); - private static TypeSyntax? _DllImportSearchPath; public static TypeSyntax DllImportSearchPath => _DllImportSearchPath ??= ParseTypeName(TypeNames.GlobalAlias + TypeNames.DllImportSearchPath); @@ -106,9 +84,6 @@ public static class TypeSyntaxes private static TypeSyntax? _System_Runtime_CompilerServices_Unsafe; public static TypeSyntax System_Runtime_CompilerServices_Unsafe => _System_Runtime_CompilerServices_Unsafe ??= ParseTypeName(TypeNames.GlobalAlias + TypeNames.System_Runtime_CompilerServices_Unsafe); - private static TypeSyntax? _System_Runtime_InteropServices_LayoutKind; - public static TypeSyntax System_Runtime_InteropServices_LayoutKind => _System_Runtime_InteropServices_LayoutKind ??= ParseTypeName(TypeNames.GlobalAlias + TypeNames.System_Runtime_InteropServices_LayoutKind); - private static TypeSyntax? _CallConvCdecl; private static TypeSyntax? _CallConvFastcall; private static TypeSyntax? _CallConvMemberFunction;