Skip to content

Commit 3f8e1d6

Browse files
[release/10.0.2xx] Fix CA1869 false positive in top-level statements (#51483)
2 parents c00e47a + 33b1ba5 commit 3f8e1d6

File tree

3 files changed

+92
-6
lines changed

3 files changed

+92
-6
lines changed

src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/Microsoft.NetCore.Analyzers/Performance/AvoidSingleUseOfLocalJsonSerializerOptions.cs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the MIT license. See License.txt in the project root for license information.
22

3-
using Microsoft.CodeAnalysis.Diagnostics;
4-
using Microsoft.CodeAnalysis;
3+
using System;
4+
using System.Collections.Generic;
55
using System.Collections.Immutable;
6+
using System.Diagnostics;
7+
using System.Diagnostics.CodeAnalysis;
68
using Analyzer.Utilities;
79
using Analyzer.Utilities.Extensions;
10+
using Microsoft.CodeAnalysis;
11+
using Microsoft.CodeAnalysis.Diagnostics;
812
using Microsoft.CodeAnalysis.Operations;
9-
using System.Diagnostics.CodeAnalysis;
10-
using System;
11-
using System.Collections.Generic;
12-
using System.Diagnostics;
1313

1414
namespace Microsoft.NetCore.Analyzers.Performance
1515
{
@@ -60,6 +60,12 @@ private static void OnCompilationStart(CompilationStartAnalysisContext context)
6060
INamedTypeSymbol? typeSymbol = operation.Constructor?.ContainingType;
6161
if (SymbolEqualityComparer.Default.Equals(typeSymbol, jsonSerializerOptionsSymbol))
6262
{
63+
// Don't report diagnostic for top-level statements as caching there is less impactful
64+
if (context.ContainingSymbol is IMethodSymbol method && method.IsTopLevelStatementsEntryPointMethod())
65+
{
66+
return;
67+
}
68+
6369
if (IsCtorUsedAsArgumentForJsonSerializer(operation, jsonSerializerSymbol) ||
6470
IsLocalUsedAsArgumentForJsonSerializerOnly(operation, jsonSerializerSymbol, jsonSerializerOptionsSymbol))
6571
{

src/Microsoft.CodeAnalysis.NetAnalyzers/src/RulesMissingDocumentation.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,7 @@
22

33
Rule ID | Missing Help Link | Title |
44
--------|-------------------|-------|
5+
CA1873 | <https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1873> | Avoid potentially expensive logging |
6+
CA1874 | <https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1874> | Use 'Regex.IsMatch' |
7+
CA1875 | <https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1875> | Use 'Regex.Count' |
8+
CA2023 | <https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2023> | Invalid braces in message template |

src/Microsoft.CodeAnalysis.NetAnalyzers/tests/Microsoft.CodeAnalysis.NetAnalyzers.UnitTests/Microsoft.NetCore.Analyzers/Performance/AvoidSingleUseOfLocalJsonSerializerOptionsTests.cs

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using System.Collections.Generic;
44
using System.Linq;
55
using System.Threading.Tasks;
6+
using Microsoft.CodeAnalysis;
67
using Microsoft.CodeAnalysis.CSharp;
78
using Xunit;
89
using VerifyCS = Test.Utilities.CSharpCodeFixVerifier<
@@ -820,6 +821,81 @@ Shared Function Serialize(Of T)(values As T()) As String
820821
End Function
821822
End Class
822823
""");
824+
825+
[Fact]
826+
public Task CS_TopLevelStatements_UseNewOptionsAsArgument_NoWarn()
827+
{
828+
var test = new VerifyCS.Test
829+
{
830+
TestState =
831+
{
832+
OutputKind = OutputKind.ConsoleApplication,
833+
Sources =
834+
{
835+
"""
836+
using System.Text.Json;
837+
838+
string json = JsonSerializer.Serialize(new[] { 1, 2, 3 }, new JsonSerializerOptions { AllowTrailingCommas = true });
839+
"""
840+
}
841+
},
842+
LanguageVersion = CodeAnalysis.CSharp.LanguageVersion.CSharp9
843+
};
844+
return test.RunAsync();
845+
}
846+
847+
[Fact]
848+
public Task CS_TopLevelStatements_UseNewLocalOptionsAsArgument_NoWarn()
849+
{
850+
var test = new VerifyCS.Test
851+
{
852+
TestState =
853+
{
854+
OutputKind = OutputKind.ConsoleApplication,
855+
Sources =
856+
{
857+
"""
858+
using System.Text.Json;
859+
860+
JsonSerializerOptions options = new()
861+
{
862+
PropertyNameCaseInsensitive = true,
863+
ReadCommentHandling = JsonCommentHandling.Skip
864+
};
865+
866+
var output = JsonSerializer.Deserialize<int[]>("[1,2,3]", options);
867+
"""
868+
}
869+
},
870+
LanguageVersion = CodeAnalysis.CSharp.LanguageVersion.CSharp9
871+
};
872+
return test.RunAsync();
873+
}
874+
875+
[Fact]
876+
public Task CS_TopLevelStatements_UseNewLocalOptionsAsArgument_Assignment_NoWarn()
877+
{
878+
var test = new VerifyCS.Test
879+
{
880+
TestState =
881+
{
882+
OutputKind = OutputKind.ConsoleApplication,
883+
Sources =
884+
{
885+
"""
886+
using System.Text.Json;
887+
888+
JsonSerializerOptions options;
889+
options = new JsonSerializerOptions();
890+
891+
var output = JsonSerializer.Deserialize<int[]>("[1,2,3]", options);
892+
"""
893+
}
894+
},
895+
LanguageVersion = CodeAnalysis.CSharp.LanguageVersion.CSharp9
896+
};
897+
return test.RunAsync();
898+
}
823899
#endregion
824900
}
825901
}

0 commit comments

Comments
 (0)