Skip to content

Commit fc0a1e6

Browse files
Merge pull request #1115 from TymurGubayev/feature/UseUncheckedFoxSomeHexLiterals
generate `unchecked((int)0x91234567)` instead of `int.MinValue + 0x11234567`
2 parents 10af52f + bec2a49 commit fc0a1e6

File tree

3 files changed

+13
-13
lines changed

3 files changed

+13
-13
lines changed

CodeConverter/CSharp/LiteralConversions.cs

+8-10
Original file line numberDiff line numberDiff line change
@@ -152,18 +152,16 @@ private static (string textForUser, ExpressionSyntax MaybeFullExpression) Conver
152152
int parsedHexValue = int.Parse(hexValue, NumberStyles.HexNumber, CultureInfo.InvariantCulture);
153153

154154
// This is a very special case where for 8 digit hex strings, C# interprets them as unsigned ints, but VB interprets them as ints
155-
// 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`
155+
// 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)`
156156
// This way the value looks pretty close to before and remains a compile time constant
157157
if (parsedHexValue < 0) {
158-
int positiveValue = parsedHexValue - int.MinValue;
159-
160-
var intMinValueExpr = SyntaxFactory.MemberAccessExpression(
161-
SyntaxKind.SimpleMemberAccessExpression,
162-
SyntaxFactory.PredefinedType(
163-
SyntaxFactory.Token(SyntaxKind.IntKeyword)),
164-
ValidSyntaxFactory.IdentifierName(nameof(int.MinValue)));
165-
var positiveValueExpr = NumericLiteral(SyntaxFactory.Literal("0x" + positiveValue.ToString("X8", CultureInfo.InvariantCulture), positiveValue));
166-
return (null, SyntaxFactory.BinaryExpression(SyntaxKind.AddExpression, intMinValueExpr, positiveValueExpr));
158+
var hexValueExpr = NumericLiteral(SyntaxFactory.Literal(textForUser, parsedHexValue));
159+
var checkedExpr = SyntaxFactory.CheckedExpression(
160+
CSSyntaxKind.UncheckedExpression,
161+
SyntaxFactory.CastExpression(
162+
SyntaxFactory.PredefinedType(SyntaxFactory.Token(CSSyntaxKind.IntKeyword)),
163+
hexValueExpr));
164+
return (null, checkedExpr);
167165
}
168166
} else if (canBeBinaryOrHex && textForUser.StartsWith("&B", StringComparison.OrdinalIgnoreCase)) {
169167
textForUser = "0b" + textForUser.Substring(2);

CodeConverter/Common/DocumentExtensions.cs

+3-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,9 @@ private static bool VbWouldBeSimplifiedIncorrectly(SyntaxNode n)
5050

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

5658
public static async Task<Document> WithExpandedRootAsync(this Document document, CancellationToken cancellationToken)

Tests/CSharp/SpecialConversionTests.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -154,8 +154,8 @@ await TestConversionVisualBasicToCSharpAsync(
154154
End Class", @"
155155
internal partial class Test754
156156
{
157-
private int value = int.MinValue + 0x00000000;
158-
private int value2 = int.MinValue + 0x71234567;
157+
private int value = unchecked((int)0x80000000);
158+
private int value2 = unchecked((int)0xF1234567);
159159
}");
160160
}
161161

0 commit comments

Comments
 (0)