@@ -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 :
@@ -68,7 +68,7 @@ public static ExpressionSyntax GetLiteralExpression(object value, string textFor
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,17 +149,35 @@ private static (string textForUser, ExpressionSyntax MaybeFullExpression) Conver
149149 string hexValue = textForUser . Substring ( 2 ) ;
150150 textForUser = "0x" + hexValue ;
151151
152- int parsedHexValue = int . Parse ( hexValue , NumberStyles . HexNumber , CultureInfo . InvariantCulture ) ;
152+ bool replaceWithUncheckedExpr = false ;
153+ LiteralExpressionSyntax hexValueExpr = default ;
154+ CSSyntaxKind csSyntaxKind = CSSyntaxKind . None ;
155+
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 ) ;
165+ if ( parsedHexValue < 0 ) {
166+ hexValueExpr = NumericLiteral ( SyntaxFactory . Literal ( textForUser , parsedHexValue ) ) ;
167+ csSyntaxKind = CSSyntaxKind . IntKeyword ;
168+ replaceWithUncheckedExpr = true ;
169+ }
170+ }
153171
154172 // This is a very special case where for 8 digit hex strings, C# interprets them as unsigned ints, but VB interprets them as ints
155173 // 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)`
156174 // This way the value looks pretty close to before and remains a compile time constant
157- if ( parsedHexValue < 0 ) {
158- var hexValueExpr = NumericLiteral ( SyntaxFactory . Literal ( textForUser , parsedHexValue ) ) ;
175+ // The same applies to 16 digit hex strings that are converted to long
176+ if ( replaceWithUncheckedExpr ) {
159177 var checkedExpr = SyntaxFactory . CheckedExpression (
160178 CSSyntaxKind . UncheckedExpression ,
161179 SyntaxFactory . CastExpression (
162- SyntaxFactory . PredefinedType ( SyntaxFactory . Token ( CSSyntaxKind . IntKeyword ) ) ,
180+ SyntaxFactory . PredefinedType ( SyntaxFactory . Token ( csSyntaxKind ) ) ,
163181 hexValueExpr ) ) ;
164182 return ( null , checkedExpr ) ;
165183 }
@@ -172,20 +190,20 @@ private static (string textForUser, ExpressionSyntax MaybeFullExpression) Conver
172190 }
173191
174192 if ( value switch {
175- ulong _ => "UL" ,
176- long _ => "L" ,
177- uint _ => "U" ,
178- int _ => "" ,
179- ushort _ => "" ,
180- short _ => "" ,
181- double _ => "d" ,
182- float _ => "f" ,
183- decimal _ => "m" ,
184- _ => default
185- } 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 ) {
186204 textForUser += suffix ;
187205 }
188206
189207 return ( textForUser , null ) ;
190208 }
191- }
209+ }
0 commit comments