Skip to content

Commit

Permalink
Improve RCS1097 (dotnet#1160)
Browse files Browse the repository at this point in the history
Co-authored-by: Josef Pihrt <josef@pihrt.net>
  • Loading branch information
2 people authored and JochemHarmes committed Oct 30, 2023
1 parent f4843b4 commit e5e6559
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 9 deletions.
1 change: 1 addition & 0 deletions ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- Add SECURITY.md ([#1147](https://github.com/josefpihrt/roslynator/pull/1147))
- Add custom FixAllProvider for [RCS1014](https://github.com/JosefPihrt/Roslynator/blob/main/docs/analyzers/RCS1014.md) ([#1070](https://github.com/JosefPihrt/Roslynator/pull/1070)).
- Add more cases to [RCS1097](https://github.com/JosefPihrt/Roslynator/blob/main/docs/analyzers/RCS1097.md) ([#1160](https://github.com/JosefPihrt/Roslynator/pull/1160)).

### Fixed

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,7 @@ public static void Analyze(SyntaxNodeAnalysisContext context, in SimpleMemberInv

IMethodSymbol methodSymbol = semanticModel.GetMethodSymbol(invocationExpression, cancellationToken);

if (methodSymbol?.DeclaredAccessibility == Accessibility.Public
&& !methodSymbol.IsStatic
&& !methodSymbol.IsGenericMethod
&& string.Equals(methodSymbol.Name, "ToString", StringComparison.Ordinal)
&& methodSymbol.ReturnType.SpecialType == SpecialType.System_String
&& !methodSymbol.Parameters.Any())
if (IsToString(methodSymbol))
{
INamedTypeSymbol containingType = methodSymbol.ContainingType;

Expand All @@ -64,15 +59,38 @@ public static void Analyze(SyntaxNodeAnalysisContext context, in SimpleMemberInv
if (containingType.SpecialType == SpecialType.System_String)
return true;

if (invocationExpression.WalkUpParentheses().IsParentKind(SyntaxKind.Interpolation)
&& IsNotHidden(methodSymbol, containingType))
ExpressionSyntax expression = invocationExpression.WalkUpParentheses();
switch (expression.Parent.Kind())
{
return true;
case SyntaxKind.Interpolation:
{
return IsNotHidden(methodSymbol, containingType);
}
case SyntaxKind.AddExpression:
{
var addExpression = (BinaryExpressionSyntax)expression.Parent;
if (addExpression.Right == expression)
return semanticModel.GetTypeInfo(addExpression.Left, cancellationToken).Type?.SpecialType == SpecialType.System_String;

return semanticModel.GetTypeInfo(addExpression.Right, cancellationToken).Type?.SpecialType == SpecialType.System_String
&& (addExpression.Right.WalkDownParentheses() is not InvocationExpressionSyntax invocationExpression2
|| !IsToString(semanticModel.GetMethodSymbol(invocationExpression2, cancellationToken)));
}
}
}
}

return false;

static bool IsToString(IMethodSymbol methodSymbol)
{
return methodSymbol?.DeclaredAccessibility == Accessibility.Public
&& !methodSymbol.IsStatic
&& !methodSymbol.IsGenericMethod
&& string.Equals(methodSymbol.Name, "ToString", StringComparison.Ordinal)
&& methodSymbol.ReturnType.SpecialType == SpecialType.System_String
&& !methodSymbol.Parameters.Any();
}
}

private static bool IsNotHidden(IMethodSymbol methodSymbol, INamedTypeSymbol containingType)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,32 @@ void M()
");
}

[Fact, Trait(Traits.Analyzer, DiagnosticIdentifiers.RemoveRedundantToStringCall)]
public async Task Test_PlusString()
{
await VerifyDiagnosticAndFixAsync(@"
class C
{
void M(object o)
{
string s = """" + o[|.ToString()|];
string s2 = o[|.ToString()|] + """";
string s3 = o.ToString() + o[|.ToString()|];
}
}
", @"
class C
{
void M(object o)
{
string s = """" + o;
string s2 = o + """";
string s3 = o.ToString() + o;
}
}
");
}

[Fact, Trait(Traits.Analyzer, DiagnosticIdentifiers.RemoveRedundantToStringCall)]
public async Task Test_Interpolation()
{
Expand Down

0 comments on commit e5e6559

Please sign in to comment.