From 048cb29a00ad61c4245dcc710ddc0021252169fb Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Mon, 9 Oct 2023 13:27:52 -0600 Subject: [PATCH] Fix handling of enum references within nested structs --- src/Microsoft.Windows.CsWin32/Generator.Struct.cs | 2 +- src/Microsoft.Windows.CsWin32/Generator.cs | 12 ++++++++++++ test/Microsoft.Windows.CsWin32.Tests/StructTests.cs | 1 + 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/Microsoft.Windows.CsWin32/Generator.Struct.cs b/src/Microsoft.Windows.CsWin32/Generator.Struct.cs index 031b6434..af754db7 100644 --- a/src/Microsoft.Windows.CsWin32/Generator.Struct.cs +++ b/src/Microsoft.Windows.CsWin32/Generator.Struct.cs @@ -86,7 +86,7 @@ private StructDeclarationSyntax DeclareStruct(TypeDefinitionHandle typeDefHandle // get => (EnumType)this._fieldName; // set => this._fieldName = (UnderlyingType)value; // } - this.RequestInteropType(this.Reader.GetString(typeDef.Namespace), propertyType.Identifier.ValueText, context); + this.RequestInteropType(this.GetNamespaceForPossiblyNestedType(typeDef), propertyType.Identifier.ValueText, context); ExpressionSyntax fieldAccess = MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, ThisExpression(), IdentifierName(fieldDeclarator.Identifier)); property = PropertyDeclaration(propertyType.WithTrailingTrivia(Space), Identifier(fieldName).WithTrailingTrivia(LineFeed)) .AddModifiers(TokenWithSpace(this.Visibility)) diff --git a/src/Microsoft.Windows.CsWin32/Generator.cs b/src/Microsoft.Windows.CsWin32/Generator.cs index 0fba37ed..47ebc3d8 100644 --- a/src/Microsoft.Windows.CsWin32/Generator.cs +++ b/src/Microsoft.Windows.CsWin32/Generator.cs @@ -1329,6 +1329,18 @@ private string GetNormalizedModuleName(MethodImport import) return moduleName; } + private string GetNamespaceForPossiblyNestedType(TypeDefinition nestedTypeDef) + { + if (nestedTypeDef.IsNested) + { + return this.GetNamespaceForPossiblyNestedType(this.Reader.GetTypeDefinition(nestedTypeDef.GetDeclaringType())); + } + else + { + return this.Reader.GetString(nestedTypeDef.Namespace); + } + } + private ParameterListSyntax CreateParameterList(MethodDefinition methodDefinition, MethodSignature signature, TypeSyntaxSettings typeSettings) => FixTrivia(ParameterList().AddParameters(methodDefinition.GetParameters().Select(this.Reader.GetParameter).Where(p => !p.Name.IsNil).Select(p => this.CreateParameter(signature.ParameterTypes[p.SequenceNumber - 1], p, typeSettings)).ToArray())); diff --git a/test/Microsoft.Windows.CsWin32.Tests/StructTests.cs b/test/Microsoft.Windows.CsWin32.Tests/StructTests.cs index f8f8d018..c7df4df6 100644 --- a/test/Microsoft.Windows.CsWin32.Tests/StructTests.cs +++ b/test/Microsoft.Windows.CsWin32.Tests/StructTests.cs @@ -177,6 +177,7 @@ public void SpecialStruct_ByRequest(string structName) "DRIVER_OBJECT", // has an inline array of delegates "DEVICE_RELATIONS", // ends with an inline "flexible" array "D3DHAL_CONTEXTCREATEDATA", // contains a field that is a pointer to a struct that is normally managed + "MIB_TCPTABLE", // a struct that references another struct with a nested anonymous type, that loosely references an enum in the same namespace (by way of an attribute). "WSD_EVENT")] // has a pointer field to a managed struct string name, bool allowMarshaling)