Skip to content

Commit 306222f

Browse files
authoredDec 16, 2024
Merge pull request #584 from dpaoliello/nested
Fix nested type names for properties
2 parents 7e211d6 + be0b852 commit 306222f

File tree

18 files changed

+1685
-11
lines changed

18 files changed

+1685
-11
lines changed
 

‎sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitDecl.cs

+12-11
Original file line numberDiff line numberDiff line change
@@ -969,12 +969,7 @@ private void VisitIndirectFieldDecl(IndirectFieldDecl indirectFieldDecl)
969969

970970
var isFixedSizedBuffer = IsTypeConstantOrIncompleteArray(indirectFieldDecl, type);
971971
var generateCompatibleCode = _config.GenerateCompatibleCode;
972-
var typeString = string.Empty;
973-
974-
if (!fieldDecl.IsBitField && (!isFixedSizedBuffer || generateCompatibleCode))
975-
{
976-
typeString = "ref ";
977-
}
972+
var typeStringBuilder = new StringBuilder();
978973

979974
if (IsType<RecordType>(indirectFieldDecl, type, out var recordType))
980975
{
@@ -985,34 +980,40 @@ private void VisitIndirectFieldDecl(IndirectFieldDecl indirectFieldDecl)
985980
var parentRecordDeclName = GetRemappedCursorName(parentRecordDecl);
986981
var escapedParentRecordDeclName = EscapeName(parentRecordDeclName);
987982

988-
typeString += escapedParentRecordDeclName + '.';
983+
_ = typeStringBuilder.Insert(0, '.').Insert(0, escapedParentRecordDeclName);
989984

990985
recordDecl = parentRecordDecl;
991986
}
992987
}
993988

989+
if (!fieldDecl.IsBitField && (!isFixedSizedBuffer || generateCompatibleCode))
990+
{
991+
_ = typeStringBuilder.Insert(0, "ref ");
992+
}
993+
994994
var isSupportedFixedSizedBufferType = isFixedSizedBuffer && IsSupportedFixedSizedBufferType(typeName);
995995

996996
if (isFixedSizedBuffer)
997997
{
998998
if (!generateCompatibleCode)
999999
{
10001000
_outputBuilder.EmitSystemSupport();
1001-
typeString += "Span<";
1001+
_ = typeStringBuilder.Append("Span<");
10021002
}
10031003
else if (!isSupportedFixedSizedBufferType)
10041004
{
1005-
typeString += contextType + '.';
1005+
_ = typeStringBuilder.Append(contextType).Append('.');
10061006
typeName = GetArtificialFixedSizedBufferName(fieldDecl);
10071007
}
10081008
}
10091009

1010-
typeString += typeName;
1010+
_ = typeStringBuilder.Append(typeName);
10111011
if (isFixedSizedBuffer && !generateCompatibleCode)
10121012
{
1013-
typeString += '>';
1013+
_ = typeStringBuilder.Append('>');
10141014
}
10151015

1016+
var typeString = typeStringBuilder.ToString();
10161017
_outputBuilder.WriteRegularField(typeString, escapedName);
10171018

10181019
var isIndirectPointerField = IsTypePointerOrReference(indirectFieldDecl, type) && !typeName.Equals("IntPtr", StringComparison.Ordinal) && !typeName.Equals("UIntPtr", StringComparison.Ordinal);

‎tests/ClangSharp.PInvokeGenerator.UnitTests/Base/UnionDeclarationTest.cs

+5
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,9 @@ public abstract class UnionDeclarationTest : PInvokeGeneratorTest
182182
[TestCase("bool", "byte")]
183183
public Task TypedefTest(string nativeType, string expectedManagedType) => TypedefTestImpl(nativeType, expectedManagedType);
184184

185+
[Test]
186+
public Task UnionWithAnonStructWithAnonUnion() => UnionWithAnonStructWithAnonUnionImpl();
187+
185188
protected abstract Task BasicTestImpl(string nativeType, string expectedManagedType);
186189

187190
protected abstract Task BasicTestInCModeImpl(string nativeType, string expectedManagedType);
@@ -237,4 +240,6 @@ public abstract class UnionDeclarationTest : PInvokeGeneratorTest
237240
protected abstract Task SkipNonDefinitionWithNativeTypeNameTestImpl(string nativeType, string expectedManagedType);
238241

239242
protected abstract Task TypedefTestImpl(string nativeType, string expectedManagedType);
243+
244+
protected abstract Task UnionWithAnonStructWithAnonUnionImpl();
240245
}

