Skip to content

Commit

Permalink
Merge pull request #7083 from CollinAlpert/issue-7053
Browse files Browse the repository at this point in the history
Suppress CA1862 for string.Contains on netfx
  • Loading branch information
mavasani authored Dec 11, 2023
2 parents 1b87f71 + 1e572fc commit 4907f61
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ public sealed class RecommendCaseInsensitiveStringComparisonAnalyzer : Diagnosti
internal const string StringIndexOfMethodName = "IndexOf";
internal const string StringStartsWithMethodName = "StartsWith";
internal const string StringCompareToMethodName = "CompareTo";
internal const string StringComparerCompareMethodName = "Compare";
internal const string StringEqualsMethodName = "Equals";
internal const string StringParameterName = "value";
internal const string StringComparisonParameterName = "comparisonType";
Expand Down Expand Up @@ -211,12 +210,19 @@ private void AnalyzeCompilationStart(CompilationStartAnalysisContext context)
return;
}

ParameterInfo[] stringStringComparisonParameters = {
ParameterInfo.GetParameterInfo(stringType),
ParameterInfo.GetParameterInfo(stringComparisonType)
};
IMethodSymbol? containsStringWithStringComparisonMethod
= stringType.GetMembers(StringContainsMethodName).OfType<IMethodSymbol>().GetFirstOrDefaultMemberWithParameterInfos(stringStringComparisonParameters);

// a.ToLower().Method(b.ToLower())
context.RegisterOperationAction(context =>
{
IInvocationOperation invocation = (IInvocationOperation)context.Operation;
AnalyzeInvocation(context, invocation, stringType,
containsStringMethod, startsWithStringMethod, compareToStringMethod,
containsStringMethod, containsStringWithStringComparisonMethod, startsWithStringMethod, compareToStringMethod,
indexOfStringMethod, indexOfStringInt32Method, indexOfStringInt32Int32Method);
}, OperationKind.Invocation);

Expand All @@ -230,13 +236,13 @@ private void AnalyzeCompilationStart(CompilationStartAnalysisContext context)
}

private static void AnalyzeInvocation(OperationAnalysisContext context, IInvocationOperation invocation, INamedTypeSymbol stringType,
IMethodSymbol containsStringMethod, IMethodSymbol startsWithStringMethod, IMethodSymbol compareToStringMethod,
IMethodSymbol containsStringMethod, IMethodSymbol? containsStringWithStringComparisonMethod, IMethodSymbol startsWithStringMethod, IMethodSymbol compareToStringMethod,
IMethodSymbol indexOfStringMethod, IMethodSymbol indexOfStringInt32Method, IMethodSymbol indexOfStringInt32Int32Method)
{
IMethodSymbol diagnosableMethod = invocation.TargetMethod;

DiagnosticDescriptor? chosenRule;
if (diagnosableMethod.Equals(containsStringMethod) ||
if (diagnosableMethod.Equals(containsStringMethod) && containsStringWithStringComparisonMethod is not null ||
diagnosableMethod.Equals(startsWithStringMethod) ||
diagnosableMethod.Equals(indexOfStringMethod) ||
diagnosableMethod.Equals(indexOfStringInt32Method) ||
Expand Down
1 change: 0 additions & 1 deletion src/NetAnalyzers/RulesMissingDocumentation.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,4 @@

Rule ID | Missing Help Link | Title |
--------|-------------------|-------|
CA1515 | <https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1515> | Consider making public types internal |
CA2262 | <https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2262> | Set 'MaxResponseHeadersLength' properly |
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Testing;
using Test.Utilities;
using Xunit;
using VerifyCS = Test.Utilities.CSharpCodeFixVerifier<
Microsoft.NetCore.Analyzers.Performance.RecommendCaseInsensitiveStringComparisonAnalyzer,
Expand Down Expand Up @@ -370,6 +371,66 @@ bool M()
await VerifyFixCSharpAsync(originalCode, originalCode);
}

[Fact, WorkItem(7053, "https://github.com/dotnet/roslyn-analyzers/issues/7053")]
public Task Net48_Contains_NoDiagnostic()
{
const string code = """
using System;
class C
{
void M(string s)
{
s.ToUpperInvariant().Contains("ABC");
}
}
""";

return new VerifyCS.Test
{
TestCode = code,
ReferenceAssemblies = ReferenceAssemblies.NetFramework.Net48.Default,
MarkupOptions = MarkupOptions.UseFirstDescriptor
}.RunAsync();
}

[Theory, WorkItem(7053, "https://github.com/dotnet/roslyn-analyzers/issues/7053")]
[InlineData("StartsWith")]
[InlineData("IndexOf")]
public Task Net48_Diagnostic(string method)
{
var code = $$"""
using System;
class C
{
void M(string s)
{
[|s.ToUpperInvariant().{{method}}("ABC")|];
}
}
""";
var fixedCode = $$"""
using System;
class C
{
void M(string s)
{
s.{{method}}("ABC", StringComparison.InvariantCultureIgnoreCase);
}
}
""";

return new VerifyCS.Test
{
TestCode = code,
FixedCode = fixedCode,
ReferenceAssemblies = ReferenceAssemblies.NetFramework.Net48.Default,
MarkupOptions = MarkupOptions.UseFirstDescriptor
}.RunAsync();
}

private async Task VerifyNoDiagnosticCSharpAsync(string originalSource)
{
VerifyCS.Test test = new()
Expand Down

0 comments on commit 4907f61

Please sign in to comment.