Fix build failures when declaring a COM-style enumerable type (#88263)
authorJeremy Koritzinsky <jekoritz@microsoft.com>
Fri, 30 Jun 2023 21:34:20 +0000 (14:34 -0700)
committerGitHub <noreply@github.com>
Fri, 30 Jun 2023 21:34:20 +0000 (14:34 -0700)
src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/MarshalAsAttributeParser.cs
src/libraries/System.Runtime.InteropServices/gen/Microsoft.Interop.SourceGeneration/Marshalling/PointerNativeTypeAssignmentRewriter.cs
src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IEnumUnknown.cs [new file with mode: 0644]

index bc49ed4..476c1c6 100644 (file)
@@ -120,9 +120,18 @@ namespace Microsoft.Interop
                 MarshallingInfo elementMarshallingInfo = NoMarshallingInfo.Instance;
                 if (elementUnmanagedType != (UnmanagedType)SizeAndParamIndexInfo.UnspecifiedConstSize)
                 {
-                    elementMarshallingInfo = elementType.SpecialType == SpecialType.System_String
-                        ? CreateStringMarshallingInfo(elementType, elementUnmanagedType)
-                        : new MarshalAsInfo(elementUnmanagedType, _defaultInfo.CharEncoding);
+                    if (elementType.SpecialType == SpecialType.System_String)
+                    {
+                        elementMarshallingInfo = CreateStringMarshallingInfo(elementType, elementUnmanagedType);
+                    }
+                    else if (elementUnmanagedType == UnmanagedType.Interface && elementType is not INamedTypeSymbol { IsComImport: true })
+                    {
+                        elementMarshallingInfo = ComInterfaceMarshallingInfoProvider.CreateComInterfaceMarshallingInfo(_compilation, elementType);
+                    }
+                    else
+                    {
+                        elementMarshallingInfo = new MarshalAsInfo(elementUnmanagedType, _defaultInfo.CharEncoding);
+                    }
                 }
                 else
                 {
index 7a0f18c..6ce89e8 100644 (file)
@@ -24,6 +24,29 @@ namespace Microsoft.Interop
             _nativeType = nativeType;
         }
 
+        public override SyntaxNode? VisitVariableDeclarator(VariableDeclaratorSyntax node)
+        {
+            if (node.Initializer is null)
+            {
+                return base.VisitVariableDeclarator(node);
+            }
+
+            if (node.Identifier.ToString() == _nativeIdentifier)
+            {
+                return node.WithInitializer(
+                    EqualsValueClause(
+                        CastExpression(MarshallerHelpers.SystemIntPtrType, node.Initializer.Value)));
+            }
+            if (node.Initializer.Value.ToString() == _nativeIdentifier)
+            {
+                return node.WithInitializer(
+                    EqualsValueClause(
+                        CastExpression(_nativeType, node.Initializer.Value)));
+            }
+
+            return base.VisitVariableDeclarator(node);
+        }
+
         public override SyntaxNode VisitAssignmentExpression(AssignmentExpressionSyntax node)
         {
             if (node.Left.ToString() == _nativeIdentifier)
diff --git a/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IEnumUnknown.cs b/src/libraries/System.Runtime.InteropServices/tests/TestAssets/SharedTypes/ComInterfaces/IEnumUnknown.cs
new file mode 100644 (file)
index 0000000..db5249a
--- /dev/null
@@ -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 System;
+using System.Runtime.InteropServices;
+using System.Runtime.InteropServices.Marshalling;
+
+namespace SharedTypes.ComInterfaces
+{
+    [GeneratedComInterface]
+    [Guid("00000100-0000-0000-C000-000000000046")]
+    internal partial interface IEnumUnknown
+    {
+        void Next(uint celt, [Out, MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.Interface)] object[] rgelt, out uint pceltFetched);
+        void Skip(uint celt);
+        void Reset();
+        void Clone(out IEnumUnknown ppenum);
+    }
+}