From b885e6b5b9338960b98a363c952ce188a20c15e9 Mon Sep 17 00:00:00 2001 From: David Cantu Date: Fri, 11 Aug 2023 10:29:58 -0500 Subject: [PATCH 1/6] Add analyzer for flagging single-use of local JsonSerializerOptions --- .../Core/AnalyzerReleases.Unshipped.md | 1 + .../MicrosoftNetCoreAnalyzersResources.resx | 9 + ...idSingleUseOfLocalJsonSerializerOptions.cs | 328 ++++++++++ .../MicrosoftNetCoreAnalyzersResources.cs.xlf | 15 + .../MicrosoftNetCoreAnalyzersResources.de.xlf | 15 + .../MicrosoftNetCoreAnalyzersResources.es.xlf | 15 + .../MicrosoftNetCoreAnalyzersResources.fr.xlf | 15 + .../MicrosoftNetCoreAnalyzersResources.it.xlf | 15 + .../MicrosoftNetCoreAnalyzersResources.ja.xlf | 15 + .../MicrosoftNetCoreAnalyzersResources.ko.xlf | 15 + .../MicrosoftNetCoreAnalyzersResources.pl.xlf | 15 + ...crosoftNetCoreAnalyzersResources.pt-BR.xlf | 15 + .../MicrosoftNetCoreAnalyzersResources.ru.xlf | 15 + .../MicrosoftNetCoreAnalyzersResources.tr.xlf | 15 + ...osoftNetCoreAnalyzersResources.zh-Hans.xlf | 15 + ...osoftNetCoreAnalyzersResources.zh-Hant.xlf | 15 + .../Microsoft.CodeAnalysis.NetAnalyzers.md | 12 + ...gleUseOfLocalJsonSerializerOptionsTests.cs | 574 ++++++++++++++++++ .../DiagnosticCategoryAndIdRanges.txt | 2 +- src/Utilities/Compiler/WellKnownTypeNames.cs | 2 + 20 files changed, 1122 insertions(+), 1 deletion(-) create mode 100644 src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Performance/AvoidSingleUseOfLocalJsonSerializerOptions.cs create mode 100644 src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Performance/AvoidSingleUseOfLocalJsonSerializerOptionsTests.cs diff --git a/src/NetAnalyzers/Core/AnalyzerReleases.Unshipped.md b/src/NetAnalyzers/Core/AnalyzerReleases.Unshipped.md index f84a761c29..4f6fd9f131 100644 --- a/src/NetAnalyzers/Core/AnalyzerReleases.Unshipped.md +++ b/src/NetAnalyzers/Core/AnalyzerReleases.Unshipped.md @@ -4,6 +4,7 @@ Rule ID | Category | Severity | Notes --------|----------|----------|------- +CA1865 | Performance | Info | AvoidSingleUseOfLocalJsonSerializerOptions, [Documentation](https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1865) CA2261 | Usage | Warning | DoNotUseConfigureAwaitWithSuppressThrowing, [Documentation](https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2250) CA1510 | Maintainability | Info | UseExceptionThrowHelpers, [Documentation](https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1510) CA1511 | Maintainability | Info | UseExceptionThrowHelpers, [Documentation](https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1511) diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx index 571ee4ee1f..6c482bc726 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx @@ -2105,4 +2105,13 @@ Widening and user defined conversions are not supported with generic types. Cache and use a 'CompositeFormat' instance as the argument to this formatting operation, rather than passing in the original format string. This reduces the cost of the formatting operation. + + Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance + + + Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance. + + + Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal + \ No newline at end of file diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Performance/AvoidSingleUseOfLocalJsonSerializerOptions.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Performance/AvoidSingleUseOfLocalJsonSerializerOptions.cs new file mode 100644 index 0000000000..8281336119 --- /dev/null +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Performance/AvoidSingleUseOfLocalJsonSerializerOptions.cs @@ -0,0 +1,328 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the MIT license. See License.txt in the project root for license information. + +using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis; +using System.Collections.Immutable; +using Analyzer.Utilities; +using Analyzer.Utilities.Extensions; +using Microsoft.CodeAnalysis.Operations; +using System.Diagnostics.CodeAnalysis; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Microsoft.NetCore.Analyzers.Performance +{ + using static MicrosoftNetCoreAnalyzersResources; + + [DiagnosticAnalyzer(LanguageNames.CSharp, LanguageNames.VisualBasic)] + public sealed class AvoidSingleUseOfLocalJsonSerializerOptions : DiagnosticAnalyzer + { + internal static readonly DiagnosticDescriptor s_Rule = DiagnosticDescriptorHelper.Create( + id: "CA1865", + title: CreateLocalizableResourceString(nameof(AvoidSingleUseOfLocalJsonSerializerOptionsTitle)), + messageFormat: CreateLocalizableResourceString(nameof(AvoidSingleUseOfLocalJsonSerializerOptionsMessage)), + category: DiagnosticCategory.Performance, + ruleLevel: RuleLevel.IdeSuggestion, + description: CreateLocalizableResourceString(nameof(AvoidSingleUseOfLocalJsonSerializerOptionsDescription)), + isPortedFxCopRule: false, + isDataflowRule: false); + + public override ImmutableArray SupportedDiagnostics => ImmutableArray.Create(s_Rule); + + public override void Initialize(AnalysisContext context) + { + context.EnableConcurrentExecution(); + context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None); + context.RegisterCompilationStartAction(OnCompilationStart); + } + + private static void OnCompilationStart(CompilationStartAnalysisContext context) + { + Compilation compilation = context.Compilation; + + compilation.TryGetOrCreateTypeByMetadataName( + WellKnownTypeNames.SystemTextJsonJsonSerializerOptions, out INamedTypeSymbol? jsonSerializerOptionsSymbol); + + compilation.TryGetOrCreateTypeByMetadataName( + WellKnownTypeNames.SystemTextJsonJsonSerializer, out INamedTypeSymbol? jsonSerializerSymbol); + + if (jsonSerializerOptionsSymbol is null || jsonSerializerSymbol is null) + { + return; + } + + context.RegisterOperationAction( + context => + { + var operation = (IObjectCreationOperation)context.Operation; + + INamedTypeSymbol? typeSymbol = operation.Constructor?.ContainingType; + if (SymbolEqualityComparer.Default.Equals(typeSymbol, jsonSerializerOptionsSymbol)) + { + if (IsCtorUsedAsArgumentForJsonSerializer(operation, jsonSerializerSymbol) || + IsLocalUsedAsArgumentForJsonSerializerOnly(operation, jsonSerializerSymbol)) + { + context.ReportDiagnostic(operation.CreateDiagnostic(s_Rule)); + } + } + }, + OperationKind.ObjectCreation); + } + + private static bool IsCtorUsedAsArgumentForJsonSerializer(IObjectCreationOperation objCreationOperation, INamedTypeSymbol jsonSerializerSymbol) + { + IOperation operation = WalkUpConditional(objCreationOperation); + + return operation.Parent is IArgumentOperation argumentOperation && + IsArgumentForJsonSerializer(argumentOperation, jsonSerializerSymbol); + } + + private static bool IsArgumentForJsonSerializer(IArgumentOperation argumentOperation, INamedTypeSymbol jsonSerializerSymbol) + { + return argumentOperation.Parent is IInvocationOperation invocationOperation && + SymbolEqualityComparer.Default.Equals(invocationOperation.TargetMethod.ContainingType, jsonSerializerSymbol); + } + + private static bool IsLocalUsedAsArgumentForJsonSerializerOnly(IObjectCreationOperation objCreation, INamedTypeSymbol jsonSerializerSymbol) + { + IOperation operation = WalkUpConditional(objCreation); + + if (!IsLocalAssignment(operation, out List? localSymbols)) + { + return false; + } + + IBlockOperation? localBlock = objCreation.GetFirstParentBlock(); + bool ret = false; + + foreach (ILocalReferenceOperation descendant in localBlock.Descendants().OfType()) + { + if (!localSymbols.Contains(descendant.Local)) + { + continue; + } + + // Avoid cases that would potentially make the local escape current block scope. + if (IsArgumentOfJsonSerializer(descendant, jsonSerializerSymbol, out bool isArgumentOfInvocation)) + { + // Case: used more than once i.e: not single-use. + if (ret) + { + return false; + } + + ret = true; + } + + // Case: passed as argument of a non-JsonSerializer method. + else if (isArgumentOfInvocation) + { + return false; + } + + if (IsFieldOrPropertyAssignment(descendant)) + { + return false; + } + + // Case: deconstruction assignment. + if (IsTupleForDeconstructionTargetingFieldOrProperty(descendant)) + { + return false; + } + + // Case: local goes into closure. + if (IsClosureOnLambdaOrLocalFunction(descendant, localBlock!)) + { + return false; + } + } + + return ret; + } + + [return: NotNullIfNotNull(nameof(operation))] + private static IOperation? WalkUpConditional(IOperation? operation) + { + if (operation is null) + return null; + + while (operation.Parent is IConditionalOperation conditionalOperation) + { + operation = conditionalOperation; + } + + return operation; + } + + private static bool IsArgumentOfJsonSerializer(IOperation operation, INamedTypeSymbol jsonSerializerSymbol, out bool isArgumentOfInvocation) + { + if (operation.Parent is IArgumentOperation arg && arg.Parent is IInvocationOperation inv) + { + isArgumentOfInvocation = true; + return SymbolEqualityComparer.Default.Equals(inv.TargetMethod.ContainingType, jsonSerializerSymbol); + } + + isArgumentOfInvocation = false; + return false; + } + + private static bool IsFieldOrPropertyAssignment(ILocalReferenceOperation operation) + { + IOperation? current = operation.Parent; + + while (current is IAssignmentOperation assignment) + { + if (assignment.Target is IFieldReferenceOperation or IPropertyReferenceOperation) + { + return true; + } + + current = current.Parent; + } + + return false; + } + + private static bool IsTupleForDeconstructionTargetingFieldOrProperty(IOperation operation) + { + IOperation? current = operation.Parent; + + if (current is not ITupleOperation tuple) + { + return false; + } + + Stack depth = new Stack(); + depth.Push(tuple.Elements.IndexOf(operation)); + + // walk-up right-hand nested tuples. + while (tuple.Parent is ITupleOperation parent) + { + depth.Push(parent.Elements.IndexOf(tuple)); + tuple = parent; + } + + current = tuple.WalkUpConversion().Parent; + if (current is not IDeconstructionAssignmentOperation deconstruction) + { + return false; + } + + // walk-down left-hand nested tuples and see if it targets a field or property. + if (deconstruction.Target is not ITupleOperation deconstructionTarget) + { + return false; + } + + tuple = deconstructionTarget; + + IOperation? target = null; + while (depth.Count > 0) + { + int idx = depth.Pop(); + target = tuple.Elements[idx]; + + if (target is ITupleOperation targetAsTuple) + { + tuple = targetAsTuple; + } + else if (depth.Count > 0) + { + return false; + } + } + + return target is IFieldReferenceOperation or IPropertyReferenceOperation; + } + + private static bool IsClosureOnLambdaOrLocalFunction(IOperation operation, IBlockOperation localBlock) + { + if (!operation.IsWithinLambdaOrLocalFunction(out IOperation? lambdaOrLocalFunc)) + { + return false; + } + + IBlockOperation? block = lambdaOrLocalFunc switch + { + IAnonymousFunctionOperation lambda => lambda.Body, + ILocalFunctionOperation localFunc => localFunc.Body, + _ => throw new InvalidOperationException() + }; + + return block != localBlock; + } + + private static bool IsLocalAssignment(IOperation operation, [NotNullWhen(true)] out List? localSymbols) + { + localSymbols = null; + IOperation? currentOperation = operation.Parent; + + while (currentOperation is not null) + { + // for cases like: + // var options; + // options = new JsonSerializerOptions(); + if (currentOperation is IExpressionStatementOperation) + { + IOperation? tmpOperation = operation.Parent; + while (tmpOperation is IAssignmentOperation assignment) + { + if (assignment.Target is IFieldReferenceOperation or IPropertyReferenceOperation) + { + return false; + } + else if (assignment.Target is ILocalReferenceOperation localRef) + { + localSymbols ??= new List(); + localSymbols.Add(localRef.Local); + } + + tmpOperation = assignment.Parent; + } + + return localSymbols != null; + } + // For cases like: + // var options = new JsonSerializerOptions(); + else if (currentOperation is IVariableDeclarationOperation declaration) + { + if (operation.Parent is IAssignmentOperation assignment) + { + foreach (IOperation children in assignment.Children) + { + if (children is IFieldReferenceOperation or IPropertyReferenceOperation) + { + return false; + } + } + } + + var local = GetLocalSymbolFromDeclaration(declaration); + if (local != null) + { + localSymbols = new List { local }; + } + + return local != null; + } + + currentOperation = currentOperation.Parent; + } + + return false; + } + + private static ILocalSymbol? GetLocalSymbolFromDeclaration(IVariableDeclarationOperation declaration) + { + if (declaration.Declarators.Length != 1) + { + return null; + } + + IVariableDeclaratorOperation declarator = declaration.Declarators[0]; + return declarator.Symbol; + } + } +} diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.cs.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.cs.xlf index 6222d73c75..67bd4bbdc6 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.cs.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.cs.xlf @@ -67,6 +67,21 @@ Vyhněte se konstantním polím jako argumentům + + Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance. + Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance. + + + + Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance + Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance + + + + Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal + Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal + + Marshalling of 'StringBuilder' always creates a native buffer copy, resulting in multiple allocations for one marshalling operation. Zařazením parametru StringBuilder se vždy vytvoří kopie nativní vyrovnávací paměti, která bude mít za následek vícenásobné přidělení pro jednu operaci zařazování. diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.de.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.de.xlf index 15cea3dd32..65211bb827 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.de.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.de.xlf @@ -67,6 +67,21 @@ Konstantenmatrizen als Argumente vermeiden + + Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance. + Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance. + + + + Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance + Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance + + + + Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal + Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal + + Marshalling of 'StringBuilder' always creates a native buffer copy, resulting in multiple allocations for one marshalling operation. Beim Marshalling von "StringBuilder" wird immer eine native Pufferkopie erstellt, sodass mehrere Zuordnungen für einen Marshallingvorgang vorhanden sind. diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.es.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.es.xlf index eba673dee2..f43beb5a09 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.es.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.es.xlf @@ -67,6 +67,21 @@ Evitar matrices constantes como argumentos + + Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance. + Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance. + + + + Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance + Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance + + + + Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal + Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal + + Marshalling of 'StringBuilder' always creates a native buffer copy, resulting in multiple allocations for one marshalling operation. Al serializar "StringBuilder" siempre se crea una copia del búfer nativo, lo que da lugar a varias asignaciones para una operación de serialización. diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.fr.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.fr.xlf index 90cb521b4c..86f29384ef 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.fr.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.fr.xlf @@ -67,6 +67,21 @@ Éviter les tableaux constants en tant qu’arguments + + Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance. + Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance. + + + + Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance + Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance + + + + Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal + Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal + + Marshalling of 'StringBuilder' always creates a native buffer copy, resulting in multiple allocations for one marshalling operation. Le marshaling de 'StringBuilder' crée toujours une copie de la mémoire tampon native, ce qui entraîne plusieurs allocations pour une seule opération de marshaling. diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.it.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.it.xlf index 8fedc9bb9b..92df42c2fa 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.it.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.it.xlf @@ -67,6 +67,21 @@ Evitare matrici costanti come argomenti + + Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance. + Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance. + + + + Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance + Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance + + + + Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal + Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal + + Marshalling of 'StringBuilder' always creates a native buffer copy, resulting in multiple allocations for one marshalling operation. Il marshalling di 'StringBuilder' crea sempre una copia del buffer nativo, di conseguenza vengono generate più allocazioni per una singola operazione di marshalling. diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ja.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ja.xlf index a60785ffee..74db5cd02f 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ja.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ja.xlf @@ -67,6 +67,21 @@ 引数として定数配列を使用しない + + Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance. + Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance. + + + + Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance + Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance + + + + Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal + Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal + + Marshalling of 'StringBuilder' always creates a native buffer copy, resulting in multiple allocations for one marshalling operation. 'StringBuilder' をマーシャリングすると、ネイティブ バッファーのコピーが常に作成され、1 回のマーシャリング操作に対して複数の割り当てが発生します。 diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ko.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ko.xlf index 53fe883ef2..8dc1de52db 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ko.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ko.xlf @@ -67,6 +67,21 @@ 상수 배열을 인수로 사용하지 않습니다. + + Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance. + Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance. + + + + Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance + Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance + + + + Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal + Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal + + Marshalling of 'StringBuilder' always creates a native buffer copy, resulting in multiple allocations for one marshalling operation. 'StringBuilder'를 마샬링하는 경우 항상 네이티브 버퍼 복사본이 만들어지므로 하나의 마샬링 작업에 대해 할당이 여러 번 이루어집니다. diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pl.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pl.xlf index a844516d82..a2ed9d0e1f 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pl.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pl.xlf @@ -67,6 +67,21 @@ Unikaj tablic stałych jako argumentów + + Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance. + Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance. + + + + Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance + Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance + + + + Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal + Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal + + Marshalling of 'StringBuilder' always creates a native buffer copy, resulting in multiple allocations for one marshalling operation. Marshalling elementu „StringBuilder” zawsze tworzy natywną kopię buforu, co powoduje powstanie wielu alokacji dla jednej operacji marshallingu. diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pt-BR.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pt-BR.xlf index ae43150a2f..be11bb4647 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pt-BR.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pt-BR.xlf @@ -67,6 +67,21 @@ Evite matrizes constantes como argumentos + + Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance. + Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance. + + + + Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance + Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance + + + + Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal + Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal + + Marshalling of 'StringBuilder' always creates a native buffer copy, resulting in multiple allocations for one marshalling operation. O marshaling de 'StringBuilder' sempre cria uma cópia de buffer nativo, resultando em várias alocações para uma operação de marshalling. diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ru.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ru.xlf index c7d55c78d0..6104bbe7fa 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ru.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ru.xlf @@ -67,6 +67,21 @@ Избегайте использования константных массивов в качестве аргументов + + Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance. + Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance. + + + + Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance + Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance + + + + Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal + Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal + + Marshalling of 'StringBuilder' always creates a native buffer copy, resulting in multiple allocations for one marshalling operation. При маршалировании "StringBuilder" всегда создается собственная копия буфера, что приводит к множественным выделениям для одной операции маршалирования. diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.tr.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.tr.xlf index 6c361a5864..bacb4b65d3 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.tr.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.tr.xlf @@ -67,6 +67,21 @@ Sabit dizileri bağımsız değişkenler olarak kullanmaktan sakının + + Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance. + Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance. + + + + Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance + Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance + + + + Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal + Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal + + Marshalling of 'StringBuilder' always creates a native buffer copy, resulting in multiple allocations for one marshalling operation. 'StringBuilder' öğesinin hazırlanması her zaman, bir hazırlama işlemi için birden çok ayırmaya neden olan yerel arabellek kopyası oluşturur. diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hans.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hans.xlf index 42c966a160..f644d4871a 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hans.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hans.xlf @@ -67,6 +67,21 @@ 不要将常量数组作为参数 + + Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance. + Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance. + + + + Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance + Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance + + + + Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal + Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal + + Marshalling of 'StringBuilder' always creates a native buffer copy, resulting in multiple allocations for one marshalling operation. "StringBuilder" 的封送处理总是会创建一个本机缓冲区副本,这导致一个封送处理操作出现多次分配。 diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hant.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hant.xlf index aa2bb17278..63c3b21e6f 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hant.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hant.xlf @@ -67,6 +67,21 @@ 避免常數陣列作為引數 + + Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance. + Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance. + + + + Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance + Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance + + + + Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal + Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal + + Marshalling of 'StringBuilder' always creates a native buffer copy, resulting in multiple allocations for one marshalling operation. 封送處理 'StringBuilder' 一律都會建立原生緩衝區複本,因而導致單一封送處理作業出現多重配置。 diff --git a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md index accfe817af..6e35343db7 100644 --- a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md +++ b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md @@ -1740,6 +1740,18 @@ Prefer a 'TryAdd' call over an 'Add' call guarded by a 'ContainsKey' check. 'Try |CodeFix|True| --- +## [CA1865](https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1865): Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal + +Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance. + +|Item|Value| +|-|-| +|Category|Performance| +|Enabled|True| +|Severity|Info| +|CodeFix|False| +--- + ## [CA2000](https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2000): Dispose objects before losing scope If a disposable object is not explicitly disposed before all references to it are out of scope, the object will be disposed at some indeterminate time when the garbage collector runs the finalizer of the object. Because an exceptional event might occur that will prevent the finalizer of the object from running, the object should be explicitly disposed instead. diff --git a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Performance/AvoidSingleUseOfLocalJsonSerializerOptionsTests.cs b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Performance/AvoidSingleUseOfLocalJsonSerializerOptionsTests.cs new file mode 100644 index 0000000000..d4d0097120 --- /dev/null +++ b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Performance/AvoidSingleUseOfLocalJsonSerializerOptionsTests.cs @@ -0,0 +1,574 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the MIT license. See License.txt in the project root for license information. + +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.CodeAnalysis.CSharp; +using Xunit; +using VerifyCS = Test.Utilities.CSharpCodeFixVerifier< + Microsoft.NetCore.Analyzers.Performance.AvoidSingleUseOfLocalJsonSerializerOptions, + Microsoft.CodeAnalysis.Testing.EmptyCodeFixProvider>; +using VerifyVB = Test.Utilities.VisualBasicCodeFixVerifier< + Microsoft.NetCore.Analyzers.Performance.AvoidSingleUseOfLocalJsonSerializerOptions, + Microsoft.CodeAnalysis.Testing.EmptyCodeFixProvider>; + +namespace Microsoft.NetCore.Analyzers.Performance.UnitTests +{ + public class AvoidSingleUseOfLocalJsonSerializerOptionsTests + { + #region Diagnostic Tests + + [Fact] + public Task CS_UseNewOptionsAsArgument() + { + string source = @" +using System; +using System.Text.Json; + +internal class Program +{ + static void Main(string[] args) + { + string json = JsonSerializer.Serialize(args, new JsonSerializerOptions { AllowTrailingCommas = true }); + Console.WriteLine(json); + } +} +"; + return VerifyCS.VerifyAnalyzerAsync(source, + VerifyCS.Diagnostic(AvoidSingleUseOfLocalJsonSerializerOptions.s_Rule) + .WithSpan(9, 54, 9, 110)); + } + + [Fact] + public Task CS_UseNewLocalOptionsAsArgument() + { + string source = @" +using System; +using System.Text.Json; + +internal class Program +{ + static void Main(string[] args) + { + JsonSerializerOptions options = new JsonSerializerOptions(); + options.AllowTrailingCommas = true; + + string json = JsonSerializer.Serialize(args, options); + Console.WriteLine(json); + } +} +"; + return VerifyCS.VerifyAnalyzerAsync(source, + VerifyCS.Diagnostic(AvoidSingleUseOfLocalJsonSerializerOptions.s_Rule) + .WithSpan(9, 41, 9, 68)); + } + + [Fact] + public Task VB_UseNewOptionsAsArgument() + { + string source = @" +Imports System +Imports System.Text.Json + +Module Program + Sub Main(args As String()) + Dim json = JsonSerializer.Serialize(args, New JsonSerializerOptions With {.AllowTrailingCommas = True}) + Console.WriteLine(json) + End Sub +End Module +"; + return VerifyVB.VerifyAnalyzerAsync(source, + VerifyVB.Diagnostic(AvoidSingleUseOfLocalJsonSerializerOptions.s_Rule) + .WithSpan(7, 51, 7, 111)); + } + + [Fact] + public Task VB_UseNewLocalOptionsAsArgument() + { + string source = @" +Imports System +Imports System.Text.Json + +Module Program + Sub Main(args As String()) + Dim options = New JsonSerializerOptions() + options.AllowTrailingCommas = True + + Dim json = JsonSerializer.Serialize(args, options) + Console.WriteLine(json) + End Sub +End Module +"; + return VerifyVB.VerifyAnalyzerAsync(source, + VerifyVB.Diagnostic(AvoidSingleUseOfLocalJsonSerializerOptions.s_Rule) + .WithSpan(7, 23, 7, 50)); + } + + [Theory] + [InlineData("new JsonSerializerOptions()", 0)] + [InlineData("new JsonSerializerOptions{}", 0)] + [InlineData("(new JsonSerializerOptions())", 1)] + [InlineData("((new JsonSerializerOptions()))", 2)] + [InlineData("1 == 1 ? new JsonSerializerOptions() : null", 9)] + [InlineData("1 == 1 ? null : 2 == 2 ? null : new JsonSerializerOptions()", 32)] + public Task CS_UseNewOptionsAsArgument_Variants(string expression, int startIndex) + { + string source = $@" +using System.Text.Json; + +class Program +{{ + static string Serialize(T value) + {{ + return JsonSerializer.Serialize(value, {expression}); + }} +}} +"; + const int startLine = 8, endLine = 8; + int startColumn = 48 + startIndex; + int endColumn = startColumn + "new JsonSerializerOptions()".Length; + + return VerifyCS.VerifyAnalyzerAsync(source, + VerifyCS.Diagnostic(AvoidSingleUseOfLocalJsonSerializerOptions.s_Rule) + .WithSpan(startLine, startColumn, endLine, endColumn)); + } + + [Theory] + [InlineData("new JsonSerializerOptions()", 0)] + [InlineData("new JsonSerializerOptions{}", 0)] + [InlineData("(new JsonSerializerOptions())", 1)] + [InlineData("((new JsonSerializerOptions()))", 2)] + [InlineData("1 == 1 ? new JsonSerializerOptions() : null", 9)] + [InlineData("1 == 1 ? null : 2 == 2 ? null : new JsonSerializerOptions()", 32)] + public Task CS_UseNewLocalOptionsAsArgument_Variants(string expression, int startIndex) + { + string source = $@" +using System.Text.Json; + +class Program +{{ + static string Serialize(T value) + {{ + var options = {expression}; + return JsonSerializer.Serialize(value, options); + }} +}} +"; + const int startLine = 8, endLine = 8; + int startColumn = 23 + startIndex; + int endColumn = startColumn + "new JsonSerializerOptions()".Length; + + return VerifyCS.VerifyAnalyzerAsync(source, + VerifyCS.Diagnostic(AvoidSingleUseOfLocalJsonSerializerOptions.s_Rule) + .WithSpan(startLine, startColumn, endLine, endColumn)); + } + + [Fact] + public Task CS_UseNewLocalOptionsAsArgument_Assignment() + => VerifyCS.VerifyAnalyzerAsync(@" +using System.Text.Json; + +class Program +{ + static string Serialize(T value) + { + JsonSerializerOptions opt; + opt = new JsonSerializerOptions(); + + return JsonSerializer.Serialize(value, opt); + } +} +", VerifyCS.Diagnostic(AvoidSingleUseOfLocalJsonSerializerOptions.s_Rule).WithSpan(9, 15, 9, 42)); + + [Fact] + public Task CS_UseNewLocalOptionsAsArgument_SecondLocalReference() + => VerifyCS.VerifyAnalyzerAsync(@" +using System.Text.Json; + +class Program +{ + static string Serialize(T value) + { + JsonSerializerOptions opt = new JsonSerializerOptions(); + _ = opt; + + return JsonSerializer.Serialize(value, opt); + } +} +", VerifyCS.Diagnostic(AvoidSingleUseOfLocalJsonSerializerOptions.s_Rule).WithSpan(8, 37, 8, 64)); + + [Fact] // this could be better handled with data flow analysis. + public Task CS_UseNewLocalOptionsAsArgument_OverwriteLocal() + => VerifyCS.VerifyAnalyzerAsync(@" +using System.Text.Json; + +class Program +{ + static JsonSerializerOptions s_options; + + static string Serialize(T value) + { + JsonSerializerOptions opt = new JsonSerializerOptions(); + opt = s_options; + + return JsonSerializer.Serialize(value, opt); + } +} +", VerifyCS.Diagnostic(AvoidSingleUseOfLocalJsonSerializerOptions.s_Rule).WithSpan(10, 37, 10, 64)); + + [Theory] + [InlineData("opt1")] + [InlineData("opt2")] + public Task CS_UseNewLocalOptionsAsArgument_MultiAssignment(string expression) + => VerifyCS.VerifyAnalyzerAsync($@" +using System.Text.Json; + +class Program +{{ + static string Serialize(T value) + {{ + JsonSerializerOptions opt1, opt2; + opt1 = opt2 = new JsonSerializerOptions(); + + return JsonSerializer.Serialize(value, {expression}); + }} +}} +", VerifyCS.Diagnostic(AvoidSingleUseOfLocalJsonSerializerOptions.s_Rule).WithSpan(9, 23, 9, 50)); + + [Fact] + public Task CS_UseNewLocalOptionsAsArgument_Delegate() + => VerifyCS.VerifyAnalyzerAsync(@" +using System; +using System.Text.Json; + +class Program +{ + static Action Serialize(T value) + { + Action lambda = () => + { + JsonSerializerOptions opt = new JsonSerializerOptions(); + JsonSerializer.Serialize(value, opt); + }; + return lambda; + } +} +", VerifyCS.Diagnostic(AvoidSingleUseOfLocalJsonSerializerOptions.s_Rule).WithSpan(11, 41, 11, 68)); + + [Fact] + public Task CS_UseNewLocalOptionsAsArgument_LocalFunction() +=> VerifyCS.VerifyAnalyzerAsync(@" +using System.Text.Json; + +class Program +{ + static string Serialize(T value) + { + return LocalFunc(); + + string LocalFunc() + { + JsonSerializerOptions opt = new JsonSerializerOptions(); + return JsonSerializer.Serialize(value, opt); + } + } +} +", VerifyCS.Diagnostic(AvoidSingleUseOfLocalJsonSerializerOptions.s_Rule).WithSpan(12, 41, 12, 68)); + + #endregion + + #region No Diagnostic Tests + [Fact] + public Task CS_UseNewOptionsAsArgument_NonSerializerMethod_NoWarn() + => VerifyCS.VerifyAnalyzerAsync(@" +using System.Text.Json; + +class Program +{ + static string Serialize(T value) + { + return MyCustomSerializeMethod(value, new JsonSerializerOptions()); + } + + static string MyCustomSerializeMethod(T value, JsonSerializerOptions options) + => JsonSerializer.Serialize(value, options); +} +"); + + [Fact] + public Task CS_UseNewLocalOptionsAsArgument_NonSerializerMethod_NoWarn() + => VerifyCS.VerifyAnalyzerAsync(@" +using System.Text.Json; + +class Program +{ + static string Serialize(T value) + { + var options = new JsonSerializerOptions(); + return MyCustomSerializeMethod(value, options); + } + + static string MyCustomSerializeMethod(T value, JsonSerializerOptions options) + => JsonSerializer.Serialize(value, options); +} +"); + + [Fact] + public Task CS_UseNewLocalOptionsAsArgument_EscapeCurrentScope_NonSerializerMethod_NoWarn() + => VerifyCS.VerifyAnalyzerAsync(@" +using System.Text.Json; + +class Program +{ + static string Serialize(T value) + { + var options = new JsonSerializerOptions(); + string json1 = MyCustomSerializeMethod(value, options); + string json2 = JsonSerializer.Serialize(value, options); + return json1 + json2; + } + + static string MyCustomSerializeMethod(T value, JsonSerializerOptions options) + => JsonSerializer.Serialize(value, options); +} +"); + + [Theory] + [MemberData(nameof(CS_UseNewLocalOptionsAsArgument_FieldAssignment_NoWarn_TheoryData))] + public Task CS_UseNewLocalOptionsAsArgument_FieldAssignment_NoWarn(string snippet) + { + var test = new VerifyCS.Test(); + test.LanguageVersion = LanguageVersion.CSharp8; // needed for coalescing assignment. + test.TestCode = $@" +using System; +using System.Text.Json; + +class Program +{{ + static JsonSerializerOptions s_options; + + static string Serialize(T value) + {{ + {snippet} + return JsonSerializer.Serialize(value, opt); + }} +}} +"; + + return test.RunAsync(); + } + + [Theory] + [MemberData(nameof(CS_UseNewLocalOptionsAsArgument_PropertyAssignment_NoWarn_TheoryData))] + public Task CS_UseNewLocalOptionsAsArgument_PropertyAssignment_NoWarn(string snippet) + { + var test = new VerifyCS.Test(); + test.LanguageVersion = LanguageVersion.CSharp8; // needed for coalescing assignment. + test.TestCode = $@" +using System; +using System.Text.Json; + +class Program +{{ + private JsonSerializerOptions Options {{ get; set; }} + + string Serialize(T value) + {{ + {snippet} + return JsonSerializer.Serialize(value, opt); + }} +}} +"; + return test.RunAsync(); + } + + public static IEnumerable CS_UseNewLocalOptionsAsArgument_FieldAssignment_NoWarn_TheoryData() + { + return CS_UseNewLocalOptionsAsArgument_Assignment_TheoryData(useField: true).Select(e => new object[] { e }); + } + + public static IEnumerable CS_UseNewLocalOptionsAsArgument_PropertyAssignment_NoWarn_TheoryData() + { + return CS_UseNewLocalOptionsAsArgument_Assignment_TheoryData(useField: false).Select(e => new object[] { e }); + } + + private static List CS_UseNewLocalOptionsAsArgument_Assignment_TheoryData(bool useField) + { + string target = useField ? "s_options" : "Options"; + + return new List() + { + $@"JsonSerializerOptions opt = new JsonSerializerOptions(); + {target} = opt;", + + $@"JsonSerializerOptions opt; + {target} = opt = new JsonSerializerOptions();", + + $@"JsonSerializerOptions opt = {target} = new JsonSerializerOptions();", + + $@"JsonSerializerOptions opt = {target} ??= new JsonSerializerOptions();", + + $@"JsonSerializerOptions opt = new JsonSerializerOptions(); + {target} ??= opt;", + + $@"JsonSerializerOptions opt = new JsonSerializerOptions(); + ({target}, _) = (opt, 42);", + + $@"JsonSerializerOptions opt = new JsonSerializerOptions(); + (({target}, _), _) = ((opt, 42), 42);" + }; + } + + [Fact] + public Task CS_UseNewLocalOptionsAsArgument_NotSingleUse_NoWarn() + => VerifyCS.VerifyAnalyzerAsync(@" +using System.Text.Json; + +class Program +{ + static string SerializeTwice(T value) + { + JsonSerializerOptions opt = new JsonSerializerOptions(); + + string str1 = JsonSerializer.Serialize(value, opt); + string str2 = JsonSerializer.Serialize(value, opt); + + return str1 + str2; + } +} +"); + + [Theory] + [InlineData("opt1", "opt2")] + [InlineData("opt1", "opt3")] + [InlineData("opt2", "opt3")] + public Task CS_UseNewLocalOptionsAsArgument_MultiAssignment_NotSingleUse_NoWarn(string expression1, string expression2) + => VerifyCS.VerifyAnalyzerAsync($@" +using System.Text.Json; + +class Program +{{ + static string Serialize(T value) + {{ + JsonSerializerOptions opt1, opt2, opt3; + opt1 = opt2 = opt3 = new JsonSerializerOptions(); + + string json1 = JsonSerializer.Serialize(value, {expression1}); + string json2 = JsonSerializer.Serialize(value, {expression2}); + + return json1 + json2; + }} +}} +"); + + [Theory] + [InlineData("opt1")] + [InlineData("opt2")] + [InlineData("opt3")] + public Task CS_UseNewLocalOptionsAsArgument_MultiAssignment_EscapeCurrentScope_FieldAssignment_NoWarn(string expression) + => VerifyCS.VerifyAnalyzerAsync($@" +using System.Text.Json; + +class Program +{{ + static JsonSerializerOptions s_options; + + static string Serialize(T value) + {{ + JsonSerializerOptions opt1, opt2, opt3; + opt1 = opt2 = opt3 = new JsonSerializerOptions(); + + s_options = {expression}; + + return JsonSerializer.Serialize(value, opt1); + }} +}} +"); + + [Theory] + [InlineData("opt1 = opt2 = s_options")] + [InlineData("opt1 = s_options = opt2")] + [InlineData("s_options = opt1 = opt2")] + public Task CS_UseNewLocalOptionsAsArgument_MultiAssignment_EscapeCurrentScope_FieldInMultiAssignment_NoWarn(string expression) + => VerifyCS.VerifyAnalyzerAsync($@" +using System.Text.Json; + +class Program +{{ + static JsonSerializerOptions s_options; + + static string Serialize(T value) + {{ + JsonSerializerOptions opt1, opt2; + {expression} = new JsonSerializerOptions(); + + return JsonSerializer.Serialize(value, opt1); + }} +}} +"); + + [Theory] + [InlineData("s_options = opt1 = opt2")] + [InlineData("opt1 = s_options = opt2")] + public Task CSharpUseNewOptionsAsLocalThenAsArgument_AssignmentOnNextStatement_Multiple_WithEscapeScopeOnAssignment_NoWarn(string expression) + => VerifyCS.VerifyAnalyzerAsync($@" +using System.Text.Json; + +class Program +{{ + static JsonSerializerOptions s_options; + + static string Serialize(T value) + {{ + JsonSerializerOptions opt1, opt2; + opt1 = opt2 = new JsonSerializerOptions(); + + {expression}; + + return JsonSerializer.Serialize(value, opt1); + }} +}} +"); + + [Fact] + public Task CS_UseNewLocalOptionsAsArgument_EscapeCurrentScope_ClosureDelegate_NoWarn() + => VerifyCS.VerifyAnalyzerAsync(@" +using System; +using System.Text.Json; + +class Program +{ + static Action Serialize(T value) + { + JsonSerializerOptions opt = new JsonSerializerOptions(); + Action lambda = () => + { + JsonSerializer.Serialize(value, opt); + }; + return lambda; + } +} +"); + + [Fact] + public Task CS_UseNewLocalOptionsAsArgument_EscapeCurrentScope_ClosureLocalFunction_NoWarn() + => VerifyCS.VerifyAnalyzerAsync(@" +using System.Text.Json; + +class Program +{ + static string Serialize(T value) + { + JsonSerializerOptions opt = new JsonSerializerOptions(); + return LocalFunc(); + + string LocalFunc() + { + return JsonSerializer.Serialize(value, opt); + } + } +} +"); + #endregion + } +} diff --git a/src/Utilities/Compiler/DiagnosticCategoryAndIdRanges.txt b/src/Utilities/Compiler/DiagnosticCategoryAndIdRanges.txt index d41b6104e2..67c217b4c2 100644 --- a/src/Utilities/Compiler/DiagnosticCategoryAndIdRanges.txt +++ b/src/Utilities/Compiler/DiagnosticCategoryAndIdRanges.txt @@ -12,7 +12,7 @@ Design: CA2210, CA1000-CA1070 Globalization: CA2101, CA1300-CA1311 Mobility: CA1600-CA1601 -Performance: HA, CA1800-CA1864 +Performance: HA, CA1800-CA1865 Security: CA2100-CA2153, CA2300-CA2330, CA3000-CA3147, CA5300-CA5405 Usage: CA1801, CA1806, CA1816, CA2200-CA2209, CA2211-CA2261 Naming: CA1700-CA1727 diff --git a/src/Utilities/Compiler/WellKnownTypeNames.cs b/src/Utilities/Compiler/WellKnownTypeNames.cs index 80a4e66690..b9606a16fc 100644 --- a/src/Utilities/Compiler/WellKnownTypeNames.cs +++ b/src/Utilities/Compiler/WellKnownTypeNames.cs @@ -401,6 +401,8 @@ internal static class WellKnownTypeNames public const string SystemSystemException = "System.SystemException"; public const string SystemTextCompositeFormat = "System.Text.CompositeFormat"; public const string SystemTextEncoding = "System.Text.Encoding"; + public const string SystemTextJsonJsonSerializerOptions = "System.Text.Json.JsonSerializerOptions"; + public const string SystemTextJsonJsonSerializer = "System.Text.Json.JsonSerializer"; public const string SystemTextRegularExpressionsRegex = "System.Text.RegularExpressions.Regex"; public const string SystemTextStringBuilder = "System.Text.StringBuilder"; public const string SystemThreadStaticAttribute = "System.ThreadStaticAttribute"; From 7b265fc6d1b85bbe8daf4ca107a01d90ccb79bfc Mon Sep 17 00:00:00 2001 From: David Cantu Date: Fri, 11 Aug 2023 10:35:04 -0500 Subject: [PATCH 2/6] Add changes made by msbuild /t:pack /v:m --- .../Microsoft.CodeAnalysis.NetAnalyzers.sarif | 20 +++++++++++++++++++ src/NetAnalyzers/RulesMissingDocumentation.md | 1 + 2 files changed, 21 insertions(+) diff --git a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif index 73af3cdaa8..8390575202 100644 --- a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif +++ b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif @@ -3216,6 +3216,26 @@ ] } }, + "CA1865": { + "id": "CA1865", + "shortDescription": "Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal", + "fullDescription": "Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance.", + "defaultLevel": "note", + "helpUri": "https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1865", + "properties": { + "category": "Performance", + "isEnabledByDefault": true, + "typeName": "AvoidSingleUseOfLocalJsonSerializerOptions", + "languages": [ + "C#", + "Visual Basic" + ], + "tags": [ + "Telemetry", + "EnabledRuleInAggressiveMode" + ] + } + }, "CA2000": { "id": "CA2000", "shortDescription": "Dispose objects before losing scope", diff --git a/src/NetAnalyzers/RulesMissingDocumentation.md b/src/NetAnalyzers/RulesMissingDocumentation.md index 0cd066184e..1b9e540ff5 100644 --- a/src/NetAnalyzers/RulesMissingDocumentation.md +++ b/src/NetAnalyzers/RulesMissingDocumentation.md @@ -10,5 +10,6 @@ CA1856 | | A constant is expected for the parameter | CA1862 | | Prefer using 'StringComparer' to perform case-insensitive string comparisons | CA1863 | | Use 'CompositeFormat' | +CA1865 | | Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal | CA2021 | | Do not call Enumerable.Cast\ or Enumerable.OfType\ with incompatible types | CA2261 | | Do not use ConfigureAwaitOptions.SuppressThrowing with Task\ | From 3df8c171697a3c76920e68bd5350fb12de69dbda Mon Sep 17 00:00:00 2001 From: David Cantu Date: Fri, 11 Aug 2023 11:14:44 -0500 Subject: [PATCH 3/6] Amend id CA1865 -> CA1869 --- src/NetAnalyzers/Core/AnalyzerReleases.Unshipped.md | 4 ++-- .../AvoidSingleUseOfLocalJsonSerializerOptions.cs | 2 +- src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md | 2 +- src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif | 6 +++--- src/NetAnalyzers/RulesMissingDocumentation.md | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/NetAnalyzers/Core/AnalyzerReleases.Unshipped.md b/src/NetAnalyzers/Core/AnalyzerReleases.Unshipped.md index 01db0904b9..a4b1a7ebbd 100644 --- a/src/NetAnalyzers/Core/AnalyzerReleases.Unshipped.md +++ b/src/NetAnalyzers/Core/AnalyzerReleases.Unshipped.md @@ -7,8 +7,8 @@ Rule ID | Category | Severity | Notes CA1865 | Performance | Info | UseStringMethodCharOverloadWithSingleCharacters, [Documentation](https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1865) CA1866 | Performance | Info | UseStringMethodCharOverloadWithSingleCharacters, [Documentation](https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1866) CA1867 | Performance | Disabled | UseStringMethodCharOverloadWithSingleCharacters, [Documentation](https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1867) -CA1868 | Performance | Info | DoNotGuardSetAddOrRemoveByContains, [Documentation](https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1865) -CA1865 | Performance | Info | AvoidSingleUseOfLocalJsonSerializerOptions, [Documentation](https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1865) +CA1868 | Performance | Info | DoNotGuardSetAddOrRemoveByContains, [Documentation](https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1868) +CA1869 | Performance | Info | AvoidSingleUseOfLocalJsonSerializerOptions, [Documentation](https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/CA1869) CA2261 | Usage | Warning | DoNotUseConfigureAwaitWithSuppressThrowing, [Documentation](https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2250) CA1510 | Maintainability | Info | UseExceptionThrowHelpers, [Documentation](https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1510) CA1511 | Maintainability | Info | UseExceptionThrowHelpers, [Documentation](https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1511) diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Performance/AvoidSingleUseOfLocalJsonSerializerOptions.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Performance/AvoidSingleUseOfLocalJsonSerializerOptions.cs index 8281336119..4246ab6daf 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Performance/AvoidSingleUseOfLocalJsonSerializerOptions.cs +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Performance/AvoidSingleUseOfLocalJsonSerializerOptions.cs @@ -19,7 +19,7 @@ namespace Microsoft.NetCore.Analyzers.Performance public sealed class AvoidSingleUseOfLocalJsonSerializerOptions : DiagnosticAnalyzer { internal static readonly DiagnosticDescriptor s_Rule = DiagnosticDescriptorHelper.Create( - id: "CA1865", + id: "CA1869", title: CreateLocalizableResourceString(nameof(AvoidSingleUseOfLocalJsonSerializerOptionsTitle)), messageFormat: CreateLocalizableResourceString(nameof(AvoidSingleUseOfLocalJsonSerializerOptionsMessage)), category: DiagnosticCategory.Performance, diff --git a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md index 6326acc1a5..5d06ab2a3b 100644 --- a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md +++ b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md @@ -1788,7 +1788,7 @@ Do not guard 'Add(item)' or 'Remove(item)' with 'Contains(item)' for the set. Th |CodeFix|True| --- -## [CA1865](https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1865): Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal +## [CA1869](https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1869): Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance. diff --git a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif index 02a18b4b94..df79c33bf6 100644 --- a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif +++ b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif @@ -3292,12 +3292,12 @@ ] } }, - "CA1865": { - "id": "CA1865", + "CA1869": { + "id": "CA1869", "shortDescription": "Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal", "fullDescription": "Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance.", "defaultLevel": "note", - "helpUri": "https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1865", + "helpUri": "https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1869", "properties": { "category": "Performance", "isEnabledByDefault": true, diff --git a/src/NetAnalyzers/RulesMissingDocumentation.md b/src/NetAnalyzers/RulesMissingDocumentation.md index e0c64bd7d8..bd15f7b511 100644 --- a/src/NetAnalyzers/RulesMissingDocumentation.md +++ b/src/NetAnalyzers/RulesMissingDocumentation.md @@ -13,6 +13,6 @@ CA1863 | | Use char overload | CA1866 | | Use char overload | CA1867 | | Use char overload | -CA1865 | | Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal | +CA1869 | | Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal | CA2021 | | Do not call Enumerable.Cast\ or Enumerable.OfType\ with incompatible types | CA2261 | | Do not use ConfigureAwaitOptions.SuppressThrowing with Task\ | From 28d5f3266e9286aca1418d355fb38368b0598ebe Mon Sep 17 00:00:00 2001 From: David Cantu Date: Mon, 14 Aug 2023 10:53:35 -0500 Subject: [PATCH 4/6] Address feedback --- .../MicrosoftNetCoreAnalyzersResources.resx | 6 +- ...idSingleUseOfLocalJsonSerializerOptions.cs | 16 +- .../MicrosoftNetCoreAnalyzersResources.cs.xlf | 12 +- .../MicrosoftNetCoreAnalyzersResources.de.xlf | 12 +- .../MicrosoftNetCoreAnalyzersResources.es.xlf | 12 +- .../MicrosoftNetCoreAnalyzersResources.fr.xlf | 12 +- .../MicrosoftNetCoreAnalyzersResources.it.xlf | 12 +- .../MicrosoftNetCoreAnalyzersResources.ja.xlf | 12 +- .../MicrosoftNetCoreAnalyzersResources.ko.xlf | 12 +- .../MicrosoftNetCoreAnalyzersResources.pl.xlf | 12 +- ...crosoftNetCoreAnalyzersResources.pt-BR.xlf | 12 +- .../MicrosoftNetCoreAnalyzersResources.ru.xlf | 12 +- .../MicrosoftNetCoreAnalyzersResources.tr.xlf | 12 +- ...osoftNetCoreAnalyzersResources.zh-Hans.xlf | 12 +- ...osoftNetCoreAnalyzersResources.zh-Hant.xlf | 12 +- ...gleUseOfLocalJsonSerializerOptionsTests.cs | 742 +++++++++--------- 16 files changed, 441 insertions(+), 479 deletions(-) diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx index 9767c9f340..788af729b9 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx @@ -2130,12 +2130,12 @@ Widening and user defined conversions are not supported with generic types.Use char overload - Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance + Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton - Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance. + Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton. Single-use 'JsonSerializerOptions' instances can substantially degrade the performance of your application. - Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal + Reuse 'JsonSerializerOptions' instances \ No newline at end of file diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Performance/AvoidSingleUseOfLocalJsonSerializerOptions.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Performance/AvoidSingleUseOfLocalJsonSerializerOptions.cs index 4246ab6daf..94f84bfc06 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Performance/AvoidSingleUseOfLocalJsonSerializerOptions.cs +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Performance/AvoidSingleUseOfLocalJsonSerializerOptions.cs @@ -9,7 +9,6 @@ using System.Diagnostics.CodeAnalysis; using System; using System.Collections.Generic; -using System.Linq; namespace Microsoft.NetCore.Analyzers.Performance { @@ -94,11 +93,12 @@ private static bool IsLocalUsedAsArgumentForJsonSerializerOnly(IObjectCreationOp } IBlockOperation? localBlock = objCreation.GetFirstParentBlock(); - bool ret = false; + bool isSingleUseJsonSerializerInvocation = false; - foreach (ILocalReferenceOperation descendant in localBlock.Descendants().OfType()) + foreach (IOperation descendant in localBlock.Descendants()) { - if (!localSymbols.Contains(descendant.Local)) + if (descendant is not ILocalReferenceOperation localRefOperation || + !localSymbols.Contains(localRefOperation.Local)) { continue; } @@ -107,12 +107,12 @@ private static bool IsLocalUsedAsArgumentForJsonSerializerOnly(IObjectCreationOp if (IsArgumentOfJsonSerializer(descendant, jsonSerializerSymbol, out bool isArgumentOfInvocation)) { // Case: used more than once i.e: not single-use. - if (ret) + if (isSingleUseJsonSerializerInvocation) { return false; } - ret = true; + isSingleUseJsonSerializerInvocation = true; } // Case: passed as argument of a non-JsonSerializer method. @@ -139,7 +139,7 @@ private static bool IsLocalUsedAsArgumentForJsonSerializerOnly(IObjectCreationOp } } - return ret; + return isSingleUseJsonSerializerInvocation; } [return: NotNullIfNotNull(nameof(operation))] @@ -168,7 +168,7 @@ private static bool IsArgumentOfJsonSerializer(IOperation operation, INamedTypeS return false; } - private static bool IsFieldOrPropertyAssignment(ILocalReferenceOperation operation) + private static bool IsFieldOrPropertyAssignment(IOperation operation) { IOperation? current = operation.Parent; diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.cs.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.cs.xlf index f24f678fd1..44ac309f8a 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.cs.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.cs.xlf @@ -68,18 +68,18 @@ - Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance. - Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance. + Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton. Single-use 'JsonSerializerOptions' instances can substantially degrade the performance of your application. + Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton. Single-use 'JsonSerializerOptions' instances can substantially degrade the performance of your application. - Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance - Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance + Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton + Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton - Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal - Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal + Reuse 'JsonSerializerOptions' instances + Reuse 'JsonSerializerOptions' instances diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.de.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.de.xlf index 9d68d5d45d..6a216de97d 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.de.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.de.xlf @@ -68,18 +68,18 @@ - Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance. - Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance. + Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton. Single-use 'JsonSerializerOptions' instances can substantially degrade the performance of your application. + Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton. Single-use 'JsonSerializerOptions' instances can substantially degrade the performance of your application. - Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance - Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance + Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton + Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton - Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal - Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal + Reuse 'JsonSerializerOptions' instances + Reuse 'JsonSerializerOptions' instances diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.es.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.es.xlf index 83694e5481..4df7844c6b 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.es.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.es.xlf @@ -68,18 +68,18 @@ - Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance. - Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance. + Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton. Single-use 'JsonSerializerOptions' instances can substantially degrade the performance of your application. + Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton. Single-use 'JsonSerializerOptions' instances can substantially degrade the performance of your application. - Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance - Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance + Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton + Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton - Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal - Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal + Reuse 'JsonSerializerOptions' instances + Reuse 'JsonSerializerOptions' instances diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.fr.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.fr.xlf index b390830d6e..123b4e875a 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.fr.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.fr.xlf @@ -68,18 +68,18 @@ - Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance. - Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance. + Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton. Single-use 'JsonSerializerOptions' instances can substantially degrade the performance of your application. + Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton. Single-use 'JsonSerializerOptions' instances can substantially degrade the performance of your application. - Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance - Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance + Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton + Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton - Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal - Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal + Reuse 'JsonSerializerOptions' instances + Reuse 'JsonSerializerOptions' instances diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.it.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.it.xlf index 15571ba2e4..1d6391b1cf 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.it.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.it.xlf @@ -68,18 +68,18 @@ - Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance. - Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance. + Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton. Single-use 'JsonSerializerOptions' instances can substantially degrade the performance of your application. + Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton. Single-use 'JsonSerializerOptions' instances can substantially degrade the performance of your application. - Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance - Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance + Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton + Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton - Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal - Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal + Reuse 'JsonSerializerOptions' instances + Reuse 'JsonSerializerOptions' instances diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ja.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ja.xlf index 9d719d1d27..4aa9fe092d 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ja.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ja.xlf @@ -68,18 +68,18 @@ - Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance. - Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance. + Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton. Single-use 'JsonSerializerOptions' instances can substantially degrade the performance of your application. + Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton. Single-use 'JsonSerializerOptions' instances can substantially degrade the performance of your application. - Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance - Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance + Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton + Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton - Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal - Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal + Reuse 'JsonSerializerOptions' instances + Reuse 'JsonSerializerOptions' instances diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ko.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ko.xlf index 6d1b710008..45fc956274 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ko.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ko.xlf @@ -68,18 +68,18 @@ - Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance. - Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance. + Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton. Single-use 'JsonSerializerOptions' instances can substantially degrade the performance of your application. + Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton. Single-use 'JsonSerializerOptions' instances can substantially degrade the performance of your application. - Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance - Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance + Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton + Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton - Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal - Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal + Reuse 'JsonSerializerOptions' instances + Reuse 'JsonSerializerOptions' instances diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pl.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pl.xlf index 041413d294..a3b2f98a42 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pl.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pl.xlf @@ -68,18 +68,18 @@ - Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance. - Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance. + Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton. Single-use 'JsonSerializerOptions' instances can substantially degrade the performance of your application. + Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton. Single-use 'JsonSerializerOptions' instances can substantially degrade the performance of your application. - Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance - Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance + Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton + Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton - Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal - Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal + Reuse 'JsonSerializerOptions' instances + Reuse 'JsonSerializerOptions' instances diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pt-BR.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pt-BR.xlf index 7157c5313a..f92ad4ed70 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pt-BR.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pt-BR.xlf @@ -68,18 +68,18 @@ - Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance. - Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance. + Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton. Single-use 'JsonSerializerOptions' instances can substantially degrade the performance of your application. + Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton. Single-use 'JsonSerializerOptions' instances can substantially degrade the performance of your application. - Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance - Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance + Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton + Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton - Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal - Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal + Reuse 'JsonSerializerOptions' instances + Reuse 'JsonSerializerOptions' instances diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ru.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ru.xlf index 0141c5fff9..db3f0e0e72 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ru.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ru.xlf @@ -68,18 +68,18 @@ - Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance. - Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance. + Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton. Single-use 'JsonSerializerOptions' instances can substantially degrade the performance of your application. + Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton. Single-use 'JsonSerializerOptions' instances can substantially degrade the performance of your application. - Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance - Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance + Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton + Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton - Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal - Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal + Reuse 'JsonSerializerOptions' instances + Reuse 'JsonSerializerOptions' instances diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.tr.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.tr.xlf index e94086f443..c5a2a613f4 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.tr.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.tr.xlf @@ -68,18 +68,18 @@ - Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance. - Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance. + Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton. Single-use 'JsonSerializerOptions' instances can substantially degrade the performance of your application. + Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton. Single-use 'JsonSerializerOptions' instances can substantially degrade the performance of your application. - Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance - Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance + Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton + Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton - Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal - Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal + Reuse 'JsonSerializerOptions' instances + Reuse 'JsonSerializerOptions' instances diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hans.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hans.xlf index f0b17e205a..b2dd8b2a89 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hans.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hans.xlf @@ -68,18 +68,18 @@ - Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance. - Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance. + Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton. Single-use 'JsonSerializerOptions' instances can substantially degrade the performance of your application. + Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton. Single-use 'JsonSerializerOptions' instances can substantially degrade the performance of your application. - Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance - Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance + Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton + Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton - Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal - Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal + Reuse 'JsonSerializerOptions' instances + Reuse 'JsonSerializerOptions' instances diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hant.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hant.xlf index 1afb8c1160..48910e4488 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hant.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hant.xlf @@ -68,18 +68,18 @@ - Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance. - Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance. + Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton. Single-use 'JsonSerializerOptions' instances can substantially degrade the performance of your application. + Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton. Single-use 'JsonSerializerOptions' instances can substantially degrade the performance of your application. - Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance - Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance + Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton + Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton - Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal - Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal + Reuse 'JsonSerializerOptions' instances + Reuse 'JsonSerializerOptions' instances diff --git a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Performance/AvoidSingleUseOfLocalJsonSerializerOptionsTests.cs b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Performance/AvoidSingleUseOfLocalJsonSerializerOptionsTests.cs index d4d0097120..e1640e49dd 100644 --- a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Performance/AvoidSingleUseOfLocalJsonSerializerOptionsTests.cs +++ b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Performance/AvoidSingleUseOfLocalJsonSerializerOptionsTests.cs @@ -20,318 +20,280 @@ public class AvoidSingleUseOfLocalJsonSerializerOptionsTests [Fact] public Task CS_UseNewOptionsAsArgument() - { - string source = @" -using System; -using System.Text.Json; - -internal class Program -{ - static void Main(string[] args) - { - string json = JsonSerializer.Serialize(args, new JsonSerializerOptions { AllowTrailingCommas = true }); - Console.WriteLine(json); - } -} -"; - return VerifyCS.VerifyAnalyzerAsync(source, - VerifyCS.Diagnostic(AvoidSingleUseOfLocalJsonSerializerOptions.s_Rule) - .WithSpan(9, 54, 9, 110)); - } + => VerifyCS.VerifyAnalyzerAsync(""" + using System; + using System.Text.Json; + + internal class Program + { + static void Main(string[] args) + { + string json = JsonSerializer.Serialize(args, {|CA1869:new JsonSerializerOptions { AllowTrailingCommas = true }|}); + Console.WriteLine(json); + } + } + """); [Fact] public Task CS_UseNewLocalOptionsAsArgument() - { - string source = @" -using System; -using System.Text.Json; - -internal class Program -{ - static void Main(string[] args) - { - JsonSerializerOptions options = new JsonSerializerOptions(); - options.AllowTrailingCommas = true; - - string json = JsonSerializer.Serialize(args, options); - Console.WriteLine(json); - } -} -"; - return VerifyCS.VerifyAnalyzerAsync(source, - VerifyCS.Diagnostic(AvoidSingleUseOfLocalJsonSerializerOptions.s_Rule) - .WithSpan(9, 41, 9, 68)); - } + => VerifyCS.VerifyAnalyzerAsync(""" + using System; + using System.Text.Json; + + internal class Program + { + static void Main(string[] args) + { + JsonSerializerOptions options = {|CA1869:new JsonSerializerOptions()|}; + options.AllowTrailingCommas = true; + + string json = JsonSerializer.Serialize(args, options); + Console.WriteLine(json); + } + } + """); [Fact] public Task VB_UseNewOptionsAsArgument() - { - string source = @" -Imports System -Imports System.Text.Json - -Module Program - Sub Main(args As String()) - Dim json = JsonSerializer.Serialize(args, New JsonSerializerOptions With {.AllowTrailingCommas = True}) - Console.WriteLine(json) - End Sub -End Module -"; - return VerifyVB.VerifyAnalyzerAsync(source, - VerifyVB.Diagnostic(AvoidSingleUseOfLocalJsonSerializerOptions.s_Rule) - .WithSpan(7, 51, 7, 111)); - } + => VerifyVB.VerifyAnalyzerAsync(""" + Imports System + Imports System.Text.Json + + Module Program + Sub Main(args As String()) + Dim json = JsonSerializer.Serialize(args, {|CA1869:New JsonSerializerOptions With {.AllowTrailingCommas = True}|}) + Console.WriteLine(json) + End Sub + End Module + """); [Fact] public Task VB_UseNewLocalOptionsAsArgument() - { - string source = @" -Imports System -Imports System.Text.Json - -Module Program - Sub Main(args As String()) - Dim options = New JsonSerializerOptions() - options.AllowTrailingCommas = True - - Dim json = JsonSerializer.Serialize(args, options) - Console.WriteLine(json) - End Sub -End Module -"; - return VerifyVB.VerifyAnalyzerAsync(source, - VerifyVB.Diagnostic(AvoidSingleUseOfLocalJsonSerializerOptions.s_Rule) - .WithSpan(7, 23, 7, 50)); - } + => VerifyVB.VerifyAnalyzerAsync(""" + Imports System + Imports System.Text.Json + + Module Program + Sub Main(args As String()) + Dim options = {|CA1869:New JsonSerializerOptions()|} + options.AllowTrailingCommas = True + + Dim json = JsonSerializer.Serialize(args, options) + Console.WriteLine(json) + End Sub + End Module + """); [Theory] - [InlineData("new JsonSerializerOptions()", 0)] - [InlineData("new JsonSerializerOptions{}", 0)] - [InlineData("(new JsonSerializerOptions())", 1)] - [InlineData("((new JsonSerializerOptions()))", 2)] - [InlineData("1 == 1 ? new JsonSerializerOptions() : null", 9)] - [InlineData("1 == 1 ? null : 2 == 2 ? null : new JsonSerializerOptions()", 32)] - public Task CS_UseNewOptionsAsArgument_Variants(string expression, int startIndex) - { - string source = $@" -using System.Text.Json; - -class Program -{{ - static string Serialize(T value) - {{ - return JsonSerializer.Serialize(value, {expression}); - }} -}} -"; - const int startLine = 8, endLine = 8; - int startColumn = 48 + startIndex; - int endColumn = startColumn + "new JsonSerializerOptions()".Length; - - return VerifyCS.VerifyAnalyzerAsync(source, - VerifyCS.Diagnostic(AvoidSingleUseOfLocalJsonSerializerOptions.s_Rule) - .WithSpan(startLine, startColumn, endLine, endColumn)); - } + [InlineData("{|CA1869:new JsonSerializerOptions()|}")] + [InlineData("{|CA1869:new JsonSerializerOptions{}|}")] + [InlineData("({|CA1869:new JsonSerializerOptions()|})")] + [InlineData("(({|CA1869:new JsonSerializerOptions()|}))")] + [InlineData("1 == 1 ? {|CA1869:new JsonSerializerOptions()|} : null")] + [InlineData("1 == 1 ? null : 2 == 2 ? null : {|CA1869:new JsonSerializerOptions()|}")] + public Task CS_UseNewOptionsAsArgument_Variants(string expression) + => VerifyCS.VerifyAnalyzerAsync($$""" + using System.Text.Json; + + class Program + { + static string Serialize(T value) + { + return JsonSerializer.Serialize(value, {{expression}}); + } + } + """); [Theory] - [InlineData("new JsonSerializerOptions()", 0)] - [InlineData("new JsonSerializerOptions{}", 0)] - [InlineData("(new JsonSerializerOptions())", 1)] - [InlineData("((new JsonSerializerOptions()))", 2)] - [InlineData("1 == 1 ? new JsonSerializerOptions() : null", 9)] - [InlineData("1 == 1 ? null : 2 == 2 ? null : new JsonSerializerOptions()", 32)] - public Task CS_UseNewLocalOptionsAsArgument_Variants(string expression, int startIndex) - { - string source = $@" -using System.Text.Json; - -class Program -{{ - static string Serialize(T value) - {{ - var options = {expression}; - return JsonSerializer.Serialize(value, options); - }} -}} -"; - const int startLine = 8, endLine = 8; - int startColumn = 23 + startIndex; - int endColumn = startColumn + "new JsonSerializerOptions()".Length; - - return VerifyCS.VerifyAnalyzerAsync(source, - VerifyCS.Diagnostic(AvoidSingleUseOfLocalJsonSerializerOptions.s_Rule) - .WithSpan(startLine, startColumn, endLine, endColumn)); - } + [InlineData("{|CA1869:new JsonSerializerOptions()|}")] + [InlineData("{|CA1869:new JsonSerializerOptions{}|}")] + [InlineData("({|CA1869:new JsonSerializerOptions()|})")] + [InlineData("(({|CA1869:new JsonSerializerOptions()|}))")] + [InlineData("1 == 1 ? {|CA1869:new JsonSerializerOptions()|} : null")] + [InlineData("1 == 1 ? null : 2 == 2 ? null : {|CA1869:new JsonSerializerOptions()|}")] + public Task CS_UseNewLocalOptionsAsArgument_Variants(string expression) + => VerifyCS.VerifyAnalyzerAsync($$""" + using System.Text.Json; + + class Program + { + static string Serialize(T value) + { + var options = {{expression}}; + return JsonSerializer.Serialize(value, options); + } + } + """); [Fact] public Task CS_UseNewLocalOptionsAsArgument_Assignment() - => VerifyCS.VerifyAnalyzerAsync(@" -using System.Text.Json; + => VerifyCS.VerifyAnalyzerAsync(""" + using System.Text.Json; -class Program -{ - static string Serialize(T value) - { - JsonSerializerOptions opt; - opt = new JsonSerializerOptions(); + class Program + { + static string Serialize(T value) + { + JsonSerializerOptions opt; + opt = {|CA1869:new JsonSerializerOptions()|}; - return JsonSerializer.Serialize(value, opt); - } -} -", VerifyCS.Diagnostic(AvoidSingleUseOfLocalJsonSerializerOptions.s_Rule).WithSpan(9, 15, 9, 42)); + return JsonSerializer.Serialize(value, opt); + } + } + """); [Fact] public Task CS_UseNewLocalOptionsAsArgument_SecondLocalReference() - => VerifyCS.VerifyAnalyzerAsync(@" -using System.Text.Json; + => VerifyCS.VerifyAnalyzerAsync(""" + using System.Text.Json; -class Program -{ - static string Serialize(T value) - { - JsonSerializerOptions opt = new JsonSerializerOptions(); - _ = opt; + class Program + { + static string Serialize(T value) + { + JsonSerializerOptions opt = {|CA1869:new JsonSerializerOptions()|}; + _ = opt; - return JsonSerializer.Serialize(value, opt); - } -} -", VerifyCS.Diagnostic(AvoidSingleUseOfLocalJsonSerializerOptions.s_Rule).WithSpan(8, 37, 8, 64)); + return JsonSerializer.Serialize(value, opt); + } + } + """); [Fact] // this could be better handled with data flow analysis. public Task CS_UseNewLocalOptionsAsArgument_OverwriteLocal() - => VerifyCS.VerifyAnalyzerAsync(@" -using System.Text.Json; + => VerifyCS.VerifyAnalyzerAsync(""" + using System.Text.Json; -class Program -{ - static JsonSerializerOptions s_options; + class Program + { + static JsonSerializerOptions s_options; - static string Serialize(T value) - { - JsonSerializerOptions opt = new JsonSerializerOptions(); - opt = s_options; + static string Serialize(T value) + { + JsonSerializerOptions opt = {|CA1869:new JsonSerializerOptions()|}; + opt = s_options; - return JsonSerializer.Serialize(value, opt); - } -} -", VerifyCS.Diagnostic(AvoidSingleUseOfLocalJsonSerializerOptions.s_Rule).WithSpan(10, 37, 10, 64)); + return JsonSerializer.Serialize(value, opt); + } + } + """); [Theory] [InlineData("opt1")] [InlineData("opt2")] public Task CS_UseNewLocalOptionsAsArgument_MultiAssignment(string expression) - => VerifyCS.VerifyAnalyzerAsync($@" -using System.Text.Json; + => VerifyCS.VerifyAnalyzerAsync($$""" + using System.Text.Json; -class Program -{{ - static string Serialize(T value) - {{ - JsonSerializerOptions opt1, opt2; - opt1 = opt2 = new JsonSerializerOptions(); + class Program + { + static string Serialize(T value) + { + JsonSerializerOptions opt1, opt2; + opt1 = opt2 = {|CA1869:new JsonSerializerOptions()|}; - return JsonSerializer.Serialize(value, {expression}); - }} -}} -", VerifyCS.Diagnostic(AvoidSingleUseOfLocalJsonSerializerOptions.s_Rule).WithSpan(9, 23, 9, 50)); + return JsonSerializer.Serialize(value, {{expression}}); + } + } + """); [Fact] public Task CS_UseNewLocalOptionsAsArgument_Delegate() - => VerifyCS.VerifyAnalyzerAsync(@" -using System; -using System.Text.Json; - -class Program -{ - static Action Serialize(T value) - { - Action lambda = () => - { - JsonSerializerOptions opt = new JsonSerializerOptions(); - JsonSerializer.Serialize(value, opt); - }; - return lambda; - } -} -", VerifyCS.Diagnostic(AvoidSingleUseOfLocalJsonSerializerOptions.s_Rule).WithSpan(11, 41, 11, 68)); + => VerifyCS.VerifyAnalyzerAsync(""" + using System; + using System.Text.Json; + + class Program + { + static Action Serialize(T value) + { + Action lambda = () => + { + JsonSerializerOptions opt = {|CA1869:new JsonSerializerOptions()|}; + JsonSerializer.Serialize(value, opt); + }; + return lambda; + } + } + """); [Fact] public Task CS_UseNewLocalOptionsAsArgument_LocalFunction() -=> VerifyCS.VerifyAnalyzerAsync(@" -using System.Text.Json; - -class Program -{ - static string Serialize(T value) - { - return LocalFunc(); - - string LocalFunc() - { - JsonSerializerOptions opt = new JsonSerializerOptions(); - return JsonSerializer.Serialize(value, opt); - } - } -} -", VerifyCS.Diagnostic(AvoidSingleUseOfLocalJsonSerializerOptions.s_Rule).WithSpan(12, 41, 12, 68)); + => VerifyCS.VerifyAnalyzerAsync(""" + using System.Text.Json; + + class Program + { + static string Serialize(T value) + { + return LocalFunc(); + + string LocalFunc() + { + JsonSerializerOptions opt = {|CA1869:new JsonSerializerOptions()|}; + return JsonSerializer.Serialize(value, opt); + } + } + } + """); #endregion #region No Diagnostic Tests [Fact] public Task CS_UseNewOptionsAsArgument_NonSerializerMethod_NoWarn() - => VerifyCS.VerifyAnalyzerAsync(@" -using System.Text.Json; + => VerifyCS.VerifyAnalyzerAsync(""" + using System.Text.Json; -class Program -{ - static string Serialize(T value) - { - return MyCustomSerializeMethod(value, new JsonSerializerOptions()); - } + class Program + { + static string Serialize(T value) + { + return MyCustomSerializeMethod(value, new JsonSerializerOptions()); + } - static string MyCustomSerializeMethod(T value, JsonSerializerOptions options) - => JsonSerializer.Serialize(value, options); -} -"); + static string MyCustomSerializeMethod(T value, JsonSerializerOptions options) + => JsonSerializer.Serialize(value, options); + } + """); [Fact] public Task CS_UseNewLocalOptionsAsArgument_NonSerializerMethod_NoWarn() - => VerifyCS.VerifyAnalyzerAsync(@" -using System.Text.Json; - -class Program -{ - static string Serialize(T value) - { - var options = new JsonSerializerOptions(); - return MyCustomSerializeMethod(value, options); - } - - static string MyCustomSerializeMethod(T value, JsonSerializerOptions options) - => JsonSerializer.Serialize(value, options); -} -"); + => VerifyCS.VerifyAnalyzerAsync(""" + using System.Text.Json; + + class Program + { + static string Serialize(T value) + { + var options = new JsonSerializerOptions(); + return MyCustomSerializeMethod(value, options); + } + + static string MyCustomSerializeMethod(T value, JsonSerializerOptions options) + => JsonSerializer.Serialize(value, options); + } + """); [Fact] public Task CS_UseNewLocalOptionsAsArgument_EscapeCurrentScope_NonSerializerMethod_NoWarn() - => VerifyCS.VerifyAnalyzerAsync(@" -using System.Text.Json; - -class Program -{ - static string Serialize(T value) - { - var options = new JsonSerializerOptions(); - string json1 = MyCustomSerializeMethod(value, options); - string json2 = JsonSerializer.Serialize(value, options); - return json1 + json2; - } - - static string MyCustomSerializeMethod(T value, JsonSerializerOptions options) - => JsonSerializer.Serialize(value, options); -} -"); + => VerifyCS.VerifyAnalyzerAsync(""" + using System.Text.Json; + + class Program + { + static string Serialize(T value) + { + var options = new JsonSerializerOptions(); + string json1 = MyCustomSerializeMethod(value, options); + string json2 = JsonSerializer.Serialize(value, options); + return json1 + json2; + } + + static string MyCustomSerializeMethod(T value, JsonSerializerOptions options) + => JsonSerializer.Serialize(value, options); + } + """); [Theory] [MemberData(nameof(CS_UseNewLocalOptionsAsArgument_FieldAssignment_NoWarn_TheoryData))] @@ -339,21 +301,21 @@ public Task CS_UseNewLocalOptionsAsArgument_FieldAssignment_NoWarn(string snippe { var test = new VerifyCS.Test(); test.LanguageVersion = LanguageVersion.CSharp8; // needed for coalescing assignment. - test.TestCode = $@" -using System; -using System.Text.Json; - -class Program -{{ - static JsonSerializerOptions s_options; - - static string Serialize(T value) - {{ - {snippet} - return JsonSerializer.Serialize(value, opt); - }} -}} -"; + test.TestCode = $$""" + using System; + using System.Text.Json; + + class Program + { + static JsonSerializerOptions s_options; + + static string Serialize(T value) + { + {{snippet}} + return JsonSerializer.Serialize(value, opt); + } + } + """; return test.RunAsync(); } @@ -364,21 +326,21 @@ public Task CS_UseNewLocalOptionsAsArgument_PropertyAssignment_NoWarn(string sni { var test = new VerifyCS.Test(); test.LanguageVersion = LanguageVersion.CSharp8; // needed for coalescing assignment. - test.TestCode = $@" -using System; -using System.Text.Json; - -class Program -{{ - private JsonSerializerOptions Options {{ get; set; }} - - string Serialize(T value) - {{ - {snippet} - return JsonSerializer.Serialize(value, opt); - }} -}} -"; + test.TestCode = $$""" + using System; + using System.Text.Json; + + class Program + { + private JsonSerializerOptions Options { get; set; } + + string Serialize(T value) + { + {{snippet}} + return JsonSerializer.Serialize(value, opt); + } + } + """; return test.RunAsync(); } @@ -421,154 +383,154 @@ private static List CS_UseNewLocalOptionsAsArgument_Assignment_TheoryDat [Fact] public Task CS_UseNewLocalOptionsAsArgument_NotSingleUse_NoWarn() - => VerifyCS.VerifyAnalyzerAsync(@" -using System.Text.Json; + => VerifyCS.VerifyAnalyzerAsync(""" + using System.Text.Json; -class Program -{ - static string SerializeTwice(T value) - { - JsonSerializerOptions opt = new JsonSerializerOptions(); + class Program + { + static string SerializeTwice(T value) + { + JsonSerializerOptions opt = new JsonSerializerOptions(); - string str1 = JsonSerializer.Serialize(value, opt); - string str2 = JsonSerializer.Serialize(value, opt); + string str1 = JsonSerializer.Serialize(value, opt); + string str2 = JsonSerializer.Serialize(value, opt); - return str1 + str2; - } -} -"); + return str1 + str2; + } + } + """); [Theory] [InlineData("opt1", "opt2")] [InlineData("opt1", "opt3")] [InlineData("opt2", "opt3")] public Task CS_UseNewLocalOptionsAsArgument_MultiAssignment_NotSingleUse_NoWarn(string expression1, string expression2) - => VerifyCS.VerifyAnalyzerAsync($@" -using System.Text.Json; - -class Program -{{ - static string Serialize(T value) - {{ - JsonSerializerOptions opt1, opt2, opt3; - opt1 = opt2 = opt3 = new JsonSerializerOptions(); - - string json1 = JsonSerializer.Serialize(value, {expression1}); - string json2 = JsonSerializer.Serialize(value, {expression2}); + => VerifyCS.VerifyAnalyzerAsync($$""" + using System.Text.Json; + + class Program + { + static string Serialize(T value) + { + JsonSerializerOptions opt1, opt2, opt3; + opt1 = opt2 = opt3 = new JsonSerializerOptions(); + + string json1 = JsonSerializer.Serialize(value, {{expression1}}); + string json2 = JsonSerializer.Serialize(value, {{expression2}}); - return json1 + json2; - }} -}} -"); + return json1 + json2; + } + } + """); [Theory] [InlineData("opt1")] [InlineData("opt2")] [InlineData("opt3")] public Task CS_UseNewLocalOptionsAsArgument_MultiAssignment_EscapeCurrentScope_FieldAssignment_NoWarn(string expression) - => VerifyCS.VerifyAnalyzerAsync($@" -using System.Text.Json; + => VerifyCS.VerifyAnalyzerAsync($$""" + using System.Text.Json; -class Program -{{ - static JsonSerializerOptions s_options; + class Program + { + static JsonSerializerOptions s_options; - static string Serialize(T value) - {{ - JsonSerializerOptions opt1, opt2, opt3; - opt1 = opt2 = opt3 = new JsonSerializerOptions(); + static string Serialize(T value) + { + JsonSerializerOptions opt1, opt2, opt3; + opt1 = opt2 = opt3 = new JsonSerializerOptions(); - s_options = {expression}; + s_options = {{expression}}; - return JsonSerializer.Serialize(value, opt1); - }} -}} -"); + return JsonSerializer.Serialize(value, opt1); + } + } + """); [Theory] [InlineData("opt1 = opt2 = s_options")] [InlineData("opt1 = s_options = opt2")] [InlineData("s_options = opt1 = opt2")] public Task CS_UseNewLocalOptionsAsArgument_MultiAssignment_EscapeCurrentScope_FieldInMultiAssignment_NoWarn(string expression) - => VerifyCS.VerifyAnalyzerAsync($@" -using System.Text.Json; + => VerifyCS.VerifyAnalyzerAsync($$""" + using System.Text.Json; -class Program -{{ - static JsonSerializerOptions s_options; + class Program + { + static JsonSerializerOptions s_options; - static string Serialize(T value) - {{ - JsonSerializerOptions opt1, opt2; - {expression} = new JsonSerializerOptions(); + static string Serialize(T value) + { + JsonSerializerOptions opt1, opt2; + {{expression}} = new JsonSerializerOptions(); - return JsonSerializer.Serialize(value, opt1); - }} -}} -"); + return JsonSerializer.Serialize(value, opt1); + } + } + """); [Theory] [InlineData("s_options = opt1 = opt2")] [InlineData("opt1 = s_options = opt2")] public Task CSharpUseNewOptionsAsLocalThenAsArgument_AssignmentOnNextStatement_Multiple_WithEscapeScopeOnAssignment_NoWarn(string expression) - => VerifyCS.VerifyAnalyzerAsync($@" -using System.Text.Json; + => VerifyCS.VerifyAnalyzerAsync($$""" + using System.Text.Json; -class Program -{{ - static JsonSerializerOptions s_options; + class Program + { + static JsonSerializerOptions s_options; - static string Serialize(T value) - {{ - JsonSerializerOptions opt1, opt2; - opt1 = opt2 = new JsonSerializerOptions(); + static string Serialize(T value) + { + JsonSerializerOptions opt1, opt2; + opt1 = opt2 = new JsonSerializerOptions(); - {expression}; + {{expression}}; - return JsonSerializer.Serialize(value, opt1); - }} -}} -"); + return JsonSerializer.Serialize(value, opt1); + } + } + """); [Fact] public Task CS_UseNewLocalOptionsAsArgument_EscapeCurrentScope_ClosureDelegate_NoWarn() - => VerifyCS.VerifyAnalyzerAsync(@" -using System; -using System.Text.Json; - -class Program -{ - static Action Serialize(T value) - { - JsonSerializerOptions opt = new JsonSerializerOptions(); - Action lambda = () => - { - JsonSerializer.Serialize(value, opt); - }; - return lambda; - } -} -"); + => VerifyCS.VerifyAnalyzerAsync(""" + using System; + using System.Text.Json; + + class Program + { + static Action Serialize(T value) + { + JsonSerializerOptions opt = new JsonSerializerOptions(); + Action lambda = () => + { + JsonSerializer.Serialize(value, opt); + }; + return lambda; + } + } + """); [Fact] public Task CS_UseNewLocalOptionsAsArgument_EscapeCurrentScope_ClosureLocalFunction_NoWarn() - => VerifyCS.VerifyAnalyzerAsync(@" -using System.Text.Json; - -class Program -{ - static string Serialize(T value) - { - JsonSerializerOptions opt = new JsonSerializerOptions(); - return LocalFunc(); - - string LocalFunc() - { - return JsonSerializer.Serialize(value, opt); - } - } -} -"); + => VerifyCS.VerifyAnalyzerAsync(""" + using System.Text.Json; + + class Program + { + static string Serialize(T value) + { + JsonSerializerOptions opt = new JsonSerializerOptions(); + return LocalFunc(); + + string LocalFunc() + { + return JsonSerializer.Serialize(value, opt); + } + } + } + """); #endregion } } From 4c24fa0f5c4c52fab8c6d7ac1ba70c52b80162b3 Mon Sep 17 00:00:00 2001 From: David Cantu Date: Mon, 14 Aug 2023 11:12:07 -0500 Subject: [PATCH 5/6] Update rule description, message and title --- .../MicrosoftNetCoreAnalyzersResources.resx | 6 +++--- .../xlf/MicrosoftNetCoreAnalyzersResources.cs.xlf | 12 ++++++------ .../xlf/MicrosoftNetCoreAnalyzersResources.de.xlf | 12 ++++++------ .../xlf/MicrosoftNetCoreAnalyzersResources.es.xlf | 12 ++++++------ .../xlf/MicrosoftNetCoreAnalyzersResources.fr.xlf | 12 ++++++------ .../xlf/MicrosoftNetCoreAnalyzersResources.it.xlf | 12 ++++++------ .../xlf/MicrosoftNetCoreAnalyzersResources.ja.xlf | 12 ++++++------ .../xlf/MicrosoftNetCoreAnalyzersResources.ko.xlf | 12 ++++++------ .../xlf/MicrosoftNetCoreAnalyzersResources.pl.xlf | 12 ++++++------ .../xlf/MicrosoftNetCoreAnalyzersResources.pt-BR.xlf | 12 ++++++------ .../xlf/MicrosoftNetCoreAnalyzersResources.ru.xlf | 12 ++++++------ .../xlf/MicrosoftNetCoreAnalyzersResources.tr.xlf | 12 ++++++------ .../MicrosoftNetCoreAnalyzersResources.zh-Hans.xlf | 12 ++++++------ .../MicrosoftNetCoreAnalyzersResources.zh-Hant.xlf | 12 ++++++------ 14 files changed, 81 insertions(+), 81 deletions(-) diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx index 788af729b9..01eac786fd 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx @@ -2130,12 +2130,12 @@ Widening and user defined conversions are not supported with generic types.Use char overload - Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton + Avoid creating a new 'JsonSerializerOptions' instance for every serialization operation. Cache and reuse instances instead. - Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton. Single-use 'JsonSerializerOptions' instances can substantially degrade the performance of your application. + Avoid creating a new 'JsonSerializerOptions' instance for every serialization operation. Cache and reuse instances instead. Single use 'JsonSerializerOptions' instances can substantially degrade the performance of your application. - Reuse 'JsonSerializerOptions' instances + Cache and reuse 'JsonSerializerOptions' instances \ No newline at end of file diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.cs.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.cs.xlf index 44ac309f8a..624885ff9e 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.cs.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.cs.xlf @@ -68,18 +68,18 @@ - Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton. Single-use 'JsonSerializerOptions' instances can substantially degrade the performance of your application. - Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton. Single-use 'JsonSerializerOptions' instances can substantially degrade the performance of your application. + Avoid creating a new 'JsonSerializerOptions' instance for every serialization operation. Cache and reuse instances instead. Single use 'JsonSerializerOptions' instances can substantially degrade the performance of your application. + Avoid creating a new 'JsonSerializerOptions' instance for every serialization operation. Cache and reuse instances instead. Single use 'JsonSerializerOptions' instances can substantially degrade the performance of your application. - Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton - Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton + Avoid creating a new 'JsonSerializerOptions' instance for every serialization operation. Cache and reuse instances instead. + Avoid creating a new 'JsonSerializerOptions' instance for every serialization operation. Cache and reuse instances instead. - Reuse 'JsonSerializerOptions' instances - Reuse 'JsonSerializerOptions' instances + Cache and reuse 'JsonSerializerOptions' instances + Cache and reuse 'JsonSerializerOptions' instances diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.de.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.de.xlf index 6a216de97d..216cd38324 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.de.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.de.xlf @@ -68,18 +68,18 @@ - Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton. Single-use 'JsonSerializerOptions' instances can substantially degrade the performance of your application. - Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton. Single-use 'JsonSerializerOptions' instances can substantially degrade the performance of your application. + Avoid creating a new 'JsonSerializerOptions' instance for every serialization operation. Cache and reuse instances instead. Single use 'JsonSerializerOptions' instances can substantially degrade the performance of your application. + Avoid creating a new 'JsonSerializerOptions' instance for every serialization operation. Cache and reuse instances instead. Single use 'JsonSerializerOptions' instances can substantially degrade the performance of your application. - Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton - Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton + Avoid creating a new 'JsonSerializerOptions' instance for every serialization operation. Cache and reuse instances instead. + Avoid creating a new 'JsonSerializerOptions' instance for every serialization operation. Cache and reuse instances instead. - Reuse 'JsonSerializerOptions' instances - Reuse 'JsonSerializerOptions' instances + Cache and reuse 'JsonSerializerOptions' instances + Cache and reuse 'JsonSerializerOptions' instances diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.es.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.es.xlf index 4df7844c6b..cacd29161e 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.es.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.es.xlf @@ -68,18 +68,18 @@ - Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton. Single-use 'JsonSerializerOptions' instances can substantially degrade the performance of your application. - Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton. Single-use 'JsonSerializerOptions' instances can substantially degrade the performance of your application. + Avoid creating a new 'JsonSerializerOptions' instance for every serialization operation. Cache and reuse instances instead. Single use 'JsonSerializerOptions' instances can substantially degrade the performance of your application. + Avoid creating a new 'JsonSerializerOptions' instance for every serialization operation. Cache and reuse instances instead. Single use 'JsonSerializerOptions' instances can substantially degrade the performance of your application. - Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton - Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton + Avoid creating a new 'JsonSerializerOptions' instance for every serialization operation. Cache and reuse instances instead. + Avoid creating a new 'JsonSerializerOptions' instance for every serialization operation. Cache and reuse instances instead. - Reuse 'JsonSerializerOptions' instances - Reuse 'JsonSerializerOptions' instances + Cache and reuse 'JsonSerializerOptions' instances + Cache and reuse 'JsonSerializerOptions' instances diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.fr.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.fr.xlf index 123b4e875a..a336bc908c 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.fr.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.fr.xlf @@ -68,18 +68,18 @@ - Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton. Single-use 'JsonSerializerOptions' instances can substantially degrade the performance of your application. - Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton. Single-use 'JsonSerializerOptions' instances can substantially degrade the performance of your application. + Avoid creating a new 'JsonSerializerOptions' instance for every serialization operation. Cache and reuse instances instead. Single use 'JsonSerializerOptions' instances can substantially degrade the performance of your application. + Avoid creating a new 'JsonSerializerOptions' instance for every serialization operation. Cache and reuse instances instead. Single use 'JsonSerializerOptions' instances can substantially degrade the performance of your application. - Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton - Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton + Avoid creating a new 'JsonSerializerOptions' instance for every serialization operation. Cache and reuse instances instead. + Avoid creating a new 'JsonSerializerOptions' instance for every serialization operation. Cache and reuse instances instead. - Reuse 'JsonSerializerOptions' instances - Reuse 'JsonSerializerOptions' instances + Cache and reuse 'JsonSerializerOptions' instances + Cache and reuse 'JsonSerializerOptions' instances diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.it.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.it.xlf index 1d6391b1cf..042c2dbccb 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.it.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.it.xlf @@ -68,18 +68,18 @@ - Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton. Single-use 'JsonSerializerOptions' instances can substantially degrade the performance of your application. - Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton. Single-use 'JsonSerializerOptions' instances can substantially degrade the performance of your application. + Avoid creating a new 'JsonSerializerOptions' instance for every serialization operation. Cache and reuse instances instead. Single use 'JsonSerializerOptions' instances can substantially degrade the performance of your application. + Avoid creating a new 'JsonSerializerOptions' instance for every serialization operation. Cache and reuse instances instead. Single use 'JsonSerializerOptions' instances can substantially degrade the performance of your application. - Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton - Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton + Avoid creating a new 'JsonSerializerOptions' instance for every serialization operation. Cache and reuse instances instead. + Avoid creating a new 'JsonSerializerOptions' instance for every serialization operation. Cache and reuse instances instead. - Reuse 'JsonSerializerOptions' instances - Reuse 'JsonSerializerOptions' instances + Cache and reuse 'JsonSerializerOptions' instances + Cache and reuse 'JsonSerializerOptions' instances diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ja.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ja.xlf index 4aa9fe092d..e4a770a9a2 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ja.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ja.xlf @@ -68,18 +68,18 @@ - Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton. Single-use 'JsonSerializerOptions' instances can substantially degrade the performance of your application. - Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton. Single-use 'JsonSerializerOptions' instances can substantially degrade the performance of your application. + Avoid creating a new 'JsonSerializerOptions' instance for every serialization operation. Cache and reuse instances instead. Single use 'JsonSerializerOptions' instances can substantially degrade the performance of your application. + Avoid creating a new 'JsonSerializerOptions' instance for every serialization operation. Cache and reuse instances instead. Single use 'JsonSerializerOptions' instances can substantially degrade the performance of your application. - Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton - Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton + Avoid creating a new 'JsonSerializerOptions' instance for every serialization operation. Cache and reuse instances instead. + Avoid creating a new 'JsonSerializerOptions' instance for every serialization operation. Cache and reuse instances instead. - Reuse 'JsonSerializerOptions' instances - Reuse 'JsonSerializerOptions' instances + Cache and reuse 'JsonSerializerOptions' instances + Cache and reuse 'JsonSerializerOptions' instances diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ko.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ko.xlf index 45fc956274..bcf12ee730 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ko.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ko.xlf @@ -68,18 +68,18 @@ - Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton. Single-use 'JsonSerializerOptions' instances can substantially degrade the performance of your application. - Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton. Single-use 'JsonSerializerOptions' instances can substantially degrade the performance of your application. + Avoid creating a new 'JsonSerializerOptions' instance for every serialization operation. Cache and reuse instances instead. Single use 'JsonSerializerOptions' instances can substantially degrade the performance of your application. + Avoid creating a new 'JsonSerializerOptions' instance for every serialization operation. Cache and reuse instances instead. Single use 'JsonSerializerOptions' instances can substantially degrade the performance of your application. - Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton - Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton + Avoid creating a new 'JsonSerializerOptions' instance for every serialization operation. Cache and reuse instances instead. + Avoid creating a new 'JsonSerializerOptions' instance for every serialization operation. Cache and reuse instances instead. - Reuse 'JsonSerializerOptions' instances - Reuse 'JsonSerializerOptions' instances + Cache and reuse 'JsonSerializerOptions' instances + Cache and reuse 'JsonSerializerOptions' instances diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pl.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pl.xlf index a3b2f98a42..93ce237ccf 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pl.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pl.xlf @@ -68,18 +68,18 @@ - Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton. Single-use 'JsonSerializerOptions' instances can substantially degrade the performance of your application. - Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton. Single-use 'JsonSerializerOptions' instances can substantially degrade the performance of your application. + Avoid creating a new 'JsonSerializerOptions' instance for every serialization operation. Cache and reuse instances instead. Single use 'JsonSerializerOptions' instances can substantially degrade the performance of your application. + Avoid creating a new 'JsonSerializerOptions' instance for every serialization operation. Cache and reuse instances instead. Single use 'JsonSerializerOptions' instances can substantially degrade the performance of your application. - Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton - Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton + Avoid creating a new 'JsonSerializerOptions' instance for every serialization operation. Cache and reuse instances instead. + Avoid creating a new 'JsonSerializerOptions' instance for every serialization operation. Cache and reuse instances instead. - Reuse 'JsonSerializerOptions' instances - Reuse 'JsonSerializerOptions' instances + Cache and reuse 'JsonSerializerOptions' instances + Cache and reuse 'JsonSerializerOptions' instances diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pt-BR.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pt-BR.xlf index f92ad4ed70..15d69fc4ee 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pt-BR.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pt-BR.xlf @@ -68,18 +68,18 @@ - Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton. Single-use 'JsonSerializerOptions' instances can substantially degrade the performance of your application. - Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton. Single-use 'JsonSerializerOptions' instances can substantially degrade the performance of your application. + Avoid creating a new 'JsonSerializerOptions' instance for every serialization operation. Cache and reuse instances instead. Single use 'JsonSerializerOptions' instances can substantially degrade the performance of your application. + Avoid creating a new 'JsonSerializerOptions' instance for every serialization operation. Cache and reuse instances instead. Single use 'JsonSerializerOptions' instances can substantially degrade the performance of your application. - Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton - Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton + Avoid creating a new 'JsonSerializerOptions' instance for every serialization operation. Cache and reuse instances instead. + Avoid creating a new 'JsonSerializerOptions' instance for every serialization operation. Cache and reuse instances instead. - Reuse 'JsonSerializerOptions' instances - Reuse 'JsonSerializerOptions' instances + Cache and reuse 'JsonSerializerOptions' instances + Cache and reuse 'JsonSerializerOptions' instances diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ru.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ru.xlf index db3f0e0e72..158d3a0b3d 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ru.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ru.xlf @@ -68,18 +68,18 @@ - Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton. Single-use 'JsonSerializerOptions' instances can substantially degrade the performance of your application. - Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton. Single-use 'JsonSerializerOptions' instances can substantially degrade the performance of your application. + Avoid creating a new 'JsonSerializerOptions' instance for every serialization operation. Cache and reuse instances instead. Single use 'JsonSerializerOptions' instances can substantially degrade the performance of your application. + Avoid creating a new 'JsonSerializerOptions' instance for every serialization operation. Cache and reuse instances instead. Single use 'JsonSerializerOptions' instances can substantially degrade the performance of your application. - Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton - Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton + Avoid creating a new 'JsonSerializerOptions' instance for every serialization operation. Cache and reuse instances instead. + Avoid creating a new 'JsonSerializerOptions' instance for every serialization operation. Cache and reuse instances instead. - Reuse 'JsonSerializerOptions' instances - Reuse 'JsonSerializerOptions' instances + Cache and reuse 'JsonSerializerOptions' instances + Cache and reuse 'JsonSerializerOptions' instances diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.tr.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.tr.xlf index c5a2a613f4..82848fdd27 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.tr.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.tr.xlf @@ -68,18 +68,18 @@ - Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton. Single-use 'JsonSerializerOptions' instances can substantially degrade the performance of your application. - Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton. Single-use 'JsonSerializerOptions' instances can substantially degrade the performance of your application. + Avoid creating a new 'JsonSerializerOptions' instance for every serialization operation. Cache and reuse instances instead. Single use 'JsonSerializerOptions' instances can substantially degrade the performance of your application. + Avoid creating a new 'JsonSerializerOptions' instance for every serialization operation. Cache and reuse instances instead. Single use 'JsonSerializerOptions' instances can substantially degrade the performance of your application. - Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton - Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton + Avoid creating a new 'JsonSerializerOptions' instance for every serialization operation. Cache and reuse instances instead. + Avoid creating a new 'JsonSerializerOptions' instance for every serialization operation. Cache and reuse instances instead. - Reuse 'JsonSerializerOptions' instances - Reuse 'JsonSerializerOptions' instances + Cache and reuse 'JsonSerializerOptions' instances + Cache and reuse 'JsonSerializerOptions' instances diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hans.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hans.xlf index b2dd8b2a89..02d8aca805 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hans.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hans.xlf @@ -68,18 +68,18 @@ - Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton. Single-use 'JsonSerializerOptions' instances can substantially degrade the performance of your application. - Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton. Single-use 'JsonSerializerOptions' instances can substantially degrade the performance of your application. + Avoid creating a new 'JsonSerializerOptions' instance for every serialization operation. Cache and reuse instances instead. Single use 'JsonSerializerOptions' instances can substantially degrade the performance of your application. + Avoid creating a new 'JsonSerializerOptions' instance for every serialization operation. Cache and reuse instances instead. Single use 'JsonSerializerOptions' instances can substantially degrade the performance of your application. - Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton - Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton + Avoid creating a new 'JsonSerializerOptions' instance for every serialization operation. Cache and reuse instances instead. + Avoid creating a new 'JsonSerializerOptions' instance for every serialization operation. Cache and reuse instances instead. - Reuse 'JsonSerializerOptions' instances - Reuse 'JsonSerializerOptions' instances + Cache and reuse 'JsonSerializerOptions' instances + Cache and reuse 'JsonSerializerOptions' instances diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hant.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hant.xlf index 48910e4488..e5a66cd4a6 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hant.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hant.xlf @@ -68,18 +68,18 @@ - Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton. Single-use 'JsonSerializerOptions' instances can substantially degrade the performance of your application. - Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton. Single-use 'JsonSerializerOptions' instances can substantially degrade the performance of your application. + Avoid creating a new 'JsonSerializerOptions' instance for every serialization operation. Cache and reuse instances instead. Single use 'JsonSerializerOptions' instances can substantially degrade the performance of your application. + Avoid creating a new 'JsonSerializerOptions' instance for every serialization operation. Cache and reuse instances instead. Single use 'JsonSerializerOptions' instances can substantially degrade the performance of your application. - Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton - Reuse the 'JsonSerializerOptions' instance by moving it to a static field, or use a singleton + Avoid creating a new 'JsonSerializerOptions' instance for every serialization operation. Cache and reuse instances instead. + Avoid creating a new 'JsonSerializerOptions' instance for every serialization operation. Cache and reuse instances instead. - Reuse 'JsonSerializerOptions' instances - Reuse 'JsonSerializerOptions' instances + Cache and reuse 'JsonSerializerOptions' instances + Cache and reuse 'JsonSerializerOptions' instances From 4c2fcc67c412898da50cafbe948e2397a720b5b5 Mon Sep 17 00:00:00 2001 From: David Cantu Date: Mon, 14 Aug 2023 11:46:43 -0500 Subject: [PATCH 6/6] Fix formatting and apply changes from msbuild /t:pack /v:m --- src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md | 4 ++-- src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif | 4 ++-- src/NetAnalyzers/RulesMissingDocumentation.md | 2 +- .../AvoidSingleUseOfLocalJsonSerializerOptionsTests.cs | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md index 5d06ab2a3b..ef63ae6f98 100644 --- a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md +++ b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md @@ -1788,9 +1788,9 @@ Do not guard 'Add(item)' or 'Remove(item)' with 'Contains(item)' for the set. Th |CodeFix|True| --- -## [CA1869](https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1869): Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal +## [CA1869](https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1869): Cache and reuse 'JsonSerializerOptions' instances -Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance. +Avoid creating a new 'JsonSerializerOptions' instance for every serialization operation. Cache and reuse instances instead. Single use 'JsonSerializerOptions' instances can substantially degrade the performance of your application. |Item|Value| |-|-| diff --git a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif index df79c33bf6..b80746b7b8 100644 --- a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif +++ b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif @@ -3294,8 +3294,8 @@ }, "CA1869": { "id": "CA1869", - "shortDescription": "Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal", - "fullDescription": "Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal, use a singleton instance instead to improve performance.", + "shortDescription": "Cache and reuse 'JsonSerializerOptions' instances", + "fullDescription": "Avoid creating a new 'JsonSerializerOptions' instance for every serialization operation. Cache and reuse instances instead. Single use 'JsonSerializerOptions' instances can substantially degrade the performance of your application.", "defaultLevel": "note", "helpUri": "https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1869", "properties": { diff --git a/src/NetAnalyzers/RulesMissingDocumentation.md b/src/NetAnalyzers/RulesMissingDocumentation.md index bd15f7b511..eb030b9cc5 100644 --- a/src/NetAnalyzers/RulesMissingDocumentation.md +++ b/src/NetAnalyzers/RulesMissingDocumentation.md @@ -13,6 +13,6 @@ CA1863 | | Use char overload | CA1866 | | Use char overload | CA1867 | | Use char overload | -CA1869 | | Avoid single-use of local 'JsonSerializerOptions' as it is suboptimal | +CA1869 | | Cache and reuse 'JsonSerializerOptions' instances | CA2021 | | Do not call Enumerable.Cast\ or Enumerable.OfType\ with incompatible types | CA2261 | | Do not use ConfigureAwaitOptions.SuppressThrowing with Task\ | diff --git a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Performance/AvoidSingleUseOfLocalJsonSerializerOptionsTests.cs b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Performance/AvoidSingleUseOfLocalJsonSerializerOptionsTests.cs index e1640e49dd..63ec104493 100644 --- a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Performance/AvoidSingleUseOfLocalJsonSerializerOptionsTests.cs +++ b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Performance/AvoidSingleUseOfLocalJsonSerializerOptionsTests.cs @@ -111,7 +111,7 @@ static string Serialize(T value) [InlineData("(({|CA1869:new JsonSerializerOptions()|}))")] [InlineData("1 == 1 ? {|CA1869:new JsonSerializerOptions()|} : null")] [InlineData("1 == 1 ? null : 2 == 2 ? null : {|CA1869:new JsonSerializerOptions()|}")] - public Task CS_UseNewLocalOptionsAsArgument_Variants(string expression) + public Task CS_UseNewLocalOptionsAsArgument_Variants(string expression) => VerifyCS.VerifyAnalyzerAsync($$""" using System.Text.Json;