diff --git a/CodeConverter/CSharp/BinaryExpressionConverter.cs b/CodeConverter/CSharp/BinaryExpressionConverter.cs index f02c085f..c9d8d76a 100644 --- a/CodeConverter/CSharp/BinaryExpressionConverter.cs +++ b/CodeConverter/CSharp/BinaryExpressionConverter.cs @@ -82,11 +82,25 @@ private async Task ConvertBinaryExpressionAsync(VBasic.Syntax. case VisualBasicEqualityComparison.RequiredType.StringOnly: if (lhsTypeInfo.ConvertedType?.SpecialType == SpecialType.System_String && rhsTypeInfo.ConvertedType?.SpecialType == SpecialType.System_String && - _visualBasicEqualityComparison.TryConvertToNullOrEmptyCheck(node, lhs, rhs, out CSharpSyntaxNode visitBinaryExpression)) { + _visualBasicEqualityComparison.TryConvertToNullOrEmptyCheck(node, lhs, rhs, lhsTypeInfo, rhsTypeInfo, out CSharpSyntaxNode visitBinaryExpression)) { return visitBinaryExpression; } - (lhs, rhs) = _visualBasicEqualityComparison.AdjustForVbStringComparison(node.Left, lhs, lhsTypeInfo, false, node.Right, rhs, rhsTypeInfo, false); - omitConversion = true; // Already handled within for the appropriate types (rhs can become int in comparison) + if (lhsTypeInfo.Type?.SpecialType == SpecialType.System_Char && rhsTypeInfo.Type?.SpecialType == SpecialType.System_Char) { + // Do nothing, char comparison + } else if (!_visualBasicEqualityComparison.OptionCompareTextCaseInsensitive && + ((lhsTypeInfo.Type?.SpecialType == SpecialType.System_Char && rhsTypeInfo.Type?.SpecialType == SpecialType.System_String && _visualBasicEqualityComparison.IsNothingOrEmpty(node.Right)) || + (rhsTypeInfo.Type?.SpecialType == SpecialType.System_Char && lhsTypeInfo.Type?.SpecialType == SpecialType.System_String && _visualBasicEqualityComparison.IsNothingOrEmpty(node.Left)))) { + if (lhsTypeInfo.Type?.SpecialType == SpecialType.System_Char) { + rhs = CS.SyntaxFactory.MemberAccessExpression(CS.SyntaxKind.SimpleMemberAccessExpression, CS.SyntaxFactory.PredefinedType(CS.SyntaxFactory.Token(CS.SyntaxKind.CharKeyword)), CS.SyntaxFactory.IdentifierName("MinValue")); + omitConversion = true; + } else { + lhs = CS.SyntaxFactory.MemberAccessExpression(CS.SyntaxKind.SimpleMemberAccessExpression, CS.SyntaxFactory.PredefinedType(CS.SyntaxFactory.Token(CS.SyntaxKind.CharKeyword)), CS.SyntaxFactory.IdentifierName("MinValue")); + omitConversion = true; + } + } else { + (lhs, rhs) = _visualBasicEqualityComparison.AdjustForVbStringComparison(node.Left, lhs, lhsTypeInfo, false, node.Right, rhs, rhsTypeInfo, false); + omitConversion = true; // Already handled within for the appropriate types (rhs can become int in comparison) + } break; case VisualBasicEqualityComparison.RequiredType.Object: return _visualBasicEqualityComparison.GetFullExpressionForVbObjectComparison(lhs, rhs, VisualBasicEqualityComparison.ComparisonKind.Equals, node.IsKind(VBasic.SyntaxKind.NotEqualsExpression)); diff --git a/CodeConverter/CSharp/VisualBasicEqualityComparison.cs b/CodeConverter/CSharp/VisualBasicEqualityComparison.cs index b05a643a..4b6d82b6 100644 --- a/CodeConverter/CSharp/VisualBasicEqualityComparison.cs +++ b/CodeConverter/CSharp/VisualBasicEqualityComparison.cs @@ -79,6 +79,7 @@ public RequiredType GetObjectEqualityType(params TypeInfo[] typeInfos) if (typeInfos.All( t => t.Type == null || t.Type.SpecialType == SpecialType.System_String || + t.Type.SpecialType == SpecialType.System_Char || t.Type.IsArrayOf(SpecialType.System_Char) ) ) { return RequiredType.StringOnly; } @@ -177,7 +178,7 @@ private static ObjectCreationExpressionSyntax NewStringFromArg(ExpressionSyntax } public bool TryConvertToNullOrEmptyCheck(VBSyntax.BinaryExpressionSyntax node, ExpressionSyntax lhs, - ExpressionSyntax rhs, out CSharpSyntaxNode? visitBinaryExpression) + ExpressionSyntax rhs, TypeInfo lhsTypeInfo, TypeInfo rhsTypeInfo, out CSharpSyntaxNode? visitBinaryExpression) { if (OptionCompareTextCaseInsensitive) { @@ -191,6 +192,12 @@ public bool TryConvertToNullOrEmptyCheck(VBSyntax.BinaryExpressionSyntax node, E if (lhsEmpty || rhsEmpty) { var arg = lhsEmpty ? rhs : lhs; + var argType = lhsEmpty ? rhsTypeInfo : lhsTypeInfo; + if (argType.Type?.SpecialType != SpecialType.System_String && argType.Type?.SpecialType != SpecialType.System_Object) { + visitBinaryExpression = null; + return false; + } + var nullOrEmpty = SyntaxFactory.InvocationExpression( SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.StringKeyword)), @@ -207,7 +214,7 @@ public bool TryConvertToNullOrEmptyCheck(VBSyntax.BinaryExpressionSyntax node, E return false; } - private bool IsNothingOrEmpty(VBSyntax.ExpressionSyntax expressionSyntax) + public bool IsNothingOrEmpty(VBSyntax.ExpressionSyntax expressionSyntax) { expressionSyntax = expressionSyntax.SkipIntoParens(); diff --git a/Tests/CSharp/ExpressionTests/StringExpressionTests.cs b/Tests/CSharp/ExpressionTests/StringExpressionTests.cs index 414ba0e5..59f09e7e 100644 --- a/Tests/CSharp/ExpressionTests/StringExpressionTests.cs +++ b/Tests/CSharp/ExpressionTests/StringExpressionTests.cs @@ -541,6 +541,29 @@ public void Foo() { string x = Conversions.ToString(DateTime.Parse(""2022-01-01"")) + "" 15:00""; } +}"); + } + + [Fact] + public async Task CharEqualityEmptyStringAsync() + { + await TestConversionVisualBasicToCSharpAsync(@"Class TestClass + Private Sub TestMethod() + Dim testChar As Char = Nothing + Dim testResult = testChar = """" + Dim testResult2 = """" = testChar + Dim testResult3 = testChar <> """" + End Sub +End Class", @" +internal partial class TestClass +{ + private void TestMethod() + { + char testChar = default; + bool testResult = testChar == char.MinValue; + bool testResult2 = char.MinValue == testChar; + bool testResult3 = testChar != char.MinValue; + } }"); } } \ No newline at end of file