Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use string.IsNullOrEmpty when comparing string to string.Empty #875

Merged
merged 1 commit into from
Apr 12, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)

* Convert immediately executed lambdas without causing a compiler error [#869](https://github.com/icsharpcode/CodeConverter/issues/869)
* Fix binary expressions for nullable types in VB->C# conversion [#840](https://github.com/icsharpcode/CodeConverter/issues/840)
* Use string.IsNullOrEmpty when comparing string to string.Empty [#874] (https://github.com/icsharpcode/CodeConverter/issues/874)

### C# -> VB

Expand Down
28 changes: 22 additions & 6 deletions CodeConverter/CSharp/VisualBasicEqualityComparison.cs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,8 @@ public static RequiredType GetObjectEqualityType(params TypeInfo[] typeInfos)

private static bool IsNonEmptyStringLiteral(VBSyntax.ExpressionSyntax vbExpr)
{
return vbExpr.SkipIntoParens().IsKind(VBSyntaxKind.StringLiteralExpression) && vbExpr is VBSyntax.LiteralExpressionSyntax literal && !IsEmptyString(literal);
vbExpr = vbExpr.SkipIntoParens();
return vbExpr.IsKind(VBSyntaxKind.StringLiteralExpression) && vbExpr is VBSyntax.LiteralExpressionSyntax literal && !IsEmptyString(literal);
}

public ExpressionSyntax VbCoerceToNonNullString(VBSyntax.ExpressionSyntax vbNode, ExpressionSyntax csNode, TypeInfo typeInfo, bool knownNotNull = false)
Expand All @@ -97,16 +98,16 @@ public ExpressionSyntax VbCoerceToNonNullString(VBSyntax.ExpressionSyntax vbNode
return csNode;
}

csNode = typeInfo.Type.SpecialType == SpecialType.System_String
? SyntaxFactory.ParenthesizedExpression(Coalesce(csNode, EmptyStringExpression()))
csNode = typeInfo.Type?.SpecialType == SpecialType.System_String
? Coalesce(csNode, EmptyStringExpression()).AddParens()
: Coalesce(csNode, EmptyCharArrayExpression());

return VbCoerceToString(csNode, typeInfo);
}

public static ExpressionSyntax VbCoerceToString(ExpressionSyntax csNode, TypeInfo typeInfo)
{
return typeInfo.Type.SpecialType switch
return typeInfo.Type?.SpecialType switch
{
SpecialType.System_String => csNode,
SpecialType.System_Char => SyntaxFactory.InvocationExpression(ValidSyntaxFactory.MemberAccess(csNode, nameof(ToString))),
Expand Down Expand Up @@ -188,11 +189,26 @@ public bool TryConvertToNullOrEmptyCheck(VBSyntax.BinaryExpressionSyntax node, E

private bool IsNothingOrEmpty(VBSyntax.ExpressionSyntax expressionSyntax)
{
expressionSyntax = expressionSyntax.SkipIntoParens();

if (expressionSyntax is VBSyntax.LiteralExpressionSyntax les &&
(les.IsKind(VBSyntaxKind.NothingLiteralExpression) ||
IsEmptyString(les))) return true;
(les.IsKind(VBSyntaxKind.NothingLiteralExpression) || IsEmptyString(les))) {
return true;
}

bool IsStringEmptyExpression() =>
expressionSyntax is VBSyntax.MemberAccessExpressionSyntax memberAccess && memberAccess.IsKind(VBSyntaxKind.SimpleMemberAccessExpression) &&
memberAccess.Expression is VBSyntax.PredefinedTypeSyntax predefinedType && predefinedType.Keyword.IsKind(VBSyntaxKind.StringKeyword) &&
memberAccess.Name.Identifier.ValueText.Equals("Empty", StringComparison.OrdinalIgnoreCase);

if (IsStringEmptyExpression()) {
return true;
}

var constantAnalysis = _semanticModel.GetConstantValue(expressionSyntax);
return constantAnalysis.HasValue && (constantAnalysis.Value == null || constantAnalysis.Value as string == "");


}

private static bool IsEmptyString(VBSyntax.LiteralExpressionSyntax les)
Expand Down
37 changes: 37 additions & 0 deletions Tests/CSharp/ExpressionTests/ExpressionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,43 @@ namespace ICSharpCode.CodeConverter.Tests.CSharp.ExpressionTests;

public class ExpressionTests : ConverterTestBase
{
[Fact]
public async Task ComparingStringsUsesCoerceToNonNullOnlyWhenNeededAsync()
{
await TestConversionVisualBasicToCSharpAsync(@"Class TestClass
Private Sub TestMethod(a as String)
Dim result = a = ("""")
result = """" = a
result = a = (String.Empty)
result = String.Empty = a
result = a = (Nothing)
result = Nothing = a
result = a Is Nothing
result = a IsNot Nothing
result = a = a
result = a = (""test"")
result = ""test"" = a
End Sub
End Class", @"
internal partial class TestClass
{
private void TestMethod(string a)
{
bool result = string.IsNullOrEmpty(a);
result = string.IsNullOrEmpty(a);
result = string.IsNullOrEmpty(a);
result = string.IsNullOrEmpty(a);
result = string.IsNullOrEmpty(a);
result = string.IsNullOrEmpty(a);
result = a is null;
result = a is not null;
result = (a ?? """") == (a ?? """");
result = a == ""test"";
result = ""test"" == a;
}
}");
}

[Fact]
public async Task ConversionOfNotUsesParensIfNeededAsync()
{
Expand Down