@@ -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