Skip to content

Commit 565886f

Browse files
committed
handling special case of 16 digit long hex literal
1 parent 586c35e commit 565886f

1 file changed

Lines changed: 44 additions & 29 deletions

File tree

CodeConverter/CSharp/LiteralConversions.cs

Lines changed: 44 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public static ExpressionSyntax GetLiteralExpression(object value, string textFor
3030
var (maybeTextForUser, maybeFullExpression) = ConvertNumericLiteralValueText(textForUser ?? value.ToString(), value);
3131
if (maybeFullExpression != null) return maybeFullExpression;
3232
textForUser = maybeTextForUser;
33-
33+
3434
switch (value)
3535
{
3636
case byte b:
@@ -59,16 +59,16 @@ public static ExpressionSyntax GetLiteralExpression(object value, string textFor
5959
return SyntaxFactory.LiteralExpression(CSSyntaxKind.CharacterLiteralExpression, SyntaxFactory.Literal(c));
6060
case DateTime dt:
6161
{
62-
var valueToOutput = dt.Date.Equals(dt) ? dt.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture) : dt.ToString("yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture);
63-
return SyntaxFactory.ParseExpression("DateTime.Parse(\"" + valueToOutput + "\")");
64-
}
62+
var valueToOutput = dt.Date.Equals(dt) ? dt.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture) : dt.ToString("yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture);
63+
return SyntaxFactory.ParseExpression("DateTime.Parse(\"" + valueToOutput + "\")");
64+
}
6565
default:
6666
throw new ArgumentOutOfRangeException(nameof(value), value, null);
6767
}
6868
}
6969

7070
private static LiteralExpressionSyntax NumericLiteral(SyntaxToken literal) => SyntaxFactory.LiteralExpression(CSSyntaxKind.NumericLiteralExpression, literal);
71-
71+
7272
/// <summary>
7373
/// See LiteralConversions.GetLiteralExpression
7474
/// These are all the literals where the type will already be correct from the literal declaration
@@ -149,23 +149,38 @@ private static (string textForUser, ExpressionSyntax MaybeFullExpression) Conver
149149
string hexValue = textForUser.Substring(2);
150150
textForUser = "0x" + hexValue;
151151

152-
// ulong/long/uint hex literals have suffixes, so we just handle ints
153-
if (value is int) {
154-
int parsedHexValue = int.Parse(hexValue, NumberStyles.HexNumber, CultureInfo.InvariantCulture);
152+
bool replaceWithUncheckedExpr = false;
153+
LiteralExpressionSyntax hexValueExpr = default;
154+
CSSyntaxKind csSyntaxKind = CSSyntaxKind.None;
155155

156-
// This is a very special case where for 8 digit hex strings, C# interprets them as unsigned ints, but VB interprets them as ints
157-
// 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)`
158-
// This way the value looks pretty close to before and remains a compile time constant
156+
if (value is long) {
157+
long parsedHexValue = long.Parse(hexValue, NumberStyles.HexNumber, CultureInfo.InvariantCulture);
158+
if (parsedHexValue < 0L) {
159+
hexValueExpr = NumericLiteral(SyntaxFactory.Literal(textForUser, parsedHexValue));
160+
csSyntaxKind = CSSyntaxKind.LongKeyword;
161+
replaceWithUncheckedExpr = true;
162+
}
163+
} else if (value is int) {
164+
int parsedHexValue = int.Parse(hexValue, NumberStyles.HexNumber, CultureInfo.InvariantCulture);
159165
if (parsedHexValue < 0) {
160-
var hexValueExpr = NumericLiteral(SyntaxFactory.Literal(textForUser, parsedHexValue));
161-
var checkedExpr = SyntaxFactory.CheckedExpression(
162-
CSSyntaxKind.UncheckedExpression,
163-
SyntaxFactory.CastExpression(
164-
SyntaxFactory.PredefinedType(SyntaxFactory.Token(CSSyntaxKind.IntKeyword)),
165-
hexValueExpr));
166-
return (null, checkedExpr);
166+
hexValueExpr = NumericLiteral(SyntaxFactory.Literal(textForUser, parsedHexValue));
167+
csSyntaxKind = CSSyntaxKind.IntKeyword;
168+
replaceWithUncheckedExpr = true;
167169
}
168170
}
171+
172+
// This is a very special case where for 8 digit hex strings, C# interprets them as unsigned ints, but VB interprets them as ints
173+
// 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)`
174+
// This way the value looks pretty close to before and remains a compile time constant
175+
// The same applies to 16 digit hex strings that are converted to long
176+
if (replaceWithUncheckedExpr) {
177+
var checkedExpr = SyntaxFactory.CheckedExpression(
178+
CSSyntaxKind.UncheckedExpression,
179+
SyntaxFactory.CastExpression(
180+
SyntaxFactory.PredefinedType(SyntaxFactory.Token(csSyntaxKind)),
181+
hexValueExpr));
182+
return (null, checkedExpr);
183+
}
169184
} else if (canBeBinaryOrHex && textForUser.StartsWith("&B", StringComparison.OrdinalIgnoreCase)) {
170185
textForUser = "0b" + textForUser.Substring(2);
171186
} else if (textForUser.StartsWith("&", StringComparison.OrdinalIgnoreCase)) {
@@ -175,17 +190,17 @@ private static (string textForUser, ExpressionSyntax MaybeFullExpression) Conver
175190
}
176191

177192
if (value switch {
178-
ulong _ => "UL",
179-
long _ => "L",
180-
uint _ => "U",
181-
int _ => "",
182-
ushort _ => "",
183-
short _ => "",
184-
double _ => "d",
185-
float _ => "f",
186-
decimal _ => "m",
187-
_ => default
188-
} is {} suffix ) {
193+
ulong _ => "UL",
194+
long _ => "L",
195+
uint _ => "U",
196+
int _ => "",
197+
ushort _ => "",
198+
short _ => "",
199+
double _ => "d",
200+
float _ => "f",
201+
decimal _ => "m",
202+
_ => default
203+
} is { } suffix) {
189204
textForUser += suffix;
190205
}
191206

0 commit comments

Comments
 (0)