Skip to content

Commit

Permalink
Add DateTime operators to SYSTEMTIME and implement IEquatable
Browse files Browse the repository at this point in the history
Add Tests for Template structs
Fix up output formatting
  • Loading branch information
elachlan committed Aug 28, 2022
1 parent 22521d1 commit 190eebe
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 1 deletion.
28 changes: 27 additions & 1 deletion src/Microsoft.Windows.CsWin32/Generator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3726,6 +3726,7 @@ private StructDeclarationSyntax DeclareStruct(TypeDefinitionHandle typeDefHandle
{
case "RECT":
case "SIZE":
case "SYSTEMTIME":
members.AddRange(this.ExtractMembersFromTemplate(name.Identifier.ValueText));
break;
default:
Expand Down Expand Up @@ -6315,6 +6316,28 @@ internal WhitespaceRewriter()

public override SyntaxNode? VisitExpressionStatement(ExpressionStatementSyntax node) => base.VisitExpressionStatement(this.WithIndentingTrivia(node));

public override SyntaxNode? VisitInitializerExpression(InitializerExpressionSyntax node)
{
node = node
.WithOpenBraceToken(Token(TriviaList(this.IndentTrivia), SyntaxKind.OpenBraceToken, TriviaList(LineFeed)))
.WithCloseBraceToken(Token(TriviaList(this.IndentTrivia), SyntaxKind.CloseBraceToken, TriviaList(LineFeed)))
.WithTrailingTrivia(TriviaList());
using var indent = new Indent(this);
return base.VisitInitializerExpression(node);
}

public override SyntaxNode? VisitAssignmentExpression(AssignmentExpressionSyntax node)
{
if (node.Parent is InitializerExpressionSyntax)
{
return base.VisitAssignmentExpression(this.WithIndentingTrivia(node));
}
else
{
return base.VisitAssignmentExpression(node);
}
}

public override SyntaxNode? VisitTryStatement(TryStatementSyntax node) => base.VisitTryStatement(this.WithIndentingTrivia(node));

public override SyntaxNode? VisitFinallyClause(FinallyClauseSyntax node) => base.VisitFinallyClause(this.WithIndentingTrivia(node));
Expand Down Expand Up @@ -6389,7 +6412,10 @@ internal WhitespaceRewriter()
}
}

public override SyntaxNode? VisitReturnStatement(ReturnStatementSyntax node) => base.VisitReturnStatement(node.WithLeadingTrivia(this.IndentTrivia));
public override SyntaxNode? VisitReturnStatement(ReturnStatementSyntax node)
{
return base.VisitReturnStatement(this.WithIndentingTrivia(node));
}

public override SyntaxToken VisitToken(SyntaxToken token)
{
Expand Down
42 changes: 42 additions & 0 deletions src/Microsoft.Windows.CsWin32/templates/SYSTEMTIME.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
partial struct SYSTEMTIME
: IEquatable<SYSTEMTIME>
{
public bool Equals(SYSTEMTIME other) => this.wYear == other.wYear && this.wMonth == other.wMonth && this.wDayOfWeek == other.wDayOfWeek && this.wDay == other.wDay && this.wHour == other.wHour && this.wMinute == other.wMinute && this.wSecond == other.wSecond && this.wMilliseconds == other.wMilliseconds;
public override bool Equals(object obj) => obj is SYSTEMTIME other && this.Equals(other);
public override int GetHashCode() => (this.wYear, this.wMonth, this.wDayOfWeek, this.wDay, this.wHour, this.wMinute, this.wSecond, this.wMilliseconds).GetHashCode();
public static bool operator ==(SYSTEMTIME d1, SYSTEMTIME d2) => d1.wYear == d2.wYear && d1.wMonth == d2.wMonth && d1.wDayOfWeek == d2.wDayOfWeek && d1.wDay == d2.wDay && d1.wHour == d2.wHour && d1.wMinute == d2.wMinute && d1.wSecond == d2.wSecond && d1.wMilliseconds == d2.wMilliseconds;
public static bool operator !=(SYSTEMTIME d1, SYSTEMTIME d2) => d1.wYear != d2.wYear && d1.wMonth != d2.wMonth && d1.wDayOfWeek != d2.wDayOfWeek && d1.wDay != d2.wDay && d1.wHour != d2.wHour && d1.wMinute != d2.wMinute && d1.wSecond != d2.wSecond && d1.wMilliseconds != d2.wMilliseconds;

public static explicit operator global::System.DateTime(SYSTEMTIME sysTime)
{
if (sysTime == default(SYSTEMTIME) || sysTime.wYear <= 0 || sysTime.wMonth <= 0 || sysTime.wDay <= 0)
{
return default;
}

// DateTime gets DayOfWeek automatically
return new global::System.DateTime(sysTime.wYear,
sysTime.wMonth, sysTime.wDay, sysTime.wHour,
sysTime.wMinute, sysTime.wSecond, sysTime.wMilliseconds);
}

public static explicit operator SYSTEMTIME(global::System.DateTime time)
{
if (time == default)
{
return default;
}

return new SYSTEMTIME
{
wYear = checked((ushort)time.Year),
wMonth = checked((ushort)time.Month),
wDayOfWeek = checked((ushort)time.DayOfWeek),
wDay = checked((ushort)time.Day),
wHour = checked((ushort)time.Hour),
wMinute = checked((ushort)time.Minute),
wSecond = checked((ushort)time.Second),
wMilliseconds = checked((ushort)time.Millisecond)
};
}
}
18 changes: 18 additions & 0 deletions test/Microsoft.Windows.CsWin32.Tests/GeneratorTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -605,6 +605,24 @@ public void HandleStructsHaveStaticNullMember(string handleName)
this.AssertGeneratedMember(handleName, "Null", $"internal static {handleName} Null => default;");
}

[Theory]
[InlineData("BOOL")]
[InlineData("BOOLEAN")]
[InlineData("HRESULT")]
[InlineData("NTSTATUS")]
[InlineData("PCSTR")]
[InlineData("PCWSTR")]
[InlineData("RECT")]
[InlineData("SIZE")]
[InlineData("SYSTEMTIME")]
public void TemplateAPIsGenerate(string handleType)
{
this.generator = this.CreateGenerator();
Assert.True(this.generator.TryGenerate(handleType, CancellationToken.None));
this.CollectGeneratedCode(this.generator);
this.AssertNoDiagnostics();
}

[Theory]
[InlineData("HANDLE")]
[InlineData("HGDIOBJ")]
Expand Down

0 comments on commit 190eebe

Please sign in to comment.