Skip to content

Commit

Permalink
Add Null static field to handles
Browse files Browse the repository at this point in the history
  • Loading branch information
elachlan committed Aug 6, 2022
1 parent 39757ab commit 3515d52
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 1 deletion.
6 changes: 6 additions & 0 deletions src/Microsoft.Windows.CsWin32/Generator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3885,6 +3885,12 @@ private IEnumerable<MemberDeclarationSyntax> CreateCommonTypeDefMembers(Identifi
// If this typedef struct represents a pointer, add an IsNull property.
if (fieldType is IdentifierNameSyntax { Identifier: { Value: nameof(IntPtr) or nameof(UIntPtr) } })
{
// internal static readonly HWND Null;
yield return FieldDeclaration(VariableDeclaration(structName.WithTrailingTrivia(TriviaList(Space)))
.AddVariables(VariableDeclarator(IdentifierName("Null").Identifier)))
.AddModifiers(TokenWithSpace(SyntaxKind.InternalKeyword), TokenWithSpace(SyntaxKind.StaticKeyword), TokenWithSpace(SyntaxKind.ReadOnlyKeyword))
.WithSemicolonToken(SemicolonWithLineFeed);

// internal static bool IsNull => value == default;
yield return PropertyDeclaration(PredefinedType(TokenWithSpace(SyntaxKind.BoolKeyword)), "IsNull")
.AddModifiers(TokenWithSpace(this.Visibility))
Expand Down
17 changes: 16 additions & 1 deletion test/Microsoft.Windows.CsWin32.Tests/GeneratorTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -587,6 +587,17 @@ public void HandleStructsHaveIsNullProperty(string handleName)
this.AssertGeneratedMember(handleName, "IsNull", "internal bool IsNull => Value == default;");
}

[Theory]
[InlineData("HANDLE")]
[InlineData("HGDIOBJ")]
[InlineData("HINSTANCE")]
public void HandleStructsHaveStaticNullField(string handleName)
{
// A null HGDIOBJ has a specific meaning beyond just the concept of an invalid handle:
// https://docs.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-selectobject#return-value
this.AssertGeneratedMember(handleName, "Null", "Null");
}

[Theory]
[InlineData("HANDLE")]
[InlineData("HGDIOBJ")]
Expand All @@ -598,7 +609,7 @@ public void HandleTypeDefsUseIntPtrAsFieldType(string handleType)
this.CollectGeneratedCode(this.generator);
this.AssertNoDiagnostics();
StructDeclarationSyntax hwnd = Assert.IsType<StructDeclarationSyntax>(this.FindGeneratedType(handleType).Single());
FieldDeclarationSyntax field = hwnd.Members.OfType<FieldDeclarationSyntax>().Single();
FieldDeclarationSyntax field = hwnd.Members.OfType<FieldDeclarationSyntax>().First();
Assert.Equal(nameof(IntPtr), Assert.IsType<IdentifierNameSyntax>(field.Declaration.Type).Identifier.ValueText);
}

Expand Down Expand Up @@ -1969,6 +1980,7 @@ namespace Foundation
{
internal readonly IntPtr Value;
internal HWND(IntPtr value) => this.Value = value;
internal static readonly HWND Null;
internal bool IsNull => Value == default;
public static implicit operator IntPtr(HWND value) => value.Value;
Expand Down Expand Up @@ -2075,6 +2087,7 @@ namespace Graphics.Gdi
{
internal readonly IntPtr Value;
internal HDC(IntPtr value) => this.Value = value;
internal static readonly HDC Null;
internal bool IsNull => Value == default;
public static implicit operator IntPtr(HDC value) => value.Value;
Expand Down Expand Up @@ -2117,6 +2130,7 @@ namespace Foundation
{
internal readonly IntPtr Value;
internal HWND(IntPtr value) => this.Value = value;
internal static readonly HWND Null;
internal bool IsNull => Value == default;
public static implicit operator IntPtr(HWND value) => value.Value;
Expand Down Expand Up @@ -2458,6 +2472,7 @@ namespace Foundation
{
internal readonly IntPtr Value;
internal HANDLE(IntPtr value) => this.Value = value;
internal static readonly HANDLE Null;
internal bool IsNull => Value == default;
public static implicit operator IntPtr(HANDLE value) => value.Value;
Expand Down

0 comments on commit 3515d52

Please sign in to comment.