diff --git a/CodeConverter/CSharp/LiteralConversions.cs b/CodeConverter/CSharp/LiteralConversions.cs index 30da594c..41c9b940 100644 --- a/CodeConverter/CSharp/LiteralConversions.cs +++ b/CodeConverter/CSharp/LiteralConversions.cs @@ -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); diff --git a/CodeConverter/Common/DocumentExtensions.cs b/CodeConverter/Common/DocumentExtensions.cs index 5cf2d89d..b0e0d9de 100644 --- a/CodeConverter/Common/DocumentExtensions.cs +++ b/CodeConverter/Common/DocumentExtensions.cs @@ -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 WithExpandedRootAsync(this Document document, CancellationToken cancellationToken) diff --git a/Tests/CSharp/SpecialConversionTests.cs b/Tests/CSharp/SpecialConversionTests.cs index 95b4bbe0..b07f5025 100644 --- a/Tests/CSharp/SpecialConversionTests.cs +++ b/Tests/CSharp/SpecialConversionTests.cs @@ -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); }"); }