@@ -178,7 +178,7 @@ public TypeConversionKind AnalyzeConversion(VBSyntax.ExpressionSyntax vbNode, bo
178178 var csConvertedType = GetCSType ( vbConvertedType ) ;
179179
180180 if ( csType != null && csConvertedType != null &&
181- TryAnalyzeCsConversion ( vbCompilation , vbNode , csType , csConvertedType , vbConversion , vbConvertedType , vbType , isConst , forceSourceType != null , out TypeConversionKind analyzeConversion ) ) {
181+ TryAnalyzeCsConversion ( vbNode , csType , csConvertedType , vbConversion , vbConvertedType , vbType , isConst , forceSourceType != null , out TypeConversionKind analyzeConversion ) ) {
182182 return analyzeConversion ;
183183 }
184184
@@ -273,28 +273,20 @@ private ITypeSymbol GetCSType(ITypeSymbol vbType, VBSyntax.ExpressionSyntax vbNo
273273 return csType ;
274274 }
275275
276- private bool TryAnalyzeCsConversion ( VBasic . VisualBasicCompilation vbCompilation , VBSyntax . ExpressionSyntax vbNode , ITypeSymbol csType ,
276+ private bool TryAnalyzeCsConversion ( VBSyntax . ExpressionSyntax vbNode , ITypeSymbol csType ,
277277 ITypeSymbol csConvertedType , Conversion vbConversion , ITypeSymbol vbConvertedType , ITypeSymbol vbType , bool isConst , bool sourceForced ,
278278 out TypeConversionKind typeConversionKind )
279279 {
280280 var csConversion = _csCompilation . ClassifyConversion ( csType , csConvertedType ) ;
281-
282- vbType . IsNullable ( out var underlyingVbType ) ;
283- vbConvertedType . IsNullable ( out var underlyingVbConvertedType ) ;
284- underlyingVbType ??= vbType ;
285- underlyingVbConvertedType ??= vbConvertedType ;
286- var vbUnderlyingConversion = vbCompilation . ClassifyConversion ( underlyingVbType , underlyingVbConvertedType ) ;
287-
288- csType . IsNullable ( out var underlyingCsType ) ;
289- csConvertedType . IsNullable ( out var underlyingCsConvertedType ) ;
290- underlyingCsType ??= csType ;
291- underlyingCsConvertedType ??= csConvertedType ;
292- var csUnderlyingConversion = _csCompilation . ClassifyConversion ( underlyingCsType , underlyingCsConvertedType ) ;
281+ vbType . IsNullable ( out var underlyingType ) ;
282+ vbConvertedType . IsNullable ( out var underlyingConvertedType ) ;
283+ var nullableVbType = underlyingType ?? vbType ;
284+ var nullableVbConvertedType = underlyingConvertedType ?? vbConvertedType ;
293285
294286 bool isConvertToString =
295287 ( vbConversion . IsString || vbConversion . IsReference && vbConversion . IsNarrowing ) && vbConvertedType . SpecialType == SpecialType . System_String ;
296288 bool isConvertFractionalToInt =
297- ! csConversion . IsImplicit && underlyingVbType . IsFractionalNumericType ( ) && underlyingVbConvertedType . IsIntegralOrEnumType ( ) ;
289+ ! csConversion . IsImplicit && nullableVbType . IsFractionalNumericType ( ) && nullableVbConvertedType . IsIntegralOrEnumType ( ) ;
298290
299291 if ( ! csConversion . Exists || csConversion . IsUnboxing ) {
300292 if ( ConvertStringToCharLiteral ( vbNode , vbConvertedType , out _ ) ) {
@@ -308,27 +300,27 @@ private bool TryAnalyzeCsConversion(VBasic.VisualBasicCompilation vbCompilation,
308300 return true ;
309301 }
310302 if ( isConvertToString || vbConversion . IsNarrowing ) {
311- typeConversionKind = underlyingVbConvertedType . IsEnumType ( ) && ! csConversion . Exists
303+ typeConversionKind = nullableVbConvertedType . IsEnumType ( ) && ! csConversion . Exists
312304 ? TypeConversionKind . EnumConversionThenCast
313305 : TypeConversionKind . Conversion ;
314306 return true ;
315307 }
316308 } else if ( vbConversion . IsNarrowing && vbConversion . IsNullableValueType && isConvertFractionalToInt ) {
317309 typeConversionKind = TypeConversionKind . FractionalNumberRoundThenCast ;
318310 return true ;
319- } else if ( vbConversion . IsNumeric && ( csConversion . IsNumeric || underlyingVbConvertedType . IsEnumType ( ) ) && isConvertFractionalToInt ) {
311+ } else if ( vbConversion . IsNumeric && ( csConversion . IsNumeric || nullableVbConvertedType . IsEnumType ( ) ) && isConvertFractionalToInt ) {
320312 typeConversionKind = TypeConversionKind . FractionalNumberRoundThenCast ;
321313 return true ;
322314 } else if ( csConversion is { IsExplicit : true , IsEnumeration : true } or { IsBoxing : true , IsImplicit : false } ) {
323315 typeConversionKind = TypeConversionKind . NonDestructiveCast ;
324316 return true ;
325- } else if ( vbUnderlyingConversion . IsNumeric && csUnderlyingConversion . IsNumeric ) {
317+ } else if ( vbConversion . IsNumeric && csConversion . IsNumeric ) {
326318 // For widening, implicit, a cast is really only needed to help resolve the overload for the operator/method used.
327319 // e.g. When VB "&" changes to C# "+", there are lots more overloads available that implicit casts could match.
328320 // e.g. sbyte * ulong uses the decimal * operator in VB. In C# it's ambiguous - see ExpressionTests.vb "TestMul".
329321 typeConversionKind =
330- isConst && IsImplicitConstantConversion ( vbNode ) || csUnderlyingConversion . IsIdentity || ! sourceForced && IsExactTypeNumericLiteral ( vbNode , underlyingVbConvertedType ) ? TypeConversionKind . Identity :
331- csUnderlyingConversion . IsImplicit || underlyingVbType . IsNumericType ( ) ? TypeConversionKind . NonDestructiveCast
322+ isConst && IsImplicitConstantConversion ( vbNode ) || csConversion . IsIdentity || ! sourceForced && IsExactTypeNumericLiteral ( vbNode , vbConvertedType ) ? TypeConversionKind . Identity :
323+ csConversion . IsImplicit || vbType . IsNumericType ( ) ? TypeConversionKind . NonDestructiveCast
332324 : TypeConversionKind . Conversion ;
333325 return true ;
334326 } else if ( isConvertToString && vbType . SpecialType == SpecialType . System_Object ) {
0 commit comments