Skip to content

Commit

Permalink
Merge pull request #1115 from TymurGubayev/feature/UseUncheckedFoxSom…
Browse files Browse the repository at this point in the history
…eHexLiterals

generate `unchecked((int)0x91234567)` instead of `int.MinValue + 0x11234567`
  • Loading branch information
GrahamTheCoder authored Jul 20, 2024
2 parents 10af52f + bec2a49 commit fc0a1e6
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 13 deletions.
18 changes: 8 additions & 10 deletions CodeConverter/CSharp/LiteralConversions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -152,18 +152,16 @@ private static (string textForUser, ExpressionSyntax MaybeFullExpression) Conver
int parsedHexValue = int.Parse(hexValue, NumberStyles.HexNumber, CultureInfo.InvariantCulture);

// This is a very special case where for 8 digit hex strings, C# interprets them as unsigned ints, but VB interprets them as ints
// This can lead to a compile error if assigned to an int in VB. So in a case like 0x91234567, we generate `int.MinValue + 0x11234567`
// This can lead to a compile error if assigned to an int in VB. So in a case like 0x91234567, we generate `unchecked((int)0x91234567)`
// This way the value looks pretty close to before and remains a compile time constant
if (parsedHexValue < 0) {
int positiveValue = parsedHexValue - int.MinValue;

var intMinValueExpr = SyntaxFactory.MemberAccessExpression(
SyntaxKind.SimpleMemberAccessExpression,
SyntaxFactory.PredefinedType(
SyntaxFactory.Token(SyntaxKind.IntKeyword)),
ValidSyntaxFactory.IdentifierName(nameof(int.MinValue)));
var positiveValueExpr = NumericLiteral(SyntaxFactory.Literal("0x" + positiveValue.ToString("X8", CultureInfo.InvariantCulture), positiveValue));
return (null, SyntaxFactory.BinaryExpression(SyntaxKind.AddExpression, intMinValueExpr, positiveValueExpr));
var hexValueExpr = NumericLiteral(SyntaxFactory.Literal(textForUser, parsedHexValue));
var checkedExpr = SyntaxFactory.CheckedExpression(
CSSyntaxKind.UncheckedExpression,
SyntaxFactory.CastExpression(
SyntaxFactory.PredefinedType(SyntaxFactory.Token(CSSyntaxKind.IntKeyword)),
hexValueExpr));
return (null, checkedExpr);
}
} else if (canBeBinaryOrHex && textForUser.StartsWith("&B", StringComparison.OrdinalIgnoreCase)) {
textForUser = "0b" + textForUser.Substring(2);
Expand Down
4 changes: 3 additions & 1 deletion CodeConverter/Common/DocumentExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,9 @@ private static bool VbWouldBeSimplifiedIncorrectly(SyntaxNode n)

private static bool CsWouldBeSimplifiedIncorrectly(SyntaxNode n)
{
return false;
//"private int value = unchecked((int)0x80000010);" is simplified to "private int value = unchecked(0x80000010);"
// which causes CS0266: "Cannot implicitly convert type 'uint' to 'int'"
return (n is CSSyntax.CastExpressionSyntax { Parent : CSSyntax.CheckedExpressionSyntax });
}

public static async Task<Document> WithExpandedRootAsync(this Document document, CancellationToken cancellationToken)
Expand Down
4 changes: 2 additions & 2 deletions Tests/CSharp/SpecialConversionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -154,8 +154,8 @@ await TestConversionVisualBasicToCSharpAsync(
End Class", @"
internal partial class Test754
{
private int value = int.MinValue + 0x00000000;
private int value2 = int.MinValue + 0x71234567;
private int value = unchecked((int)0x80000000);
private int value2 = unchecked((int)0xF1234567);
}");
}

Expand Down

0 comments on commit fc0a1e6

Please sign in to comment.