‎tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleUnix/UnionDeclarationTest.cs

+128
Original file line numberDiff line numberDiff line change
@@ -1449,6 +1449,134 @@ public partial struct MyUnion
14491449
public {expectedManagedType} b;
14501450
}}
14511451
}}
1452+
";
1453+
1454+
return ValidateGeneratedCSharpCompatibleUnixBindingsAsync(inputContents, expectedOutputContents);
1455+
}
1456+
1457+
protected override Task UnionWithAnonStructWithAnonUnionImpl()
1458+
{
1459+
var inputContents = $@"typedef union _MY_UNION
1460+
{{
1461+
long AsArray[2];
1462+
struct
1463+
{{
1464+
long First;
1465+
union
1466+
{{
1467+
struct
1468+
{{
1469+
long Second;
1470+
}} A;
1471+
1472+
struct
1473+
{{
1474+
long Second;
1475+
}} B;
1476+
}};
1477+
}};
1478+
}} MY_UNION;";
1479+
1480+
var expectedOutputContents = $@"using System;
1481+
using System.Runtime.InteropServices;
1482+
1483+
namespace ClangSharp.Test
1484+
{{
1485+
[StructLayout(LayoutKind.Explicit)]
1486+
public unsafe partial struct _MY_UNION
1487+
{{
1488+
[FieldOffset(0)]
1489+
[NativeTypeName(""long[2]"")]
1490+
public _AsArray_e__FixedBuffer AsArray;
1491+
1492+
[FieldOffset(0)]
1493+
[NativeTypeName(""__AnonymousRecord_ClangUnsavedFile_L4_C5"")]
1494+
public _Anonymous_e__Struct Anonymous;
1495+
1496+
public ref IntPtr First
1497+
{{
1498+
get
1499+
{{
1500+
fixed (_Anonymous_e__Struct* pField = &Anonymous)
1501+
{{
1502+
return ref pField->First;
1503+
}}
1504+
}}
1505+
}}
1506+
1507+
public ref _Anonymous_e__Struct._Anonymous_e__Union._A_e__Struct A
1508+
{{
1509+
get
1510+
{{
1511+
fixed (_Anonymous_e__Struct._Anonymous_e__Union* pField = &Anonymous.Anonymous)
1512+
{{
1513+
return ref pField->A;
1514+
}}
1515+
}}
1516+
}}
1517+
1518+
public ref _Anonymous_e__Struct._Anonymous_e__Union._B_e__Struct B
1519+
{{
1520+
get
1521+
{{
1522+
fixed (_Anonymous_e__Struct._Anonymous_e__Union* pField = &Anonymous.Anonymous)
1523+
{{
1524+
return ref pField->B;
1525+
}}
1526+
}}
1527+
}}
1528+
1529+
public unsafe partial struct _Anonymous_e__Struct
1530+
{{
1531+
[NativeTypeName(""long"")]
1532+
public IntPtr First;
1533+
1534+
[NativeTypeName(""__AnonymousRecord_ClangUnsavedFile_L7_C9"")]
1535+
public _Anonymous_e__Union Anonymous;
1536+
1537+
[StructLayout(LayoutKind.Explicit)]
1538+
public partial struct _Anonymous_e__Union
1539+
{{
1540+
[FieldOffset(0)]
1541+
[NativeTypeName(""__AnonymousRecord_ClangUnsavedFile_L9_C13"")]
1542+
public _A_e__Struct A;
1543+
1544+
[FieldOffset(0)]
1545+
[NativeTypeName(""__AnonymousRecord_ClangUnsavedFile_L14_C13"")]
1546+
public _B_e__Struct B;
1547+
1548+
public partial struct _A_e__Struct
1549+
{{
1550+
[NativeTypeName(""long"")]
1551+
public IntPtr Second;
1552+
}}
1553+
1554+
public partial struct _B_e__Struct
1555+
{{
1556+
[NativeTypeName(""long"")]
1557+
public IntPtr Second;
1558+
}}
1559+
}}
1560+
}}
1561+
1562+
public partial struct _AsArray_e__FixedBuffer
1563+
{{
1564+
public IntPtr e0;
1565+
public IntPtr e1;
1566+
1567+
public unsafe ref IntPtr this[int index]
1568+
{{
1569+
get
1570+
{{
1571+
fixed (IntPtr* pThis = &e0)
1572+
{{
1573+
return ref pThis[index];
1574+
}}
1575+
}}
1576+
}}
1577+
}}
1578+
}}
1579+
}}
14521580
";
14531581

14541582
return ValidateGeneratedCSharpCompatibleUnixBindingsAsync(inputContents, expectedOutputContents);

‎tests/ClangSharp.PInvokeGenerator.UnitTests/CSharpCompatibleWindows/UnionDeclarationTest.cs

+110
Original file line numberDiff line numberDiff line change
@@ -1456,6 +1456,116 @@ public partial struct MyUnion
14561456
public {expectedManagedType} b;
14571457
}}
14581458
}}
1459+
";
1460+
1461+
return ValidateGeneratedCSharpCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents);
1462+
}
1463+
1464+
protected override Task UnionWithAnonStructWithAnonUnionImpl()
1465+
{
1466+
var inputContents = $@"typedef union _MY_UNION
1467+
{{
1468+
long AsArray[2];
1469+
struct
1470+
{{
1471+
long First;
1472+
union
1473+
{{
1474+
struct
1475+
{{
1476+
long Second;
1477+
}} A;
1478+
1479+
struct
1480+
{{
1481+
long Second;
1482+
}} B;
1483+
}};
1484+
}};
1485+
}} MY_UNION;";
1486+
1487+
var expectedOutputContents = $@"using System.Runtime.InteropServices;
1488+
1489+
namespace ClangSharp.Test
1490+
{{
1491+
[StructLayout(LayoutKind.Explicit)]
1492+
public unsafe partial struct _MY_UNION
1493+
{{
1494+
[FieldOffset(0)]
1495+
[NativeTypeName(""long[2]"")]
1496+
public fixed int AsArray[2];
1497+
1498+
[FieldOffset(0)]
1499+
[NativeTypeName(""__AnonymousRecord_ClangUnsavedFile_L4_C5"")]
1500+
public _Anonymous_e__Struct Anonymous;
1501+
1502+
public ref int First
1503+
{{
1504+
get
1505+
{{
1506+
fixed (_Anonymous_e__Struct* pField = &Anonymous)
1507+
{{
1508+
return ref pField->First;
1509+
}}
1510+
}}
1511+
}}
1512+
1513+
public ref _Anonymous_e__Struct._Anonymous_e__Union._A_e__Struct A
1514+
{{
1515+
get
1516+
{{
1517+
fixed (_Anonymous_e__Struct._Anonymous_e__Union* pField = &Anonymous.Anonymous)
1518+
{{
1519+
return ref pField->A;
1520+
}}
1521+
}}
1522+
}}
1523+
1524+
public ref _Anonymous_e__Struct._Anonymous_e__Union._B_e__Struct B
1525+
{{
1526+
get
1527+
{{
1528+
fixed (_Anonymous_e__Struct._Anonymous_e__Union* pField = &Anonymous.Anonymous)
1529+
{{
1530+
return ref pField->B;
1531+
}}
1532+
}}
1533+
}}
1534+
1535+
public unsafe partial struct _Anonymous_e__Struct
1536+
{{
1537+
[NativeTypeName(""long"")]
1538+
public int First;
1539+
1540+
[NativeTypeName(""__AnonymousRecord_ClangUnsavedFile_L7_C9"")]
1541+
public _Anonymous_e__Union Anonymous;
1542+
1543+
[StructLayout(LayoutKind.Explicit)]
1544+
public partial struct _Anonymous_e__Union
1545+
{{
1546+
[FieldOffset(0)]
1547+
[NativeTypeName(""__AnonymousRecord_ClangUnsavedFile_L9_C13"")]
1548+
public _A_e__Struct A;
1549+
1550+
[FieldOffset(0)]
1551+
[NativeTypeName(""__AnonymousRecord_ClangUnsavedFile_L14_C13"")]
1552+
public _B_e__Struct B;
1553+
1554+
public partial struct _A_e__Struct
1555+
{{
1556+
[NativeTypeName(""long"")]
1557+
public int Second;
1558+
}}
1559+
1560+
public partial struct _B_e__Struct
1561+
{{
1562+
[NativeTypeName(""long"")]
1563+
public int Second;
1564+
}}
1565+
}}
1566+
}}
1567+
}}
1568+
}}
14591569
";
14601570

14611571
return ValidateGeneratedCSharpCompatibleWindowsBindingsAsync(inputContents, expectedOutputContents);

0 commit comments

Comments
 (0)