Skip to content

Commit

Permalink
Merge pull request #97 from microsoft/fix92
Browse files Browse the repository at this point in the history
Add HRESULT struct members: Succeeded and Failed
  • Loading branch information
AArnott committed Feb 16, 2021
2 parents e4168f1 + 4f54561 commit ebf0836
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 4 deletions.
45 changes: 41 additions & 4 deletions src/Microsoft.Windows.CsWin32/Generator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ public class Generator : IDisposable
private static readonly TypeSyntax SafeHandleTypeSyntax = IdentifierName("SafeHandle");
private static readonly IdentifierNameSyntax IntPtrTypeSyntax = IdentifierName(nameof(IntPtr));
private static readonly TypeSyntax VoidStar = SyntaxFactory.ParseTypeName("void*");
private static readonly AttributeListSyntax DebuggerBrowsableNever = AttributeList().AddAttributes(DebuggerBrowsable(DebuggerBrowsableState.Never));

/// <summary>
/// This is the preferred capitalizations for modules and class names.
Expand Down Expand Up @@ -1340,6 +1341,13 @@ private static AttributeSyntax DebuggerBrowsable(DebuggerBrowsableState state)
IdentifierName(Enum.GetName(typeof(DebuggerBrowsableState), state)!))));
}

private static AttributeSyntax DebuggerDisplay(string format)
{
return Attribute(IdentifierName("DebuggerDisplay"))
.AddArgumentListArguments(
AttributeArgument(LiteralExpression(SyntaxKind.StringLiteralExpression, Literal(format))));
}

private static SyntaxToken SafeIdentifier(string name) => SafeIdentifierName(name).Identifier;

private static IdentifierNameSyntax SafeIdentifierName(string name) => IdentifierName(CSharpKeywords.Contains(name) ? "@" + name : name);
Expand Down Expand Up @@ -1906,7 +1914,7 @@ private StructDeclarationSyntax CreateInteropStruct(TypeDefinition typeDef)

if (fieldInfo.AdditionalMembers.Count > 0)
{
field = field.AddAttributeLists(AttributeList().AddAttributes(DebuggerBrowsable(DebuggerBrowsableState.Never)));
field = field.AddAttributeLists(DebuggerBrowsableNever);
}

if (fieldInfo.FieldType is PointerTypeSyntax || fieldInfo.FieldType is FunctionPointerTypeSyntax)
Expand Down Expand Up @@ -2065,15 +2073,23 @@ private StructDeclarationSyntax CreateTypeDefStruct(TypeDefinition typeDef)
ArgumentList())))
.WithSemicolonToken(Token(SyntaxKind.SemicolonToken)));

if (name == "BSTR")
switch (name)
{
members = members.AddRange(this.CreateAdditionalTypeDefBSTRMembers());
case "BSTR":
members = members.AddRange(this.CreateAdditionalTypeDefBSTRMembers());
break;
case "HRESULT":
members = members.AddRange(this.CreateAdditionalTypeDefHRESULTMembers());
break;
default:
break;
}

StructDeclarationSyntax result = StructDeclaration(name)
.AddBaseListTypes(SimpleBaseType(GenericName(nameof(IEquatable<int>)).AddTypeArgumentListArguments(IdentifierName(name))))
.WithMembers(members)
.WithModifiers(TokenList(Token(this.Visibility), Token(SyntaxKind.ReadOnlyKeyword), Token(SyntaxKind.PartialKeyword)));
.WithModifiers(TokenList(Token(this.Visibility), Token(SyntaxKind.ReadOnlyKeyword), Token(SyntaxKind.PartialKeyword)))
.AddAttributeLists(AttributeList().AddAttributes(DebuggerDisplay("{" + fieldName + "}")));

result = AddApiDocumentation(name, result);
return result;
Expand Down Expand Up @@ -2126,6 +2142,27 @@ private IEnumerable<MemberDeclarationSyntax> CreateAdditionalTypeDefBSTRMembers(
.WithSemicolonToken(Token(SyntaxKind.SemicolonToken));
}

private IEnumerable<MemberDeclarationSyntax> CreateAdditionalTypeDefHRESULTMembers()
{
ExpressionSyntax thisValue = MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, ThisExpression(), IdentifierName("Value"));

// [DebuggerBrowsable(DebuggerBrowsableState.Never)]
// public bool Succeeded => this.Value >= 0;
yield return PropertyDeclaration(PredefinedType(Token(SyntaxKind.BoolKeyword)), "Succeeded")
.AddModifiers(Token(this.Visibility))
.WithExpressionBody(ArrowExpressionClause(BinaryExpression(SyntaxKind.GreaterThanOrEqualExpression, thisValue, LiteralExpression(SyntaxKind.NumericLiteralExpression, Literal(0)))))
.WithSemicolonToken(Token(SyntaxKind.SemicolonToken))
.AddAttributeLists(DebuggerBrowsableNever);

// [DebuggerBrowsable(DebuggerBrowsableState.Never)]
// public bool Failed => this.Value < 0;
yield return PropertyDeclaration(PredefinedType(Token(SyntaxKind.BoolKeyword)), "Failed")
.AddModifiers(Token(this.Visibility))
.WithExpressionBody(ArrowExpressionClause(BinaryExpression(SyntaxKind.LessThanExpression, thisValue, LiteralExpression(SyntaxKind.NumericLiteralExpression, Literal(0)))))
.WithSemicolonToken(Token(SyntaxKind.SemicolonToken))
.AddAttributeLists(DebuggerBrowsableNever);
}

private StructDeclarationSyntax CreateTypeDefBOOLStruct(TypeDefinition typeDef)
{
const string name = "BOOL";
Expand Down
16 changes: 16 additions & 0 deletions test/GenerationSandbox.Tests/BasicTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -139,4 +139,20 @@ public void SafeHandle_Null_IsZero()
{
Assert.Equal(IntPtr.Zero, CloseHandleSafeHandle.Null.DangerousGetHandle());
}

[Fact]
public void HRESULT_Succeeded()
{
Assert.True(((HRESULT)0).Succeeded);
Assert.True(((HRESULT)1).Succeeded);
Assert.False(((HRESULT)(-1)).Succeeded);
}

[Fact]
public void HRESULT_Failed()
{
Assert.False(((HRESULT)0).Failed);
Assert.False(((HRESULT)1).Failed);
Assert.True(((HRESULT)(-1)).Failed);
}
}

0 comments on commit ebf0836

Please sign in to comment.