diff --git a/src/Microsoft.Windows.CsWin32/Generator.cs b/src/Microsoft.Windows.CsWin32/Generator.cs index 0415e48e..76c55ad1 100644 --- a/src/Microsoft.Windows.CsWin32/Generator.cs +++ b/src/Microsoft.Windows.CsWin32/Generator.cs @@ -96,6 +96,9 @@ public class Generator : IDisposable /// "); + private static readonly XmlTextSyntax DocCommentStart = XmlText(" ").WithLeadingTrivia(DocumentationCommentExterior("///")); + private static readonly XmlTextSyntax DocCommentEnd = XmlText(XmlTextNewLine("\r\n", continueXmlDocumentationComment: false)); + private static readonly IdentifierNameSyntax ConstantsClassName = IdentifierName("Constants"); private static readonly IdentifierNameSyntax InlineArrayIndexerExtensionsClassName = IdentifierName("InlineArrayIndexerExtensions"); private static readonly TypeSyntax SafeHandleTypeSyntax = IdentifierName("SafeHandle"); @@ -3158,9 +3161,13 @@ ExpressionSyntax GetHiddenFieldAccess() => MemberAccessExpression( elementType = IntPtrTypeSyntax; } - // private struct __TheStruct_Count + var lengthLiteralSyntax = LiteralExpression(SyntaxKind.NumericLiteralExpression, Literal(length)); + + // internal struct __TheStruct_Count // { - // private TheStruct _0, _1, _2, _3, _4, _5, _6, _7, _8; + // internal TheStruct _0, _1, _2, _3, _4, _5, _6, _7, _8; + // /// Always 8. + // internal int Length => 8; // ... IdentifierNameSyntax fixedLengthStructName = IdentifierName($"__{fieldName}_{length}"); var fixedLengthStruct = StructDeclaration(fixedLengthStructName.Identifier) @@ -3168,7 +3175,20 @@ ExpressionSyntax GetHiddenFieldAccess() => MemberAccessExpression( .AddMembers( FieldDeclaration(VariableDeclaration(elementType) .AddVariables(Enumerable.Range(0, length).Select(n => VariableDeclarator($"_{n}")).ToArray())) - .AddModifiers(Token(this.Visibility))); + .AddModifiers(Token(this.Visibility)), + PropertyDeclaration(PredefinedType(Token(SyntaxKind.IntKeyword)), "Length") + .AddModifiers(Token(this.Visibility)) + .WithExpressionBody(ArrowExpressionClause(lengthLiteralSyntax)) + .WithSemicolonToken(Token(SyntaxKind.SemicolonToken)) + .WithLeadingTrivia(Trivia(DocumentationCommentTrivia(SyntaxKind.SingleLineDocumentationCommentTrivia).AddContent( + DocCommentStart, + XmlElement("summary", List(new XmlNodeSyntax[] + { + XmlText("Always "), + XmlElement("c", List(new XmlNodeSyntax[] { XmlText(length.ToString(CultureInfo.InvariantCulture)) })), + XmlText("."), + })), + DocCommentEnd)))); var firstElementFieldName = IdentifierName("_0"); if (this.canCallCreateSpan) @@ -3192,7 +3212,7 @@ ExpressionSyntax GetHiddenFieldAccess() => MemberAccessExpression( InvocationExpression(MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, IdentifierName("MemoryMarshal"), IdentifierName("CreateSpan"))) .AddArgumentListArguments( Argument(nameColon: null, Token(SyntaxKind.RefKeyword), firstElementFieldName), - Argument(LiteralExpression(SyntaxKind.NumericLiteralExpression, Literal(length)))))) + Argument(lengthLiteralSyntax)))) .WithSemicolonToken(Token(SyntaxKind.SemicolonToken)) .WithLeadingTrivia(InlineArrayUnsafeAsSpanComment)); } diff --git a/test/Microsoft.Windows.CsWin32.Tests/GeneratorTests.cs b/test/Microsoft.Windows.CsWin32.Tests/GeneratorTests.cs index 651b5147..b8a40831 100644 --- a/test/Microsoft.Windows.CsWin32.Tests/GeneratorTests.cs +++ b/test/Microsoft.Windows.CsWin32.Tests/GeneratorTests.cs @@ -399,6 +399,8 @@ internal partial struct MainAVIHeader internal struct __dwReserved_4 { internal uint _0, _1, _2, _3; + /// Always 4. + internal int Length => 4; } } "; @@ -446,6 +448,8 @@ internal partial struct MainAVIHeader internal struct __dwReserved_4 { internal uint _0, _1, _2, _3; + /// Always 4. + internal int Length => 4; /// /// Gets a ref to an individual element of the inline array. /// ⚠ Important ⚠: When this struct is on the stack, do not let the returned reference outlive the stack frame that defines it.