From 3dedbb204d69e908d870a05852d1c5ffbdc3a636 Mon Sep 17 00:00:00 2001 From: psxvoid Date: Thu, 11 Feb 2021 10:17:38 +0300 Subject: [PATCH 01/64] Add ConstructorParamShouldMatchPropNames analyzer --- .../Core/AnalyzerReleases.Unshipped.md | 4 + .../Maintainability/ReviewUnusedParameters.cs | 1 + .../MicrosoftNetCoreAnalyzersResources.resx | 12 + ...uctorParametersShouldMatchPropertyNames.cs | 194 +++++++++ .../SerializationRulesDiagnosticAnalyzer.cs | 14 +- .../MicrosoftNetCoreAnalyzersResources.cs.xlf | 20 + .../MicrosoftNetCoreAnalyzersResources.de.xlf | 20 + .../MicrosoftNetCoreAnalyzersResources.es.xlf | 20 + .../MicrosoftNetCoreAnalyzersResources.fr.xlf | 20 + .../MicrosoftNetCoreAnalyzersResources.it.xlf | 20 + .../MicrosoftNetCoreAnalyzersResources.ja.xlf | 20 + .../MicrosoftNetCoreAnalyzersResources.ko.xlf | 20 + .../MicrosoftNetCoreAnalyzersResources.pl.xlf | 20 + ...crosoftNetCoreAnalyzersResources.pt-BR.xlf | 20 + .../MicrosoftNetCoreAnalyzersResources.ru.xlf | 20 + .../MicrosoftNetCoreAnalyzersResources.tr.xlf | 20 + ...osoftNetCoreAnalyzersResources.zh-Hans.xlf | 20 + ...osoftNetCoreAnalyzersResources.zh-Hant.xlf | 20 + ...CodeAnalysis.NetAnalyzers.UnitTests.csproj | 1 + ...ParametersShouldMatchPropertyNamesTests.cs | 387 ++++++++++++++++++ .../AdditionalMetadataReferences.cs | 3 + src/Test.Utilities/Test.Utilities.csproj | 1 + .../DiagnosticCategoryAndIdRanges.txt | 2 +- .../Extensions/IMethodSymbolExtensions.cs | 4 + src/Utilities/Compiler/WellKnownTypeNames.cs | 1 + 25 files changed, 881 insertions(+), 3 deletions(-) create mode 100644 src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyNames.cs create mode 100644 src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyNamesTests.cs diff --git a/src/NetAnalyzers/Core/AnalyzerReleases.Unshipped.md b/src/NetAnalyzers/Core/AnalyzerReleases.Unshipped.md index cdf4f1397e..6d655dfe18 100644 --- a/src/NetAnalyzers/Core/AnalyzerReleases.Unshipped.md +++ b/src/NetAnalyzers/Core/AnalyzerReleases.Unshipped.md @@ -1 +1,5 @@ ; Please do not edit this file manually, it should only be updated through code fix application. +### New Rules +Rule ID | Category | Severity | Notes +--------|----------|----------|------- +CA1071 | Design | Warning | ConstructorParametersShouldMatchPropertyNamesAnalyzer, [Documentation](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1071) \ No newline at end of file diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/Maintainability/ReviewUnusedParameters.cs b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/Maintainability/ReviewUnusedParameters.cs index 3174fdf251..ae99dd9445 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/Maintainability/ReviewUnusedParameters.cs +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/Maintainability/ReviewUnusedParameters.cs @@ -196,6 +196,7 @@ private bool ShouldAnalyzeMethod( } // Ignore primary constructor (body-less) of positional records. + // TODO: I have to handle a similar situation if (IsPositionalRecordPrimaryConstructor(method)) { return false; diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx index e240378b84..fbf699706f 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx @@ -1519,4 +1519,16 @@ and all other platforms This call site is reachable on: 'windows' 10.0.2000 and later, and all other platforms + + In the constructor of '{0}', change the name of parameter '{1}', to match the referenced field '{2}' + + + In the constructor of '{0}', change the name of parameter '{1}' to match the referenced property '{2}' + + + Constructor parameters should match referenced property or field names. + + + Constructor parameters should match referenced property and field names + \ No newline at end of file diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyNames.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyNames.cs new file mode 100644 index 0000000000..2ec4a3f3ca --- /dev/null +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyNames.cs @@ -0,0 +1,194 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Collections.Immutable; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using Analyzer.Utilities; +using Analyzer.Utilities.Extensions; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.Operations; + +namespace Microsoft.NetCore.Analyzers.Runtime +{ + /// + /// CA1071: Constructor parameters should match property and field names + /// + [DiagnosticAnalyzer(LanguageNames.CSharp, LanguageNames.VisualBasic)] + public sealed class ConstructorParametersShouldMatchPropertyNamesAnalyzer : DiagnosticAnalyzer + { + internal const string RuleId = "CA1071"; + + private static readonly LocalizableString s_localizableTitle = new LocalizableResourceString(nameof(MicrosoftNetCoreAnalyzersResources.ConstructorParametersShouldMatchPropertyNamesTitle), MicrosoftNetCoreAnalyzersResources.ResourceManager, typeof(MicrosoftNetCoreAnalyzersResources)); + + private static readonly LocalizableString s_localizableMessageProperty = new LocalizableResourceString(nameof(MicrosoftNetCoreAnalyzersResources.ConstructorParameterShouldMatchPropertyName), MicrosoftNetCoreAnalyzersResources.ResourceManager, typeof(MicrosoftNetCoreAnalyzersResources)); + private static readonly LocalizableString s_localizableMessageField = new LocalizableResourceString(nameof(MicrosoftNetCoreAnalyzersResources.ConstructorParameterShouldMatchFieldName), MicrosoftNetCoreAnalyzersResources.ResourceManager, typeof(MicrosoftNetCoreAnalyzersResources)); + private static readonly LocalizableString s_localizableDescription = new LocalizableResourceString(nameof(MicrosoftNetCoreAnalyzersResources.ConstructorParametersShouldMatchPropertyNamesDescription), MicrosoftNetCoreAnalyzersResources.ResourceManager, typeof(MicrosoftNetCoreAnalyzersResources)); + + internal static DiagnosticDescriptor PropertyRule = DiagnosticDescriptorHelper.Create(RuleId, + s_localizableTitle, + s_localizableMessageProperty, + DiagnosticCategory.Design, + RuleLevel.BuildWarning, + description: s_localizableDescription, + isPortedFxCopRule: true, + isDataflowRule: false); + internal static DiagnosticDescriptor FieldRule = DiagnosticDescriptorHelper.Create(RuleId, + s_localizableTitle, + s_localizableMessageField, + DiagnosticCategory.Design, + RuleLevel.BuildWarning, + description: s_localizableDescription, + isPortedFxCopRule: true, + isDataflowRule: false); + + public override ImmutableArray SupportedDiagnostics => ImmutableArray.Create(PropertyRule, FieldRule); + + public override void Initialize(AnalysisContext context) + { + context.EnableConcurrentExecution(); + context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None); + + context.RegisterCompilationStartAction( + (compilationStartContext) => + { + INamedTypeSymbol? jsonConstructorAttributeNamedSymbol = compilationStartContext.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemTextJsonSerializationJsonConstructorAttribute); + if (jsonConstructorAttributeNamedSymbol == null) + { + return; + } + + var paramAnalyzer = new ParameterAnalyzer(jsonConstructorAttributeNamedSymbol); + + compilationStartContext.RegisterOperationBlockStartAction( + (startOperationBlockContext) => + { + if (startOperationBlockContext.OwningSymbol is IMethodSymbol method + && !paramAnalyzer.ShouldAnalyzeMethod(method)) + { + return; + } + + startOperationBlockContext.RegisterOperationAction( + context => ParameterAnalyzer.AnalyzeOperationAndReport(context), + OperationKind.ParameterReference); + }); + }); + } + + private sealed class ParameterAnalyzer + { + private readonly INamedTypeSymbol _jsonConstructorAttributeInfoType; + + public ParameterAnalyzer(INamedTypeSymbol jsonConstructorAttributeInfoType) + { + _jsonConstructorAttributeInfoType = jsonConstructorAttributeInfoType; + } + + public static void AnalyzeOperationAndReport(OperationAnalysisContext context) + { + var operation = (IParameterReferenceOperation)context.Operation; + + if (operation.Parent is not IAssignmentOperation assignment) + { + return; + } + + IParameterSymbol param = operation.Parameter; + ISymbol? referencedSymbol = assignment.Target.GetReferencedMemberOrLocalOrParameter(); + + if (referencedSymbol == null) + { + return; + } + + var field = referencedSymbol as IFieldSymbol; + var prop = referencedSymbol as IPropertySymbol; + + if (field == null && prop == null) + { + return; + } + + // Only process instance fields and properties + if (referencedSymbol.IsStatic) + { + return; + } + + if (IsSupportedField(field) && !IsParamMatchFieldName(param, field)) + { + context.ReportDiagnostic( + param.CreateDiagnostic( + FieldRule, + param.ContainingType.ToDisplayString(SymbolDisplayFormats.ShortSymbolDisplayFormat), + param.Name, + field.Name)); + } + + if (IsSupportedProp(prop) && !IsParamMatchPropName(param, prop)) + { + context.ReportDiagnostic( + param.CreateDiagnostic( + PropertyRule, + param.ContainingType.ToDisplayString(SymbolDisplayFormats.ShortSymbolDisplayFormat), + param.Name, + prop.Name)); + } + } + + private static bool IsSupportedProp([NotNullWhen(true)] IPropertySymbol? prop) + { + if (prop == null) + { + return false; + } + + return true; + } + + private static bool IsSupportedField([NotNullWhen(true)] IFieldSymbol? field) + { + if (field == null) + { + return false; + } + + return true; + } + + private static bool IsParamMatchFieldName(IParameterSymbol param, IFieldSymbol field) + { + var paramWords = WordParser.Parse(param.Name, WordParserOptions.SplitCompoundWords); + var fieldWords = WordParser.Parse(field.Name, WordParserOptions.SplitCompoundWords).ToImmutableArray(); + + return paramWords.All(x => WordParser.ContainsWord(x, WordParserOptions.SplitCompoundWords, fieldWords)); + } + + private static bool IsParamMatchPropName(IParameterSymbol param, IPropertySymbol prop) + { + var paramWords = WordParser.Parse(param.Name, WordParserOptions.SplitCompoundWords); + var propWords = WordParser.Parse(prop.Name, WordParserOptions.SplitCompoundWords).ToImmutableArray(); + + return paramWords.All(x => WordParser.ContainsWord(x, WordParserOptions.SplitCompoundWords, propWords)); + } + + public bool ShouldAnalyzeMethod(IMethodSymbol method) + { + // We only care about constructors with parameters. + if (method.Parameters.IsEmpty) + { + return false; + } + + // We only care about constructors that are marked with JsonConstructor attribute. + if (!method.IsJsonConstructor(_jsonConstructorAttributeInfoType)) + { + return false; + } + + return true; + } + } + } +} \ No newline at end of file diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/SerializationRulesDiagnosticAnalyzer.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/SerializationRulesDiagnosticAnalyzer.cs index 397c077d55..c631b27464 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/SerializationRulesDiagnosticAnalyzer.cs +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/SerializationRulesDiagnosticAnalyzer.cs @@ -15,9 +15,10 @@ public sealed class SerializationRulesDiagnosticAnalyzer : DiagnosticAnalyzer // Implement serialization constructors internal const string RuleCA2229Id = "CA2229"; + #region Diagnostic Descriptor Definitions private static readonly LocalizableString s_localizableTitleCA2229 = - new LocalizableResourceString(nameof(MicrosoftNetCoreAnalyzersResources.ImplementSerializationConstructorsTitle), - MicrosoftNetCoreAnalyzersResources.ResourceManager, typeof(MicrosoftNetCoreAnalyzersResources)); + new LocalizableResourceString(nameof(MicrosoftNetCoreAnalyzersResources.ImplementSerializationConstructorsTitle), + MicrosoftNetCoreAnalyzersResources.ResourceManager, typeof(MicrosoftNetCoreAnalyzersResources)); private static readonly LocalizableString s_localizableDescriptionCA2229 = new LocalizableResourceString(nameof(MicrosoftNetCoreAnalyzersResources.ImplementSerializationConstructorsDescription), @@ -101,6 +102,9 @@ public sealed class SerializationRulesDiagnosticAnalyzer : DiagnosticAnalyzer public override ImmutableArray SupportedDiagnostics => ImmutableArray.Create(RuleCA2229Default, RuleCA2229Sealed, RuleCA2229Unsealed, RuleCA2235, RuleCA2237); + #endregion + + #region Public Methods public override void Initialize(AnalysisContext context) { context.EnableConcurrentExecution(); @@ -146,6 +150,10 @@ public override void Initialize(AnalysisContext context) }); } + #endregion + + #region Private Classes + private sealed class SymbolAnalyzer { private readonly INamedTypeSymbol _iserializableTypeSymbol; @@ -297,5 +305,7 @@ private bool IsSerializable(ITypeSymbol type) }; } } + + #endregion } } 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 be063a9c1a..ddd4345a88 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.cs.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.cs.xlf @@ -177,6 +177,26 @@ , Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’} + + In the constructor of '{0}', change the name of parameter '{1}', to match the referenced field '{2}' + In the constructor of '{0}', change the name of parameter '{1}', to match the referenced field '{2}' + + + + In the constructor of '{0}', change the name of parameter '{1}' to match the referenced property '{2}' + In the constructor of '{0}', change the name of parameter '{1}' to match the referenced property '{2}' + + + + Constructor parameters should match referenced property or field names. + Constructor parameters should match referenced property or field names. + + + + Constructor parameters should match referenced property and field names + Constructor parameters should match referenced property and field names + + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0} Při deserializaci nedůvěryhodného vstupu není deserializace objektu {0} bezpečná. Objekt {1} je buď objektem {0}, nebo je z tohoto objektu odvozený. 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 52ca3a058f..04159b65d0 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.de.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.de.xlf @@ -177,6 +177,26 @@ , Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’} + + In the constructor of '{0}', change the name of parameter '{1}', to match the referenced field '{2}' + In the constructor of '{0}', change the name of parameter '{1}', to match the referenced field '{2}' + + + + In the constructor of '{0}', change the name of parameter '{1}' to match the referenced property '{2}' + In the constructor of '{0}', change the name of parameter '{1}' to match the referenced property '{2}' + + + + Constructor parameters should match referenced property or field names. + Constructor parameters should match referenced property or field names. + + + + Constructor parameters should match referenced property and field names + Constructor parameters should match referenced property and field names + + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0} Beim Deserialisieren einer nicht vertrauenswürdigen Eingabe ist die Deserialisierung eines {0}-Objekts unsicher. "{1}" ist entweder "{0}" oder davon abgeleitet. 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 18668ee783..90ffa798bb 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.es.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.es.xlf @@ -177,6 +177,26 @@ , Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’} + + In the constructor of '{0}', change the name of parameter '{1}', to match the referenced field '{2}' + In the constructor of '{0}', change the name of parameter '{1}', to match the referenced field '{2}' + + + + In the constructor of '{0}', change the name of parameter '{1}' to match the referenced property '{2}' + In the constructor of '{0}', change the name of parameter '{1}' to match the referenced property '{2}' + + + + Constructor parameters should match referenced property or field names. + Constructor parameters should match referenced property or field names. + + + + Constructor parameters should match referenced property and field names + Constructor parameters should match referenced property and field names + + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0} Cuando se deserializa una entrada que no es de confianza, no es segura la deserialización de un objeto {0}. "{1}" es {0} o se deriva de este. 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 d90f9ec3af..025586291a 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.fr.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.fr.xlf @@ -177,6 +177,26 @@ , Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’} + + In the constructor of '{0}', change the name of parameter '{1}', to match the referenced field '{2}' + In the constructor of '{0}', change the name of parameter '{1}', to match the referenced field '{2}' + + + + In the constructor of '{0}', change the name of parameter '{1}' to match the referenced property '{2}' + In the constructor of '{0}', change the name of parameter '{1}' to match the referenced property '{2}' + + + + Constructor parameters should match referenced property or field names. + Constructor parameters should match referenced property or field names. + + + + Constructor parameters should match referenced property and field names + Constructor parameters should match referenced property and field names + + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0} Quand vous désérialisez une entrée non fiable, la désérialisation d'un objet {0} n'est pas une action sécurisée. '{1}' est égal à ou dérive de {0} 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 09c16a9f6e..e56eaadafd 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.it.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.it.xlf @@ -177,6 +177,26 @@ , Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’} + + In the constructor of '{0}', change the name of parameter '{1}', to match the referenced field '{2}' + In the constructor of '{0}', change the name of parameter '{1}', to match the referenced field '{2}' + + + + In the constructor of '{0}', change the name of parameter '{1}' to match the referenced property '{2}' + In the constructor of '{0}', change the name of parameter '{1}' to match the referenced property '{2}' + + + + Constructor parameters should match referenced property or field names. + Constructor parameters should match referenced property or field names. + + + + Constructor parameters should match referenced property and field names + Constructor parameters should match referenced property and field names + + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0} Quando si deserializza input non attendibile, la deserializzazione di un oggetto {0} non è sicura. '{1}' è {0} o deriva da esso 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 6937c685a2..4e69cf0078 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ja.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ja.xlf @@ -177,6 +177,26 @@ , Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’} + + In the constructor of '{0}', change the name of parameter '{1}', to match the referenced field '{2}' + In the constructor of '{0}', change the name of parameter '{1}', to match the referenced field '{2}' + + + + In the constructor of '{0}', change the name of parameter '{1}' to match the referenced property '{2}' + In the constructor of '{0}', change the name of parameter '{1}' to match the referenced property '{2}' + + + + Constructor parameters should match referenced property or field names. + Constructor parameters should match referenced property or field names. + + + + Constructor parameters should match referenced property and field names + Constructor parameters should match referenced property and field names + + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0} 信頼されていない入力を逆シリアル化する場合、{0} オブジェクトの逆シリアル化は安全ではありません。'{1}' は {0} であるか、それから派生しています 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 d329428df3..230bb5e5c2 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ko.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ko.xlf @@ -177,6 +177,26 @@ , Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’} + + In the constructor of '{0}', change the name of parameter '{1}', to match the referenced field '{2}' + In the constructor of '{0}', change the name of parameter '{1}', to match the referenced field '{2}' + + + + In the constructor of '{0}', change the name of parameter '{1}' to match the referenced property '{2}' + In the constructor of '{0}', change the name of parameter '{1}' to match the referenced property '{2}' + + + + Constructor parameters should match referenced property or field names. + Constructor parameters should match referenced property or field names. + + + + Constructor parameters should match referenced property and field names + Constructor parameters should match referenced property and field names + + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0} 신뢰할 수 없는 입력을 역직렬화하는 경우 {0} 개체를 역직렬화하는 것은 안전하지 않습니다. '{1}'은(는) {0}이거나 이 항목에서 파생됩니다. 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 0131fbd52a..7729095cf2 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pl.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pl.xlf @@ -177,6 +177,26 @@ , Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’} + + In the constructor of '{0}', change the name of parameter '{1}', to match the referenced field '{2}' + In the constructor of '{0}', change the name of parameter '{1}', to match the referenced field '{2}' + + + + In the constructor of '{0}', change the name of parameter '{1}' to match the referenced property '{2}' + In the constructor of '{0}', change the name of parameter '{1}' to match the referenced property '{2}' + + + + Constructor parameters should match referenced property or field names. + Constructor parameters should match referenced property or field names. + + + + Constructor parameters should match referenced property and field names + Constructor parameters should match referenced property and field names + + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0} Deserializowanie obiektu {0} podczas deserializacji niezaufanych danych wejściowych nie jest bezpieczne. Element „{1}” jest elementem {0} lub pochodzi od niego 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 9e63b6fc06..5e0f55f638 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 @@ -177,6 +177,26 @@ , Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’} + + In the constructor of '{0}', change the name of parameter '{1}', to match the referenced field '{2}' + In the constructor of '{0}', change the name of parameter '{1}', to match the referenced field '{2}' + + + + In the constructor of '{0}', change the name of parameter '{1}' to match the referenced property '{2}' + In the constructor of '{0}', change the name of parameter '{1}' to match the referenced property '{2}' + + + + Constructor parameters should match referenced property or field names. + Constructor parameters should match referenced property or field names. + + + + Constructor parameters should match referenced property and field names + Constructor parameters should match referenced property and field names + + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0} Ao desserializar uma entrada não confiável, a desserialização de um objeto {0} não é segura. '{1}' é {0} ou deriva-se dele 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 6dbafe9c23..0a4b2e4960 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ru.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ru.xlf @@ -177,6 +177,26 @@ , Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’} + + In the constructor of '{0}', change the name of parameter '{1}', to match the referenced field '{2}' + In the constructor of '{0}', change the name of parameter '{1}', to match the referenced field '{2}' + + + + In the constructor of '{0}', change the name of parameter '{1}' to match the referenced property '{2}' + In the constructor of '{0}', change the name of parameter '{1}' to match the referenced property '{2}' + + + + Constructor parameters should match referenced property or field names. + Constructor parameters should match referenced property or field names. + + + + Constructor parameters should match referenced property and field names + Constructor parameters should match referenced property and field names + + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0} При десериализации недоверенных входных данных десериализация объекта {0} является небезопасной. Объект "{1}" является объектом {0} или производным от него объектом. 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 c4dd09e3bd..2b7a0543ba 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.tr.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.tr.xlf @@ -177,6 +177,26 @@ , Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’} + + In the constructor of '{0}', change the name of parameter '{1}', to match the referenced field '{2}' + In the constructor of '{0}', change the name of parameter '{1}', to match the referenced field '{2}' + + + + In the constructor of '{0}', change the name of parameter '{1}' to match the referenced property '{2}' + In the constructor of '{0}', change the name of parameter '{1}' to match the referenced property '{2}' + + + + Constructor parameters should match referenced property or field names. + Constructor parameters should match referenced property or field names. + + + + Constructor parameters should match referenced property and field names + Constructor parameters should match referenced property and field names + + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0} Güvenilmeyen giriş seri durumdan çıkarılırken, {0} nesnesinin seri durumdan çıkarılması güvenli değildir. '{1}', {0} nesnesidir veya bu nesneden türetilmiştir 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 1a161cab86..fffc4a6619 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 @@ -177,6 +177,26 @@ , Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’} + + In the constructor of '{0}', change the name of parameter '{1}', to match the referenced field '{2}' + In the constructor of '{0}', change the name of parameter '{1}', to match the referenced field '{2}' + + + + In the constructor of '{0}', change the name of parameter '{1}' to match the referenced property '{2}' + In the constructor of '{0}', change the name of parameter '{1}' to match the referenced property '{2}' + + + + Constructor parameters should match referenced property or field names. + Constructor parameters should match referenced property or field names. + + + + Constructor parameters should match referenced property and field names + Constructor parameters should match referenced property and field names + + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0} 对不受信任的输入进行反序列化处理时,反序列化 {0} 对象是不安全的。“{1}”是或派生自 {0} 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 7bd5957db2..58d1156c99 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 @@ -177,6 +177,26 @@ , Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’} + + In the constructor of '{0}', change the name of parameter '{1}', to match the referenced field '{2}' + In the constructor of '{0}', change the name of parameter '{1}', to match the referenced field '{2}' + + + + In the constructor of '{0}', change the name of parameter '{1}' to match the referenced property '{2}' + In the constructor of '{0}', change the name of parameter '{1}' to match the referenced property '{2}' + + + + Constructor parameters should match referenced property or field names. + Constructor parameters should match referenced property or field names. + + + + Constructor parameters should match referenced property and field names + Constructor parameters should match referenced property and field names + + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0} 還原序列化不受信任的輸入時,將 {0} 物件還原序列化並不安全。'{1}' 屬於或衍生自 {0} diff --git a/src/NetAnalyzers/UnitTests/Microsoft.CodeAnalysis.NetAnalyzers.UnitTests.csproj b/src/NetAnalyzers/UnitTests/Microsoft.CodeAnalysis.NetAnalyzers.UnitTests.csproj index 9feef642b0..2e92d6f4df 100644 --- a/src/NetAnalyzers/UnitTests/Microsoft.CodeAnalysis.NetAnalyzers.UnitTests.csproj +++ b/src/NetAnalyzers/UnitTests/Microsoft.CodeAnalysis.NetAnalyzers.UnitTests.csproj @@ -7,6 +7,7 @@ + diff --git a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyNamesTests.cs b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyNamesTests.cs new file mode 100644 index 0000000000..4a5d9ec68d --- /dev/null +++ b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyNamesTests.cs @@ -0,0 +1,387 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Threading.Tasks; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.Testing; +using Test.Utilities; +using Xunit; +using VerifyCS = Test.Utilities.CSharpCodeFixVerifier< + Microsoft.NetCore.Analyzers.Runtime.ConstructorParametersShouldMatchPropertyNamesAnalyzer, + Microsoft.CodeAnalysis.Testing.EmptyCodeFixProvider>; +using VerifyVB = Test.Utilities.VisualBasicCodeFixVerifier< + Microsoft.NetCore.Analyzers.Runtime.ConstructorParametersShouldMatchPropertyNamesAnalyzer, + Microsoft.CodeAnalysis.Testing.EmptyCodeFixProvider>; + +namespace Microsoft.NetCore.Analyzers.Runtime.UnitTests +{ + public class ConstructorParametersShouldMatchPropertyNamesTests + { + [Fact] + public async Task CA1071_ClassPropsDoNotMatch_ConstructorParametersShouldMatchPropertyNames_CSharp() + { + await VerifyCSharpAnalyzerAsync(@" + using System.Text.Json.Serialization; + + public class C1 + { + public int FirstProp { get; } + + public object SecondProp { get; } + + [JsonConstructor] + public C1(int firstDrop, object secondDrop) + { + this.FirstProp = firstDrop; + this.SecondProp = secondDrop; + } + }", + CA1071CSharpPropertyResultAt(11, 35, "C1", "firstDrop", "FirstProp"), + CA1071CSharpPropertyResultAt(11, 53, "C1", "secondDrop", "SecondProp")); + } + + [Fact] + public async Task CA1071_RecordPropsDoNotMatch_ConstructorParametersShouldMatchPropertyNames_CSharp() + { + await VerifyCSharp9AnalyzerAsync(@" + using System.Text.Json.Serialization; + + public record C1 + { + public int FirstProp { get; } + + public object SecondProp { get; } + + [JsonConstructor] + public C1(int firstDrop, object secondDrop) + { + this.FirstProp = firstDrop; + this.SecondProp = secondDrop; + } + }", + CA1071CSharpPropertyResultAt(11, 35, "C1", "firstDrop", "FirstProp"), + CA1071CSharpPropertyResultAt(11, 53, "C1", "secondDrop", "SecondProp")); + } + + [Fact] + public async Task CA1071_ClassPropsDoNotMatch_ConstructorParametersShouldMatchPropertyNames_Basic() + { + await VerifyBasicAnalyzerAsync(@" +Imports System.Text.Json.Serialization + +Public Class C1 + Property FirstProp() As Integer + Property SecondProp() as Object + + + Public Sub New(firstDrop as Integer, secondDrop as Object) + Me.FirstProp = firstDrop + Me.SecondProp = secondDrop + End Sub +End Class", + CA2243BasicPropertyResultAt(9, 20, "C1", "firstDrop", "FirstProp"), + CA2243BasicPropertyResultAt(9, 42, "C1", "secondDrop", "SecondProp")); + } + + [Fact] + public async Task CA1071_ClassPropsDoNotMatchNotJsonCtor_NoDiagnostics_CSharp() + { + await VerifyCSharpAnalyzerAsync(@" + using System.Text.Json.Serialization; + + public class C1 + { + public int FirstProp { get; } + + public object SecondProp { get; } + + public C1(int firstDrop, object secondDrop) + { + this.FirstProp = firstDrop; + this.SecondProp = secondDrop; + } + }"); + } + + [Fact] + public async Task CA1071_ClassPropsDoNotMatchNotJsonCtor_NoDiagnostics_Basic() + { + await VerifyBasicAnalyzerAsync(@" +Imports System.Text.Json.Serialization + +Public Class C1 + Property firstProp() As Integer + Property secondProp() as Object + + Public Sub New(firstDrop as Integer, secondDrop as Object) + Me.firstProp = firstDrop + Me.secondProp = secondDrop + End Sub +End Class"); + } + + [Fact] + public async Task CA1071_RecordPropsDoNotMatchNotJsonCtor_NoDiagnostics_CSharp() + { + await VerifyCSharp9AnalyzerAsync(@" + using System.Text.Json.Serialization; + + public record C1 + { + public int FirstProp { get; } + + public object SecondProp { get; } + + public C1(int firstDrop, object secondDrop) + { + this.FirstProp = firstDrop; + this.SecondProp = secondDrop; + } + }"); + } + + [Fact] + public async Task CA1071_ClassPropsMatch_NoDiagnostics_CSharp() + { + await VerifyCSharpAnalyzerAsync(@" + using System.Text.Json.Serialization; + + public class C1 + { + public int FirstProp { get; } + + public object SecondProp { get; } + + [JsonConstructor] + public C1(int firstProp, object secondProp) + { + this.FirstProp = firstProp; + this.SecondProp = secondProp; + } + }"); + } + + [Fact] + public async Task CA1071_ClassPropsMatch_NoDiagnostics_Basic() + { + await VerifyBasicAnalyzerAsync(@" +Imports System.Text.Json.Serialization + +Public Class C1 + Property firstProp() As Integer + Property secondProp() as Object + + Public Sub New(firstDrop as Integer, secondDrop as Object) + Me.firstProp = firstDrop + Me.secondProp = secondDrop + End Sub +End Class"); + } + + [Fact] + public async Task CA1071_ClassFieldsDoNotMatch_ConstructorParametersShouldMatchFieldNames_CSharp() + { + await VerifyCSharpAnalyzerAsync(@" + using System.Text.Json.Serialization; + + public class C1 + { + public int firstField; + public object secondField; + + [JsonConstructor] + public C1(int firstIField, object secondIField) + { + this.firstField = firstIField; + this.secondField = secondIField; + } + }", + CA1071CSharpFieldResultAt(10, 35, "C1", "firstIField", "firstField"), + CA1071CSharpFieldResultAt(10, 55, "C1", "secondIField", "secondField")); + } + + [Fact] + public async Task CA1071_ClassFieldsDoNotMatch_ConstructorParametersShouldMatchFieldNames_Basic() + { + await VerifyBasicAnalyzerAsync(@" +Imports System.Text.Json.Serialization + +Public Class C1 + Public firstField as Integer + Public secondField as Object + + + Public Sub New(firstIField as Integer, secondIField as Object) + Me.firstField = firstIField + Me.secondField = secondIField + End Sub +End Class", + CA2243BasicFieldResultAt(9, 20, "C1", "firstIField", "firstField"), + CA2243BasicFieldResultAt(9, 44, "C1", "secondIField", "secondField")); + } + + [Fact] + public async Task CA1071_RecordFieldsDoNotMatch_ConstructorParametersShouldMatchFieldNames_CSharp() + { + await VerifyCSharp9AnalyzerAsync(@" + using System.Text.Json.Serialization; + + public record C1 + { + public int firstField; + + public object secondField; + + [JsonConstructor] + public C1(int firstIField, object secondIField) + { + this.firstField = firstIField; + this.secondField = secondIField; + } + }", + CA1071CSharpFieldResultAt(11, 35, "C1", "firstIField", "firstField"), + CA1071CSharpFieldResultAt(11, 55, "C1", "secondIField", "secondField")); + } + + [Fact] + public async Task CA1071_ClassFieldsDoNotMatchNotJsonCtor_NoDiagnostics_CSharp() + { + await VerifyCSharpAnalyzerAsync(@" + using System.Text.Json.Serialization; + + public class C1 + { + public int firstField; + public object secondField; + + public C1(int firstIField, object secondIField) + { + this.firstField = firstIField; + this.secondField = secondIField; + } + }"); + } + + [Fact] + public async Task CA1071_ClassFieldsDoNotMatchNotJsonCtor_NoDiagnostics_Basic() + { + await VerifyBasicAnalyzerAsync(@" +Imports System.Text.Json.Serialization + +Public Class C1 + Public firstField as Integer + Public secondField as Object + + Public Sub New(firstIField as Integer, secondIField as Object) + Me.firstField = firstIField + Me.secondField = secondIField + End Sub +End Class"); + } + + [Fact] + public async Task CA1071_ClassFieldsMatch_NoDiagnostics_CSharp() + { + await VerifyCSharpAnalyzerAsync(@" + using System.Text.Json.Serialization; + + public class C1 + { + public int firstField; + public object secondField; + + [JsonConstructor] + public C1(int firstField, object secondField) + { + this.firstField = firstField; + this.secondField = secondField; + } + }" + ); + } + + [Fact] + public async Task CA1071_ClassFieldsMatch_NoDiagnostics_Basic() + { + await VerifyBasicAnalyzerAsync(@" +Imports System.Text.Json.Serialization + +Public Class C1 + Public firstField as Integer + Public secondField as Object + + + Public Sub New(firstField as Integer, secondField as Object) + Me.firstField = firstField + Me.secondField = secondField + End Sub +End Class"); + } + + private static async Task VerifyCSharpAnalyzerAsync(string source, params DiagnosticResult[] expected) + { + var csharpTest = new VerifyCS.Test + { + ReferenceAssemblies = AdditionalMetadataReferences.DefaultWithSystemTextJson50, + TestCode = source, + }; + + csharpTest.ExpectedDiagnostics.AddRange(expected); + + await csharpTest.RunAsync(); + } + + private static async Task VerifyCSharp9AnalyzerAsync(string source, params DiagnosticResult[] expected) + { + var csharpTest = new VerifyCS.Test + { + LanguageVersion = LanguageVersion.CSharp9, + ReferenceAssemblies = AdditionalMetadataReferences.DefaultWithSystemTextJson50, + TestCode = source, + }; + + csharpTest.ExpectedDiagnostics.AddRange(expected); + + await csharpTest.RunAsync(); + } + + private static async Task VerifyBasicAnalyzerAsync(string source, params DiagnosticResult[] expected) + { + var basicTest = new VerifyVB.Test + { + ReferenceAssemblies = AdditionalMetadataReferences.DefaultWithSystemTextJson50, + TestCode = source, + }; + + basicTest.ExpectedDiagnostics.AddRange(expected); + + await basicTest.RunAsync(); + } + + private DiagnosticResult CA1071CSharpPropertyResultAt(int line, int column, params string[] arguments) +#pragma warning disable RS0030 // Do not used banned APIs + => VerifyCS.Diagnostic(ConstructorParametersShouldMatchPropertyNamesAnalyzer.PropertyRule) + .WithLocation(line, column) +#pragma warning restore RS0030 // Do not used banned APIs + .WithArguments(arguments); + + private DiagnosticResult CA2243BasicPropertyResultAt(int line, int column, params string[] arguments) +#pragma warning disable RS0030 // Do not used banned APIs + => VerifyVB.Diagnostic(ConstructorParametersShouldMatchPropertyNamesAnalyzer.PropertyRule) + .WithLocation(line, column) +#pragma warning restore RS0030 // Do not used banned APIs + .WithArguments(arguments); + private DiagnosticResult CA1071CSharpFieldResultAt(int line, int column, params string[] arguments) +#pragma warning disable RS0030 // Do not used banned APIs + => VerifyCS.Diagnostic(ConstructorParametersShouldMatchPropertyNamesAnalyzer.FieldRule) + .WithLocation(line, column) +#pragma warning restore RS0030 // Do not used banned APIs + .WithArguments(arguments); + + private DiagnosticResult CA2243BasicFieldResultAt(int line, int column, params string[] arguments) +#pragma warning disable RS0030 // Do not used banned APIs + => VerifyVB.Diagnostic(ConstructorParametersShouldMatchPropertyNamesAnalyzer.FieldRule) + .WithLocation(line, column) +#pragma warning restore RS0030 // Do not used banned APIs + .WithArguments(arguments); + } +} \ No newline at end of file diff --git a/src/Test.Utilities/AdditionalMetadataReferences.cs b/src/Test.Utilities/AdditionalMetadataReferences.cs index 1cf2b61c34..47c5102bdd 100644 --- a/src/Test.Utilities/AdditionalMetadataReferences.cs +++ b/src/Test.Utilities/AdditionalMetadataReferences.cs @@ -37,6 +37,9 @@ public static class AdditionalMetadataReferences public static ReferenceAssemblies DefaultWithNewtonsoftJson12 { get; } = Default .AddPackages(ImmutableArray.Create(new PackageIdentity("Newtonsoft.Json", "12.0.1"))); + public static ReferenceAssemblies DefaultWithSystemTextJson50 { get; } = ReferenceAssemblies.NetStandard.NetStandard20 + .AddPackages(ImmutableArray.Create(new PackageIdentity("System.Text.Json", "5.0.1"))); + public static ReferenceAssemblies DefaultWithWinForms { get; } = ReferenceAssemblies.NetFramework.Net472.WindowsForms; public static ReferenceAssemblies DefaultWithWinHttpHandler { get; } = ReferenceAssemblies.NetStandard.NetStandard20 diff --git a/src/Test.Utilities/Test.Utilities.csproj b/src/Test.Utilities/Test.Utilities.csproj index b21e1815f4..4bab799fe9 100644 --- a/src/Test.Utilities/Test.Utilities.csproj +++ b/src/Test.Utilities/Test.Utilities.csproj @@ -13,6 +13,7 @@ + diff --git a/src/Utilities/Compiler/DiagnosticCategoryAndIdRanges.txt b/src/Utilities/Compiler/DiagnosticCategoryAndIdRanges.txt index 793ed1c657..0602d8880e 100644 --- a/src/Utilities/Compiler/DiagnosticCategoryAndIdRanges.txt +++ b/src/Utilities/Compiler/DiagnosticCategoryAndIdRanges.txt @@ -9,7 +9,7 @@ # 1. Choose the rule ID immediately following the range end. # 2. Update the range end to the chosen rule ID. # -Design: CA2210, CA1000-CA1070 +Design: CA2210, CA1000-CA1071 Globalization: CA2101, CA1300-CA1310 Mobility: CA1600-CA1601 Performance: HA, CA1800-CA1838 diff --git a/src/Utilities/Compiler/Extensions/IMethodSymbolExtensions.cs b/src/Utilities/Compiler/Extensions/IMethodSymbolExtensions.cs index 320f1f03eb..f1371c6ea6 100644 --- a/src/Utilities/Compiler/Extensions/IMethodSymbolExtensions.cs +++ b/src/Utilities/Compiler/Extensions/IMethodSymbolExtensions.cs @@ -384,6 +384,10 @@ public static bool IsSerializationConstructor([NotNullWhen(returnValue: true)] t method.Parameters[0].Type.Equals(serializationInfoType) && method.Parameters[1].Type.Equals(streamingContextType); + public static bool IsJsonConstructor([NotNullWhen(returnValue: true)] this IMethodSymbol? method, INamedTypeSymbol? jsonAttributeInfoType) + => method.IsConstructor() && + method.HasAttribute(jsonAttributeInfoType); + public static bool IsGetObjectData([NotNullWhen(returnValue: true)] this IMethodSymbol? method, INamedTypeSymbol? serializationInfoType, INamedTypeSymbol? streamingContextType) => method?.Name == "GetObjectData" && method.ReturnsVoid && diff --git a/src/Utilities/Compiler/WellKnownTypeNames.cs b/src/Utilities/Compiler/WellKnownTypeNames.cs index ca67f5eec2..dbc6fc9ab5 100644 --- a/src/Utilities/Compiler/WellKnownTypeNames.cs +++ b/src/Utilities/Compiler/WellKnownTypeNames.cs @@ -333,6 +333,7 @@ internal static class WellKnownTypeNames public const string SystemTextEncoding = "System.Text.Encoding"; public const string SystemTextRegularExpressionsRegex = "System.Text.RegularExpressions.Regex"; public const string SystemTextStringBuilder = "System.Text.StringBuilder"; + public const string SystemTextJsonSerializationJsonConstructorAttribute = "System.Text.Json.Serialization.JsonConstructorAttribute"; public const string SystemThreadingCancellationToken = "System.Threading.CancellationToken"; public const string SystemThreadingInterlocked = "System.Threading.Interlocked"; public const string SystemThreadingMonitor = "System.Threading.Monitor"; From 6dc3ef905e9080f750ac8aebf00a5a4d2cb3c2ea Mon Sep 17 00:00:00 2001 From: psxvoid Date: Wed, 24 Feb 2021 06:54:52 +0300 Subject: [PATCH 02/64] Fix - remove unused package reference --- src/Test.Utilities/Test.Utilities.csproj | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Test.Utilities/Test.Utilities.csproj b/src/Test.Utilities/Test.Utilities.csproj index 4bab799fe9..b21e1815f4 100644 --- a/src/Test.Utilities/Test.Utilities.csproj +++ b/src/Test.Utilities/Test.Utilities.csproj @@ -13,7 +13,6 @@ - From 6b715777f2f34559467ccf800fb4f13feb80a195 Mon Sep 17 00:00:00 2001 From: psxvoid Date: Wed, 24 Feb 2021 07:04:19 +0300 Subject: [PATCH 03/64] Fix json-ctor order in well-known-names --- src/Utilities/Compiler/WellKnownTypeNames.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Utilities/Compiler/WellKnownTypeNames.cs b/src/Utilities/Compiler/WellKnownTypeNames.cs index dbc6fc9ab5..a9b867e5f6 100644 --- a/src/Utilities/Compiler/WellKnownTypeNames.cs +++ b/src/Utilities/Compiler/WellKnownTypeNames.cs @@ -331,9 +331,9 @@ internal static class WellKnownTypeNames public const string SystemStringComparison = "System.StringComparison"; public const string SystemSystemException = "System.SystemException"; public const string SystemTextEncoding = "System.Text.Encoding"; + public const string SystemTextJsonSerializationJsonConstructorAttribute = "System.Text.Json.Serialization.JsonConstructorAttribute"; public const string SystemTextRegularExpressionsRegex = "System.Text.RegularExpressions.Regex"; public const string SystemTextStringBuilder = "System.Text.StringBuilder"; - public const string SystemTextJsonSerializationJsonConstructorAttribute = "System.Text.Json.Serialization.JsonConstructorAttribute"; public const string SystemThreadingCancellationToken = "System.Threading.CancellationToken"; public const string SystemThreadingInterlocked = "System.Threading.Interlocked"; public const string SystemThreadingMonitor = "System.Threading.Monitor"; From 52360bb93c2e9571a6cfdd4938bf12967e90842d Mon Sep 17 00:00:00 2001 From: psxvoid Date: Thu, 25 Feb 2021 10:41:45 +0300 Subject: [PATCH 04/64] Fix code alignment in tests --- ...ParametersShouldMatchPropertyNamesTests.cs | 134 +++++++++--------- 1 file changed, 67 insertions(+), 67 deletions(-) diff --git a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyNamesTests.cs b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyNamesTests.cs index 4a5d9ec68d..dfba8d4b2a 100644 --- a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyNamesTests.cs +++ b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyNamesTests.cs @@ -66,20 +66,20 @@ public C1(int firstDrop, object secondDrop) public async Task CA1071_ClassPropsDoNotMatch_ConstructorParametersShouldMatchPropertyNames_Basic() { await VerifyBasicAnalyzerAsync(@" -Imports System.Text.Json.Serialization - -Public Class C1 - Property FirstProp() As Integer - Property SecondProp() as Object - - - Public Sub New(firstDrop as Integer, secondDrop as Object) - Me.FirstProp = firstDrop - Me.SecondProp = secondDrop - End Sub -End Class", - CA2243BasicPropertyResultAt(9, 20, "C1", "firstDrop", "FirstProp"), - CA2243BasicPropertyResultAt(9, 42, "C1", "secondDrop", "SecondProp")); + Imports System.Text.Json.Serialization + + Public Class C1 + Property FirstProp() As Integer + Property SecondProp() as Object + + + Public Sub New(firstDrop as Integer, secondDrop as Object) + Me.FirstProp = firstDrop + Me.SecondProp = secondDrop + End Sub + End Class", + CA2243BasicPropertyResultAt(9, 36, "C1", "firstDrop", "FirstProp"), + CA2243BasicPropertyResultAt(9, 58, "C1", "secondDrop", "SecondProp")); } [Fact] @@ -106,17 +106,17 @@ public C1(int firstDrop, object secondDrop) public async Task CA1071_ClassPropsDoNotMatchNotJsonCtor_NoDiagnostics_Basic() { await VerifyBasicAnalyzerAsync(@" -Imports System.Text.Json.Serialization + Imports System.Text.Json.Serialization -Public Class C1 - Property firstProp() As Integer - Property secondProp() as Object + Public Class C1 + Property firstProp() As Integer + Property secondProp() as Object - Public Sub New(firstDrop as Integer, secondDrop as Object) - Me.firstProp = firstDrop - Me.secondProp = secondDrop - End Sub -End Class"); + Public Sub New(firstDrop as Integer, secondDrop as Object) + Me.firstProp = firstDrop + Me.secondProp = secondDrop + End Sub + End Class"); } [Fact] @@ -164,17 +164,17 @@ public C1(int firstProp, object secondProp) public async Task CA1071_ClassPropsMatch_NoDiagnostics_Basic() { await VerifyBasicAnalyzerAsync(@" -Imports System.Text.Json.Serialization + Imports System.Text.Json.Serialization -Public Class C1 - Property firstProp() As Integer - Property secondProp() as Object + Public Class C1 + Property firstProp() As Integer + Property secondProp() as Object - Public Sub New(firstDrop as Integer, secondDrop as Object) - Me.firstProp = firstDrop - Me.secondProp = secondDrop - End Sub -End Class"); + Public Sub New(firstDrop as Integer, secondDrop as Object) + Me.firstProp = firstDrop + Me.secondProp = secondDrop + End Sub + End Class"); } [Fact] @@ -203,20 +203,20 @@ public C1(int firstIField, object secondIField) public async Task CA1071_ClassFieldsDoNotMatch_ConstructorParametersShouldMatchFieldNames_Basic() { await VerifyBasicAnalyzerAsync(@" -Imports System.Text.Json.Serialization - -Public Class C1 - Public firstField as Integer - Public secondField as Object - - - Public Sub New(firstIField as Integer, secondIField as Object) - Me.firstField = firstIField - Me.secondField = secondIField - End Sub -End Class", - CA2243BasicFieldResultAt(9, 20, "C1", "firstIField", "firstField"), - CA2243BasicFieldResultAt(9, 44, "C1", "secondIField", "secondField")); + Imports System.Text.Json.Serialization + + Public Class C1 + Public firstField as Integer + Public secondField as Object + + + Public Sub New(firstIField as Integer, secondIField as Object) + Me.firstField = firstIField + Me.secondField = secondIField + End Sub + End Class", + CA2243BasicFieldResultAt(9, 36, "C1", "firstIField", "firstField"), + CA2243BasicFieldResultAt(9, 60, "C1", "secondIField", "secondField")); } [Fact] @@ -265,17 +265,17 @@ public C1(int firstIField, object secondIField) public async Task CA1071_ClassFieldsDoNotMatchNotJsonCtor_NoDiagnostics_Basic() { await VerifyBasicAnalyzerAsync(@" -Imports System.Text.Json.Serialization + Imports System.Text.Json.Serialization -Public Class C1 - Public firstField as Integer - Public secondField as Object + Public Class C1 + Public firstField as Integer + Public secondField as Object - Public Sub New(firstIField as Integer, secondIField as Object) - Me.firstField = firstIField - Me.secondField = secondIField - End Sub -End Class"); + Public Sub New(firstIField as Integer, secondIField as Object) + Me.firstField = firstIField + Me.secondField = secondIField + End Sub + End Class"); } [Fact] @@ -303,18 +303,18 @@ public C1(int firstField, object secondField) public async Task CA1071_ClassFieldsMatch_NoDiagnostics_Basic() { await VerifyBasicAnalyzerAsync(@" -Imports System.Text.Json.Serialization - -Public Class C1 - Public firstField as Integer - Public secondField as Object - - - Public Sub New(firstField as Integer, secondField as Object) - Me.firstField = firstField - Me.secondField = secondField - End Sub -End Class"); + Imports System.Text.Json.Serialization + + Public Class C1 + Public firstField as Integer + Public secondField as Object + + + Public Sub New(firstField as Integer, secondField as Object) + Me.firstField = firstField + Me.secondField = secondField + End Sub + End Class"); } private static async Task VerifyCSharpAnalyzerAsync(string source, params DiagnosticResult[] expected) From d9308a4f19b1dd9d7cadce53988b6a78b4caef20 Mon Sep 17 00:00:00 2001 From: psxvoid Date: Thu, 25 Feb 2021 10:45:54 +0300 Subject: [PATCH 05/64] Mark the diagnostic as non-fx-cop-ported --- .../Runtime/ConstructorParametersShouldMatchPropertyNames.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyNames.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyNames.cs index 2ec4a3f3ca..4e3a120793 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyNames.cs +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyNames.cs @@ -31,7 +31,7 @@ public sealed class ConstructorParametersShouldMatchPropertyNamesAnalyzer : Diag DiagnosticCategory.Design, RuleLevel.BuildWarning, description: s_localizableDescription, - isPortedFxCopRule: true, + isPortedFxCopRule: false, isDataflowRule: false); internal static DiagnosticDescriptor FieldRule = DiagnosticDescriptorHelper.Create(RuleId, s_localizableTitle, @@ -39,7 +39,7 @@ public sealed class ConstructorParametersShouldMatchPropertyNamesAnalyzer : Diag DiagnosticCategory.Design, RuleLevel.BuildWarning, description: s_localizableDescription, - isPortedFxCopRule: true, + isPortedFxCopRule: false, isDataflowRule: false); public override ImmutableArray SupportedDiagnostics => ImmutableArray.Create(PropertyRule, FieldRule); From 700c4ac0799033f54c267a015812cd13f55e45c3 Mon Sep 17 00:00:00 2001 From: psxvoid Date: Thu, 25 Feb 2021 11:01:48 +0300 Subject: [PATCH 06/64] Add missing msbuild autogenerated assets --- .../Microsoft.CodeAnalysis.NetAnalyzers.md | 12 +++++++++++ .../Microsoft.CodeAnalysis.NetAnalyzers.sarif | 20 +++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md index 1dff4237dc..10fdf691df 100644 --- a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md +++ b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md @@ -576,6 +576,18 @@ Do not declare virtual events in a base class. Overridden events in a derived cl |CodeFix|False| --- +## [CA1071](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1071): Constructor parameters should match referenced property and field names + +Constructor parameters should match referenced property or field names. + +|Item|Value| +|-|-| +|Category|Design| +|Enabled|True| +|Severity|Warning| +|CodeFix|False| +--- + ## [CA1200](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1200): Avoid using cref tags with a prefix Use of cref tags with prefixes should be avoided, since it prevents the compiler from verifying references and the IDE from updating references during refactorings. It is permissible to suppress this error at a single documentation site if the cref must use a prefix because the type being mentioned is not findable by the compiler. For example, if a cref is mentioning a special attribute in the full framework but you're in a file that compiles against the portable framework, or if you want to reference a type at higher layer of Roslyn, you should suppress the error. You should not suppress the error just because you want to take a shortcut and avoid using the full syntax. diff --git a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif index 17057589dd..c9602f2dc6 100644 --- a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif +++ b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif @@ -1346,6 +1346,26 @@ ] } }, + "CA1071": { + "id": "CA1071", + "shortDescription": "Constructor parameters should match referenced property and field names", + "fullDescription": "Constructor parameters should match referenced property or field names.", + "defaultLevel": "warning", + "helpUri": "https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1071", + "properties": { + "category": "Design", + "isEnabledByDefault": true, + "typeName": "ConstructorParametersShouldMatchPropertyNamesAnalyzer", + "languages": [ + "C#", + "Visual Basic" + ], + "tags": [ + "Telemetry", + "EnabledRuleInAggressiveMode" + ] + } + }, "CA1303": { "id": "CA1303", "shortDescription": "Do not pass literals as localized parameters", From d3769d662e5419d4dddc00d8350be1cbf36779d1 Mon Sep 17 00:00:00 2001 From: psxvoid Date: Thu, 25 Feb 2021 11:31:44 +0300 Subject: [PATCH 07/64] Fix - remove unused package reference, part 2 --- .../Microsoft.CodeAnalysis.NetAnalyzers.UnitTests.csproj | 1 - 1 file changed, 1 deletion(-) diff --git a/src/NetAnalyzers/UnitTests/Microsoft.CodeAnalysis.NetAnalyzers.UnitTests.csproj b/src/NetAnalyzers/UnitTests/Microsoft.CodeAnalysis.NetAnalyzers.UnitTests.csproj index 2e92d6f4df..9feef642b0 100644 --- a/src/NetAnalyzers/UnitTests/Microsoft.CodeAnalysis.NetAnalyzers.UnitTests.csproj +++ b/src/NetAnalyzers/UnitTests/Microsoft.CodeAnalysis.NetAnalyzers.UnitTests.csproj @@ -7,7 +7,6 @@ - From 5c828036478a5a16bec7d154d188c6d091f0e938 Mon Sep 17 00:00:00 2001 From: psxvoid Date: Thu, 25 Feb 2021 12:32:38 +0300 Subject: [PATCH 08/64] Update rule's message --- .../MicrosoftNetCoreAnalyzersResources.resx | 4 ++-- ...uctorParametersShouldMatchPropertyNames.cs | 2 -- .../MicrosoftNetCoreAnalyzersResources.cs.xlf | 8 +++---- .../MicrosoftNetCoreAnalyzersResources.de.xlf | 8 +++---- .../MicrosoftNetCoreAnalyzersResources.es.xlf | 8 +++---- .../MicrosoftNetCoreAnalyzersResources.fr.xlf | 8 +++---- .../MicrosoftNetCoreAnalyzersResources.it.xlf | 8 +++---- .../MicrosoftNetCoreAnalyzersResources.ja.xlf | 8 +++---- .../MicrosoftNetCoreAnalyzersResources.ko.xlf | 8 +++---- .../MicrosoftNetCoreAnalyzersResources.pl.xlf | 8 +++---- ...crosoftNetCoreAnalyzersResources.pt-BR.xlf | 8 +++---- .../MicrosoftNetCoreAnalyzersResources.ru.xlf | 8 +++---- .../MicrosoftNetCoreAnalyzersResources.tr.xlf | 8 +++---- ...osoftNetCoreAnalyzersResources.zh-Hans.xlf | 8 +++---- ...osoftNetCoreAnalyzersResources.zh-Hant.xlf | 8 +++---- ...ParametersShouldMatchPropertyNamesTests.cs | 24 +++++++++---------- 16 files changed, 66 insertions(+), 68 deletions(-) diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx index fbf699706f..1dbd751455 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx @@ -1520,10 +1520,10 @@ This call site is reachable on: 'windows' 10.0.2000 and later, and all other platforms - In the constructor of '{0}', change the name of parameter '{1}', to match the referenced field '{2}' + For proper deserialization change the name of parameter '{1}', to match the bound field '{2}' - In the constructor of '{0}', change the name of parameter '{1}' to match the referenced property '{2}' + For proper deserialization change the name of parameter '{1}', to match the bound property '{2}' Constructor parameters should match referenced property or field names. diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyNames.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyNames.cs index 4e3a120793..69e193a414 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyNames.cs +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyNames.cs @@ -121,7 +121,6 @@ public static void AnalyzeOperationAndReport(OperationAnalysisContext context) context.ReportDiagnostic( param.CreateDiagnostic( FieldRule, - param.ContainingType.ToDisplayString(SymbolDisplayFormats.ShortSymbolDisplayFormat), param.Name, field.Name)); } @@ -131,7 +130,6 @@ public static void AnalyzeOperationAndReport(OperationAnalysisContext context) context.ReportDiagnostic( param.CreateDiagnostic( PropertyRule, - param.ContainingType.ToDisplayString(SymbolDisplayFormats.ShortSymbolDisplayFormat), param.Name, prop.Name)); } 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 ddd4345a88..c16c20f355 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.cs.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.cs.xlf @@ -178,13 +178,13 @@ Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’} - In the constructor of '{0}', change the name of parameter '{1}', to match the referenced field '{2}' - In the constructor of '{0}', change the name of parameter '{1}', to match the referenced field '{2}' + For proper deserialization change the name of parameter '{1}', to match the bound field '{2}' + For proper deserialization change the name of parameter '{1}', to match the bound field '{2}' - In the constructor of '{0}', change the name of parameter '{1}' to match the referenced property '{2}' - In the constructor of '{0}', change the name of parameter '{1}' to match the referenced property '{2}' + For proper deserialization change the name of parameter '{1}', to match the bound property '{2}' + For proper deserialization change the name of parameter '{1}', to match the bound property '{2}' 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 04159b65d0..ae128e9a53 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.de.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.de.xlf @@ -178,13 +178,13 @@ Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’} - In the constructor of '{0}', change the name of parameter '{1}', to match the referenced field '{2}' - In the constructor of '{0}', change the name of parameter '{1}', to match the referenced field '{2}' + For proper deserialization change the name of parameter '{1}', to match the bound field '{2}' + For proper deserialization change the name of parameter '{1}', to match the bound field '{2}' - In the constructor of '{0}', change the name of parameter '{1}' to match the referenced property '{2}' - In the constructor of '{0}', change the name of parameter '{1}' to match the referenced property '{2}' + For proper deserialization change the name of parameter '{1}', to match the bound property '{2}' + For proper deserialization change the name of parameter '{1}', to match the bound property '{2}' 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 90ffa798bb..66b21d1f5a 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.es.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.es.xlf @@ -178,13 +178,13 @@ Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’} - In the constructor of '{0}', change the name of parameter '{1}', to match the referenced field '{2}' - In the constructor of '{0}', change the name of parameter '{1}', to match the referenced field '{2}' + For proper deserialization change the name of parameter '{1}', to match the bound field '{2}' + For proper deserialization change the name of parameter '{1}', to match the bound field '{2}' - In the constructor of '{0}', change the name of parameter '{1}' to match the referenced property '{2}' - In the constructor of '{0}', change the name of parameter '{1}' to match the referenced property '{2}' + For proper deserialization change the name of parameter '{1}', to match the bound property '{2}' + For proper deserialization change the name of parameter '{1}', to match the bound property '{2}' 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 025586291a..9af44ef065 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.fr.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.fr.xlf @@ -178,13 +178,13 @@ Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’} - In the constructor of '{0}', change the name of parameter '{1}', to match the referenced field '{2}' - In the constructor of '{0}', change the name of parameter '{1}', to match the referenced field '{2}' + For proper deserialization change the name of parameter '{1}', to match the bound field '{2}' + For proper deserialization change the name of parameter '{1}', to match the bound field '{2}' - In the constructor of '{0}', change the name of parameter '{1}' to match the referenced property '{2}' - In the constructor of '{0}', change the name of parameter '{1}' to match the referenced property '{2}' + For proper deserialization change the name of parameter '{1}', to match the bound property '{2}' + For proper deserialization change the name of parameter '{1}', to match the bound property '{2}' 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 e56eaadafd..db293cf6cf 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.it.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.it.xlf @@ -178,13 +178,13 @@ Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’} - In the constructor of '{0}', change the name of parameter '{1}', to match the referenced field '{2}' - In the constructor of '{0}', change the name of parameter '{1}', to match the referenced field '{2}' + For proper deserialization change the name of parameter '{1}', to match the bound field '{2}' + For proper deserialization change the name of parameter '{1}', to match the bound field '{2}' - In the constructor of '{0}', change the name of parameter '{1}' to match the referenced property '{2}' - In the constructor of '{0}', change the name of parameter '{1}' to match the referenced property '{2}' + For proper deserialization change the name of parameter '{1}', to match the bound property '{2}' + For proper deserialization change the name of parameter '{1}', to match the bound property '{2}' 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 4e69cf0078..deccbf15cc 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ja.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ja.xlf @@ -178,13 +178,13 @@ Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’} - In the constructor of '{0}', change the name of parameter '{1}', to match the referenced field '{2}' - In the constructor of '{0}', change the name of parameter '{1}', to match the referenced field '{2}' + For proper deserialization change the name of parameter '{1}', to match the bound field '{2}' + For proper deserialization change the name of parameter '{1}', to match the bound field '{2}' - In the constructor of '{0}', change the name of parameter '{1}' to match the referenced property '{2}' - In the constructor of '{0}', change the name of parameter '{1}' to match the referenced property '{2}' + For proper deserialization change the name of parameter '{1}', to match the bound property '{2}' + For proper deserialization change the name of parameter '{1}', to match the bound property '{2}' 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 230bb5e5c2..cccd268bc0 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ko.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ko.xlf @@ -178,13 +178,13 @@ Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’} - In the constructor of '{0}', change the name of parameter '{1}', to match the referenced field '{2}' - In the constructor of '{0}', change the name of parameter '{1}', to match the referenced field '{2}' + For proper deserialization change the name of parameter '{1}', to match the bound field '{2}' + For proper deserialization change the name of parameter '{1}', to match the bound field '{2}' - In the constructor of '{0}', change the name of parameter '{1}' to match the referenced property '{2}' - In the constructor of '{0}', change the name of parameter '{1}' to match the referenced property '{2}' + For proper deserialization change the name of parameter '{1}', to match the bound property '{2}' + For proper deserialization change the name of parameter '{1}', to match the bound property '{2}' 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 7729095cf2..0836cd4e03 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pl.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pl.xlf @@ -178,13 +178,13 @@ Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’} - In the constructor of '{0}', change the name of parameter '{1}', to match the referenced field '{2}' - In the constructor of '{0}', change the name of parameter '{1}', to match the referenced field '{2}' + For proper deserialization change the name of parameter '{1}', to match the bound field '{2}' + For proper deserialization change the name of parameter '{1}', to match the bound field '{2}' - In the constructor of '{0}', change the name of parameter '{1}' to match the referenced property '{2}' - In the constructor of '{0}', change the name of parameter '{1}' to match the referenced property '{2}' + For proper deserialization change the name of parameter '{1}', to match the bound property '{2}' + For proper deserialization change the name of parameter '{1}', to match the bound property '{2}' 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 5e0f55f638..18f25119b5 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 @@ -178,13 +178,13 @@ Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’} - In the constructor of '{0}', change the name of parameter '{1}', to match the referenced field '{2}' - In the constructor of '{0}', change the name of parameter '{1}', to match the referenced field '{2}' + For proper deserialization change the name of parameter '{1}', to match the bound field '{2}' + For proper deserialization change the name of parameter '{1}', to match the bound field '{2}' - In the constructor of '{0}', change the name of parameter '{1}' to match the referenced property '{2}' - In the constructor of '{0}', change the name of parameter '{1}' to match the referenced property '{2}' + For proper deserialization change the name of parameter '{1}', to match the bound property '{2}' + For proper deserialization change the name of parameter '{1}', to match the bound property '{2}' 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 0a4b2e4960..53d336eb6a 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ru.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ru.xlf @@ -178,13 +178,13 @@ Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’} - In the constructor of '{0}', change the name of parameter '{1}', to match the referenced field '{2}' - In the constructor of '{0}', change the name of parameter '{1}', to match the referenced field '{2}' + For proper deserialization change the name of parameter '{1}', to match the bound field '{2}' + For proper deserialization change the name of parameter '{1}', to match the bound field '{2}' - In the constructor of '{0}', change the name of parameter '{1}' to match the referenced property '{2}' - In the constructor of '{0}', change the name of parameter '{1}' to match the referenced property '{2}' + For proper deserialization change the name of parameter '{1}', to match the bound property '{2}' + For proper deserialization change the name of parameter '{1}', to match the bound property '{2}' 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 2b7a0543ba..5b6be744fe 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.tr.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.tr.xlf @@ -178,13 +178,13 @@ Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’} - In the constructor of '{0}', change the name of parameter '{1}', to match the referenced field '{2}' - In the constructor of '{0}', change the name of parameter '{1}', to match the referenced field '{2}' + For proper deserialization change the name of parameter '{1}', to match the bound field '{2}' + For proper deserialization change the name of parameter '{1}', to match the bound field '{2}' - In the constructor of '{0}', change the name of parameter '{1}' to match the referenced property '{2}' - In the constructor of '{0}', change the name of parameter '{1}' to match the referenced property '{2}' + For proper deserialization change the name of parameter '{1}', to match the bound property '{2}' + For proper deserialization change the name of parameter '{1}', to match the bound property '{2}' 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 fffc4a6619..7b4e11383e 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 @@ -178,13 +178,13 @@ Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’} - In the constructor of '{0}', change the name of parameter '{1}', to match the referenced field '{2}' - In the constructor of '{0}', change the name of parameter '{1}', to match the referenced field '{2}' + For proper deserialization change the name of parameter '{1}', to match the bound field '{2}' + For proper deserialization change the name of parameter '{1}', to match the bound field '{2}' - In the constructor of '{0}', change the name of parameter '{1}' to match the referenced property '{2}' - In the constructor of '{0}', change the name of parameter '{1}' to match the referenced property '{2}' + For proper deserialization change the name of parameter '{1}', to match the bound property '{2}' + For proper deserialization change the name of parameter '{1}', to match the bound property '{2}' 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 58d1156c99..dcfeb239d9 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 @@ -178,13 +178,13 @@ Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’} - In the constructor of '{0}', change the name of parameter '{1}', to match the referenced field '{2}' - In the constructor of '{0}', change the name of parameter '{1}', to match the referenced field '{2}' + For proper deserialization change the name of parameter '{1}', to match the bound field '{2}' + For proper deserialization change the name of parameter '{1}', to match the bound field '{2}' - In the constructor of '{0}', change the name of parameter '{1}' to match the referenced property '{2}' - In the constructor of '{0}', change the name of parameter '{1}' to match the referenced property '{2}' + For proper deserialization change the name of parameter '{1}', to match the bound property '{2}' + For proper deserialization change the name of parameter '{1}', to match the bound property '{2}' diff --git a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyNamesTests.cs b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyNamesTests.cs index dfba8d4b2a..eda23d6fae 100644 --- a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyNamesTests.cs +++ b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyNamesTests.cs @@ -35,8 +35,8 @@ public C1(int firstDrop, object secondDrop) this.SecondProp = secondDrop; } }", - CA1071CSharpPropertyResultAt(11, 35, "C1", "firstDrop", "FirstProp"), - CA1071CSharpPropertyResultAt(11, 53, "C1", "secondDrop", "SecondProp")); + CA1071CSharpPropertyResultAt(11, 35, "firstDrop", "FirstProp"), + CA1071CSharpPropertyResultAt(11, 53, "secondDrop", "SecondProp")); } [Fact] @@ -58,8 +58,8 @@ public C1(int firstDrop, object secondDrop) this.SecondProp = secondDrop; } }", - CA1071CSharpPropertyResultAt(11, 35, "C1", "firstDrop", "FirstProp"), - CA1071CSharpPropertyResultAt(11, 53, "C1", "secondDrop", "SecondProp")); + CA1071CSharpPropertyResultAt(11, 35, "firstDrop", "FirstProp"), + CA1071CSharpPropertyResultAt(11, 53, "secondDrop", "SecondProp")); } [Fact] @@ -78,8 +78,8 @@ Public Sub New(firstDrop as Integer, secondDrop as Object) Me.SecondProp = secondDrop End Sub End Class", - CA2243BasicPropertyResultAt(9, 36, "C1", "firstDrop", "FirstProp"), - CA2243BasicPropertyResultAt(9, 58, "C1", "secondDrop", "SecondProp")); + CA2243BasicPropertyResultAt(9, 36, "firstDrop", "FirstProp"), + CA2243BasicPropertyResultAt(9, 58, "secondDrop", "SecondProp")); } [Fact] @@ -195,8 +195,8 @@ public C1(int firstIField, object secondIField) this.secondField = secondIField; } }", - CA1071CSharpFieldResultAt(10, 35, "C1", "firstIField", "firstField"), - CA1071CSharpFieldResultAt(10, 55, "C1", "secondIField", "secondField")); + CA1071CSharpFieldResultAt(10, 35, "firstIField", "firstField"), + CA1071CSharpFieldResultAt(10, 55, "secondIField", "secondField")); } [Fact] @@ -215,8 +215,8 @@ Public Sub New(firstIField as Integer, secondIField as Object) Me.secondField = secondIField End Sub End Class", - CA2243BasicFieldResultAt(9, 36, "C1", "firstIField", "firstField"), - CA2243BasicFieldResultAt(9, 60, "C1", "secondIField", "secondField")); + CA2243BasicFieldResultAt(9, 36, "firstIField", "firstField"), + CA2243BasicFieldResultAt(9, 60, "secondIField", "secondField")); } [Fact] @@ -238,8 +238,8 @@ public C1(int firstIField, object secondIField) this.secondField = secondIField; } }", - CA1071CSharpFieldResultAt(11, 35, "C1", "firstIField", "firstField"), - CA1071CSharpFieldResultAt(11, 55, "C1", "secondIField", "secondField")); + CA1071CSharpFieldResultAt(11, 35, "firstIField", "firstField"), + CA1071CSharpFieldResultAt(11, 55, "secondIField", "secondField")); } [Fact] From 43ad9b17bfd58eff8875927e60eb40cb56fb4ab1 Mon Sep 17 00:00:00 2001 From: psxvoid Date: Thu, 25 Feb 2021 12:59:17 +0300 Subject: [PATCH 09/64] Rollback unrelated analyzer to the original state --- .../SerializationRulesDiagnosticAnalyzer.cs | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/SerializationRulesDiagnosticAnalyzer.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/SerializationRulesDiagnosticAnalyzer.cs index c631b27464..397c077d55 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/SerializationRulesDiagnosticAnalyzer.cs +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/SerializationRulesDiagnosticAnalyzer.cs @@ -15,10 +15,9 @@ public sealed class SerializationRulesDiagnosticAnalyzer : DiagnosticAnalyzer // Implement serialization constructors internal const string RuleCA2229Id = "CA2229"; - #region Diagnostic Descriptor Definitions private static readonly LocalizableString s_localizableTitleCA2229 = - new LocalizableResourceString(nameof(MicrosoftNetCoreAnalyzersResources.ImplementSerializationConstructorsTitle), - MicrosoftNetCoreAnalyzersResources.ResourceManager, typeof(MicrosoftNetCoreAnalyzersResources)); + new LocalizableResourceString(nameof(MicrosoftNetCoreAnalyzersResources.ImplementSerializationConstructorsTitle), + MicrosoftNetCoreAnalyzersResources.ResourceManager, typeof(MicrosoftNetCoreAnalyzersResources)); private static readonly LocalizableString s_localizableDescriptionCA2229 = new LocalizableResourceString(nameof(MicrosoftNetCoreAnalyzersResources.ImplementSerializationConstructorsDescription), @@ -102,9 +101,6 @@ public sealed class SerializationRulesDiagnosticAnalyzer : DiagnosticAnalyzer public override ImmutableArray SupportedDiagnostics => ImmutableArray.Create(RuleCA2229Default, RuleCA2229Sealed, RuleCA2229Unsealed, RuleCA2235, RuleCA2237); - #endregion - - #region Public Methods public override void Initialize(AnalysisContext context) { context.EnableConcurrentExecution(); @@ -150,10 +146,6 @@ public override void Initialize(AnalysisContext context) }); } - #endregion - - #region Private Classes - private sealed class SymbolAnalyzer { private readonly INamedTypeSymbol _iserializableTypeSymbol; @@ -305,7 +297,5 @@ private bool IsSerializable(ITypeSymbol type) }; } } - - #endregion } } From 41d44b20628214945c66315c46c3d7e48f04307c Mon Sep 17 00:00:00 2001 From: psxvoid Date: Fri, 26 Feb 2021 09:20:41 +0300 Subject: [PATCH 10/64] Update the description message for the analyzer --- .../MicrosoftNetCoreAnalyzersResources.resx | 2 +- .../xlf/MicrosoftNetCoreAnalyzersResources.cs.xlf | 4 ++-- .../xlf/MicrosoftNetCoreAnalyzersResources.de.xlf | 4 ++-- .../xlf/MicrosoftNetCoreAnalyzersResources.es.xlf | 4 ++-- .../xlf/MicrosoftNetCoreAnalyzersResources.fr.xlf | 4 ++-- .../xlf/MicrosoftNetCoreAnalyzersResources.it.xlf | 4 ++-- .../xlf/MicrosoftNetCoreAnalyzersResources.ja.xlf | 4 ++-- .../xlf/MicrosoftNetCoreAnalyzersResources.ko.xlf | 4 ++-- .../xlf/MicrosoftNetCoreAnalyzersResources.pl.xlf | 4 ++-- .../xlf/MicrosoftNetCoreAnalyzersResources.pt-BR.xlf | 4 ++-- .../xlf/MicrosoftNetCoreAnalyzersResources.ru.xlf | 4 ++-- .../xlf/MicrosoftNetCoreAnalyzersResources.tr.xlf | 4 ++-- .../xlf/MicrosoftNetCoreAnalyzersResources.zh-Hans.xlf | 4 ++-- .../xlf/MicrosoftNetCoreAnalyzersResources.zh-Hant.xlf | 4 ++-- src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md | 2 +- src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif | 2 +- 16 files changed, 29 insertions(+), 29 deletions(-) diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx index 1dbd751455..3242a81d9d 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx @@ -1526,7 +1526,7 @@ For proper deserialization change the name of parameter '{1}', to match the bound property '{2}' - Constructor parameters should match referenced property or field names. + For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. Constructor parameters should match referenced property and field names 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 c16c20f355..c6ab7e6543 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.cs.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.cs.xlf @@ -188,8 +188,8 @@ - Constructor parameters should match referenced property or field names. - Constructor parameters should match referenced property or field names. + For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. + For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. 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 ae128e9a53..96a5452450 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.de.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.de.xlf @@ -188,8 +188,8 @@ - Constructor parameters should match referenced property or field names. - Constructor parameters should match referenced property or field names. + For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. + For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. 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 66b21d1f5a..affd53fdd7 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.es.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.es.xlf @@ -188,8 +188,8 @@ - Constructor parameters should match referenced property or field names. - Constructor parameters should match referenced property or field names. + For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. + For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. 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 9af44ef065..577d69aaa2 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.fr.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.fr.xlf @@ -188,8 +188,8 @@ - Constructor parameters should match referenced property or field names. - Constructor parameters should match referenced property or field names. + For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. + For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. 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 db293cf6cf..93a2ab671a 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.it.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.it.xlf @@ -188,8 +188,8 @@ - Constructor parameters should match referenced property or field names. - Constructor parameters should match referenced property or field names. + For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. + For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. 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 deccbf15cc..8dc0e76730 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ja.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ja.xlf @@ -188,8 +188,8 @@ - Constructor parameters should match referenced property or field names. - Constructor parameters should match referenced property or field names. + For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. + For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. 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 cccd268bc0..349fcf4370 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ko.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ko.xlf @@ -188,8 +188,8 @@ - Constructor parameters should match referenced property or field names. - Constructor parameters should match referenced property or field names. + For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. + For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. 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 0836cd4e03..4962131d98 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pl.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pl.xlf @@ -188,8 +188,8 @@ - Constructor parameters should match referenced property or field names. - Constructor parameters should match referenced property or field names. + For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. + For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. 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 18f25119b5..dbf3ff5f99 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 @@ -188,8 +188,8 @@ - Constructor parameters should match referenced property or field names. - Constructor parameters should match referenced property or field names. + For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. + For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. 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 53d336eb6a..583724d2d9 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ru.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ru.xlf @@ -188,8 +188,8 @@ - Constructor parameters should match referenced property or field names. - Constructor parameters should match referenced property or field names. + For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. + For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. 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 5b6be744fe..186d6e1cdd 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.tr.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.tr.xlf @@ -188,8 +188,8 @@ - Constructor parameters should match referenced property or field names. - Constructor parameters should match referenced property or field names. + For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. + For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. 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 7b4e11383e..4f6c2427a9 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 @@ -188,8 +188,8 @@ - Constructor parameters should match referenced property or field names. - Constructor parameters should match referenced property or field names. + For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. + For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. 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 dcfeb239d9..b1aad0529c 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 @@ -188,8 +188,8 @@ - Constructor parameters should match referenced property or field names. - Constructor parameters should match referenced property or field names. + For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. + For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. diff --git a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md index 10fdf691df..b7fe878caf 100644 --- a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md +++ b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md @@ -578,7 +578,7 @@ Do not declare virtual events in a base class. Overridden events in a derived cl ## [CA1071](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1071): Constructor parameters should match referenced property and field names -Constructor parameters should match referenced property or field names. +For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. |Item|Value| |-|-| diff --git a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif index c9602f2dc6..6e9878f4c2 100644 --- a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif +++ b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif @@ -1349,7 +1349,7 @@ "CA1071": { "id": "CA1071", "shortDescription": "Constructor parameters should match referenced property and field names", - "fullDescription": "Constructor parameters should match referenced property or field names.", + "fullDescription": "For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization.", "defaultLevel": "warning", "helpUri": "https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1071", "properties": { From e3db94693d2b6259ea18ed894060d76a8aea8df8 Mon Sep 17 00:00:00 2001 From: psxvoid Date: Fri, 26 Feb 2021 09:58:54 +0300 Subject: [PATCH 11/64] Fix misplaced comma and update the message --- .../MicrosoftNetCoreAnalyzersResources.resx | 4 ++-- ...uctorParametersShouldMatchPropertyNames.cs | 2 ++ .../MicrosoftNetCoreAnalyzersResources.cs.xlf | 8 +++---- .../MicrosoftNetCoreAnalyzersResources.de.xlf | 8 +++---- .../MicrosoftNetCoreAnalyzersResources.es.xlf | 8 +++---- .../MicrosoftNetCoreAnalyzersResources.fr.xlf | 8 +++---- .../MicrosoftNetCoreAnalyzersResources.it.xlf | 8 +++---- .../MicrosoftNetCoreAnalyzersResources.ja.xlf | 8 +++---- .../MicrosoftNetCoreAnalyzersResources.ko.xlf | 8 +++---- .../MicrosoftNetCoreAnalyzersResources.pl.xlf | 8 +++---- ...crosoftNetCoreAnalyzersResources.pt-BR.xlf | 8 +++---- .../MicrosoftNetCoreAnalyzersResources.ru.xlf | 8 +++---- .../MicrosoftNetCoreAnalyzersResources.tr.xlf | 8 +++---- ...osoftNetCoreAnalyzersResources.zh-Hans.xlf | 8 +++---- ...osoftNetCoreAnalyzersResources.zh-Hant.xlf | 8 +++---- ...ParametersShouldMatchPropertyNamesTests.cs | 24 +++++++++---------- 16 files changed, 68 insertions(+), 66 deletions(-) diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx index 3242a81d9d..5be825557c 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx @@ -1520,10 +1520,10 @@ This call site is reachable on: 'windows' 10.0.2000 and later, and all other platforms - For proper deserialization change the name of parameter '{1}', to match the bound field '{2}' + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' - For proper deserialization change the name of parameter '{1}', to match the bound property '{2}' + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyNames.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyNames.cs index 69e193a414..4e3a120793 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyNames.cs +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyNames.cs @@ -121,6 +121,7 @@ public static void AnalyzeOperationAndReport(OperationAnalysisContext context) context.ReportDiagnostic( param.CreateDiagnostic( FieldRule, + param.ContainingType.ToDisplayString(SymbolDisplayFormats.ShortSymbolDisplayFormat), param.Name, field.Name)); } @@ -130,6 +131,7 @@ public static void AnalyzeOperationAndReport(OperationAnalysisContext context) context.ReportDiagnostic( param.CreateDiagnostic( PropertyRule, + param.ContainingType.ToDisplayString(SymbolDisplayFormats.ShortSymbolDisplayFormat), param.Name, prop.Name)); } 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 c6ab7e6543..8c049c97e4 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.cs.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.cs.xlf @@ -178,13 +178,13 @@ Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’} - For proper deserialization change the name of parameter '{1}', to match the bound field '{2}' - For proper deserialization change the name of parameter '{1}', to match the bound field '{2}' + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' - For proper deserialization change the name of parameter '{1}', to match the bound property '{2}' - For proper deserialization change the name of parameter '{1}', to match the bound property '{2}' + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' 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 96a5452450..cfabe26715 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.de.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.de.xlf @@ -178,13 +178,13 @@ Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’} - For proper deserialization change the name of parameter '{1}', to match the bound field '{2}' - For proper deserialization change the name of parameter '{1}', to match the bound field '{2}' + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' - For proper deserialization change the name of parameter '{1}', to match the bound property '{2}' - For proper deserialization change the name of parameter '{1}', to match the bound property '{2}' + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' 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 affd53fdd7..d012a9d4c5 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.es.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.es.xlf @@ -178,13 +178,13 @@ Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’} - For proper deserialization change the name of parameter '{1}', to match the bound field '{2}' - For proper deserialization change the name of parameter '{1}', to match the bound field '{2}' + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' - For proper deserialization change the name of parameter '{1}', to match the bound property '{2}' - For proper deserialization change the name of parameter '{1}', to match the bound property '{2}' + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' 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 577d69aaa2..9a86b7856d 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.fr.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.fr.xlf @@ -178,13 +178,13 @@ Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’} - For proper deserialization change the name of parameter '{1}', to match the bound field '{2}' - For proper deserialization change the name of parameter '{1}', to match the bound field '{2}' + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' - For proper deserialization change the name of parameter '{1}', to match the bound property '{2}' - For proper deserialization change the name of parameter '{1}', to match the bound property '{2}' + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' 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 93a2ab671a..1979fde73f 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.it.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.it.xlf @@ -178,13 +178,13 @@ Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’} - For proper deserialization change the name of parameter '{1}', to match the bound field '{2}' - For proper deserialization change the name of parameter '{1}', to match the bound field '{2}' + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' - For proper deserialization change the name of parameter '{1}', to match the bound property '{2}' - For proper deserialization change the name of parameter '{1}', to match the bound property '{2}' + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' 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 8dc0e76730..a2d5fd06ce 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ja.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ja.xlf @@ -178,13 +178,13 @@ Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’} - For proper deserialization change the name of parameter '{1}', to match the bound field '{2}' - For proper deserialization change the name of parameter '{1}', to match the bound field '{2}' + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' - For proper deserialization change the name of parameter '{1}', to match the bound property '{2}' - For proper deserialization change the name of parameter '{1}', to match the bound property '{2}' + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' 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 349fcf4370..156c9904d5 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ko.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ko.xlf @@ -178,13 +178,13 @@ Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’} - For proper deserialization change the name of parameter '{1}', to match the bound field '{2}' - For proper deserialization change the name of parameter '{1}', to match the bound field '{2}' + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' - For proper deserialization change the name of parameter '{1}', to match the bound property '{2}' - For proper deserialization change the name of parameter '{1}', to match the bound property '{2}' + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' 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 4962131d98..f1f531456f 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pl.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pl.xlf @@ -178,13 +178,13 @@ Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’} - For proper deserialization change the name of parameter '{1}', to match the bound field '{2}' - For proper deserialization change the name of parameter '{1}', to match the bound field '{2}' + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' - For proper deserialization change the name of parameter '{1}', to match the bound property '{2}' - For proper deserialization change the name of parameter '{1}', to match the bound property '{2}' + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' 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 dbf3ff5f99..cb47a7d23e 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 @@ -178,13 +178,13 @@ Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’} - For proper deserialization change the name of parameter '{1}', to match the bound field '{2}' - For proper deserialization change the name of parameter '{1}', to match the bound field '{2}' + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' - For proper deserialization change the name of parameter '{1}', to match the bound property '{2}' - For proper deserialization change the name of parameter '{1}', to match the bound property '{2}' + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' 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 583724d2d9..44d8fc7f7a 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ru.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ru.xlf @@ -178,13 +178,13 @@ Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’} - For proper deserialization change the name of parameter '{1}', to match the bound field '{2}' - For proper deserialization change the name of parameter '{1}', to match the bound field '{2}' + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' - For proper deserialization change the name of parameter '{1}', to match the bound property '{2}' - For proper deserialization change the name of parameter '{1}', to match the bound property '{2}' + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' 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 186d6e1cdd..7eedfb5024 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.tr.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.tr.xlf @@ -178,13 +178,13 @@ Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’} - For proper deserialization change the name of parameter '{1}', to match the bound field '{2}' - For proper deserialization change the name of parameter '{1}', to match the bound field '{2}' + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' - For proper deserialization change the name of parameter '{1}', to match the bound property '{2}' - For proper deserialization change the name of parameter '{1}', to match the bound property '{2}' + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' 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 4f6c2427a9..346c91122a 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 @@ -178,13 +178,13 @@ Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’} - For proper deserialization change the name of parameter '{1}', to match the bound field '{2}' - For proper deserialization change the name of parameter '{1}', to match the bound field '{2}' + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' - For proper deserialization change the name of parameter '{1}', to match the bound property '{2}' - For proper deserialization change the name of parameter '{1}', to match the bound property '{2}' + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' 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 b1aad0529c..4f89efa54d 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 @@ -178,13 +178,13 @@ Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’} - For proper deserialization change the name of parameter '{1}', to match the bound field '{2}' - For proper deserialization change the name of parameter '{1}', to match the bound field '{2}' + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' - For proper deserialization change the name of parameter '{1}', to match the bound property '{2}' - For proper deserialization change the name of parameter '{1}', to match the bound property '{2}' + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' diff --git a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyNamesTests.cs b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyNamesTests.cs index eda23d6fae..dfba8d4b2a 100644 --- a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyNamesTests.cs +++ b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyNamesTests.cs @@ -35,8 +35,8 @@ public C1(int firstDrop, object secondDrop) this.SecondProp = secondDrop; } }", - CA1071CSharpPropertyResultAt(11, 35, "firstDrop", "FirstProp"), - CA1071CSharpPropertyResultAt(11, 53, "secondDrop", "SecondProp")); + CA1071CSharpPropertyResultAt(11, 35, "C1", "firstDrop", "FirstProp"), + CA1071CSharpPropertyResultAt(11, 53, "C1", "secondDrop", "SecondProp")); } [Fact] @@ -58,8 +58,8 @@ public C1(int firstDrop, object secondDrop) this.SecondProp = secondDrop; } }", - CA1071CSharpPropertyResultAt(11, 35, "firstDrop", "FirstProp"), - CA1071CSharpPropertyResultAt(11, 53, "secondDrop", "SecondProp")); + CA1071CSharpPropertyResultAt(11, 35, "C1", "firstDrop", "FirstProp"), + CA1071CSharpPropertyResultAt(11, 53, "C1", "secondDrop", "SecondProp")); } [Fact] @@ -78,8 +78,8 @@ Public Sub New(firstDrop as Integer, secondDrop as Object) Me.SecondProp = secondDrop End Sub End Class", - CA2243BasicPropertyResultAt(9, 36, "firstDrop", "FirstProp"), - CA2243BasicPropertyResultAt(9, 58, "secondDrop", "SecondProp")); + CA2243BasicPropertyResultAt(9, 36, "C1", "firstDrop", "FirstProp"), + CA2243BasicPropertyResultAt(9, 58, "C1", "secondDrop", "SecondProp")); } [Fact] @@ -195,8 +195,8 @@ public C1(int firstIField, object secondIField) this.secondField = secondIField; } }", - CA1071CSharpFieldResultAt(10, 35, "firstIField", "firstField"), - CA1071CSharpFieldResultAt(10, 55, "secondIField", "secondField")); + CA1071CSharpFieldResultAt(10, 35, "C1", "firstIField", "firstField"), + CA1071CSharpFieldResultAt(10, 55, "C1", "secondIField", "secondField")); } [Fact] @@ -215,8 +215,8 @@ Public Sub New(firstIField as Integer, secondIField as Object) Me.secondField = secondIField End Sub End Class", - CA2243BasicFieldResultAt(9, 36, "firstIField", "firstField"), - CA2243BasicFieldResultAt(9, 60, "secondIField", "secondField")); + CA2243BasicFieldResultAt(9, 36, "C1", "firstIField", "firstField"), + CA2243BasicFieldResultAt(9, 60, "C1", "secondIField", "secondField")); } [Fact] @@ -238,8 +238,8 @@ public C1(int firstIField, object secondIField) this.secondField = secondIField; } }", - CA1071CSharpFieldResultAt(11, 35, "firstIField", "firstField"), - CA1071CSharpFieldResultAt(11, 55, "secondIField", "secondField")); + CA1071CSharpFieldResultAt(11, 35, "C1", "firstIField", "firstField"), + CA1071CSharpFieldResultAt(11, 55, "C1", "secondIField", "secondField")); } [Fact] From e9bc939bfa1adb06d59777e94bf8923090fb8dfe Mon Sep 17 00:00:00 2001 From: psxvoid Date: Fri, 26 Feb 2021 10:00:56 +0300 Subject: [PATCH 12/64] Fix incorrect helper test method name prefix --- ...tructorParametersShouldMatchPropertyNamesTests.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyNamesTests.cs b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyNamesTests.cs index dfba8d4b2a..97147960c9 100644 --- a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyNamesTests.cs +++ b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyNamesTests.cs @@ -78,8 +78,8 @@ Public Sub New(firstDrop as Integer, secondDrop as Object) Me.SecondProp = secondDrop End Sub End Class", - CA2243BasicPropertyResultAt(9, 36, "C1", "firstDrop", "FirstProp"), - CA2243BasicPropertyResultAt(9, 58, "C1", "secondDrop", "SecondProp")); + CA1071BasicPropertyResultAt(9, 36, "C1", "firstDrop", "FirstProp"), + CA1071BasicPropertyResultAt(9, 58, "C1", "secondDrop", "SecondProp")); } [Fact] @@ -215,8 +215,8 @@ Public Sub New(firstIField as Integer, secondIField as Object) Me.secondField = secondIField End Sub End Class", - CA2243BasicFieldResultAt(9, 36, "C1", "firstIField", "firstField"), - CA2243BasicFieldResultAt(9, 60, "C1", "secondIField", "secondField")); + CA1071BasicFieldResultAt(9, 36, "C1", "firstIField", "firstField"), + CA1071BasicFieldResultAt(9, 60, "C1", "secondIField", "secondField")); } [Fact] @@ -364,7 +364,7 @@ private DiagnosticResult CA1071CSharpPropertyResultAt(int line, int column, para #pragma warning restore RS0030 // Do not used banned APIs .WithArguments(arguments); - private DiagnosticResult CA2243BasicPropertyResultAt(int line, int column, params string[] arguments) + private DiagnosticResult CA1071BasicPropertyResultAt(int line, int column, params string[] arguments) #pragma warning disable RS0030 // Do not used banned APIs => VerifyVB.Diagnostic(ConstructorParametersShouldMatchPropertyNamesAnalyzer.PropertyRule) .WithLocation(line, column) @@ -377,7 +377,7 @@ private DiagnosticResult CA1071CSharpFieldResultAt(int line, int column, params #pragma warning restore RS0030 // Do not used banned APIs .WithArguments(arguments); - private DiagnosticResult CA2243BasicFieldResultAt(int line, int column, params string[] arguments) + private DiagnosticResult CA1071BasicFieldResultAt(int line, int column, params string[] arguments) #pragma warning disable RS0030 // Do not used banned APIs => VerifyVB.Diagnostic(ConstructorParametersShouldMatchPropertyNamesAnalyzer.FieldRule) .WithLocation(line, column) From 481f5ed39aa6db2b97037de08511cf9726dfc0a7 Mon Sep 17 00:00:00 2001 From: psxvoid Date: Fri, 26 Feb 2021 10:15:40 +0300 Subject: [PATCH 13/64] Update the message title with the recommended one --- .../MicrosoftNetCoreAnalyzersResources.resx | 2 +- .../xlf/MicrosoftNetCoreAnalyzersResources.cs.xlf | 4 ++-- .../xlf/MicrosoftNetCoreAnalyzersResources.de.xlf | 4 ++-- .../xlf/MicrosoftNetCoreAnalyzersResources.es.xlf | 4 ++-- .../xlf/MicrosoftNetCoreAnalyzersResources.fr.xlf | 4 ++-- .../xlf/MicrosoftNetCoreAnalyzersResources.it.xlf | 4 ++-- .../xlf/MicrosoftNetCoreAnalyzersResources.ja.xlf | 4 ++-- .../xlf/MicrosoftNetCoreAnalyzersResources.ko.xlf | 4 ++-- .../xlf/MicrosoftNetCoreAnalyzersResources.pl.xlf | 4 ++-- .../xlf/MicrosoftNetCoreAnalyzersResources.pt-BR.xlf | 4 ++-- .../xlf/MicrosoftNetCoreAnalyzersResources.ru.xlf | 4 ++-- .../xlf/MicrosoftNetCoreAnalyzersResources.tr.xlf | 4 ++-- .../xlf/MicrosoftNetCoreAnalyzersResources.zh-Hans.xlf | 4 ++-- .../xlf/MicrosoftNetCoreAnalyzersResources.zh-Hant.xlf | 4 ++-- src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md | 2 +- src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif | 2 +- 16 files changed, 29 insertions(+), 29 deletions(-) diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx index 5be825557c..a7b176e8e0 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx @@ -1529,6 +1529,6 @@ For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. - Constructor parameters should match referenced property and field names + Constructor parameter names should match the bound property or field names \ 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 8c049c97e4..84b2ee67e5 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.cs.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.cs.xlf @@ -193,8 +193,8 @@ - Constructor parameters should match referenced property and field names - Constructor parameters should match referenced property and field names + Constructor parameter names should match the bound property or field names + Constructor parameter names should match the bound property or field names 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 cfabe26715..2d757ca4f4 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.de.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.de.xlf @@ -193,8 +193,8 @@ - Constructor parameters should match referenced property and field names - Constructor parameters should match referenced property and field names + Constructor parameter names should match the bound property or field names + Constructor parameter names should match the bound property or field names 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 d012a9d4c5..45f1e3ce4d 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.es.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.es.xlf @@ -193,8 +193,8 @@ - Constructor parameters should match referenced property and field names - Constructor parameters should match referenced property and field names + Constructor parameter names should match the bound property or field names + Constructor parameter names should match the bound property or field names 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 9a86b7856d..4af12b7947 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.fr.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.fr.xlf @@ -193,8 +193,8 @@ - Constructor parameters should match referenced property and field names - Constructor parameters should match referenced property and field names + Constructor parameter names should match the bound property or field names + Constructor parameter names should match the bound property or field names 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 1979fde73f..893fbe79ee 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.it.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.it.xlf @@ -193,8 +193,8 @@ - Constructor parameters should match referenced property and field names - Constructor parameters should match referenced property and field names + Constructor parameter names should match the bound property or field names + Constructor parameter names should match the bound property or field names 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 a2d5fd06ce..86822bacac 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ja.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ja.xlf @@ -193,8 +193,8 @@ - Constructor parameters should match referenced property and field names - Constructor parameters should match referenced property and field names + Constructor parameter names should match the bound property or field names + Constructor parameter names should match the bound property or field names 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 156c9904d5..a2d8881e04 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ko.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ko.xlf @@ -193,8 +193,8 @@ - Constructor parameters should match referenced property and field names - Constructor parameters should match referenced property and field names + Constructor parameter names should match the bound property or field names + Constructor parameter names should match the bound property or field names 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 f1f531456f..e89d87aad6 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pl.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pl.xlf @@ -193,8 +193,8 @@ - Constructor parameters should match referenced property and field names - Constructor parameters should match referenced property and field names + Constructor parameter names should match the bound property or field names + Constructor parameter names should match the bound property or field names 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 cb47a7d23e..6872dc8645 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 @@ -193,8 +193,8 @@ - Constructor parameters should match referenced property and field names - Constructor parameters should match referenced property and field names + Constructor parameter names should match the bound property or field names + Constructor parameter names should match the bound property or field names 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 44d8fc7f7a..84d02c082a 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ru.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ru.xlf @@ -193,8 +193,8 @@ - Constructor parameters should match referenced property and field names - Constructor parameters should match referenced property and field names + Constructor parameter names should match the bound property or field names + Constructor parameter names should match the bound property or field names 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 7eedfb5024..e9b7bbc5c0 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.tr.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.tr.xlf @@ -193,8 +193,8 @@ - Constructor parameters should match referenced property and field names - Constructor parameters should match referenced property and field names + Constructor parameter names should match the bound property or field names + Constructor parameter names should match the bound property or field names 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 346c91122a..a0d5f1d97e 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 @@ -193,8 +193,8 @@ - Constructor parameters should match referenced property and field names - Constructor parameters should match referenced property and field names + Constructor parameter names should match the bound property or field names + Constructor parameter names should match the bound property or field names 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 4f89efa54d..a27c992125 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 @@ -193,8 +193,8 @@ - Constructor parameters should match referenced property and field names - Constructor parameters should match referenced property and field names + Constructor parameter names should match the bound property or field names + Constructor parameter names should match the bound property or field names diff --git a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md index b7fe878caf..ad32360608 100644 --- a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md +++ b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md @@ -576,7 +576,7 @@ Do not declare virtual events in a base class. Overridden events in a derived cl |CodeFix|False| --- -## [CA1071](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1071): Constructor parameters should match referenced property and field names +## [CA1071](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1071): Constructor parameter names should match the bound property or field names For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. diff --git a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif index 6e9878f4c2..ee3f282f4f 100644 --- a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif +++ b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif @@ -1348,7 +1348,7 @@ }, "CA1071": { "id": "CA1071", - "shortDescription": "Constructor parameters should match referenced property and field names", + "shortDescription": "Constructor parameter names should match the bound property or field names", "fullDescription": "For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization.", "defaultLevel": "warning", "helpUri": "https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1071", From 93c0429f220ab59103e7a2a19165b639bd8f6395 Mon Sep 17 00:00:00 2001 From: psxvoid Date: Fri, 26 Feb 2021 10:40:58 +0300 Subject: [PATCH 14/64] Use net50 references instead netstandard20 in tests --- .../ConstructorParametersShouldMatchPropertyNamesTests.cs | 6 +++--- src/Test.Utilities/AdditionalMetadataReferences.cs | 3 --- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyNamesTests.cs b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyNamesTests.cs index 97147960c9..f5d399ad5d 100644 --- a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyNamesTests.cs +++ b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyNamesTests.cs @@ -321,7 +321,7 @@ private static async Task VerifyCSharpAnalyzerAsync(string source, params Diagno { var csharpTest = new VerifyCS.Test { - ReferenceAssemblies = AdditionalMetadataReferences.DefaultWithSystemTextJson50, + ReferenceAssemblies = ReferenceAssemblies.Net.Net50, TestCode = source, }; @@ -335,7 +335,7 @@ private static async Task VerifyCSharp9AnalyzerAsync(string source, params Diagn var csharpTest = new VerifyCS.Test { LanguageVersion = LanguageVersion.CSharp9, - ReferenceAssemblies = AdditionalMetadataReferences.DefaultWithSystemTextJson50, + ReferenceAssemblies = ReferenceAssemblies.Net.Net50, TestCode = source, }; @@ -348,7 +348,7 @@ private static async Task VerifyBasicAnalyzerAsync(string source, params Diagnos { var basicTest = new VerifyVB.Test { - ReferenceAssemblies = AdditionalMetadataReferences.DefaultWithSystemTextJson50, + ReferenceAssemblies = ReferenceAssemblies.Net.Net50, TestCode = source, }; diff --git a/src/Test.Utilities/AdditionalMetadataReferences.cs b/src/Test.Utilities/AdditionalMetadataReferences.cs index 47c5102bdd..1cf2b61c34 100644 --- a/src/Test.Utilities/AdditionalMetadataReferences.cs +++ b/src/Test.Utilities/AdditionalMetadataReferences.cs @@ -37,9 +37,6 @@ public static class AdditionalMetadataReferences public static ReferenceAssemblies DefaultWithNewtonsoftJson12 { get; } = Default .AddPackages(ImmutableArray.Create(new PackageIdentity("Newtonsoft.Json", "12.0.1"))); - public static ReferenceAssemblies DefaultWithSystemTextJson50 { get; } = ReferenceAssemblies.NetStandard.NetStandard20 - .AddPackages(ImmutableArray.Create(new PackageIdentity("System.Text.Json", "5.0.1"))); - public static ReferenceAssemblies DefaultWithWinForms { get; } = ReferenceAssemblies.NetFramework.Net472.WindowsForms; public static ReferenceAssemblies DefaultWithWinHttpHandler { get; } = ReferenceAssemblies.NetStandard.NetStandard20 From 3efee13324389aa07b7da5087d4b81a87c332685 Mon Sep 17 00:00:00 2001 From: psxvoid Date: Fri, 26 Feb 2021 10:56:39 +0300 Subject: [PATCH 15/64] Replace IsJsonCtor extension-method with private method --- .../ConstructorParametersShouldMatchPropertyNames.cs | 6 +++++- .../Compiler/Extensions/IMethodSymbolExtensions.cs | 4 ---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyNames.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyNames.cs index 4e3a120793..fbc6ef2302 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyNames.cs +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyNames.cs @@ -173,6 +173,10 @@ private static bool IsParamMatchPropName(IParameterSymbol param, IPropertySymbol return paramWords.All(x => WordParser.ContainsWord(x, WordParserOptions.SplitCompoundWords, propWords)); } + private bool IsJsonConstructor([NotNullWhen(returnValue: true)] IMethodSymbol? method) + => method.IsConstructor() && + method.HasAttribute(this._jsonConstructorAttributeInfoType); + public bool ShouldAnalyzeMethod(IMethodSymbol method) { // We only care about constructors with parameters. @@ -182,7 +186,7 @@ public bool ShouldAnalyzeMethod(IMethodSymbol method) } // We only care about constructors that are marked with JsonConstructor attribute. - if (!method.IsJsonConstructor(_jsonConstructorAttributeInfoType)) + if (!this.IsJsonConstructor(method)) { return false; } diff --git a/src/Utilities/Compiler/Extensions/IMethodSymbolExtensions.cs b/src/Utilities/Compiler/Extensions/IMethodSymbolExtensions.cs index f1371c6ea6..320f1f03eb 100644 --- a/src/Utilities/Compiler/Extensions/IMethodSymbolExtensions.cs +++ b/src/Utilities/Compiler/Extensions/IMethodSymbolExtensions.cs @@ -384,10 +384,6 @@ public static bool IsSerializationConstructor([NotNullWhen(returnValue: true)] t method.Parameters[0].Type.Equals(serializationInfoType) && method.Parameters[1].Type.Equals(streamingContextType); - public static bool IsJsonConstructor([NotNullWhen(returnValue: true)] this IMethodSymbol? method, INamedTypeSymbol? jsonAttributeInfoType) - => method.IsConstructor() && - method.HasAttribute(jsonAttributeInfoType); - public static bool IsGetObjectData([NotNullWhen(returnValue: true)] this IMethodSymbol? method, INamedTypeSymbol? serializationInfoType, INamedTypeSymbol? streamingContextType) => method?.Name == "GetObjectData" && method.ReturnsVoid && From 2b491197c7a186f0a78fde27d3309bc085bde444 Mon Sep 17 00:00:00 2001 From: psxvoid Date: Fri, 26 Feb 2021 11:19:55 +0300 Subject: [PATCH 16/64] Rename the analyzer - add "field" in its name --- ...rParametersShouldMatchPropertyAndFieldNames.cs} | 2 +- .../Microsoft.CodeAnalysis.NetAnalyzers.sarif | 2 +- ...metersShouldMatchPropertyAndFieldNamesTests.cs} | 14 +++++++------- 3 files changed, 9 insertions(+), 9 deletions(-) rename src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/{ConstructorParametersShouldMatchPropertyNames.cs => ConstructorParametersShouldMatchPropertyAndFieldNames.cs} (99%) rename src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/{ConstructorParametersShouldMatchPropertyNamesTests.cs => ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs} (97%) diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyNames.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs similarity index 99% rename from src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyNames.cs rename to src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs index fbc6ef2302..8f70a1c643 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyNames.cs +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs @@ -15,7 +15,7 @@ namespace Microsoft.NetCore.Analyzers.Runtime /// CA1071: Constructor parameters should match property and field names /// [DiagnosticAnalyzer(LanguageNames.CSharp, LanguageNames.VisualBasic)] - public sealed class ConstructorParametersShouldMatchPropertyNamesAnalyzer : DiagnosticAnalyzer + public sealed class ConstructorParametersShouldMatchPropertyAndFieldNamesAnalyzer : DiagnosticAnalyzer { internal const string RuleId = "CA1071"; diff --git a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif index ee3f282f4f..2e683b6fb1 100644 --- a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif +++ b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif @@ -1355,7 +1355,7 @@ "properties": { "category": "Design", "isEnabledByDefault": true, - "typeName": "ConstructorParametersShouldMatchPropertyNamesAnalyzer", + "typeName": "ConstructorParametersShouldMatchPropertyAndFieldNamesAnalyzer", "languages": [ "C#", "Visual Basic" diff --git a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyNamesTests.cs b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs similarity index 97% rename from src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyNamesTests.cs rename to src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs index f5d399ad5d..d02be4a75d 100644 --- a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyNamesTests.cs +++ b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs @@ -6,15 +6,15 @@ using Test.Utilities; using Xunit; using VerifyCS = Test.Utilities.CSharpCodeFixVerifier< - Microsoft.NetCore.Analyzers.Runtime.ConstructorParametersShouldMatchPropertyNamesAnalyzer, + Microsoft.NetCore.Analyzers.Runtime.ConstructorParametersShouldMatchPropertyAndFieldNamesAnalyzer, Microsoft.CodeAnalysis.Testing.EmptyCodeFixProvider>; using VerifyVB = Test.Utilities.VisualBasicCodeFixVerifier< - Microsoft.NetCore.Analyzers.Runtime.ConstructorParametersShouldMatchPropertyNamesAnalyzer, + Microsoft.NetCore.Analyzers.Runtime.ConstructorParametersShouldMatchPropertyAndFieldNamesAnalyzer, Microsoft.CodeAnalysis.Testing.EmptyCodeFixProvider>; namespace Microsoft.NetCore.Analyzers.Runtime.UnitTests { - public class ConstructorParametersShouldMatchPropertyNamesTests + public class ConstructorParametersShouldMatchPropertyAndFieldNamesTests { [Fact] public async Task CA1071_ClassPropsDoNotMatch_ConstructorParametersShouldMatchPropertyNames_CSharp() @@ -359,27 +359,27 @@ private static async Task VerifyBasicAnalyzerAsync(string source, params Diagnos private DiagnosticResult CA1071CSharpPropertyResultAt(int line, int column, params string[] arguments) #pragma warning disable RS0030 // Do not used banned APIs - => VerifyCS.Diagnostic(ConstructorParametersShouldMatchPropertyNamesAnalyzer.PropertyRule) + => VerifyCS.Diagnostic(ConstructorParametersShouldMatchPropertyAndFieldNamesAnalyzer.PropertyRule) .WithLocation(line, column) #pragma warning restore RS0030 // Do not used banned APIs .WithArguments(arguments); private DiagnosticResult CA1071BasicPropertyResultAt(int line, int column, params string[] arguments) #pragma warning disable RS0030 // Do not used banned APIs - => VerifyVB.Diagnostic(ConstructorParametersShouldMatchPropertyNamesAnalyzer.PropertyRule) + => VerifyVB.Diagnostic(ConstructorParametersShouldMatchPropertyAndFieldNamesAnalyzer.PropertyRule) .WithLocation(line, column) #pragma warning restore RS0030 // Do not used banned APIs .WithArguments(arguments); private DiagnosticResult CA1071CSharpFieldResultAt(int line, int column, params string[] arguments) #pragma warning disable RS0030 // Do not used banned APIs - => VerifyCS.Diagnostic(ConstructorParametersShouldMatchPropertyNamesAnalyzer.FieldRule) + => VerifyCS.Diagnostic(ConstructorParametersShouldMatchPropertyAndFieldNamesAnalyzer.FieldRule) .WithLocation(line, column) #pragma warning restore RS0030 // Do not used banned APIs .WithArguments(arguments); private DiagnosticResult CA1071BasicFieldResultAt(int line, int column, params string[] arguments) #pragma warning disable RS0030 // Do not used banned APIs - => VerifyVB.Diagnostic(ConstructorParametersShouldMatchPropertyNamesAnalyzer.FieldRule) + => VerifyVB.Diagnostic(ConstructorParametersShouldMatchPropertyAndFieldNamesAnalyzer.FieldRule) .WithLocation(line, column) #pragma warning restore RS0030 // Do not used banned APIs .WithArguments(arguments); From c2051bfc4d8e9cf6a0225395f9608c673722292c Mon Sep 17 00:00:00 2001 From: psxvoid Date: Fri, 26 Feb 2021 11:23:26 +0300 Subject: [PATCH 17/64] Remove unused using in tests --- ...ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs index d02be4a75d..3d977fa52c 100644 --- a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs +++ b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs @@ -3,7 +3,6 @@ using System.Threading.Tasks; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.Testing; -using Test.Utilities; using Xunit; using VerifyCS = Test.Utilities.CSharpCodeFixVerifier< Microsoft.NetCore.Analyzers.Runtime.ConstructorParametersShouldMatchPropertyAndFieldNamesAnalyzer, From e9aa04107ac13c884f6eb1feec870f934d6da2dc Mon Sep 17 00:00:00 2001 From: psxvoid Date: Sat, 27 Feb 2021 13:39:53 +0300 Subject: [PATCH 18/64] Replace banned-API with non-banned in tests --- ...rsShouldMatchPropertyAndFieldNamesTests.cs | 80 ++++++++----------- 1 file changed, 32 insertions(+), 48 deletions(-) diff --git a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs index 3d977fa52c..2b089e4da4 100644 --- a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs +++ b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs @@ -28,14 +28,14 @@ public class C1 public object SecondProp { get; } [JsonConstructor] - public C1(int firstDrop, object secondDrop) + public C1(int {|#0:firstDrop|}, object {|#1:secondDrop|}) { this.FirstProp = firstDrop; this.SecondProp = secondDrop; } }", - CA1071CSharpPropertyResultAt(11, 35, "C1", "firstDrop", "FirstProp"), - CA1071CSharpPropertyResultAt(11, 53, "C1", "secondDrop", "SecondProp")); + CA1071CSharpPropertyResultAt(0, "C1", "firstDrop", "FirstProp"), + CA1071CSharpPropertyResultAt(1, "C1", "secondDrop", "SecondProp")); } [Fact] @@ -51,14 +51,14 @@ public record C1 public object SecondProp { get; } [JsonConstructor] - public C1(int firstDrop, object secondDrop) + public C1(int {|#0:firstDrop|}, object {|#1:secondDrop|}) { this.FirstProp = firstDrop; this.SecondProp = secondDrop; } }", - CA1071CSharpPropertyResultAt(11, 35, "C1", "firstDrop", "FirstProp"), - CA1071CSharpPropertyResultAt(11, 53, "C1", "secondDrop", "SecondProp")); + CA1071CSharpPropertyResultAt(0, "C1", "firstDrop", "FirstProp"), + CA1071CSharpPropertyResultAt(1, "C1", "secondDrop", "SecondProp")); } [Fact] @@ -72,21 +72,19 @@ Property FirstProp() As Integer Property SecondProp() as Object - Public Sub New(firstDrop as Integer, secondDrop as Object) + Public Sub New({|#0:firstDrop|} as Integer, {|#1:secondDrop|} as Object) Me.FirstProp = firstDrop Me.SecondProp = secondDrop End Sub End Class", - CA1071BasicPropertyResultAt(9, 36, "C1", "firstDrop", "FirstProp"), - CA1071BasicPropertyResultAt(9, 58, "C1", "secondDrop", "SecondProp")); + CA1071BasicPropertyResultAt(0, "C1", "firstDrop", "FirstProp"), + CA1071BasicPropertyResultAt(1, "C1", "secondDrop", "SecondProp")); } [Fact] public async Task CA1071_ClassPropsDoNotMatchNotJsonCtor_NoDiagnostics_CSharp() { await VerifyCSharpAnalyzerAsync(@" - using System.Text.Json.Serialization; - public class C1 { public int FirstProp { get; } @@ -105,8 +103,6 @@ public C1(int firstDrop, object secondDrop) public async Task CA1071_ClassPropsDoNotMatchNotJsonCtor_NoDiagnostics_Basic() { await VerifyBasicAnalyzerAsync(@" - Imports System.Text.Json.Serialization - Public Class C1 Property firstProp() As Integer Property secondProp() as Object @@ -122,8 +118,6 @@ End Sub public async Task CA1071_RecordPropsDoNotMatchNotJsonCtor_NoDiagnostics_CSharp() { await VerifyCSharp9AnalyzerAsync(@" - using System.Text.Json.Serialization; - public record C1 { public int FirstProp { get; } @@ -169,9 +163,10 @@ Public Class C1 Property firstProp() As Integer Property secondProp() as Object - Public Sub New(firstDrop as Integer, secondDrop as Object) - Me.firstProp = firstDrop - Me.secondProp = secondDrop + + Public Sub New(firstProp as Integer, secondProp as Object) + Me.firstProp = firstProp + Me.secondProp = secondProp End Sub End Class"); } @@ -188,14 +183,14 @@ public class C1 public object secondField; [JsonConstructor] - public C1(int firstIField, object secondIField) + public C1(int {|#0:firstIField|}, object {|#1:secondIField|}) { this.firstField = firstIField; this.secondField = secondIField; } }", - CA1071CSharpFieldResultAt(10, 35, "C1", "firstIField", "firstField"), - CA1071CSharpFieldResultAt(10, 55, "C1", "secondIField", "secondField")); + CA1071CSharpFieldResultAt(0, "C1", "firstIField", "firstField"), + CA1071CSharpFieldResultAt(1, "C1", "secondIField", "secondField")); } [Fact] @@ -209,13 +204,13 @@ Public firstField as Integer Public secondField as Object - Public Sub New(firstIField as Integer, secondIField as Object) + Public Sub New({|#0:firstIField|} as Integer, {|#1:secondIField|} as Object) Me.firstField = firstIField Me.secondField = secondIField End Sub End Class", - CA1071BasicFieldResultAt(9, 36, "C1", "firstIField", "firstField"), - CA1071BasicFieldResultAt(9, 60, "C1", "secondIField", "secondField")); + CA1071BasicFieldResultAt(0, "C1", "firstIField", "firstField"), + CA1071BasicFieldResultAt(1, "C1", "secondIField", "secondField")); } [Fact] @@ -231,22 +226,20 @@ public record C1 public object secondField; [JsonConstructor] - public C1(int firstIField, object secondIField) + public C1(int {|#0:firstIField|}, object {|#1:secondIField|}) { this.firstField = firstIField; this.secondField = secondIField; } }", - CA1071CSharpFieldResultAt(11, 35, "C1", "firstIField", "firstField"), - CA1071CSharpFieldResultAt(11, 55, "C1", "secondIField", "secondField")); + CA1071CSharpFieldResultAt(0, "C1", "firstIField", "firstField"), + CA1071CSharpFieldResultAt(1, "C1", "secondIField", "secondField")); } [Fact] public async Task CA1071_ClassFieldsDoNotMatchNotJsonCtor_NoDiagnostics_CSharp() { await VerifyCSharpAnalyzerAsync(@" - using System.Text.Json.Serialization; - public class C1 { public int firstField; @@ -264,8 +257,6 @@ public C1(int firstIField, object secondIField) public async Task CA1071_ClassFieldsDoNotMatchNotJsonCtor_NoDiagnostics_Basic() { await VerifyBasicAnalyzerAsync(@" - Imports System.Text.Json.Serialization - Public Class C1 Public firstField as Integer Public secondField as Object @@ -356,31 +347,24 @@ private static async Task VerifyBasicAnalyzerAsync(string source, params Diagnos await basicTest.RunAsync(); } - private DiagnosticResult CA1071CSharpPropertyResultAt(int line, int column, params string[] arguments) -#pragma warning disable RS0030 // Do not used banned APIs + private DiagnosticResult CA1071CSharpPropertyResultAt(int markupKey, params string[] arguments) => VerifyCS.Diagnostic(ConstructorParametersShouldMatchPropertyAndFieldNamesAnalyzer.PropertyRule) - .WithLocation(line, column) -#pragma warning restore RS0030 // Do not used banned APIs + .WithLocation(markupKey) .WithArguments(arguments); - private DiagnosticResult CA1071BasicPropertyResultAt(int line, int column, params string[] arguments) -#pragma warning disable RS0030 // Do not used banned APIs + private DiagnosticResult CA1071BasicPropertyResultAt(int markupKey, params string[] arguments) => VerifyVB.Diagnostic(ConstructorParametersShouldMatchPropertyAndFieldNamesAnalyzer.PropertyRule) - .WithLocation(line, column) -#pragma warning restore RS0030 // Do not used banned APIs + .WithLocation(markupKey) .WithArguments(arguments); - private DiagnosticResult CA1071CSharpFieldResultAt(int line, int column, params string[] arguments) -#pragma warning disable RS0030 // Do not used banned APIs + + private DiagnosticResult CA1071CSharpFieldResultAt(int markupKey, params string[] arguments) => VerifyCS.Diagnostic(ConstructorParametersShouldMatchPropertyAndFieldNamesAnalyzer.FieldRule) - .WithLocation(line, column) -#pragma warning restore RS0030 // Do not used banned APIs + .WithLocation(markupKey) .WithArguments(arguments); - private DiagnosticResult CA1071BasicFieldResultAt(int line, int column, params string[] arguments) -#pragma warning disable RS0030 // Do not used banned APIs + private DiagnosticResult CA1071BasicFieldResultAt(int markupKey, params string[] arguments) => VerifyVB.Diagnostic(ConstructorParametersShouldMatchPropertyAndFieldNamesAnalyzer.FieldRule) - .WithLocation(line, column) -#pragma warning restore RS0030 // Do not used banned APIs - .WithArguments(arguments); + .WithLocation(markupKey) + .WithArguments(arguments); } } \ No newline at end of file From 9579d93835c8dba5d73d4f5304c7110794642698 Mon Sep 17 00:00:00 2001 From: psxvoid Date: Sat, 27 Feb 2021 16:06:05 +0300 Subject: [PATCH 19/64] Add a code fix provider, partially tested with C# --- ...sShouldMatchPropertyAndFieldNames.Fixer.cs | 70 ++++++++++++ ...ametersShouldMatchPropertyAndFieldNames.cs | 9 ++ .../Microsoft.CodeAnalysis.NetAnalyzers.md | 2 +- ...ldMatchPropertyAndFieldNamesTests.Fixer.cs | 105 ++++++++++++++++++ 4 files changed, 185 insertions(+), 1 deletion(-) create mode 100644 src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.Fixer.cs create mode 100644 src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.Fixer.cs diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.Fixer.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.Fixer.cs new file mode 100644 index 0000000000..7d0dc4e134 --- /dev/null +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.Fixer.cs @@ -0,0 +1,70 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Collections.Immutable; +using System.Composition; +using System.Globalization; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CodeActions; +using Microsoft.CodeAnalysis.CodeFixes; +using Microsoft.CodeAnalysis.Rename; +using Microsoft.CodeQuality.Analyzers.ApiDesignGuidelines; + +namespace Microsoft.NetCore.Analyzers.Runtime +{ + /// + /// CA1071: Constructor parameters should match property and field names. + /// Based on . + /// + [ExportCodeFixProvider(LanguageNames.CSharp, LanguageNames.VisualBasic)] + [Shared] + public sealed class ConstructorParametersShouldMatchPropertyAndFieldNamesFixer : CodeFixProvider + { + public override ImmutableArray FixableDiagnosticIds => ImmutableArray.Create(ConstructorParametersShouldMatchPropertyAndFieldNamesAnalyzer.RuleId); + + public sealed override FixAllProvider GetFixAllProvider() + { + // See https://github.com/dotnet/roslyn/blob/master/docs/analyzers/FixAllProvider.md for more information on Fix All Providers + return WellKnownFixAllProviders.BatchFixer; + } + + public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) + { + SyntaxNode syntaxRoot = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false); + SemanticModel semanticModel = await context.Document.GetSemanticModelAsync(context.CancellationToken).ConfigureAwait(false); + + foreach (Diagnostic diagnostic in context.Diagnostics) + { + SyntaxNode node = syntaxRoot.FindNode(context.Span); + ISymbol declaredSymbol = semanticModel.GetDeclaredSymbol(node, context.CancellationToken); + + if (declaredSymbol.Kind != SymbolKind.Parameter) + { + continue; + } + + // This approach is very naive. Most likely we want to support NamingStyleOptions, available in Roslyn. + string newName = LowerFirstLetter(diagnostic.Properties[ConstructorParametersShouldMatchPropertyAndFieldNamesAnalyzer.ReferencedFieldOrPropertyName]); + + context.RegisterCodeFix( + CodeAction.Create( + string.Format(CultureInfo.CurrentCulture, MicrosoftNetCoreAnalyzersResources.ConstructorParametersShouldMatchPropertyNamesTitle, newName), + cancellationToken => GetUpdatedDocumentForParameterRenameAsync(context.Document, declaredSymbol, newName, cancellationToken), + nameof(ConstructorParametersShouldMatchPropertyAndFieldNamesFixer)), + diagnostic); + } + } + + private static string LowerFirstLetter(string targetName) + { + return $"{targetName[0].ToString().ToLower(CultureInfo.CurrentCulture)}{targetName[1..]}"; + } + + private static async Task GetUpdatedDocumentForParameterRenameAsync(Document document, ISymbol parameter, string newName, CancellationToken cancellationToken) + { + Solution newSolution = await Renamer.RenameSymbolAsync(document.Project.Solution, parameter, newName, null, cancellationToken).ConfigureAwait(false); + return newSolution.GetDocument(document.Id)!; + } + } +} \ No newline at end of file diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs index 8f70a1c643..53474f159c 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs @@ -18,6 +18,7 @@ namespace Microsoft.NetCore.Analyzers.Runtime public sealed class ConstructorParametersShouldMatchPropertyAndFieldNamesAnalyzer : DiagnosticAnalyzer { internal const string RuleId = "CA1071"; + internal const string ReferencedFieldOrPropertyName = "ReferencedMemberName"; private static readonly LocalizableString s_localizableTitle = new LocalizableResourceString(nameof(MicrosoftNetCoreAnalyzersResources.ConstructorParametersShouldMatchPropertyNamesTitle), MicrosoftNetCoreAnalyzersResources.ResourceManager, typeof(MicrosoftNetCoreAnalyzersResources)); @@ -118,19 +119,27 @@ public static void AnalyzeOperationAndReport(OperationAnalysisContext context) if (IsSupportedField(field) && !IsParamMatchFieldName(param, field)) { + var properties = ImmutableDictionary.Empty.SetItem(ReferencedFieldOrPropertyName, field.Name); + context.ReportDiagnostic( param.CreateDiagnostic( FieldRule, + properties, param.ContainingType.ToDisplayString(SymbolDisplayFormats.ShortSymbolDisplayFormat), param.Name, field.Name)); + + return; } if (IsSupportedProp(prop) && !IsParamMatchPropName(param, prop)) { + var properties = ImmutableDictionary.Empty.SetItem(ReferencedFieldOrPropertyName, prop.Name); + context.ReportDiagnostic( param.CreateDiagnostic( PropertyRule, + properties, param.ContainingType.ToDisplayString(SymbolDisplayFormats.ShortSymbolDisplayFormat), param.Name, prop.Name)); diff --git a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md index ad32360608..28455edca1 100644 --- a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md +++ b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md @@ -585,7 +585,7 @@ For a constructor having [JsonConstructor] attribute each parameter name must ma |Category|Design| |Enabled|True| |Severity|Warning| -|CodeFix|False| +|CodeFix|True| --- ## [CA1200](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1200): Avoid using cref tags with a prefix diff --git a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.Fixer.cs b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.Fixer.cs new file mode 100644 index 0000000000..f6b31c0dfc --- /dev/null +++ b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.Fixer.cs @@ -0,0 +1,105 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Threading.Tasks; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.Testing; +using Xunit; +using VerifyCS = Test.Utilities.CSharpCodeFixVerifier< + Microsoft.NetCore.Analyzers.Runtime.ConstructorParametersShouldMatchPropertyAndFieldNamesAnalyzer, + Microsoft.NetCore.Analyzers.Runtime.ConstructorParametersShouldMatchPropertyAndFieldNamesFixer>; +using VerifyVB = Test.Utilities.VisualBasicCodeFixVerifier< + Microsoft.NetCore.Analyzers.Runtime.ConstructorParametersShouldMatchPropertyAndFieldNamesAnalyzer, + Microsoft.NetCore.Analyzers.Runtime.ConstructorParametersShouldMatchPropertyAndFieldNamesFixer>; + +namespace Microsoft.NetCore.Analyzers.Runtime.UnitTests +{ + public class ConstructorParametersShouldMatchPropertyAndFieldNamesFixerTests + { + [Fact] + public async Task CA1071_ClassSinglePropDoesNotMatch_ConstructorParametersShouldMatchPropertyNames_CSharp() + { + await VerifyCSharpCodeFixAsync(@" + using System.Text.Json.Serialization; + + public class C1 + { + public int FirstProp { get; } + + public object SecondProp { get; } + + [JsonConstructor] + public C1(int [|firstDrop|], object secondProp) + { + this.FirstProp = firstDrop; + this.SecondProp = secondProp; + } + }", + @" + using System.Text.Json.Serialization; + + public class C1 + { + public int FirstProp { get; } + + public object SecondProp { get; } + + [JsonConstructor] + public C1(int firstProp, object secondProp) + { + this.FirstProp = firstProp; + this.SecondProp = secondProp; + } + }"); + } + + [Fact] + public async Task CA1071_ClassPropsDoNotMatch_ConstructorParametersShouldMatchPropertyNames_CSharp() + { + await VerifyCSharpCodeFixAsync(@" + using System.Text.Json.Serialization; + + public class C1 + { + public int FirstProp { get; } + + public object SecondProp { get; } + + [JsonConstructor] + public C1(int [|firstDrop|], object [|secondDrop|]) + { + this.FirstProp = firstDrop; + this.SecondProp = secondDrop; + } + }", + @" + using System.Text.Json.Serialization; + + public class C1 + { + public int FirstProp { get; } + + public object SecondProp { get; } + + [JsonConstructor] + public C1(int firstProp, object secondProp) + { + this.FirstProp = firstProp; + this.SecondProp = secondProp; + } + }"); + } + + private static async Task VerifyCSharpCodeFixAsync(string source, string expected) + { + var csharpTest = new VerifyCS.Test + { + ReferenceAssemblies = ReferenceAssemblies.Net.Net50, + TestCode = source, + FixedCode = expected, + MarkupOptions = MarkupOptions.UseFirstDescriptor + }; + + await csharpTest.RunAsync(); + } + } +} \ No newline at end of file From 5a625475e610b85c312c04588feda0d4104ccc51 Mon Sep 17 00:00:00 2001 From: psxvoid Date: Mon, 1 Mar 2021 11:04:04 +0300 Subject: [PATCH 20/64] [POC] Verify tuple assignment is working with CA1071 --- ...rsShouldMatchPropertyAndFieldNamesTests.cs | 59 ++++++++++++++++++- 1 file changed, 58 insertions(+), 1 deletion(-) diff --git a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs index 2b089e4da4..e2e907af39 100644 --- a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs +++ b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs @@ -153,6 +153,26 @@ public C1(int firstProp, object secondProp) }"); } + [Fact] + public async Task CA1071_ClassPropsMatchAndTupleAssignment_NoDiagnostics_CSharp() + { + await VerifyCSharpAnalyzerAsync(@" + using System.Text.Json.Serialization; + + public class C1 + { + public int FirstProp { get; } + + public object SecondProp { get; } + + [JsonConstructor] + public C1(int {|#0:firstProp|}, object {|#1:secondProp|}) + { + (this.FirstProp, this.SecondProp) = (firstProp, secondProp); + } + }"); + } + [Fact] public async Task CA1071_ClassPropsMatch_NoDiagnostics_Basic() { @@ -164,13 +184,30 @@ Property firstProp() As Integer Property secondProp() as Object - Public Sub New(firstProp as Integer, secondProp as Object) + Public Sub New({|#0:firstProp|} as Integer, {|#1:secondProp|} as Object) Me.firstProp = firstProp Me.secondProp = secondProp End Sub End Class"); } + [Fact(Skip = "Not sure if this syntax is possible in VB.")] + public async Task CA1071_ClassPropsMatchAndTupleAssignment_NoDiagnostics_Basic() + { + await VerifyBasicAnalyzerAsync(@" + Imports System.Text.Json.Serialization + + Public Class C1 + Property firstProp() As Integer + Property secondProp() as Object + + + Public Sub New({|#0:firstProp|} as Integer, {|#1:secondProp|} as Object) + new Tuple(As String, Object)(Me.firstProp, Me.secondProp) = new Tuple(As String, Object)(firstDrop, secondDrop) + End Sub + End Class"); + } + [Fact] public async Task CA1071_ClassFieldsDoNotMatch_ConstructorParametersShouldMatchFieldNames_CSharp() { @@ -289,6 +326,26 @@ public C1(int firstField, object secondField) ); } + [Fact] + public async Task CA1071_ClassFieldsMatchAndTupleAssignment_NoDiagnostics_CSharp() + { + await VerifyCSharpAnalyzerAsync(@" + using System.Text.Json.Serialization; + + public class C1 + { + public int firstField; + public object secondField; + + [JsonConstructor] + public C1(int {|#0:firstField|}, object {|#1:secondField|}) + { + (firstField, secondField) = (firstField, secondField); + } + }" + ); + } + [Fact] public async Task CA1071_ClassFieldsMatch_NoDiagnostics_Basic() { From 33dccddf0e628a0a498556a5723e6d86a30e1ff2 Mon Sep 17 00:00:00 2001 From: psxvoid Date: Mon, 1 Mar 2021 11:05:23 +0300 Subject: [PATCH 21/64] Revert "[POC] Verify tuple assignment is working with CA1071" This reverts commit 5a625475e610b85c312c04588feda0d4104ccc51. --- ...rsShouldMatchPropertyAndFieldNamesTests.cs | 59 +------------------ 1 file changed, 1 insertion(+), 58 deletions(-) diff --git a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs index e2e907af39..2b089e4da4 100644 --- a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs +++ b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs @@ -153,26 +153,6 @@ public C1(int firstProp, object secondProp) }"); } - [Fact] - public async Task CA1071_ClassPropsMatchAndTupleAssignment_NoDiagnostics_CSharp() - { - await VerifyCSharpAnalyzerAsync(@" - using System.Text.Json.Serialization; - - public class C1 - { - public int FirstProp { get; } - - public object SecondProp { get; } - - [JsonConstructor] - public C1(int {|#0:firstProp|}, object {|#1:secondProp|}) - { - (this.FirstProp, this.SecondProp) = (firstProp, secondProp); - } - }"); - } - [Fact] public async Task CA1071_ClassPropsMatch_NoDiagnostics_Basic() { @@ -184,30 +164,13 @@ Property firstProp() As Integer Property secondProp() as Object - Public Sub New({|#0:firstProp|} as Integer, {|#1:secondProp|} as Object) + Public Sub New(firstProp as Integer, secondProp as Object) Me.firstProp = firstProp Me.secondProp = secondProp End Sub End Class"); } - [Fact(Skip = "Not sure if this syntax is possible in VB.")] - public async Task CA1071_ClassPropsMatchAndTupleAssignment_NoDiagnostics_Basic() - { - await VerifyBasicAnalyzerAsync(@" - Imports System.Text.Json.Serialization - - Public Class C1 - Property firstProp() As Integer - Property secondProp() as Object - - - Public Sub New({|#0:firstProp|} as Integer, {|#1:secondProp|} as Object) - new Tuple(As String, Object)(Me.firstProp, Me.secondProp) = new Tuple(As String, Object)(firstDrop, secondDrop) - End Sub - End Class"); - } - [Fact] public async Task CA1071_ClassFieldsDoNotMatch_ConstructorParametersShouldMatchFieldNames_CSharp() { @@ -326,26 +289,6 @@ public C1(int firstField, object secondField) ); } - [Fact] - public async Task CA1071_ClassFieldsMatchAndTupleAssignment_NoDiagnostics_CSharp() - { - await VerifyCSharpAnalyzerAsync(@" - using System.Text.Json.Serialization; - - public class C1 - { - public int firstField; - public object secondField; - - [JsonConstructor] - public C1(int {|#0:firstField|}, object {|#1:secondField|}) - { - (firstField, secondField) = (firstField, secondField); - } - }" - ); - } - [Fact] public async Task CA1071_ClassFieldsMatch_NoDiagnostics_Basic() { From 57437ba3c3bc646b94dc6bb4df45a7a920c7e136 Mon Sep 17 00:00:00 2001 From: psxvoid Date: Mon, 1 Mar 2021 12:24:57 +0300 Subject: [PATCH 22/64] Add C# tests for classes with fields and props --- ...ldMatchPropertyAndFieldNamesTests.Fixer.cs | 79 ++++++++++++++++++- 1 file changed, 76 insertions(+), 3 deletions(-) diff --git a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.Fixer.cs b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.Fixer.cs index f6b31c0dfc..848858a5fe 100644 --- a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.Fixer.cs +++ b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.Fixer.cs @@ -1,7 +1,6 @@ // Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Threading.Tasks; -using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.Testing; using Xunit; using VerifyCS = Test.Utilities.CSharpCodeFixVerifier< @@ -16,7 +15,7 @@ namespace Microsoft.NetCore.Analyzers.Runtime.UnitTests public class ConstructorParametersShouldMatchPropertyAndFieldNamesFixerTests { [Fact] - public async Task CA1071_ClassSinglePropDoesNotMatch_ConstructorParametersShouldMatchPropertyNames_CSharp() + public async Task CA1071_ClassSinglePropDoesNotMatch_CSharp() { await VerifyCSharpCodeFixAsync(@" using System.Text.Json.Serialization; @@ -53,7 +52,7 @@ public C1(int firstProp, object secondProp) } [Fact] - public async Task CA1071_ClassPropsDoNotMatch_ConstructorParametersShouldMatchPropertyNames_CSharp() + public async Task CA1071_ClassPropsDoNotMatch_CSharp() { await VerifyCSharpCodeFixAsync(@" using System.Text.Json.Serialization; @@ -89,6 +88,80 @@ public C1(int firstProp, object secondProp) }"); } + [Fact] + public async Task CA1071_ClassSingleFieldDoesNotMatch_CSharp() + { + await VerifyCSharpCodeFixAsync(@" + using System.Text.Json.Serialization; + + public class C1 + { + public int firstField { get; } + + public object secondField { get; } + + [JsonConstructor] + public C1(int [|firstIField|], object secondField) + { + this.firstField = firstIField; + this.secondField = secondField; + } + }", + @" + using System.Text.Json.Serialization; + + public class C1 + { + public int firstField { get; } + + public object secondField { get; } + + [JsonConstructor] + public C1(int firstField, object secondField) + { + this.firstField = firstField; + this.secondField = secondField; + } + }"); + } + + [Fact] + public async Task CA1071_ClassFieldsDoNotMatch_CSharp() + { + await VerifyCSharpCodeFixAsync(@" + using System.Text.Json.Serialization; + + public class C1 + { + public int firstField { get; } + + public object secondField { get; } + + [JsonConstructor] + public C1(int [|firstIField|], object [|secondIField|]) + { + this.firstField = firstIField; + this.secondField = secondIField; + } + }", + @" + using System.Text.Json.Serialization; + + public class C1 + { + public int firstField { get; } + + public object secondField { get; } + + [JsonConstructor] + public C1(int firstField, object secondField) + { + this.firstField = firstField; + this.secondField = secondField; + } + }"); + } + private static async Task VerifyCSharpCodeFixAsync(string source, string expected) { var csharpTest = new VerifyCS.Test From 727423b378e95bad8907b2ec76130d5287beae7a Mon Sep 17 00:00:00 2001 From: psxvoid Date: Mon, 1 Mar 2021 13:44:09 +0300 Subject: [PATCH 23/64] Add VB tests for classes with fields and props --- ...ldMatchPropertyAndFieldNamesTests.Fixer.cs | 137 ++++++++++++++++++ 1 file changed, 137 insertions(+) diff --git a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.Fixer.cs b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.Fixer.cs index 848858a5fe..af101c1596 100644 --- a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.Fixer.cs +++ b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.Fixer.cs @@ -51,6 +51,37 @@ public C1(int firstProp, object secondProp) }"); } + [Fact] + public async Task CA1071_ClassSinglePropDoesNotMatch_Basic() + { + await VerifyBasicCodeFixAsync(@" + Imports System.Text.Json.Serialization + + Public Class C1 + Property FirstProp() As Integer + Property SecondProp() as Object + + + Public Sub New([|firstDrop|] as Integer, secondProp as Object) + Me.FirstProp = firstDrop + Me.SecondProp = secondProp + End Sub + End Class", + @" + Imports System.Text.Json.Serialization + + Public Class C1 + Property FirstProp() As Integer + Property SecondProp() as Object + + + Public Sub New(firstProp as Integer, secondProp as Object) + Me.FirstProp = firstProp + Me.SecondProp = secondProp + End Sub + End Class"); + } + [Fact] public async Task CA1071_ClassPropsDoNotMatch_CSharp() { @@ -88,6 +119,37 @@ public C1(int firstProp, object secondProp) }"); } + [Fact] + public async Task CA1071_ClassPropsDoNotMatch_Basic() + { + await VerifyBasicCodeFixAsync(@" + Imports System.Text.Json.Serialization + + Public Class C1 + Property FirstProp() As Integer + Property SecondProp() as Object + + + Public Sub New([|firstDrop|] as Integer, [|secondDrop|] as Object) + Me.FirstProp = firstDrop + Me.SecondProp = secondDrop + End Sub + End Class", + @" + Imports System.Text.Json.Serialization + + Public Class C1 + Property FirstProp() As Integer + Property SecondProp() as Object + + + Public Sub New(firstProp as Integer, secondProp as Object) + Me.FirstProp = firstProp + Me.SecondProp = secondProp + End Sub + End Class"); + } + [Fact] public async Task CA1071_ClassSingleFieldDoesNotMatch_CSharp() { @@ -125,6 +187,37 @@ public C1(int firstField, object secondField) }"); } + [Fact] + public async Task CA1071_ClassSingleFieldDoesNotMatch_Basic() + { + await VerifyBasicCodeFixAsync(@" + Imports System.Text.Json.Serialization + + Public Class C1 + Public firstField As Integer + Public secondField as Object + + + Public Sub New([|firstIField|] as Integer, secondField as Object) + Me.firstField = firstIField + Me.secondField = secondField + End Sub + End Class", + @" + Imports System.Text.Json.Serialization + + Public Class C1 + Public firstField As Integer + Public secondField as Object + + + Public Sub New(firstField as Integer, secondField as Object) + Me.firstField = firstField + Me.secondField = secondField + End Sub + End Class"); + } + [Fact] public async Task CA1071_ClassFieldsDoNotMatch_CSharp() { @@ -162,6 +255,37 @@ public C1(int firstField, object secondField) }"); } + [Fact] + public async Task CA1071_ClassFieldsDoNotMatch_Basic() + { + await VerifyBasicCodeFixAsync(@" + Imports System.Text.Json.Serialization + + Public Class C1 + Public firstField As Integer + Public secondField as Object + + + Public Sub New([|firstIField|] as Integer, [|secondIField|] as Object) + Me.firstField = firstIField + Me.secondField = secondIField + End Sub + End Class", + @" + Imports System.Text.Json.Serialization + + Public Class C1 + Public firstField As Integer + Public secondField as Object + + + Public Sub New(firstField as Integer, secondField as Object) + Me.firstField = firstField + Me.secondField = secondField + End Sub + End Class"); + } + private static async Task VerifyCSharpCodeFixAsync(string source, string expected) { var csharpTest = new VerifyCS.Test @@ -174,5 +298,18 @@ private static async Task VerifyCSharpCodeFixAsync(string source, string expecte await csharpTest.RunAsync(); } + + private static async Task VerifyBasicCodeFixAsync(string source, string expected) + { + var basicTest = new VerifyVB.Test + { + ReferenceAssemblies = ReferenceAssemblies.Net.Net50, + TestCode = source, + FixedCode = expected, + MarkupOptions = MarkupOptions.UseFirstDescriptor + }; + + await basicTest.RunAsync(); + } } } \ No newline at end of file From 6c83c6e5debf8468dfc91aea16ca174f413b5b15 Mon Sep 17 00:00:00 2001 From: psxvoid Date: Wed, 3 Mar 2021 14:02:46 +0300 Subject: [PATCH 24/64] The analyzer - ensure bound properties are public --- .../MicrosoftNetCoreAnalyzersResources.resx | 6 ++ ...ametersShouldMatchPropertyAndFieldNames.cs | 57 +++++++++++++++---- .../MicrosoftNetCoreAnalyzersResources.cs.xlf | 10 ++++ .../MicrosoftNetCoreAnalyzersResources.de.xlf | 10 ++++ .../MicrosoftNetCoreAnalyzersResources.es.xlf | 10 ++++ .../MicrosoftNetCoreAnalyzersResources.fr.xlf | 10 ++++ .../MicrosoftNetCoreAnalyzersResources.it.xlf | 10 ++++ .../MicrosoftNetCoreAnalyzersResources.ja.xlf | 10 ++++ .../MicrosoftNetCoreAnalyzersResources.ko.xlf | 10 ++++ .../MicrosoftNetCoreAnalyzersResources.pl.xlf | 10 ++++ ...crosoftNetCoreAnalyzersResources.pt-BR.xlf | 10 ++++ .../MicrosoftNetCoreAnalyzersResources.ru.xlf | 10 ++++ .../MicrosoftNetCoreAnalyzersResources.tr.xlf | 10 ++++ ...osoftNetCoreAnalyzersResources.zh-Hans.xlf | 10 ++++ ...osoftNetCoreAnalyzersResources.zh-Hant.xlf | 10 ++++ ...rsShouldMatchPropertyAndFieldNamesTests.cs | 57 ++++++++++++++++++- 16 files changed, 236 insertions(+), 14 deletions(-) diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx index a7b176e8e0..4c6433a542 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx @@ -1525,9 +1525,15 @@ For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' + + For proper deserialization, change the visibility of the bound property '{2}' to public + For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. + + For a constructor having [JsonConstructor] attribute each parameter must be bound to a public property for proper deserialization. + Constructor parameter names should match the bound property or field names diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs index 53474f159c..3cbfe22e4e 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs @@ -18,7 +18,8 @@ namespace Microsoft.NetCore.Analyzers.Runtime public sealed class ConstructorParametersShouldMatchPropertyAndFieldNamesAnalyzer : DiagnosticAnalyzer { internal const string RuleId = "CA1071"; - internal const string ReferencedFieldOrPropertyName = "ReferencedMemberName"; + internal const string ReferencedFieldOrPropertyName = "ReferencedFieldOrPropertyName"; + internal const string DiagnosticReason = "DiagnosticReason"; private static readonly LocalizableString s_localizableTitle = new LocalizableResourceString(nameof(MicrosoftNetCoreAnalyzersResources.ConstructorParametersShouldMatchPropertyNamesTitle), MicrosoftNetCoreAnalyzersResources.ResourceManager, typeof(MicrosoftNetCoreAnalyzersResources)); @@ -26,7 +27,10 @@ public sealed class ConstructorParametersShouldMatchPropertyAndFieldNamesAnalyze private static readonly LocalizableString s_localizableMessageField = new LocalizableResourceString(nameof(MicrosoftNetCoreAnalyzersResources.ConstructorParameterShouldMatchFieldName), MicrosoftNetCoreAnalyzersResources.ResourceManager, typeof(MicrosoftNetCoreAnalyzersResources)); private static readonly LocalizableString s_localizableDescription = new LocalizableResourceString(nameof(MicrosoftNetCoreAnalyzersResources.ConstructorParametersShouldMatchPropertyNamesDescription), MicrosoftNetCoreAnalyzersResources.ResourceManager, typeof(MicrosoftNetCoreAnalyzersResources)); - internal static DiagnosticDescriptor PropertyRule = DiagnosticDescriptorHelper.Create(RuleId, + private static readonly LocalizableString s_localizableMessagePropertyPublic = new LocalizableResourceString(nameof(MicrosoftNetCoreAnalyzersResources.ConstructorParameterShouldMatchPropertyWithPublicVisibility), MicrosoftNetCoreAnalyzersResources.ResourceManager, typeof(MicrosoftNetCoreAnalyzersResources)); + private static readonly LocalizableString s_localizableDescriptionPropertyPublic = new LocalizableResourceString(nameof(MicrosoftNetCoreAnalyzersResources.ConstructorParametersShouldMatchPropertyWithPublicVisibilityDescription), MicrosoftNetCoreAnalyzersResources.ResourceManager, typeof(MicrosoftNetCoreAnalyzersResources)); + + internal static DiagnosticDescriptor PropertyNameRule = DiagnosticDescriptorHelper.Create(RuleId, s_localizableTitle, s_localizableMessageProperty, DiagnosticCategory.Design, @@ -34,6 +38,14 @@ public sealed class ConstructorParametersShouldMatchPropertyAndFieldNamesAnalyze description: s_localizableDescription, isPortedFxCopRule: false, isDataflowRule: false); + internal static DiagnosticDescriptor PropertyPublicRule = DiagnosticDescriptorHelper.Create(RuleId, + s_localizableTitle, + s_localizableMessagePropertyPublic, + DiagnosticCategory.Design, + RuleLevel.BuildWarning, + description: s_localizableDescriptionPropertyPublic, + isPortedFxCopRule: false, + isDataflowRule: false); internal static DiagnosticDescriptor FieldRule = DiagnosticDescriptorHelper.Create(RuleId, s_localizableTitle, s_localizableMessageField, @@ -43,7 +55,7 @@ public sealed class ConstructorParametersShouldMatchPropertyAndFieldNamesAnalyze isPortedFxCopRule: false, isDataflowRule: false); - public override ImmutableArray SupportedDiagnostics => ImmutableArray.Create(PropertyRule, FieldRule); + public override ImmutableArray SupportedDiagnostics => ImmutableArray.Create(PropertyNameRule, FieldRule); public override void Initialize(AnalysisContext context) { @@ -77,6 +89,12 @@ public override void Initialize(AnalysisContext context) }); } + internal enum ParameterDiagnosticReason + { + NameMismatch, + PropertyInappropriateVisibility + } + private sealed class ParameterAnalyzer { private readonly INamedTypeSymbol _jsonConstructorAttributeInfoType; @@ -132,17 +150,17 @@ public static void AnalyzeOperationAndReport(OperationAnalysisContext context) return; } - if (IsSupportedProp(prop) && !IsParamMatchPropName(param, prop)) + if (IsSupportedProp(prop)) { - var properties = ImmutableDictionary.Empty.SetItem(ReferencedFieldOrPropertyName, prop.Name); + if (!IsParamMatchPropName(param, prop)) + { + ReportPropertyDiagnostic(context, PropertyNameRule, ParameterDiagnosticReason.NameMismatch, param, prop); + } - context.ReportDiagnostic( - param.CreateDiagnostic( - PropertyRule, - properties, - param.ContainingType.ToDisplayString(SymbolDisplayFormats.ShortSymbolDisplayFormat), - param.Name, - prop.Name)); + if (!prop.IsPublic()) + { + ReportPropertyDiagnostic(context, PropertyPublicRule, ParameterDiagnosticReason.PropertyInappropriateVisibility, param, prop); + } } } @@ -202,6 +220,21 @@ public bool ShouldAnalyzeMethod(IMethodSymbol method) return true; } + + private static void ReportPropertyDiagnostic(OperationAnalysisContext context, DiagnosticDescriptor diagnosticDescriptor, ParameterDiagnosticReason reason, IParameterSymbol param, IPropertySymbol prop) + { + var properties = ImmutableDictionary.Empty + .SetItem(ReferencedFieldOrPropertyName, prop.Name) + .SetItem(DiagnosticReason, reason.ToString()); + + context.ReportDiagnostic( + param.CreateDiagnostic( + diagnosticDescriptor, + properties, + param.ContainingType.ToDisplayString(SymbolDisplayFormats.ShortSymbolDisplayFormat), + param.Name, + prop.Name)); + } } } } \ 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 84b2ee67e5..92d4beed19 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.cs.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.cs.xlf @@ -187,6 +187,11 @@ For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' + + For proper deserialization, change the visibility of the bound property '{2}' to public + For proper deserialization, change the visibility of the bound property '{2}' to public + + For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. @@ -197,6 +202,11 @@ Constructor parameter names should match the bound property or field names + + For a constructor having [JsonConstructor] attribute each parameter must be bound to a public property for proper deserialization. + For a constructor having [JsonConstructor] attribute each parameter must be bound to a public property for proper deserialization. + + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0} Při deserializaci nedůvěryhodného vstupu není deserializace objektu {0} bezpečná. Objekt {1} je buď objektem {0}, nebo je z tohoto objektu odvozený. 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 2d757ca4f4..30a415a15b 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.de.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.de.xlf @@ -187,6 +187,11 @@ For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' + + For proper deserialization, change the visibility of the bound property '{2}' to public + For proper deserialization, change the visibility of the bound property '{2}' to public + + For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. @@ -197,6 +202,11 @@ Constructor parameter names should match the bound property or field names + + For a constructor having [JsonConstructor] attribute each parameter must be bound to a public property for proper deserialization. + For a constructor having [JsonConstructor] attribute each parameter must be bound to a public property for proper deserialization. + + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0} Beim Deserialisieren einer nicht vertrauenswürdigen Eingabe ist die Deserialisierung eines {0}-Objekts unsicher. "{1}" ist entweder "{0}" oder davon abgeleitet. 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 45f1e3ce4d..f52e5ac872 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.es.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.es.xlf @@ -187,6 +187,11 @@ For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' + + For proper deserialization, change the visibility of the bound property '{2}' to public + For proper deserialization, change the visibility of the bound property '{2}' to public + + For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. @@ -197,6 +202,11 @@ Constructor parameter names should match the bound property or field names + + For a constructor having [JsonConstructor] attribute each parameter must be bound to a public property for proper deserialization. + For a constructor having [JsonConstructor] attribute each parameter must be bound to a public property for proper deserialization. + + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0} Cuando se deserializa una entrada que no es de confianza, no es segura la deserialización de un objeto {0}. "{1}" es {0} o se deriva de este. 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 4af12b7947..7fb5cfe31b 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.fr.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.fr.xlf @@ -187,6 +187,11 @@ For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' + + For proper deserialization, change the visibility of the bound property '{2}' to public + For proper deserialization, change the visibility of the bound property '{2}' to public + + For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. @@ -197,6 +202,11 @@ Constructor parameter names should match the bound property or field names + + For a constructor having [JsonConstructor] attribute each parameter must be bound to a public property for proper deserialization. + For a constructor having [JsonConstructor] attribute each parameter must be bound to a public property for proper deserialization. + + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0} Quand vous désérialisez une entrée non fiable, la désérialisation d'un objet {0} n'est pas une action sécurisée. '{1}' est égal à ou dérive de {0} 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 893fbe79ee..c88c8f3cdf 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.it.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.it.xlf @@ -187,6 +187,11 @@ For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' + + For proper deserialization, change the visibility of the bound property '{2}' to public + For proper deserialization, change the visibility of the bound property '{2}' to public + + For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. @@ -197,6 +202,11 @@ Constructor parameter names should match the bound property or field names + + For a constructor having [JsonConstructor] attribute each parameter must be bound to a public property for proper deserialization. + For a constructor having [JsonConstructor] attribute each parameter must be bound to a public property for proper deserialization. + + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0} Quando si deserializza input non attendibile, la deserializzazione di un oggetto {0} non è sicura. '{1}' è {0} o deriva da esso 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 86822bacac..b3ab4f6db6 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ja.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ja.xlf @@ -187,6 +187,11 @@ For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' + + For proper deserialization, change the visibility of the bound property '{2}' to public + For proper deserialization, change the visibility of the bound property '{2}' to public + + For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. @@ -197,6 +202,11 @@ Constructor parameter names should match the bound property or field names + + For a constructor having [JsonConstructor] attribute each parameter must be bound to a public property for proper deserialization. + For a constructor having [JsonConstructor] attribute each parameter must be bound to a public property for proper deserialization. + + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0} 信頼されていない入力を逆シリアル化する場合、{0} オブジェクトの逆シリアル化は安全ではありません。'{1}' は {0} であるか、それから派生しています 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 a2d8881e04..be11e5fc13 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ko.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ko.xlf @@ -187,6 +187,11 @@ For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' + + For proper deserialization, change the visibility of the bound property '{2}' to public + For proper deserialization, change the visibility of the bound property '{2}' to public + + For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. @@ -197,6 +202,11 @@ Constructor parameter names should match the bound property or field names + + For a constructor having [JsonConstructor] attribute each parameter must be bound to a public property for proper deserialization. + For a constructor having [JsonConstructor] attribute each parameter must be bound to a public property for proper deserialization. + + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0} 신뢰할 수 없는 입력을 역직렬화하는 경우 {0} 개체를 역직렬화하는 것은 안전하지 않습니다. '{1}'은(는) {0}이거나 이 항목에서 파생됩니다. 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 e89d87aad6..a15a30455d 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pl.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pl.xlf @@ -187,6 +187,11 @@ For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' + + For proper deserialization, change the visibility of the bound property '{2}' to public + For proper deserialization, change the visibility of the bound property '{2}' to public + + For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. @@ -197,6 +202,11 @@ Constructor parameter names should match the bound property or field names + + For a constructor having [JsonConstructor] attribute each parameter must be bound to a public property for proper deserialization. + For a constructor having [JsonConstructor] attribute each parameter must be bound to a public property for proper deserialization. + + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0} Deserializowanie obiektu {0} podczas deserializacji niezaufanych danych wejściowych nie jest bezpieczne. Element „{1}” jest elementem {0} lub pochodzi od niego 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 6872dc8645..4355752437 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 @@ -187,6 +187,11 @@ For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' + + For proper deserialization, change the visibility of the bound property '{2}' to public + For proper deserialization, change the visibility of the bound property '{2}' to public + + For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. @@ -197,6 +202,11 @@ Constructor parameter names should match the bound property or field names + + For a constructor having [JsonConstructor] attribute each parameter must be bound to a public property for proper deserialization. + For a constructor having [JsonConstructor] attribute each parameter must be bound to a public property for proper deserialization. + + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0} Ao desserializar uma entrada não confiável, a desserialização de um objeto {0} não é segura. '{1}' é {0} ou deriva-se dele 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 84d02c082a..f75c24cd6b 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ru.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ru.xlf @@ -187,6 +187,11 @@ For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' + + For proper deserialization, change the visibility of the bound property '{2}' to public + For proper deserialization, change the visibility of the bound property '{2}' to public + + For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. @@ -197,6 +202,11 @@ Constructor parameter names should match the bound property or field names + + For a constructor having [JsonConstructor] attribute each parameter must be bound to a public property for proper deserialization. + For a constructor having [JsonConstructor] attribute each parameter must be bound to a public property for proper deserialization. + + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0} При десериализации недоверенных входных данных десериализация объекта {0} является небезопасной. Объект "{1}" является объектом {0} или производным от него объектом. 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 e9b7bbc5c0..7130ea8c6e 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.tr.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.tr.xlf @@ -187,6 +187,11 @@ For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' + + For proper deserialization, change the visibility of the bound property '{2}' to public + For proper deserialization, change the visibility of the bound property '{2}' to public + + For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. @@ -197,6 +202,11 @@ Constructor parameter names should match the bound property or field names + + For a constructor having [JsonConstructor] attribute each parameter must be bound to a public property for proper deserialization. + For a constructor having [JsonConstructor] attribute each parameter must be bound to a public property for proper deserialization. + + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0} Güvenilmeyen giriş seri durumdan çıkarılırken, {0} nesnesinin seri durumdan çıkarılması güvenli değildir. '{1}', {0} nesnesidir veya bu nesneden türetilmiştir 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 a0d5f1d97e..d1e88b2d7a 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 @@ -187,6 +187,11 @@ For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' + + For proper deserialization, change the visibility of the bound property '{2}' to public + For proper deserialization, change the visibility of the bound property '{2}' to public + + For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. @@ -197,6 +202,11 @@ Constructor parameter names should match the bound property or field names + + For a constructor having [JsonConstructor] attribute each parameter must be bound to a public property for proper deserialization. + For a constructor having [JsonConstructor] attribute each parameter must be bound to a public property for proper deserialization. + + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0} 对不受信任的输入进行反序列化处理时,反序列化 {0} 对象是不安全的。“{1}”是或派生自 {0} 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 a27c992125..bf324567ac 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 @@ -187,6 +187,11 @@ For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' + + For proper deserialization, change the visibility of the bound property '{2}' to public + For proper deserialization, change the visibility of the bound property '{2}' to public + + For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. @@ -197,6 +202,11 @@ Constructor parameter names should match the bound property or field names + + For a constructor having [JsonConstructor] attribute each parameter must be bound to a public property for proper deserialization. + For a constructor having [JsonConstructor] attribute each parameter must be bound to a public property for proper deserialization. + + When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0} 還原序列化不受信任的輸入時,將 {0} 物件還原序列化並不安全。'{1}' 屬於或衍生自 {0} diff --git a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs index 2b089e4da4..20a66eaa6d 100644 --- a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs +++ b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs @@ -171,6 +171,49 @@ End Sub End Class"); } + [Fact] + public async Task CA1071_ClassPropsMatchButPrivate_ConstructorParametersShouldMatchFieldNames_CSharp() + { + await VerifyCSharpAnalyzerAsync(@" + using System.Text.Json.Serialization; + + public class C1 + { + private int FirstProp { get; } + + private object SecondProp { get; } + + [JsonConstructor] + public C1(int {|#0:firstProp|}, object {|#1:secondProp|}) + { + this.FirstProp = firstProp; + this.SecondProp = secondProp; + } + }", + CA1071CSharpPublicPropertyResultAt(0, "C1", "firstProp", "FirstProp"), + CA1071CSharpPublicPropertyResultAt(1, "C1", "secondProp", "SecondProp")); + } + + [Fact] + public async Task CA1071_ClassPropsMatchButPrivate_ConstructorParametersShouldMatchFieldNames_Basic() + { + await VerifyBasicAnalyzerAsync(@" + Imports System.Text.Json.Serialization + + Public Class C1 + Private Property FirstProp() As Integer + Private Property SecondProp() as Object + + + Public Sub New({|#0:firstProp|} as Integer, {|#1:secondProp|} as Object) + Me.FirstProp = firstProp + Me.SecondProp = secondProp + End Sub + End Class", + CA1071BasicPublicPropertyResultAt(0, "C1", "firstProp", "FirstProp"), + CA1071BasicPublicPropertyResultAt(1, "C1", "secondProp", "SecondProp")); + } + [Fact] public async Task CA1071_ClassFieldsDoNotMatch_ConstructorParametersShouldMatchFieldNames_CSharp() { @@ -348,12 +391,22 @@ private static async Task VerifyBasicAnalyzerAsync(string source, params Diagnos } private DiagnosticResult CA1071CSharpPropertyResultAt(int markupKey, params string[] arguments) - => VerifyCS.Diagnostic(ConstructorParametersShouldMatchPropertyAndFieldNamesAnalyzer.PropertyRule) + => VerifyCS.Diagnostic(ConstructorParametersShouldMatchPropertyAndFieldNamesAnalyzer.PropertyNameRule) .WithLocation(markupKey) .WithArguments(arguments); private DiagnosticResult CA1071BasicPropertyResultAt(int markupKey, params string[] arguments) - => VerifyVB.Diagnostic(ConstructorParametersShouldMatchPropertyAndFieldNamesAnalyzer.PropertyRule) + => VerifyVB.Diagnostic(ConstructorParametersShouldMatchPropertyAndFieldNamesAnalyzer.PropertyNameRule) + .WithLocation(markupKey) + .WithArguments(arguments); + + private DiagnosticResult CA1071CSharpPublicPropertyResultAt(int markupKey, params string[] arguments) + => VerifyCS.Diagnostic(ConstructorParametersShouldMatchPropertyAndFieldNamesAnalyzer.PropertyPublicRule) + .WithLocation(markupKey) + .WithArguments(arguments); + + private DiagnosticResult CA1071BasicPublicPropertyResultAt(int markupKey, params string[] arguments) + => VerifyVB.Diagnostic(ConstructorParametersShouldMatchPropertyAndFieldNamesAnalyzer.PropertyPublicRule) .WithLocation(markupKey) .WithArguments(arguments); From 2482c4c0d4112abf95e9ee0816c8c8e418acea1e Mon Sep 17 00:00:00 2001 From: psxvoid Date: Wed, 3 Mar 2021 14:41:01 +0300 Subject: [PATCH 25/64] Fix minor dis-alignment in tests --- ...structorParametersShouldMatchPropertyAndFieldNamesTests.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs index 20a66eaa6d..e52b7f4bbe 100644 --- a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs +++ b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs @@ -398,7 +398,7 @@ private DiagnosticResult CA1071CSharpPropertyResultAt(int markupKey, params stri private DiagnosticResult CA1071BasicPropertyResultAt(int markupKey, params string[] arguments) => VerifyVB.Diagnostic(ConstructorParametersShouldMatchPropertyAndFieldNamesAnalyzer.PropertyNameRule) .WithLocation(markupKey) - .WithArguments(arguments); + .WithArguments(arguments); private DiagnosticResult CA1071CSharpPublicPropertyResultAt(int markupKey, params string[] arguments) => VerifyCS.Diagnostic(ConstructorParametersShouldMatchPropertyAndFieldNamesAnalyzer.PropertyPublicRule) @@ -408,7 +408,7 @@ private DiagnosticResult CA1071CSharpPublicPropertyResultAt(int markupKey, param private DiagnosticResult CA1071BasicPublicPropertyResultAt(int markupKey, params string[] arguments) => VerifyVB.Diagnostic(ConstructorParametersShouldMatchPropertyAndFieldNamesAnalyzer.PropertyPublicRule) .WithLocation(markupKey) - .WithArguments(arguments); + .WithArguments(arguments); private DiagnosticResult CA1071CSharpFieldResultAt(int markupKey, params string[] arguments) => VerifyCS.Diagnostic(ConstructorParametersShouldMatchPropertyAndFieldNamesAnalyzer.FieldRule) From d4bec8bff37de06150959044ed338b113e25130e Mon Sep 17 00:00:00 2001 From: psxvoid Date: Thu, 4 Mar 2021 11:23:53 +0300 Subject: [PATCH 26/64] Fix tuple assignment reference not detected --- ...ametersShouldMatchPropertyAndFieldNames.cs | 45 ++++++++++++++++++- ...rsShouldMatchPropertyAndFieldNamesTests.cs | 43 ++++++++++++++++++ 2 files changed, 86 insertions(+), 2 deletions(-) diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs index 3cbfe22e4e..a12c9db6d0 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs @@ -108,13 +108,26 @@ public static void AnalyzeOperationAndReport(OperationAnalysisContext context) { var operation = (IParameterReferenceOperation)context.Operation; + IOperation memberReferenceOperation; + if (operation.Parent is not IAssignmentOperation assignment) { - return; + var memberReference = TryGetMemberReferenceOperation(operation); + + if (memberReference == null) + { + return; + } + + memberReferenceOperation = memberReference; + } + else + { + memberReferenceOperation = assignment.Target; } IParameterSymbol param = operation.Parameter; - ISymbol? referencedSymbol = assignment.Target.GetReferencedMemberOrLocalOrParameter(); + ISymbol? referencedSymbol = memberReferenceOperation.GetReferencedMemberOrLocalOrParameter(); if (referencedSymbol == null) { @@ -186,6 +199,11 @@ private static bool IsSupportedField([NotNullWhen(true)] IFieldSymbol? field) private static bool IsParamMatchFieldName(IParameterSymbol param, IFieldSymbol field) { + if (param.Name.Length != field.Name.Length) + { + return false; + } + var paramWords = WordParser.Parse(param.Name, WordParserOptions.SplitCompoundWords); var fieldWords = WordParser.Parse(field.Name, WordParserOptions.SplitCompoundWords).ToImmutableArray(); @@ -194,6 +212,11 @@ private static bool IsParamMatchFieldName(IParameterSymbol param, IFieldSymbol f private static bool IsParamMatchPropName(IParameterSymbol param, IPropertySymbol prop) { + if (param.Name.Length != prop.Name.Length) + { + return false; + } + var paramWords = WordParser.Parse(param.Name, WordParserOptions.SplitCompoundWords); var propWords = WordParser.Parse(prop.Name, WordParserOptions.SplitCompoundWords).ToImmutableArray(); @@ -235,6 +258,24 @@ private static void ReportPropertyDiagnostic(OperationAnalysisContext context, D param.Name, prop.Name)); } + + private static IMemberReferenceOperation? TryGetMemberReferenceOperation(IParameterReferenceOperation paramOperation) + { + if (paramOperation.Parent is ITupleOperation tupleOperation + && tupleOperation.Parent is IConversionOperation conversion + && conversion.Parent is IDeconstructionAssignmentOperation deconstruction + && deconstruction.Target is ITupleOperation targetTuple) + { + var paramIndexInTuple = tupleOperation.Elements.IndexOf(paramOperation); + + var propertyReference = targetTuple.Elements[paramIndexInTuple] as IPropertyReferenceOperation; + var fieldReference = targetTuple.Elements[paramIndexInTuple] as IFieldReferenceOperation; + + return propertyReference ?? (IMemberReferenceOperation?)fieldReference; + } + + return null; + } } } } \ No newline at end of file diff --git a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs index e52b7f4bbe..ed121c891b 100644 --- a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs +++ b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs @@ -153,6 +153,28 @@ public C1(int firstProp, object secondProp) }"); } + [Fact] + public async Task CA1071_ClassPropsDoNotMatchAndTupleAssignment_ConstructorParametersShouldMatchFieldNames_CSharp() + { + await VerifyCSharpAnalyzerAsync(@" + using System.Text.Json.Serialization; + + public class C1 + { + public int _FirstProp { get; } + + public object _SecondProp { get; } + + [JsonConstructor] + public C1(int {|#0:firstProp|}, object {|#1:secondProp|}) + { + (this._FirstProp, this._SecondProp) = (firstProp, secondProp); + } + }", + CA1071CSharpPropertyResultAt(0, "C1", "firstProp", "_FirstProp"), + CA1071CSharpPropertyResultAt(1, "C1", "secondProp", "_SecondProp")); + } + [Fact] public async Task CA1071_ClassPropsMatch_NoDiagnostics_Basic() { @@ -332,6 +354,27 @@ public C1(int firstField, object secondField) ); } + [Fact] + public async Task CA1071_ClassFieldsDoNotMatchAndTupleAssignment_ConstructorParametersShouldMatchFieldNames_CSharp() + { + await VerifyCSharpAnalyzerAsync(@" + using System.Text.Json.Serialization; + + public class C1 + { + public int _firstField; + public object _secondField; + + [JsonConstructor] + public C1(int {|#0:firstField|}, object {|#1:secondField|}) + { + (_firstField, _secondField) = (firstField, secondField); + } + }", + CA1071CSharpFieldResultAt(0, "C1", "firstField", "_firstField"), + CA1071CSharpFieldResultAt(1, "C1", "secondField", "_secondField")); + } + [Fact] public async Task CA1071_ClassFieldsMatch_NoDiagnostics_Basic() { From 9089e0a4c985eb9acfafbf6078f657d24bdd006f Mon Sep 17 00:00:00 2001 From: psxvoid Date: Thu, 4 Mar 2021 11:37:36 +0300 Subject: [PATCH 27/64] Simplify member reference retrieval --- ...ametersShouldMatchPropertyAndFieldNames.cs | 34 ++++++------------- 1 file changed, 10 insertions(+), 24 deletions(-) diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs index a12c9db6d0..fbbc736d45 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs @@ -108,32 +108,15 @@ public static void AnalyzeOperationAndReport(OperationAnalysisContext context) { var operation = (IParameterReferenceOperation)context.Operation; - IOperation memberReferenceOperation; - - if (operation.Parent is not IAssignmentOperation assignment) - { - var memberReference = TryGetMemberReferenceOperation(operation); - - if (memberReference == null) - { - return; - } - - memberReferenceOperation = memberReference; - } - else - { - memberReferenceOperation = assignment.Target; - } - - IParameterSymbol param = operation.Parameter; - ISymbol? referencedSymbol = memberReferenceOperation.GetReferencedMemberOrLocalOrParameter(); + IMemberReferenceOperation? memberReferenceOperation = TryGetMemberReferenceOperation(operation); + ISymbol? referencedSymbol = memberReferenceOperation?.GetReferencedMemberOrLocalOrParameter(); if (referencedSymbol == null) { return; } + IParameterSymbol param = operation.Parameter; var field = referencedSymbol as IFieldSymbol; var prop = referencedSymbol as IPropertySymbol; @@ -261,6 +244,12 @@ private static void ReportPropertyDiagnostic(OperationAnalysisContext context, D private static IMemberReferenceOperation? TryGetMemberReferenceOperation(IParameterReferenceOperation paramOperation) { + if (paramOperation.Parent is IAssignmentOperation assignmentOperation + && assignmentOperation.Target is IMemberReferenceOperation assignmentTarget) + { + return assignmentTarget; + } + if (paramOperation.Parent is ITupleOperation tupleOperation && tupleOperation.Parent is IConversionOperation conversion && conversion.Parent is IDeconstructionAssignmentOperation deconstruction @@ -268,10 +257,7 @@ private static void ReportPropertyDiagnostic(OperationAnalysisContext context, D { var paramIndexInTuple = tupleOperation.Elements.IndexOf(paramOperation); - var propertyReference = targetTuple.Elements[paramIndexInTuple] as IPropertyReferenceOperation; - var fieldReference = targetTuple.Elements[paramIndexInTuple] as IFieldReferenceOperation; - - return propertyReference ?? (IMemberReferenceOperation?)fieldReference; + return targetTuple.Elements[paramIndexInTuple] as IMemberReferenceOperation; } return null; From 5aff394f58ab6f16ac70eefee90438ca49defd18 Mon Sep 17 00:00:00 2001 From: psxvoid Date: Thu, 4 Mar 2021 12:12:23 +0300 Subject: [PATCH 28/64] Merge reference symbol null and static checks --- ...nstructorParametersShouldMatchPropertyAndFieldNames.cs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs index fbbc736d45..7733b3bde2 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs @@ -111,7 +111,7 @@ public static void AnalyzeOperationAndReport(OperationAnalysisContext context) IMemberReferenceOperation? memberReferenceOperation = TryGetMemberReferenceOperation(operation); ISymbol? referencedSymbol = memberReferenceOperation?.GetReferencedMemberOrLocalOrParameter(); - if (referencedSymbol == null) + if (referencedSymbol == null || referencedSymbol.IsStatic) { return; } @@ -125,12 +125,6 @@ public static void AnalyzeOperationAndReport(OperationAnalysisContext context) return; } - // Only process instance fields and properties - if (referencedSymbol.IsStatic) - { - return; - } - if (IsSupportedField(field) && !IsParamMatchFieldName(param, field)) { var properties = ImmutableDictionary.Empty.SetItem(ReferencedFieldOrPropertyName, field.Name); From 5fba883c99bbbb1ad68c13d1fcf14144248ff5a2 Mon Sep 17 00:00:00 2001 From: psxvoid Date: Thu, 4 Mar 2021 12:18:01 +0300 Subject: [PATCH 29/64] Rename local variable in member reference retrival --- ...ConstructorParametersShouldMatchPropertyAndFieldNames.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs index 7733b3bde2..dd76e61dfa 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs @@ -244,12 +244,12 @@ private static void ReportPropertyDiagnostic(OperationAnalysisContext context, D return assignmentTarget; } - if (paramOperation.Parent is ITupleOperation tupleOperation - && tupleOperation.Parent is IConversionOperation conversion + if (paramOperation.Parent is ITupleOperation sourceTuple + && sourceTuple.Parent is IConversionOperation conversion && conversion.Parent is IDeconstructionAssignmentOperation deconstruction && deconstruction.Target is ITupleOperation targetTuple) { - var paramIndexInTuple = tupleOperation.Elements.IndexOf(paramOperation); + var paramIndexInTuple = sourceTuple.Elements.IndexOf(paramOperation); return targetTuple.Elements[paramIndexInTuple] as IMemberReferenceOperation; } From cd373f6064a42b32b90c0696b00f54f2abc1860a Mon Sep 17 00:00:00 2001 From: psxvoid Date: Thu, 4 Mar 2021 12:32:25 +0300 Subject: [PATCH 30/64] Add tuple assignment test for records --- ...rsShouldMatchPropertyAndFieldNamesTests.cs | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs index ed121c891b..1bf92098fe 100644 --- a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs +++ b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs @@ -61,6 +61,28 @@ public C1(int {|#0:firstDrop|}, object {|#1:secondDrop|}) CA1071CSharpPropertyResultAt(1, "C1", "secondDrop", "SecondProp")); } + [Fact] + public async Task CA1071_RecordPropsDoNotMatchAndTupleAssignment_ConstructorParametersShouldMatchPropertyNames_CSharp() + { + await VerifyCSharp9AnalyzerAsync(@" + using System.Text.Json.Serialization; + + public record C1 + { + public int FirstProp { get; } + + public object SecondProp { get; } + + [JsonConstructor] + public C1(int {|#0:firstDrop|}, object {|#1:secondDrop|}) + { + (this.FirstProp, this.SecondProp) = (firstDrop, secondDrop); + } + }", + CA1071CSharpPropertyResultAt(0, "C1", "firstDrop", "FirstProp"), + CA1071CSharpPropertyResultAt(1, "C1", "secondDrop", "SecondProp")); + } + [Fact] public async Task CA1071_ClassPropsDoNotMatch_ConstructorParametersShouldMatchPropertyNames_Basic() { @@ -301,6 +323,28 @@ public C1(int {|#0:firstIField|}, object {|#1:secondIField|}) CA1071CSharpFieldResultAt(1, "C1", "secondIField", "secondField")); } + [Fact] + public async Task CA1071_RecordFieldsDoNotMatchAndTupleAssignment_ConstructorParametersShouldMatchFieldNames_CSharp() + { + await VerifyCSharp9AnalyzerAsync(@" + using System.Text.Json.Serialization; + + public record C1 + { + public int firstField; + + public object secondField; + + [JsonConstructor] + public C1(int {|#0:firstIField|}, object {|#1:secondIField|}) + { + (this.firstField, this.secondField) = (firstIField, secondIField); + } + }", + CA1071CSharpFieldResultAt(0, "C1", "firstIField", "firstField"), + CA1071CSharpFieldResultAt(1, "C1", "secondIField", "secondField")); + } + [Fact] public async Task CA1071_ClassFieldsDoNotMatchNotJsonCtor_NoDiagnostics_CSharp() { From 1fb8c27b6239bcbdd45ffe8ca00202a753a04ec5 Mon Sep 17 00:00:00 2001 From: psxvoid Date: Sun, 7 Mar 2021 07:51:25 +0300 Subject: [PATCH 31/64] Analyzer - group tests for records below tests for classes --- ...rsShouldMatchPropertyAndFieldNamesTests.cs | 216 +++++++++--------- 1 file changed, 108 insertions(+), 108 deletions(-) diff --git a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs index 1bf92098fe..9d4b7ed5c1 100644 --- a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs +++ b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs @@ -38,51 +38,6 @@ public C1(int {|#0:firstDrop|}, object {|#1:secondDrop|}) CA1071CSharpPropertyResultAt(1, "C1", "secondDrop", "SecondProp")); } - [Fact] - public async Task CA1071_RecordPropsDoNotMatch_ConstructorParametersShouldMatchPropertyNames_CSharp() - { - await VerifyCSharp9AnalyzerAsync(@" - using System.Text.Json.Serialization; - - public record C1 - { - public int FirstProp { get; } - - public object SecondProp { get; } - - [JsonConstructor] - public C1(int {|#0:firstDrop|}, object {|#1:secondDrop|}) - { - this.FirstProp = firstDrop; - this.SecondProp = secondDrop; - } - }", - CA1071CSharpPropertyResultAt(0, "C1", "firstDrop", "FirstProp"), - CA1071CSharpPropertyResultAt(1, "C1", "secondDrop", "SecondProp")); - } - - [Fact] - public async Task CA1071_RecordPropsDoNotMatchAndTupleAssignment_ConstructorParametersShouldMatchPropertyNames_CSharp() - { - await VerifyCSharp9AnalyzerAsync(@" - using System.Text.Json.Serialization; - - public record C1 - { - public int FirstProp { get; } - - public object SecondProp { get; } - - [JsonConstructor] - public C1(int {|#0:firstDrop|}, object {|#1:secondDrop|}) - { - (this.FirstProp, this.SecondProp) = (firstDrop, secondDrop); - } - }", - CA1071CSharpPropertyResultAt(0, "C1", "firstDrop", "FirstProp"), - CA1071CSharpPropertyResultAt(1, "C1", "secondDrop", "SecondProp")); - } - [Fact] public async Task CA1071_ClassPropsDoNotMatch_ConstructorParametersShouldMatchPropertyNames_Basic() { @@ -136,24 +91,6 @@ End Sub End Class"); } - [Fact] - public async Task CA1071_RecordPropsDoNotMatchNotJsonCtor_NoDiagnostics_CSharp() - { - await VerifyCSharp9AnalyzerAsync(@" - public record C1 - { - public int FirstProp { get; } - - public object SecondProp { get; } - - public C1(int firstDrop, object secondDrop) - { - this.FirstProp = firstDrop; - this.SecondProp = secondDrop; - } - }"); - } - [Fact] public async Task CA1071_ClassPropsMatch_NoDiagnostics_CSharp() { @@ -300,51 +237,6 @@ End Sub CA1071BasicFieldResultAt(1, "C1", "secondIField", "secondField")); } - [Fact] - public async Task CA1071_RecordFieldsDoNotMatch_ConstructorParametersShouldMatchFieldNames_CSharp() - { - await VerifyCSharp9AnalyzerAsync(@" - using System.Text.Json.Serialization; - - public record C1 - { - public int firstField; - - public object secondField; - - [JsonConstructor] - public C1(int {|#0:firstIField|}, object {|#1:secondIField|}) - { - this.firstField = firstIField; - this.secondField = secondIField; - } - }", - CA1071CSharpFieldResultAt(0, "C1", "firstIField", "firstField"), - CA1071CSharpFieldResultAt(1, "C1", "secondIField", "secondField")); - } - - [Fact] - public async Task CA1071_RecordFieldsDoNotMatchAndTupleAssignment_ConstructorParametersShouldMatchFieldNames_CSharp() - { - await VerifyCSharp9AnalyzerAsync(@" - using System.Text.Json.Serialization; - - public record C1 - { - public int firstField; - - public object secondField; - - [JsonConstructor] - public C1(int {|#0:firstIField|}, object {|#1:secondIField|}) - { - (this.firstField, this.secondField) = (firstIField, secondIField); - } - }", - CA1071CSharpFieldResultAt(0, "C1", "firstIField", "firstField"), - CA1071CSharpFieldResultAt(1, "C1", "secondIField", "secondField")); - } - [Fact] public async Task CA1071_ClassFieldsDoNotMatchNotJsonCtor_NoDiagnostics_CSharp() { @@ -437,6 +329,114 @@ End Sub End Class"); } + [Fact] + public async Task CA1071_RecordPropsDoNotMatchNotJsonCtor_NoDiagnostics_CSharp() + { + await VerifyCSharp9AnalyzerAsync(@" + public record C1 + { + public int FirstProp { get; } + + public object SecondProp { get; } + + public C1(int firstDrop, object secondDrop) + { + this.FirstProp = firstDrop; + this.SecondProp = secondDrop; + } + }"); + } + + [Fact] + public async Task CA1071_RecordPropsDoNotMatch_ConstructorParametersShouldMatchPropertyNames_CSharp() + { + await VerifyCSharp9AnalyzerAsync(@" + using System.Text.Json.Serialization; + + public record C1 + { + public int FirstProp { get; } + + public object SecondProp { get; } + + [JsonConstructor] + public C1(int {|#0:firstDrop|}, object {|#1:secondDrop|}) + { + this.FirstProp = firstDrop; + this.SecondProp = secondDrop; + } + }", + CA1071CSharpPropertyResultAt(0, "C1", "firstDrop", "FirstProp"), + CA1071CSharpPropertyResultAt(1, "C1", "secondDrop", "SecondProp")); + } + + [Fact] + public async Task CA1071_RecordPropsDoNotMatchAndTupleAssignment_ConstructorParametersShouldMatchPropertyNames_CSharp() + { + await VerifyCSharp9AnalyzerAsync(@" + using System.Text.Json.Serialization; + + public record C1 + { + public int FirstProp { get; } + + public object SecondProp { get; } + + [JsonConstructor] + public C1(int {|#0:firstDrop|}, object {|#1:secondDrop|}) + { + (this.FirstProp, this.SecondProp) = (firstDrop, secondDrop); + } + }", + CA1071CSharpPropertyResultAt(0, "C1", "firstDrop", "FirstProp"), + CA1071CSharpPropertyResultAt(1, "C1", "secondDrop", "SecondProp")); + } + + [Fact] + public async Task CA1071_RecordFieldsDoNotMatch_ConstructorParametersShouldMatchFieldNames_CSharp() + { + await VerifyCSharp9AnalyzerAsync(@" + using System.Text.Json.Serialization; + + public record C1 + { + public int firstField; + + public object secondField; + + [JsonConstructor] + public C1(int {|#0:firstIField|}, object {|#1:secondIField|}) + { + this.firstField = firstIField; + this.secondField = secondIField; + } + }", + CA1071CSharpFieldResultAt(0, "C1", "firstIField", "firstField"), + CA1071CSharpFieldResultAt(1, "C1", "secondIField", "secondField")); + } + + [Fact] + public async Task CA1071_RecordFieldsDoNotMatchAndTupleAssignment_ConstructorParametersShouldMatchFieldNames_CSharp() + { + await VerifyCSharp9AnalyzerAsync(@" + using System.Text.Json.Serialization; + + public record C1 + { + public int firstField; + + public object secondField; + + [JsonConstructor] + public C1(int {|#0:firstIField|}, object {|#1:secondIField|}) + { + (this.firstField, this.secondField) = (firstIField, secondIField); + } + }", + CA1071CSharpFieldResultAt(0, "C1", "firstIField", "firstField"), + CA1071CSharpFieldResultAt(1, "C1", "secondIField", "secondField")); + } + private static async Task VerifyCSharpAnalyzerAsync(string source, params DiagnosticResult[] expected) { var csharpTest = new VerifyCS.Test From da07af5bae27fb193645f6d470938cb6918b9f8d Mon Sep 17 00:00:00 2001 From: psxvoid Date: Sun, 7 Mar 2021 07:58:52 +0300 Subject: [PATCH 32/64] Analyzer - sort tests for classes --- ...rsShouldMatchPropertyAndFieldNamesTests.cs | 62 +++++++++---------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs index 9d4b7ed5c1..c5aeee77d1 100644 --- a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs +++ b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs @@ -92,46 +92,46 @@ End Sub } [Fact] - public async Task CA1071_ClassPropsMatch_NoDiagnostics_CSharp() + public async Task CA1071_ClassPropsDoNotMatchAndTupleAssignment_ConstructorParametersShouldMatchFieldNames_CSharp() { await VerifyCSharpAnalyzerAsync(@" using System.Text.Json.Serialization; public class C1 { - public int FirstProp { get; } + public int _FirstProp { get; } - public object SecondProp { get; } + public object _SecondProp { get; } [JsonConstructor] - public C1(int firstProp, object secondProp) + public C1(int {|#0:firstProp|}, object {|#1:secondProp|}) { - this.FirstProp = firstProp; - this.SecondProp = secondProp; + (this._FirstProp, this._SecondProp) = (firstProp, secondProp); } - }"); + }", + CA1071CSharpPropertyResultAt(0, "C1", "firstProp", "_FirstProp"), + CA1071CSharpPropertyResultAt(1, "C1", "secondProp", "_SecondProp")); } [Fact] - public async Task CA1071_ClassPropsDoNotMatchAndTupleAssignment_ConstructorParametersShouldMatchFieldNames_CSharp() + public async Task CA1071_ClassPropsMatch_NoDiagnostics_CSharp() { await VerifyCSharpAnalyzerAsync(@" using System.Text.Json.Serialization; public class C1 { - public int _FirstProp { get; } + public int FirstProp { get; } - public object _SecondProp { get; } + public object SecondProp { get; } [JsonConstructor] - public C1(int {|#0:firstProp|}, object {|#1:secondProp|}) + public C1(int firstProp, object secondProp) { - (this._FirstProp, this._SecondProp) = (firstProp, secondProp); + this.FirstProp = firstProp; + this.SecondProp = secondProp; } - }", - CA1071CSharpPropertyResultAt(0, "C1", "firstProp", "_FirstProp"), - CA1071CSharpPropertyResultAt(1, "C1", "secondProp", "_SecondProp")); + }"); } [Fact] @@ -270,45 +270,45 @@ End Sub } [Fact] - public async Task CA1071_ClassFieldsMatch_NoDiagnostics_CSharp() + public async Task CA1071_ClassFieldsDoNotMatchAndTupleAssignment_ConstructorParametersShouldMatchFieldNames_CSharp() { await VerifyCSharpAnalyzerAsync(@" using System.Text.Json.Serialization; public class C1 { - public int firstField; - public object secondField; + public int _firstField; + public object _secondField; [JsonConstructor] - public C1(int firstField, object secondField) + public C1(int {|#0:firstField|}, object {|#1:secondField|}) { - this.firstField = firstField; - this.secondField = secondField; + (_firstField, _secondField) = (firstField, secondField); } - }" - ); + }", + CA1071CSharpFieldResultAt(0, "C1", "firstField", "_firstField"), + CA1071CSharpFieldResultAt(1, "C1", "secondField", "_secondField")); } [Fact] - public async Task CA1071_ClassFieldsDoNotMatchAndTupleAssignment_ConstructorParametersShouldMatchFieldNames_CSharp() + public async Task CA1071_ClassFieldsMatch_NoDiagnostics_CSharp() { await VerifyCSharpAnalyzerAsync(@" using System.Text.Json.Serialization; public class C1 { - public int _firstField; - public object _secondField; + public int firstField; + public object secondField; [JsonConstructor] - public C1(int {|#0:firstField|}, object {|#1:secondField|}) + public C1(int firstField, object secondField) { - (_firstField, _secondField) = (firstField, secondField); + this.firstField = firstField; + this.secondField = secondField; } - }", - CA1071CSharpFieldResultAt(0, "C1", "firstField", "_firstField"), - CA1071CSharpFieldResultAt(1, "C1", "secondField", "_secondField")); + }" + ); } [Fact] From 0c3e2a9ec6034a3f91ecc838fc9b720d911db679 Mon Sep 17 00:00:00 2001 From: psxvoid Date: Sun, 7 Mar 2021 10:07:23 +0300 Subject: [PATCH 33/64] Analyzer - ensure bound fields are public --- .../MicrosoftNetCoreAnalyzersResources.resx | 6 + ...ametersShouldMatchPropertyAndFieldNames.cs | 52 ++++++-- .../MicrosoftNetCoreAnalyzersResources.cs.xlf | 10 ++ .../MicrosoftNetCoreAnalyzersResources.de.xlf | 10 ++ .../MicrosoftNetCoreAnalyzersResources.es.xlf | 10 ++ .../MicrosoftNetCoreAnalyzersResources.fr.xlf | 10 ++ .../MicrosoftNetCoreAnalyzersResources.it.xlf | 10 ++ .../MicrosoftNetCoreAnalyzersResources.ja.xlf | 10 ++ .../MicrosoftNetCoreAnalyzersResources.ko.xlf | 10 ++ .../MicrosoftNetCoreAnalyzersResources.pl.xlf | 10 ++ ...crosoftNetCoreAnalyzersResources.pt-BR.xlf | 10 ++ .../MicrosoftNetCoreAnalyzersResources.ru.xlf | 10 ++ .../MicrosoftNetCoreAnalyzersResources.tr.xlf | 10 ++ ...osoftNetCoreAnalyzersResources.zh-Hans.xlf | 10 ++ ...osoftNetCoreAnalyzersResources.zh-Hant.xlf | 10 ++ ...rsShouldMatchPropertyAndFieldNamesTests.cs | 125 ++++++++++++++++++ 16 files changed, 300 insertions(+), 13 deletions(-) diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx index 4c6433a542..343639d6f3 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx @@ -1537,4 +1537,10 @@ Constructor parameter names should match the bound property or field names + + For proper deserialization, change the visibility of the bound field '{2}' to public + + + For a constructor having [JsonConstructor] attribute each parameter must be bound to a public field for proper deserialization. + \ No newline at end of file diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs index dd76e61dfa..11cc96d2e3 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs @@ -29,6 +29,8 @@ public sealed class ConstructorParametersShouldMatchPropertyAndFieldNamesAnalyze private static readonly LocalizableString s_localizableMessagePropertyPublic = new LocalizableResourceString(nameof(MicrosoftNetCoreAnalyzersResources.ConstructorParameterShouldMatchPropertyWithPublicVisibility), MicrosoftNetCoreAnalyzersResources.ResourceManager, typeof(MicrosoftNetCoreAnalyzersResources)); private static readonly LocalizableString s_localizableDescriptionPropertyPublic = new LocalizableResourceString(nameof(MicrosoftNetCoreAnalyzersResources.ConstructorParametersShouldMatchPropertyWithPublicVisibilityDescription), MicrosoftNetCoreAnalyzersResources.ResourceManager, typeof(MicrosoftNetCoreAnalyzersResources)); + private static readonly LocalizableString s_localizableMessageFieldPublic = new LocalizableResourceString(nameof(MicrosoftNetCoreAnalyzersResources.ConstructorParameterShouldMatchFieldWithPublicVisibility), MicrosoftNetCoreAnalyzersResources.ResourceManager, typeof(MicrosoftNetCoreAnalyzersResources)); + private static readonly LocalizableString s_localizableDescriptionFieldPublic = new LocalizableResourceString(nameof(MicrosoftNetCoreAnalyzersResources.ConstructorParametersShouldMatchFieldWithPublicVisibilityDescription), MicrosoftNetCoreAnalyzersResources.ResourceManager, typeof(MicrosoftNetCoreAnalyzersResources)); internal static DiagnosticDescriptor PropertyNameRule = DiagnosticDescriptorHelper.Create(RuleId, s_localizableTitle, @@ -38,6 +40,14 @@ public sealed class ConstructorParametersShouldMatchPropertyAndFieldNamesAnalyze description: s_localizableDescription, isPortedFxCopRule: false, isDataflowRule: false); + internal static DiagnosticDescriptor FieldRule = DiagnosticDescriptorHelper.Create(RuleId, + s_localizableTitle, + s_localizableMessageField, + DiagnosticCategory.Design, + RuleLevel.BuildWarning, + description: s_localizableDescription, + isPortedFxCopRule: false, + isDataflowRule: false); internal static DiagnosticDescriptor PropertyPublicRule = DiagnosticDescriptorHelper.Create(RuleId, s_localizableTitle, s_localizableMessagePropertyPublic, @@ -46,12 +56,12 @@ public sealed class ConstructorParametersShouldMatchPropertyAndFieldNamesAnalyze description: s_localizableDescriptionPropertyPublic, isPortedFxCopRule: false, isDataflowRule: false); - internal static DiagnosticDescriptor FieldRule = DiagnosticDescriptorHelper.Create(RuleId, + internal static DiagnosticDescriptor FieldPublicRule = DiagnosticDescriptorHelper.Create(RuleId, s_localizableTitle, - s_localizableMessageField, + s_localizableMessageFieldPublic, DiagnosticCategory.Design, RuleLevel.BuildWarning, - description: s_localizableDescription, + description: s_localizableDescriptionFieldPublic, isPortedFxCopRule: false, isDataflowRule: false); @@ -92,7 +102,8 @@ public override void Initialize(AnalysisContext context) internal enum ParameterDiagnosticReason { NameMismatch, - PropertyInappropriateVisibility + PropertyInappropriateVisibility, + FieldInappropriateVisibility } private sealed class ParameterAnalyzer @@ -125,17 +136,17 @@ public static void AnalyzeOperationAndReport(OperationAnalysisContext context) return; } - if (IsSupportedField(field) && !IsParamMatchFieldName(param, field)) + if (IsSupportedField(field)) { - var properties = ImmutableDictionary.Empty.SetItem(ReferencedFieldOrPropertyName, field.Name); + if (!IsParamMatchFieldName(param, field)) + { + ReportFieldDiagnostic(context, FieldRule, ParameterDiagnosticReason.NameMismatch, param, field); + } - context.ReportDiagnostic( - param.CreateDiagnostic( - FieldRule, - properties, - param.ContainingType.ToDisplayString(SymbolDisplayFormats.ShortSymbolDisplayFormat), - param.Name, - field.Name)); + if (!field.IsPublic()) + { + ReportFieldDiagnostic(context, FieldPublicRule, ParameterDiagnosticReason.FieldInappropriateVisibility, param, field); + } return; } @@ -221,6 +232,21 @@ public bool ShouldAnalyzeMethod(IMethodSymbol method) return true; } + private static void ReportFieldDiagnostic(OperationAnalysisContext context, DiagnosticDescriptor diagnosticDescriptor, ParameterDiagnosticReason reason, IParameterSymbol param, IFieldSymbol field) + { + var properties = ImmutableDictionary.Empty + .SetItem(ReferencedFieldOrPropertyName, field.Name) + .SetItem(DiagnosticReason, reason.ToString()); + + context.ReportDiagnostic( + param.CreateDiagnostic( + diagnosticDescriptor, + properties, + param.ContainingType.ToDisplayString(SymbolDisplayFormats.ShortSymbolDisplayFormat), + param.Name, + field.Name)); + } + private static void ReportPropertyDiagnostic(OperationAnalysisContext context, DiagnosticDescriptor diagnosticDescriptor, ParameterDiagnosticReason reason, IParameterSymbol param, IPropertySymbol prop) { var properties = ImmutableDictionary.Empty 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 92d4beed19..84b168052d 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.cs.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.cs.xlf @@ -182,6 +182,11 @@ For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' + + For proper deserialization, change the visibility of the bound field '{2}' to public + For proper deserialization, change the visibility of the bound field '{2}' to public + + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' @@ -192,6 +197,11 @@ For proper deserialization, change the visibility of the bound property '{2}' to public + + For a constructor having [JsonConstructor] attribute each parameter must be bound to a public field for proper deserialization. + For a constructor having [JsonConstructor] attribute each parameter must be bound to a public field for proper deserialization. + + For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. 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 30a415a15b..f9728b7a2e 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.de.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.de.xlf @@ -182,6 +182,11 @@ For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' + + For proper deserialization, change the visibility of the bound field '{2}' to public + For proper deserialization, change the visibility of the bound field '{2}' to public + + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' @@ -192,6 +197,11 @@ For proper deserialization, change the visibility of the bound property '{2}' to public + + For a constructor having [JsonConstructor] attribute each parameter must be bound to a public field for proper deserialization. + For a constructor having [JsonConstructor] attribute each parameter must be bound to a public field for proper deserialization. + + For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. 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 f52e5ac872..6c2dc4012c 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.es.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.es.xlf @@ -182,6 +182,11 @@ For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' + + For proper deserialization, change the visibility of the bound field '{2}' to public + For proper deserialization, change the visibility of the bound field '{2}' to public + + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' @@ -192,6 +197,11 @@ For proper deserialization, change the visibility of the bound property '{2}' to public + + For a constructor having [JsonConstructor] attribute each parameter must be bound to a public field for proper deserialization. + For a constructor having [JsonConstructor] attribute each parameter must be bound to a public field for proper deserialization. + + For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. 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 7fb5cfe31b..61f9a45938 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.fr.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.fr.xlf @@ -182,6 +182,11 @@ For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' + + For proper deserialization, change the visibility of the bound field '{2}' to public + For proper deserialization, change the visibility of the bound field '{2}' to public + + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' @@ -192,6 +197,11 @@ For proper deserialization, change the visibility of the bound property '{2}' to public + + For a constructor having [JsonConstructor] attribute each parameter must be bound to a public field for proper deserialization. + For a constructor having [JsonConstructor] attribute each parameter must be bound to a public field for proper deserialization. + + For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. 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 c88c8f3cdf..bcbaba7ac7 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.it.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.it.xlf @@ -182,6 +182,11 @@ For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' + + For proper deserialization, change the visibility of the bound field '{2}' to public + For proper deserialization, change the visibility of the bound field '{2}' to public + + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' @@ -192,6 +197,11 @@ For proper deserialization, change the visibility of the bound property '{2}' to public + + For a constructor having [JsonConstructor] attribute each parameter must be bound to a public field for proper deserialization. + For a constructor having [JsonConstructor] attribute each parameter must be bound to a public field for proper deserialization. + + For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. 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 b3ab4f6db6..82c90b267e 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ja.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ja.xlf @@ -182,6 +182,11 @@ For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' + + For proper deserialization, change the visibility of the bound field '{2}' to public + For proper deserialization, change the visibility of the bound field '{2}' to public + + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' @@ -192,6 +197,11 @@ For proper deserialization, change the visibility of the bound property '{2}' to public + + For a constructor having [JsonConstructor] attribute each parameter must be bound to a public field for proper deserialization. + For a constructor having [JsonConstructor] attribute each parameter must be bound to a public field for proper deserialization. + + For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. 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 be11e5fc13..d9970fc482 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ko.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ko.xlf @@ -182,6 +182,11 @@ For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' + + For proper deserialization, change the visibility of the bound field '{2}' to public + For proper deserialization, change the visibility of the bound field '{2}' to public + + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' @@ -192,6 +197,11 @@ For proper deserialization, change the visibility of the bound property '{2}' to public + + For a constructor having [JsonConstructor] attribute each parameter must be bound to a public field for proper deserialization. + For a constructor having [JsonConstructor] attribute each parameter must be bound to a public field for proper deserialization. + + For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. 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 a15a30455d..5739565f66 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pl.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pl.xlf @@ -182,6 +182,11 @@ For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' + + For proper deserialization, change the visibility of the bound field '{2}' to public + For proper deserialization, change the visibility of the bound field '{2}' to public + + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' @@ -192,6 +197,11 @@ For proper deserialization, change the visibility of the bound property '{2}' to public + + For a constructor having [JsonConstructor] attribute each parameter must be bound to a public field for proper deserialization. + For a constructor having [JsonConstructor] attribute each parameter must be bound to a public field for proper deserialization. + + For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. 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 4355752437..4d18167fb4 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 @@ -182,6 +182,11 @@ For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' + + For proper deserialization, change the visibility of the bound field '{2}' to public + For proper deserialization, change the visibility of the bound field '{2}' to public + + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' @@ -192,6 +197,11 @@ For proper deserialization, change the visibility of the bound property '{2}' to public + + For a constructor having [JsonConstructor] attribute each parameter must be bound to a public field for proper deserialization. + For a constructor having [JsonConstructor] attribute each parameter must be bound to a public field for proper deserialization. + + For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. 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 f75c24cd6b..0560898cea 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ru.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ru.xlf @@ -182,6 +182,11 @@ For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' + + For proper deserialization, change the visibility of the bound field '{2}' to public + For proper deserialization, change the visibility of the bound field '{2}' to public + + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' @@ -192,6 +197,11 @@ For proper deserialization, change the visibility of the bound property '{2}' to public + + For a constructor having [JsonConstructor] attribute each parameter must be bound to a public field for proper deserialization. + For a constructor having [JsonConstructor] attribute each parameter must be bound to a public field for proper deserialization. + + For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. 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 7130ea8c6e..804b3281da 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.tr.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.tr.xlf @@ -182,6 +182,11 @@ For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' + + For proper deserialization, change the visibility of the bound field '{2}' to public + For proper deserialization, change the visibility of the bound field '{2}' to public + + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' @@ -192,6 +197,11 @@ For proper deserialization, change the visibility of the bound property '{2}' to public + + For a constructor having [JsonConstructor] attribute each parameter must be bound to a public field for proper deserialization. + For a constructor having [JsonConstructor] attribute each parameter must be bound to a public field for proper deserialization. + + For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. 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 d1e88b2d7a..5020183ce4 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 @@ -182,6 +182,11 @@ For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' + + For proper deserialization, change the visibility of the bound field '{2}' to public + For proper deserialization, change the visibility of the bound field '{2}' to public + + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' @@ -192,6 +197,11 @@ For proper deserialization, change the visibility of the bound property '{2}' to public + + For a constructor having [JsonConstructor] attribute each parameter must be bound to a public field for proper deserialization. + For a constructor having [JsonConstructor] attribute each parameter must be bound to a public field for proper deserialization. + + For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. 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 bf324567ac..2c6de7b9c3 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 @@ -182,6 +182,11 @@ For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' + + For proper deserialization, change the visibility of the bound field '{2}' to public + For proper deserialization, change the visibility of the bound field '{2}' to public + + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' @@ -192,6 +197,11 @@ For proper deserialization, change the visibility of the bound property '{2}' to public + + For a constructor having [JsonConstructor] attribute each parameter must be bound to a public field for proper deserialization. + For a constructor having [JsonConstructor] attribute each parameter must be bound to a public field for proper deserialization. + + For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. diff --git a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs index c5aeee77d1..4d6c267ed8 100644 --- a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs +++ b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs @@ -329,6 +329,80 @@ End Sub End Class"); } + [Fact] + public async Task CA1071_ClassFieldsMatchButPrivateHasJsonCtor_ConstructorParametersShouldMatchFieldNames_CSharp() + { + await VerifyCSharpAnalyzerAsync(@" + using System.Text.Json.Serialization; + + public class C1 + { + private int firstField; + private object secondField; + + [JsonConstructor] + public C1(int {|#0:firstField|}, object {|#1:secondField|}) + { + this.firstField = firstField; + this.secondField = secondField; + } + }", + CA1071CSharpPublicFieldResultAt(0, "C1", "firstField", "firstField"), + CA1071CSharpPublicFieldResultAt(1, "C1", "secondField", "secondField")); + } + + [Fact] + public async Task CA1071_ClassFieldsMatchButPrivateHasJsonCtor_ConstructorParametersShouldMatchFieldNames_Basic() + { + await VerifyBasicAnalyzerAsync(@" + Imports System.Text.Json.Serialization + + Public Class C1 + Private firstField as Integer + Private secondField as Object + + + Public Sub New({|#0:firstField|} as Integer, {|#1:secondField|} as Object) + Me.firstField = firstField + Me.secondField = secondField + End Sub + End Class", + CA1071BasicPublicFieldResultAt(0, "C1", "firstField", "firstField"), + CA1071BasicPublicFieldResultAt(1, "C1", "secondField", "secondField")); + } + + [Fact] + public async Task CA1071_ClassFieldsMatchButPrivateNotJsonCtor_NoDiagnostics_CSharp() + { + await VerifyCSharpAnalyzerAsync(@" + public class C1 + { + private int firstField; + private object secondField; + + public C1(int firstField, object secondField) + { + this.firstField = firstField; + this.secondField = secondField; + } + }"); + } + + [Fact] + public async Task CA1071_ClassFieldsMatchButPrivateNotJsonCtor_NoDiagnostics_Basic() + { + await VerifyBasicAnalyzerAsync(@" + Public Class C1 + Private firstField as Integer + Private secondField as Object + + Public Sub New(firstField as Integer, secondField as Object) + Me.firstField = firstField + Me.secondField = secondField + End Sub + End Class"); + } + [Fact] public async Task CA1071_RecordPropsDoNotMatchNotJsonCtor_NoDiagnostics_CSharp() { @@ -437,6 +511,47 @@ public C1(int {|#0:firstIField|}, object {|#1:secondIField|}) CA1071CSharpFieldResultAt(1, "C1", "secondIField", "secondField")); } + [Fact] + public async Task CA1071_RecordFieldsMatchButPrivateHasJsonCtor_ConstructorParametersShouldMatchFieldNames_CSharp() + { + await VerifyCSharp9AnalyzerAsync(@" + using System.Text.Json.Serialization; + + public record C1 + { + private int firstField; + + private object secondField; + + [JsonConstructor] + public C1(int {|#0:firstField|}, object {|#1:secondField|}) + { + this.firstField = firstField; + this.secondField = secondField; + } + }", + CA1071CSharpPublicFieldResultAt(0, "C1", "firstField", "firstField"), + CA1071CSharpPublicFieldResultAt(1, "C1", "secondField", "secondField")); + } + + [Fact] + public async Task CA1071_RecordFieldsMatchButPrivateNotJsonCtor_NoDiagnostics_CSharp() + { + await VerifyCSharp9AnalyzerAsync(@" + public record C1 + { + private int firstField; + + private object secondField; + + public C1(int firstField, object secondField) + { + this.firstField = firstField; + this.secondField = secondField; + } + }"); + } + private static async Task VerifyCSharpAnalyzerAsync(string source, params DiagnosticResult[] expected) { var csharpTest = new VerifyCS.Test @@ -497,6 +612,16 @@ private DiagnosticResult CA1071BasicPublicPropertyResultAt(int markupKey, params .WithLocation(markupKey) .WithArguments(arguments); + private DiagnosticResult CA1071CSharpPublicFieldResultAt(int markupKey, params string[] arguments) + => VerifyCS.Diagnostic(ConstructorParametersShouldMatchPropertyAndFieldNamesAnalyzer.FieldPublicRule) + .WithLocation(markupKey) + .WithArguments(arguments); + + private DiagnosticResult CA1071BasicPublicFieldResultAt(int markupKey, params string[] arguments) + => VerifyVB.Diagnostic(ConstructorParametersShouldMatchPropertyAndFieldNamesAnalyzer.FieldPublicRule) + .WithLocation(markupKey) + .WithArguments(arguments); + private DiagnosticResult CA1071CSharpFieldResultAt(int markupKey, params string[] arguments) => VerifyCS.Diagnostic(ConstructorParametersShouldMatchPropertyAndFieldNamesAnalyzer.FieldRule) .WithLocation(markupKey) From 2309cb018a6a6aff9ad382749447fbef99d2d7b8 Mon Sep 17 00:00:00 2001 From: psxvoid Date: Sun, 7 Mar 2021 10:08:48 +0300 Subject: [PATCH 34/64] Fix parameter alignment in analyzer tests --- ...rsShouldMatchPropertyAndFieldNamesTests.cs | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs index 4d6c267ed8..d80cbb161d 100644 --- a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs +++ b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs @@ -34,8 +34,8 @@ public C1(int {|#0:firstDrop|}, object {|#1:secondDrop|}) this.SecondProp = secondDrop; } }", - CA1071CSharpPropertyResultAt(0, "C1", "firstDrop", "FirstProp"), - CA1071CSharpPropertyResultAt(1, "C1", "secondDrop", "SecondProp")); + CA1071CSharpPropertyResultAt(0, "C1", "firstDrop", "FirstProp"), + CA1071CSharpPropertyResultAt(1, "C1", "secondDrop", "SecondProp")); } [Fact] @@ -54,8 +54,8 @@ Public Sub New({|#0:firstDrop|} as Integer, {|#1:secondDrop|} as Object) Me.SecondProp = secondDrop End Sub End Class", - CA1071BasicPropertyResultAt(0, "C1", "firstDrop", "FirstProp"), - CA1071BasicPropertyResultAt(1, "C1", "secondDrop", "SecondProp")); + CA1071BasicPropertyResultAt(0, "C1", "firstDrop", "FirstProp"), + CA1071BasicPropertyResultAt(1, "C1", "secondDrop", "SecondProp")); } [Fact] @@ -213,8 +213,8 @@ public C1(int {|#0:firstIField|}, object {|#1:secondIField|}) this.secondField = secondIField; } }", - CA1071CSharpFieldResultAt(0, "C1", "firstIField", "firstField"), - CA1071CSharpFieldResultAt(1, "C1", "secondIField", "secondField")); + CA1071CSharpFieldResultAt(0, "C1", "firstIField", "firstField"), + CA1071CSharpFieldResultAt(1, "C1", "secondIField", "secondField")); } [Fact] @@ -233,8 +233,8 @@ Public Sub New({|#0:firstIField|} as Integer, {|#1:secondIField|} as Object) Me.secondField = secondIField End Sub End Class", - CA1071BasicFieldResultAt(0, "C1", "firstIField", "firstField"), - CA1071BasicFieldResultAt(1, "C1", "secondIField", "secondField")); + CA1071BasicFieldResultAt(0, "C1", "firstIField", "firstField"), + CA1071BasicFieldResultAt(1, "C1", "secondIField", "secondField")); } [Fact] @@ -440,8 +440,8 @@ public C1(int {|#0:firstDrop|}, object {|#1:secondDrop|}) this.SecondProp = secondDrop; } }", - CA1071CSharpPropertyResultAt(0, "C1", "firstDrop", "FirstProp"), - CA1071CSharpPropertyResultAt(1, "C1", "secondDrop", "SecondProp")); + CA1071CSharpPropertyResultAt(0, "C1", "firstDrop", "FirstProp"), + CA1071CSharpPropertyResultAt(1, "C1", "secondDrop", "SecondProp")); } [Fact] @@ -462,8 +462,8 @@ public C1(int {|#0:firstDrop|}, object {|#1:secondDrop|}) (this.FirstProp, this.SecondProp) = (firstDrop, secondDrop); } }", - CA1071CSharpPropertyResultAt(0, "C1", "firstDrop", "FirstProp"), - CA1071CSharpPropertyResultAt(1, "C1", "secondDrop", "SecondProp")); + CA1071CSharpPropertyResultAt(0, "C1", "firstDrop", "FirstProp"), + CA1071CSharpPropertyResultAt(1, "C1", "secondDrop", "SecondProp")); } [Fact] @@ -485,8 +485,8 @@ public C1(int {|#0:firstIField|}, object {|#1:secondIField|}) this.secondField = secondIField; } }", - CA1071CSharpFieldResultAt(0, "C1", "firstIField", "firstField"), - CA1071CSharpFieldResultAt(1, "C1", "secondIField", "secondField")); + CA1071CSharpFieldResultAt(0, "C1", "firstIField", "firstField"), + CA1071CSharpFieldResultAt(1, "C1", "secondIField", "secondField")); } [Fact] @@ -507,8 +507,8 @@ public C1(int {|#0:firstIField|}, object {|#1:secondIField|}) (this.firstField, this.secondField) = (firstIField, secondIField); } }", - CA1071CSharpFieldResultAt(0, "C1", "firstIField", "firstField"), - CA1071CSharpFieldResultAt(1, "C1", "secondIField", "secondField")); + CA1071CSharpFieldResultAt(0, "C1", "firstIField", "firstField"), + CA1071CSharpFieldResultAt(1, "C1", "secondIField", "secondField")); } [Fact] From 7285658d86b6103315aa9983761e0ed64afc3a13 Mon Sep 17 00:00:00 2001 From: psxvoid Date: Mon, 8 Mar 2021 09:43:02 +0300 Subject: [PATCH 35/64] Analyzer - add tests for private fields with JsonInclude --- ...rsShouldMatchPropertyAndFieldNamesTests.cs | 102 +++++++++++++++++- 1 file changed, 99 insertions(+), 3 deletions(-) diff --git a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs index d80cbb161d..28e585e857 100644 --- a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs +++ b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs @@ -330,7 +330,7 @@ End Sub } [Fact] - public async Task CA1071_ClassFieldsMatchButPrivateHasJsonCtor_ConstructorParametersShouldMatchFieldNames_CSharp() + public async Task CA1071_ClassFieldsMatchButPrivateNoJsonInclude_ConstructorParametersShouldMatchFieldNames_CSharp() { await VerifyCSharpAnalyzerAsync(@" using System.Text.Json.Serialization; @@ -338,6 +338,53 @@ await VerifyCSharpAnalyzerAsync(@" public class C1 { private int firstField; + + private object secondField; + + [JsonConstructor] + public C1(int {|#0:firstField|}, object {|#1:secondField|}) + { + this.firstField = firstField; + this.secondField = secondField; + } + }", + CA1071CSharpPublicFieldResultAt(0, "C1", "firstField", "firstField"), + CA1071CSharpPublicFieldResultAt(1, "C1", "secondField", "secondField")); + } + + [Fact] + public async Task CA1071_ClassFieldsMatchButPrivateNoJsonInclude_ConstructorParametersShouldMatchFieldNames_Basic() + { + await VerifyBasicAnalyzerAsync(@" + Imports System.Text.Json.Serialization + + Public Class C1 + Private firstField as Integer + + Private secondField as Object + + + Public Sub New({|#0:firstField|} as Integer, {|#1:secondField|} as Object) + Me.firstField = firstField + Me.secondField = secondField + End Sub + End Class", + CA1071BasicPublicFieldResultAt(0, "C1", "firstField", "firstField"), + CA1071BasicPublicFieldResultAt(1, "C1", "secondField", "secondField")); + } + + [Fact] + public async Task CA1071_ClassFieldsMatchButPrivateHasJsonInclude_ConstructorParametersShouldMatchFieldNames_CSharp() + { + await VerifyCSharpAnalyzerAsync(@" + using System.Text.Json.Serialization; + + public class C1 + { + [JsonInclude] + private int firstField; + + [JsonInclude] private object secondField; [JsonConstructor] @@ -352,13 +399,16 @@ public C1(int {|#0:firstField|}, object {|#1:secondField|}) } [Fact] - public async Task CA1071_ClassFieldsMatchButPrivateHasJsonCtor_ConstructorParametersShouldMatchFieldNames_Basic() + public async Task CA1071_ClassFieldsMatchButPrivateHasJsonInclude_ConstructorParametersShouldMatchFieldNames_Basic() { await VerifyBasicAnalyzerAsync(@" Imports System.Text.Json.Serialization Public Class C1 + Private firstField as Integer + + Private secondField as Object @@ -512,15 +562,61 @@ public C1(int {|#0:firstIField|}, object {|#1:secondIField|}) } [Fact] - public async Task CA1071_RecordFieldsMatchButPrivateHasJsonCtor_ConstructorParametersShouldMatchFieldNames_CSharp() + public async Task CA1071_RecordFieldsMatch_NoDiagnostics_CSharp() + { + await VerifyCSharp9AnalyzerAsync(@" + using System.Text.Json.Serialization; + + public record C1 + { + public int firstField; + + public object secondField; + + [JsonConstructor] + public C1(int firstField, object secondField) + { + this.firstField = firstField; + this.secondField = secondField; + } + }"); + } + + [Fact] + public async Task CA1071_RecordFieldsMatchButPrivateNoJsonInclude_ConstructorParametersShouldMatchFieldNames_CSharp() + { + await VerifyCSharp9AnalyzerAsync(@" + using System.Text.Json.Serialization; + + public record C1 + { + private int firstField; + + private object secondField; + + [JsonConstructor] + public C1(int {|#0:firstField|}, object {|#1:secondField|}) + { + this.firstField = firstField; + this.secondField = secondField; + } + }", + CA1071CSharpPublicFieldResultAt(0, "C1", "firstField", "firstField"), + CA1071CSharpPublicFieldResultAt(1, "C1", "secondField", "secondField")); + } + + [Fact] + public async Task CA1071_RecordFieldsMatchButPrivateHasJsonInclude_ConstructorParametersShouldMatchFieldNames_CSharp() { await VerifyCSharp9AnalyzerAsync(@" using System.Text.Json.Serialization; public record C1 { + [JsonInclude] private int firstField; + [JsonInclude] private object secondField; [JsonConstructor] From 52dce8effaf1361f36cb90b1c7572dbdd759674b Mon Sep 17 00:00:00 2001 From: psxvoid Date: Mon, 8 Mar 2021 16:02:58 +0300 Subject: [PATCH 36/64] Analyzer - add tests with JsonPropertyName --- ...rsShouldMatchPropertyAndFieldNamesTests.cs | 152 ++++++++++++++++++ 1 file changed, 152 insertions(+) diff --git a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs index 28e585e857..c3281bba49 100644 --- a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs +++ b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs @@ -91,6 +91,56 @@ End Sub End Class"); } + [Fact] + public async Task CA1071_ClassPropsDoNotMatchButMatchWithJsonPropertyName_ConstructorParametersShouldMatchFieldNames_CSharp() + { + // This is the current behavior on deserialization - JsonPropertyName is ignored by the JsonConstructor's logic. + await VerifyCSharpAnalyzerAsync(@" + using System.Text.Json.Serialization; + + public class C1 + { + [JsonPropertyName(""FirstProp"")] + public int _FirstProp { get; } + + [JsonPropertyName(""SecondProp"")] + public object _SecondProp { get; } + + [JsonConstructor] + public C1(int {|#0:firstProp|}, object {|#1:secondProp|}) + { + this._FirstProp = firstProp; + this._SecondProp = secondProp; + } + }", + CA1071CSharpPropertyResultAt(0, "C1", "firstProp", "_FirstProp"), + CA1071CSharpPropertyResultAt(1, "C1", "secondProp", "_SecondProp")); + } + + [Fact] + public async Task CA1071_ClassPropsDoNotMatchButMatchWithJsonPropertyName_ConstructorParametersShouldMatchFieldNames_Basic() + { + // This is the current behavior on deserialization - JsonPropertyName is ignored by the JsonConstructor's logic. + await VerifyBasicAnalyzerAsync(@" + Imports System.Text.Json.Serialization + + Public Class C1 + + Public Property _FirstProp() As Integer + + + Public Property _SecondProp() as Object + + + Public Sub New({|#0:firstProp|} as Integer, {|#1:secondProp|} as Object) + Me._FirstProp = firstProp + Me._SecondProp = secondProp + End Sub + End Class", + CA1071BasicPropertyResultAt(0, "C1", "firstProp", "_FirstProp"), + CA1071BasicPropertyResultAt(1, "C1", "secondProp", "_SecondProp")); + } + [Fact] public async Task CA1071_ClassPropsDoNotMatchAndTupleAssignment_ConstructorParametersShouldMatchFieldNames_CSharp() { @@ -254,6 +304,56 @@ public C1(int firstIField, object secondIField) }"); } + [Fact] + public async Task CA1071_ClassFieldsDoNotMatchButMatchWithJsonPropertyName_ConstructorParametersShouldMatchFieldNames_CSharp() + { + // This is the current behavior on deserialization - JsonPropertyName is ignored by the JsonConstructor's logic. + await VerifyCSharpAnalyzerAsync(@" + using System.Text.Json.Serialization; + + public class C1 + { + [JsonPropertyName(""firstField"")] + public int _firstField; + + [JsonPropertyName(""secondField"")] + public object _secondField; + + [JsonConstructor] + public C1(int {|#0:firstField|}, object {|#1:secondField|}) + { + this._firstField = firstField; + this._secondField = secondField; + } + }", + CA1071CSharpFieldResultAt(0, "C1", "firstField", "_firstField"), + CA1071CSharpFieldResultAt(1, "C1", "secondField", "_secondField")); + } + + [Fact] + public async Task CA1071_ClassFieldsDoNotMatchButMatchWithJsonPropertyName_ConstructorParametersShouldMatchFieldNames_Basic() + { + // This is the current behavior on deserialization - JsonFieldertyName is ignored by the JsonConstructor's logic. + await VerifyBasicAnalyzerAsync(@" + Imports System.Text.Json.Serialization + + Public Class C1 + + Public _firstField As Integer + + + Public _secondField as Object + + + Public Sub New({|#0:firstField|} as Integer, {|#1:secondField|} as Object) + Me._firstField = firstField + Me._secondField = secondField + End Sub + End Class", + CA1071BasicFieldResultAt(0, "C1", "firstField", "_firstField"), + CA1071BasicFieldResultAt(1, "C1", "secondField", "_secondField")); + } + [Fact] public async Task CA1071_ClassFieldsDoNotMatchNotJsonCtor_NoDiagnostics_Basic() { @@ -561,6 +661,32 @@ public C1(int {|#0:firstIField|}, object {|#1:secondIField|}) CA1071CSharpFieldResultAt(1, "C1", "secondIField", "secondField")); } + [Fact] + public async Task CA1071_RecordPropsDoNotMatchButMatchWithJsonPropertyName_ConstructorParametersShouldMatchFieldNames_CSharp() + { + // This is the current behavior on deserialization - JsonPropertyName is ignored by the JsonConstructor's logic. + await VerifyCSharp9AnalyzerAsync(@" + using System.Text.Json.Serialization; + + public record C1 + { + [JsonPropertyName(""FirstProp"")] + public int _FirstProp { get; } + + [JsonPropertyName(""SecondProp"")] + public object _SecondProp { get; } + + [JsonConstructor] + public C1(int {|#0:firstProp|}, object {|#1:secondProp|}) + { + this._FirstProp = firstProp; + this._SecondProp = secondProp; + } + }", + CA1071CSharpPropertyResultAt(0, "C1", "firstProp", "_FirstProp"), + CA1071CSharpPropertyResultAt(1, "C1", "secondProp", "_SecondProp")); + } + [Fact] public async Task CA1071_RecordFieldsMatch_NoDiagnostics_CSharp() { @@ -648,6 +774,32 @@ public C1(int firstField, object secondField) }"); } + [Fact] + public async Task CA1071_RecordFieldsDoNotMatchButMatchWithJsonPropertyName_ConstructorParametersShouldMatchFieldNames_CSharp() + { + // This is the current behavior on deserialization - JsonPropertyName is ignored by the JsonConstructor's logic. + await VerifyCSharp9AnalyzerAsync(@" + using System.Text.Json.Serialization; + + public record C1 + { + [JsonPropertyName(""firstField"")] + public int _firstField; + + [JsonPropertyName(""secondField"")] + public object _secondField; + + [JsonConstructor] + public C1(int {|#0:firstField|}, object {|#1:secondField|}) + { + this._firstField = firstField; + this._secondField = secondField; + } + }", + CA1071CSharpFieldResultAt(0, "C1", "firstField", "_firstField"), + CA1071CSharpFieldResultAt(1, "C1", "secondField", "_secondField")); + } + private static async Task VerifyCSharpAnalyzerAsync(string source, params DiagnosticResult[] expected) { var csharpTest = new VerifyCS.Test From c603b664d8439e88abb5a3edc0c2fcdab1579a99 Mon Sep 17 00:00:00 2001 From: psxvoid Date: Mon, 8 Mar 2021 18:52:45 +0300 Subject: [PATCH 37/64] Analyzer - report unreferenced params (no messages) --- ...ametersShouldMatchPropertyAndFieldNames.cs | 70 ++++++-- ...rsShouldMatchPropertyAndFieldNamesTests.cs | 149 ++++++++++++++++++ 2 files changed, 207 insertions(+), 12 deletions(-) diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs index 11cc96d2e3..c0ecbceb24 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs @@ -5,6 +5,7 @@ using System.Linq; using Analyzer.Utilities; using Analyzer.Utilities.Extensions; +using Analyzer.Utilities.PooledObjects; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.Operations; @@ -20,6 +21,7 @@ public sealed class ConstructorParametersShouldMatchPropertyAndFieldNamesAnalyze internal const string RuleId = "CA1071"; internal const string ReferencedFieldOrPropertyName = "ReferencedFieldOrPropertyName"; internal const string DiagnosticReason = "DiagnosticReason"; + internal const string UnreferencedParameterName = "UnreferencedParameterName"; private static readonly LocalizableString s_localizableTitle = new LocalizableResourceString(nameof(MicrosoftNetCoreAnalyzersResources.ConstructorParametersShouldMatchPropertyNamesTitle), MicrosoftNetCoreAnalyzersResources.ResourceManager, typeof(MicrosoftNetCoreAnalyzersResources)); @@ -64,6 +66,14 @@ public sealed class ConstructorParametersShouldMatchPropertyAndFieldNamesAnalyze description: s_localizableDescriptionFieldPublic, isPortedFxCopRule: false, isDataflowRule: false); + internal static DiagnosticDescriptor UnreferencedParameterRule = DiagnosticDescriptorHelper.Create(RuleId, + s_localizableTitle, + s_localizableMessageFieldPublic, + DiagnosticCategory.Design, + RuleLevel.BuildWarning, + description: s_localizableDescriptionFieldPublic, + isPortedFxCopRule: false, + isDataflowRule: false); public override ImmutableArray SupportedDiagnostics => ImmutableArray.Create(PropertyNameRule, FieldRule); @@ -83,19 +93,25 @@ public override void Initialize(AnalysisContext context) var paramAnalyzer = new ParameterAnalyzer(jsonConstructorAttributeNamedSymbol); - compilationStartContext.RegisterOperationBlockStartAction( - (startOperationBlockContext) => + compilationStartContext.RegisterSymbolStartAction((symbolStartContext) => + { + var constructors = ((INamedTypeSymbol)symbolStartContext.Symbol).InstanceConstructors; + + foreach (var ctor in constructors) { - if (startOperationBlockContext.OwningSymbol is IMethodSymbol method - && !paramAnalyzer.ShouldAnalyzeMethod(method)) + if (paramAnalyzer.ShouldAnalyzeMethod(ctor)) { - return; - } + var referencedParameters = PooledConcurrentSet.GetInstance(); - startOperationBlockContext.RegisterOperationAction( - context => ParameterAnalyzer.AnalyzeOperationAndReport(context), - OperationKind.ParameterReference); - }); + symbolStartContext.RegisterOperationAction( + context => ParameterAnalyzer.AnalyzeOperationAndReport(context, referencedParameters), + OperationKind.ParameterReference); + + symbolStartContext.RegisterSymbolEndAction( + context => ParameterAnalyzer.ReportUnusedParameters(context, ctor, referencedParameters)); + } + } + }, SymbolKind.NamedType); }); } @@ -103,7 +119,8 @@ internal enum ParameterDiagnosticReason { NameMismatch, PropertyInappropriateVisibility, - FieldInappropriateVisibility + FieldInappropriateVisibility, + UnreferencedParameter, } private sealed class ParameterAnalyzer @@ -115,10 +132,12 @@ public ParameterAnalyzer(INamedTypeSymbol jsonConstructorAttributeInfoType) _jsonConstructorAttributeInfoType = jsonConstructorAttributeInfoType; } - public static void AnalyzeOperationAndReport(OperationAnalysisContext context) + public static void AnalyzeOperationAndReport(OperationAnalysisContext context, PooledConcurrentSet referencedParameters) { var operation = (IParameterReferenceOperation)context.Operation; + referencedParameters.Add(operation.Parameter); + IMemberReferenceOperation? memberReferenceOperation = TryGetMemberReferenceOperation(operation); ISymbol? referencedSymbol = memberReferenceOperation?.GetReferencedMemberOrLocalOrParameter(); @@ -262,6 +281,20 @@ private static void ReportPropertyDiagnostic(OperationAnalysisContext context, D prop.Name)); } + private static void ReportUnreferencedParameterDiagnostic(SymbolAnalysisContext context, IParameterSymbol param) + { + var properties = ImmutableDictionary.Empty + .SetItem(UnreferencedParameterName, param.Name) + .SetItem(DiagnosticReason, ParameterDiagnosticReason.UnreferencedParameter.ToString()); + + context.ReportDiagnostic( + param.CreateDiagnostic( + UnreferencedParameterRule, + properties, + param.ContainingType.ToDisplayString(SymbolDisplayFormats.ShortSymbolDisplayFormat), + param.Name)); + } + private static IMemberReferenceOperation? TryGetMemberReferenceOperation(IParameterReferenceOperation paramOperation) { if (paramOperation.Parent is IAssignmentOperation assignmentOperation @@ -282,6 +315,19 @@ private static void ReportPropertyDiagnostic(OperationAnalysisContext context, D return null; } + + public static void ReportUnusedParameters(SymbolAnalysisContext context, IMethodSymbol ctor, PooledConcurrentSet referencedParameters) + { + foreach (var param in ctor.Parameters) + { + if (referencedParameters.Contains(param)) + { + continue; + } + + ReportUnreferencedParameterDiagnostic(context, param); + } + } } } } \ No newline at end of file diff --git a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs index c3281bba49..b88fb481f5 100644 --- a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs +++ b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs @@ -202,6 +202,45 @@ End Sub End Class"); } + [Fact] + public async Task CA1071_ClassPropsMatchButUnreferenced_ConstructorParametersShouldMatchFieldNames_CSharp() + { + await VerifyCSharpAnalyzerAsync(@" + using System.Text.Json.Serialization; + + public class C1 + { + private int FirstProp { get; } + + private object SecondProp { get; } + + [JsonConstructor] + public C1(int {|#0:firstProp|}, object {|#1:secondProp|}) + { + } + }", + CA1071CSharpUnreferencedParamResultAt(0, "C1", "firstProp"), + CA1071CSharpUnreferencedParamResultAt(1, "C1", "secondProp")); + } + + [Fact] + public async Task CA1071_ClassPropsMatchButUnreferenced_ConstructorParametersShouldMatchFieldNames_Basic() + { + await VerifyBasicAnalyzerAsync(@" + Imports System.Text.Json.Serialization + + Public Class C1 + Private Property FirstProp() As Integer + Private Property SecondProp() as Object + + + Public Sub New({|#0:firstProp|} as Integer, {|#1:secondProp|} as Object) + End Sub + End Class", + CA1071BasicUnreferencedParamResultAt(0, "C1", "firstProp"), + CA1071BasicUnreferencedParamResultAt(1, "C1", "secondProp")); + } + [Fact] public async Task CA1071_ClassPropsMatchButPrivate_ConstructorParametersShouldMatchFieldNames_CSharp() { @@ -429,6 +468,44 @@ End Sub End Class"); } + [Fact] + public async Task CA1071_ClassFieldsMatchButUnreferenced_ConstructorParametersShouldMatchFieldNames_CSharp() + { + await VerifyCSharpAnalyzerAsync(@" + using System.Text.Json.Serialization; + + public class C1 + { + public int firstField; + public object secondField; + + [JsonConstructor] + public C1(int {|#0:firstField|}, object {|#1:secondField|}) + { + } + }", + CA1071CSharpUnreferencedParamResultAt(0, "C1", "firstField"), + CA1071CSharpUnreferencedParamResultAt(1, "C1", "secondField")); + } + + [Fact] + public async Task CA1071_ClassFieldsMatchButUnreferenced_ConstructorParametersShouldMatchFieldNames_Basic() + { + await VerifyBasicAnalyzerAsync(@" + Imports System.Text.Json.Serialization + + Public Class C1 + Public firstField as Integer + Public secondField as Object + + + Public Sub New({|#0:firstField|} as Integer, {|#1:secondField|} as Object) + End Sub + End Class", + CA1071BasicUnreferencedParamResultAt(0, "C1", "firstField"), + CA1071BasicUnreferencedParamResultAt(1, "C1", "secondField")); + } + [Fact] public async Task CA1071_ClassFieldsMatchButPrivateNoJsonInclude_ConstructorParametersShouldMatchFieldNames_CSharp() { @@ -553,6 +630,48 @@ End Sub End Class"); } + [Fact] + public async Task CA1071_RecordPropsMatch_NoDiagnostics_CSharp() + { + await VerifyCSharp9AnalyzerAsync(@" + using System.Text.Json.Serialization; + + public record C1 + { + public int FirstProp { get; } + + public object SecondProp { get; } + + [JsonConstructor] + public C1(int firstProp, object secondProp) + { + this.FirstProp = firstProp; + this.SecondProp = secondProp; + } + }"); + } + + [Fact] + public async Task CA1071_RecordPropsMatchButUnreferenced_ConstructorParametersShouldMatchFieldNames_CSharp() + { + await VerifyCSharp9AnalyzerAsync(@" + using System.Text.Json.Serialization; + + public record C1 + { + private int FirstProp { get; } + + private object SecondProp { get; } + + [JsonConstructor] + public C1(int {|#0:firstProp|}, object {|#1:secondProp|}) + { + } + }", + CA1071CSharpUnreferencedParamResultAt(0, "C1", "firstProp"), + CA1071CSharpUnreferencedParamResultAt(1, "C1", "secondProp")); + } + [Fact] public async Task CA1071_RecordPropsDoNotMatchNotJsonCtor_NoDiagnostics_CSharp() { @@ -708,6 +827,26 @@ public C1(int firstField, object secondField) }"); } + [Fact] + public async Task CA1071_RecordFieldsMatchButUnreferenced_ConstructorParametersShouldMatchFieldNames_CSharp() + { + await VerifyCSharp9AnalyzerAsync(@" + using System.Text.Json.Serialization; + + public record C1 + { + public int firstField; + public object secondField; + + [JsonConstructor] + public C1(int {|#0:firstField|}, object {|#1:secondField|}) + { + } + }", + CA1071CSharpUnreferencedParamResultAt(0, "C1", "firstField"), + CA1071CSharpUnreferencedParamResultAt(1, "C1", "secondField")); + } + [Fact] public async Task CA1071_RecordFieldsMatchButPrivateNoJsonInclude_ConstructorParametersShouldMatchFieldNames_CSharp() { @@ -879,5 +1018,15 @@ private DiagnosticResult CA1071BasicFieldResultAt(int markupKey, params string[] => VerifyVB.Diagnostic(ConstructorParametersShouldMatchPropertyAndFieldNamesAnalyzer.FieldRule) .WithLocation(markupKey) .WithArguments(arguments); + + private DiagnosticResult CA1071CSharpUnreferencedParamResultAt(int markupKey, params string[] arguments) + => VerifyCS.Diagnostic(ConstructorParametersShouldMatchPropertyAndFieldNamesAnalyzer.UnreferencedParameterRule) + .WithLocation(markupKey) + .WithArguments(arguments); + + private DiagnosticResult CA1071BasicUnreferencedParamResultAt(int markupKey, params string[] arguments) + => VerifyVB.Diagnostic(ConstructorParametersShouldMatchPropertyAndFieldNamesAnalyzer.UnreferencedParameterRule) + .WithLocation(markupKey) + .WithArguments(arguments); } } \ No newline at end of file From afb760aca02b5a3d60bdc713c880e1cd9f344a42 Mon Sep 17 00:00:00 2001 From: psxvoid Date: Mon, 8 Mar 2021 19:13:02 +0300 Subject: [PATCH 38/64] Analyzer - add messages for unreferenced parameters --- .../MicrosoftNetCoreAnalyzersResources.resx | 6 ++++++ ...ructorParametersShouldMatchPropertyAndFieldNames.cs | 7 +++++-- .../xlf/MicrosoftNetCoreAnalyzersResources.cs.xlf | 10 ++++++++++ .../xlf/MicrosoftNetCoreAnalyzersResources.de.xlf | 10 ++++++++++ .../xlf/MicrosoftNetCoreAnalyzersResources.es.xlf | 10 ++++++++++ .../xlf/MicrosoftNetCoreAnalyzersResources.fr.xlf | 10 ++++++++++ .../xlf/MicrosoftNetCoreAnalyzersResources.it.xlf | 10 ++++++++++ .../xlf/MicrosoftNetCoreAnalyzersResources.ja.xlf | 10 ++++++++++ .../xlf/MicrosoftNetCoreAnalyzersResources.ko.xlf | 10 ++++++++++ .../xlf/MicrosoftNetCoreAnalyzersResources.pl.xlf | 10 ++++++++++ .../xlf/MicrosoftNetCoreAnalyzersResources.pt-BR.xlf | 10 ++++++++++ .../xlf/MicrosoftNetCoreAnalyzersResources.ru.xlf | 10 ++++++++++ .../xlf/MicrosoftNetCoreAnalyzersResources.tr.xlf | 10 ++++++++++ .../xlf/MicrosoftNetCoreAnalyzersResources.zh-Hans.xlf | 10 ++++++++++ .../xlf/MicrosoftNetCoreAnalyzersResources.zh-Hant.xlf | 10 ++++++++++ 15 files changed, 141 insertions(+), 2 deletions(-) diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx index 343639d6f3..088ce99b6d 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx @@ -1543,4 +1543,10 @@ For a constructor having [JsonConstructor] attribute each parameter must be bound to a public field for proper deserialization. + + For proper deserialization, remove the unreferenced parameter '{1}' in the constructor of '{0}' + + + For a constructor having [JsonConstructor] attribute each parameter must be bound to a field or property for proper deserialization. + \ No newline at end of file diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs index c0ecbceb24..13ef358213 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs @@ -34,6 +34,9 @@ public sealed class ConstructorParametersShouldMatchPropertyAndFieldNamesAnalyze private static readonly LocalizableString s_localizableMessageFieldPublic = new LocalizableResourceString(nameof(MicrosoftNetCoreAnalyzersResources.ConstructorParameterShouldMatchFieldWithPublicVisibility), MicrosoftNetCoreAnalyzersResources.ResourceManager, typeof(MicrosoftNetCoreAnalyzersResources)); private static readonly LocalizableString s_localizableDescriptionFieldPublic = new LocalizableResourceString(nameof(MicrosoftNetCoreAnalyzersResources.ConstructorParametersShouldMatchFieldWithPublicVisibilityDescription), MicrosoftNetCoreAnalyzersResources.ResourceManager, typeof(MicrosoftNetCoreAnalyzersResources)); + private static readonly LocalizableString s_localizableMessageUnreferencedParameter = new LocalizableResourceString(nameof(MicrosoftNetCoreAnalyzersResources.ConstructorParameterShouldBeReferenced), MicrosoftNetCoreAnalyzersResources.ResourceManager, typeof(MicrosoftNetCoreAnalyzersResources)); + private static readonly LocalizableString s_localizableDescriptionUnreferencedParameter = new LocalizableResourceString(nameof(MicrosoftNetCoreAnalyzersResources.ConstructorParameterShouldBeReferencedDescription), MicrosoftNetCoreAnalyzersResources.ResourceManager, typeof(MicrosoftNetCoreAnalyzersResources)); + internal static DiagnosticDescriptor PropertyNameRule = DiagnosticDescriptorHelper.Create(RuleId, s_localizableTitle, s_localizableMessageProperty, @@ -68,10 +71,10 @@ public sealed class ConstructorParametersShouldMatchPropertyAndFieldNamesAnalyze isDataflowRule: false); internal static DiagnosticDescriptor UnreferencedParameterRule = DiagnosticDescriptorHelper.Create(RuleId, s_localizableTitle, - s_localizableMessageFieldPublic, + s_localizableMessageUnreferencedParameter, DiagnosticCategory.Design, RuleLevel.BuildWarning, - description: s_localizableDescriptionFieldPublic, + description: s_localizableDescriptionUnreferencedParameter, isPortedFxCopRule: false, isDataflowRule: false); 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 84b168052d..1412dc25d1 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.cs.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.cs.xlf @@ -177,6 +177,16 @@ , Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’} + + For proper deserialization, remove the unreferenced parameter '{1}' in the constructor of '{0}' + For proper deserialization, remove the unreferenced parameter '{1}' in the constructor of '{0}' + + + + For a constructor having [JsonConstructor] attribute each parameter must be bound to a field or property for proper deserialization. + For a constructor having [JsonConstructor] attribute each parameter must be bound to a field or property for proper deserialization. + + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' 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 f9728b7a2e..5c8866b415 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.de.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.de.xlf @@ -177,6 +177,16 @@ , Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’} + + For proper deserialization, remove the unreferenced parameter '{1}' in the constructor of '{0}' + For proper deserialization, remove the unreferenced parameter '{1}' in the constructor of '{0}' + + + + For a constructor having [JsonConstructor] attribute each parameter must be bound to a field or property for proper deserialization. + For a constructor having [JsonConstructor] attribute each parameter must be bound to a field or property for proper deserialization. + + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' 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 6c2dc4012c..ee1528274d 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.es.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.es.xlf @@ -177,6 +177,16 @@ , Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’} + + For proper deserialization, remove the unreferenced parameter '{1}' in the constructor of '{0}' + For proper deserialization, remove the unreferenced parameter '{1}' in the constructor of '{0}' + + + + For a constructor having [JsonConstructor] attribute each parameter must be bound to a field or property for proper deserialization. + For a constructor having [JsonConstructor] attribute each parameter must be bound to a field or property for proper deserialization. + + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' 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 61f9a45938..43cee97695 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.fr.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.fr.xlf @@ -177,6 +177,16 @@ , Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’} + + For proper deserialization, remove the unreferenced parameter '{1}' in the constructor of '{0}' + For proper deserialization, remove the unreferenced parameter '{1}' in the constructor of '{0}' + + + + For a constructor having [JsonConstructor] attribute each parameter must be bound to a field or property for proper deserialization. + For a constructor having [JsonConstructor] attribute each parameter must be bound to a field or property for proper deserialization. + + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' 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 bcbaba7ac7..aa6c44c4b4 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.it.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.it.xlf @@ -177,6 +177,16 @@ , Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’} + + For proper deserialization, remove the unreferenced parameter '{1}' in the constructor of '{0}' + For proper deserialization, remove the unreferenced parameter '{1}' in the constructor of '{0}' + + + + For a constructor having [JsonConstructor] attribute each parameter must be bound to a field or property for proper deserialization. + For a constructor having [JsonConstructor] attribute each parameter must be bound to a field or property for proper deserialization. + + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' 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 82c90b267e..6c6c5a8283 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ja.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ja.xlf @@ -177,6 +177,16 @@ , Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’} + + For proper deserialization, remove the unreferenced parameter '{1}' in the constructor of '{0}' + For proper deserialization, remove the unreferenced parameter '{1}' in the constructor of '{0}' + + + + For a constructor having [JsonConstructor] attribute each parameter must be bound to a field or property for proper deserialization. + For a constructor having [JsonConstructor] attribute each parameter must be bound to a field or property for proper deserialization. + + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' 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 d9970fc482..24f4200090 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ko.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ko.xlf @@ -177,6 +177,16 @@ , Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’} + + For proper deserialization, remove the unreferenced parameter '{1}' in the constructor of '{0}' + For proper deserialization, remove the unreferenced parameter '{1}' in the constructor of '{0}' + + + + For a constructor having [JsonConstructor] attribute each parameter must be bound to a field or property for proper deserialization. + For a constructor having [JsonConstructor] attribute each parameter must be bound to a field or property for proper deserialization. + + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' 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 5739565f66..978d5b1755 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pl.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pl.xlf @@ -177,6 +177,16 @@ , Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’} + + For proper deserialization, remove the unreferenced parameter '{1}' in the constructor of '{0}' + For proper deserialization, remove the unreferenced parameter '{1}' in the constructor of '{0}' + + + + For a constructor having [JsonConstructor] attribute each parameter must be bound to a field or property for proper deserialization. + For a constructor having [JsonConstructor] attribute each parameter must be bound to a field or property for proper deserialization. + + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' 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 4d18167fb4..bf9c9d467c 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 @@ -177,6 +177,16 @@ , Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’} + + For proper deserialization, remove the unreferenced parameter '{1}' in the constructor of '{0}' + For proper deserialization, remove the unreferenced parameter '{1}' in the constructor of '{0}' + + + + For a constructor having [JsonConstructor] attribute each parameter must be bound to a field or property for proper deserialization. + For a constructor having [JsonConstructor] attribute each parameter must be bound to a field or property for proper deserialization. + + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' 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 0560898cea..bc66ea60ba 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ru.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ru.xlf @@ -177,6 +177,16 @@ , Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’} + + For proper deserialization, remove the unreferenced parameter '{1}' in the constructor of '{0}' + For proper deserialization, remove the unreferenced parameter '{1}' in the constructor of '{0}' + + + + For a constructor having [JsonConstructor] attribute each parameter must be bound to a field or property for proper deserialization. + For a constructor having [JsonConstructor] attribute each parameter must be bound to a field or property for proper deserialization. + + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' 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 804b3281da..f1a5bf5d2c 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.tr.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.tr.xlf @@ -177,6 +177,16 @@ , Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’} + + For proper deserialization, remove the unreferenced parameter '{1}' in the constructor of '{0}' + For proper deserialization, remove the unreferenced parameter '{1}' in the constructor of '{0}' + + + + For a constructor having [JsonConstructor] attribute each parameter must be bound to a field or property for proper deserialization. + For a constructor having [JsonConstructor] attribute each parameter must be bound to a field or property for proper deserialization. + + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' 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 5020183ce4..07149d3e16 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 @@ -177,6 +177,16 @@ , Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’} + + For proper deserialization, remove the unreferenced parameter '{1}' in the constructor of '{0}' + For proper deserialization, remove the unreferenced parameter '{1}' in the constructor of '{0}' + + + + For a constructor having [JsonConstructor] attribute each parameter must be bound to a field or property for proper deserialization. + For a constructor having [JsonConstructor] attribute each parameter must be bound to a field or property for proper deserialization. + + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' 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 2c6de7b9c3..cae9a40df8 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 @@ -177,6 +177,16 @@ , Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’} + + For proper deserialization, remove the unreferenced parameter '{1}' in the constructor of '{0}' + For proper deserialization, remove the unreferenced parameter '{1}' in the constructor of '{0}' + + + + For a constructor having [JsonConstructor] attribute each parameter must be bound to a field or property for proper deserialization. + For a constructor having [JsonConstructor] attribute each parameter must be bound to a field or property for proper deserialization. + + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' From 4d30c8fa654c9df1d4b3e20e894afffb05a368f3 Mon Sep 17 00:00:00 2001 From: psxvoid Date: Mon, 8 Mar 2021 19:17:03 +0300 Subject: [PATCH 39/64] Analyzer - free unused parameter set on symbol-end --- .../ConstructorParametersShouldMatchPropertyAndFieldNames.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs index 13ef358213..59e5ea279c 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs @@ -330,6 +330,8 @@ public static void ReportUnusedParameters(SymbolAnalysisContext context, IMethod ReportUnreferencedParameterDiagnostic(context, param); } + + referencedParameters.Free(context.CancellationToken); } } } From 641721db6f48ed716b0cc8fdae5ee40b9968b729 Mon Sep 17 00:00:00 2001 From: psxvoid Date: Mon, 8 Mar 2021 19:28:44 +0300 Subject: [PATCH 40/64] Analyzer - sort methods by visibility and logically --- ...ametersShouldMatchPropertyAndFieldNames.cs | 92 +++++++++---------- 1 file changed, 46 insertions(+), 46 deletions(-) diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs index 59e5ea279c..c60abe0833 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs @@ -187,6 +187,38 @@ public static void AnalyzeOperationAndReport(OperationAnalysisContext context, P } } + public bool ShouldAnalyzeMethod(IMethodSymbol method) + { + // We only care about constructors with parameters. + if (method.Parameters.IsEmpty) + { + return false; + } + + // We only care about constructors that are marked with JsonConstructor attribute. + if (!this.IsJsonConstructor(method)) + { + return false; + } + + return true; + } + + public static void ReportUnusedParameters(SymbolAnalysisContext context, IMethodSymbol ctor, PooledConcurrentSet referencedParameters) + { + foreach (var param in ctor.Parameters) + { + if (referencedParameters.Contains(param)) + { + continue; + } + + ReportUnreferencedParameterDiagnostic(context, param); + } + + referencedParameters.Free(context.CancellationToken); + } + private static bool IsSupportedProp([NotNullWhen(true)] IPropertySymbol? prop) { if (prop == null) @@ -234,24 +266,28 @@ private static bool IsParamMatchPropName(IParameterSymbol param, IPropertySymbol } private bool IsJsonConstructor([NotNullWhen(returnValue: true)] IMethodSymbol? method) - => method.IsConstructor() && - method.HasAttribute(this._jsonConstructorAttributeInfoType); + => method.IsConstructor() && + method.HasAttribute(this._jsonConstructorAttributeInfoType); - public bool ShouldAnalyzeMethod(IMethodSymbol method) + private static IMemberReferenceOperation? TryGetMemberReferenceOperation(IParameterReferenceOperation paramOperation) { - // We only care about constructors with parameters. - if (method.Parameters.IsEmpty) + if (paramOperation.Parent is IAssignmentOperation assignmentOperation + && assignmentOperation.Target is IMemberReferenceOperation assignmentTarget) { - return false; + return assignmentTarget; } - // We only care about constructors that are marked with JsonConstructor attribute. - if (!this.IsJsonConstructor(method)) + if (paramOperation.Parent is ITupleOperation sourceTuple + && sourceTuple.Parent is IConversionOperation conversion + && conversion.Parent is IDeconstructionAssignmentOperation deconstruction + && deconstruction.Target is ITupleOperation targetTuple) { - return false; + var paramIndexInTuple = sourceTuple.Elements.IndexOf(paramOperation); + + return targetTuple.Elements[paramIndexInTuple] as IMemberReferenceOperation; } - return true; + return null; } private static void ReportFieldDiagnostic(OperationAnalysisContext context, DiagnosticDescriptor diagnosticDescriptor, ParameterDiagnosticReason reason, IParameterSymbol param, IFieldSymbol field) @@ -297,42 +333,6 @@ private static void ReportUnreferencedParameterDiagnostic(SymbolAnalysisContext param.ContainingType.ToDisplayString(SymbolDisplayFormats.ShortSymbolDisplayFormat), param.Name)); } - - private static IMemberReferenceOperation? TryGetMemberReferenceOperation(IParameterReferenceOperation paramOperation) - { - if (paramOperation.Parent is IAssignmentOperation assignmentOperation - && assignmentOperation.Target is IMemberReferenceOperation assignmentTarget) - { - return assignmentTarget; - } - - if (paramOperation.Parent is ITupleOperation sourceTuple - && sourceTuple.Parent is IConversionOperation conversion - && conversion.Parent is IDeconstructionAssignmentOperation deconstruction - && deconstruction.Target is ITupleOperation targetTuple) - { - var paramIndexInTuple = sourceTuple.Elements.IndexOf(paramOperation); - - return targetTuple.Elements[paramIndexInTuple] as IMemberReferenceOperation; - } - - return null; - } - - public static void ReportUnusedParameters(SymbolAnalysisContext context, IMethodSymbol ctor, PooledConcurrentSet referencedParameters) - { - foreach (var param in ctor.Parameters) - { - if (referencedParameters.Contains(param)) - { - continue; - } - - ReportUnreferencedParameterDiagnostic(context, param); - } - - referencedParameters.Free(context.CancellationToken); - } } } } \ No newline at end of file From 65ea1adad3cf11eab76ff1a5c01d048e7267892f Mon Sep 17 00:00:00 2001 From: psxvoid Date: Tue, 9 Mar 2021 09:25:33 +0300 Subject: [PATCH 41/64] Analyzer - fix reversed words match (should not) --- ...ametersShouldMatchPropertyAndFieldNames.cs | 9 +- ...rsShouldMatchPropertyAndFieldNamesTests.cs | 164 ++++++++++++++++-- 2 files changed, 152 insertions(+), 21 deletions(-) diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs index c60abe0833..9eaf66b40f 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs @@ -1,5 +1,6 @@ // Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System; using System.Collections.Immutable; using System.Diagnostics.CodeAnalysis; using System.Linq; @@ -247,9 +248,9 @@ private static bool IsParamMatchFieldName(IParameterSymbol param, IFieldSymbol f } var paramWords = WordParser.Parse(param.Name, WordParserOptions.SplitCompoundWords); - var fieldWords = WordParser.Parse(field.Name, WordParserOptions.SplitCompoundWords).ToImmutableArray(); + var fieldWords = WordParser.Parse(field.Name, WordParserOptions.SplitCompoundWords); - return paramWords.All(x => WordParser.ContainsWord(x, WordParserOptions.SplitCompoundWords, fieldWords)); + return paramWords.SequenceEqual(fieldWords, StringComparer.OrdinalIgnoreCase); } private static bool IsParamMatchPropName(IParameterSymbol param, IPropertySymbol prop) @@ -260,9 +261,9 @@ private static bool IsParamMatchPropName(IParameterSymbol param, IPropertySymbol } var paramWords = WordParser.Parse(param.Name, WordParserOptions.SplitCompoundWords); - var propWords = WordParser.Parse(prop.Name, WordParserOptions.SplitCompoundWords).ToImmutableArray(); + var propWords = WordParser.Parse(prop.Name, WordParserOptions.SplitCompoundWords); - return paramWords.All(x => WordParser.ContainsWord(x, WordParserOptions.SplitCompoundWords, propWords)); + return paramWords.SequenceEqual(propWords, StringComparer.OrdinalIgnoreCase); } private bool IsJsonConstructor([NotNullWhen(returnValue: true)] IMethodSymbol? method) diff --git a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs index b88fb481f5..416a305eb6 100644 --- a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs +++ b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs @@ -80,15 +80,58 @@ public C1(int firstDrop, object secondDrop) public async Task CA1071_ClassPropsDoNotMatchNotJsonCtor_NoDiagnostics_Basic() { await VerifyBasicAnalyzerAsync(@" - Public Class C1 - Property firstProp() As Integer - Property secondProp() as Object - - Public Sub New(firstDrop as Integer, secondDrop as Object) - Me.firstProp = firstDrop - Me.secondProp = secondDrop - End Sub - End Class"); + Public Class C1 + Property firstProp() As Integer + Property secondProp() as Object + + Public Sub New(firstDrop as Integer, secondDrop as Object) + Me.firstProp = firstDrop + Me.secondProp = secondDrop + End Sub + End Class"); + } + + [Fact] + public async Task CA1071_ClassPropsDoNotMatchReversedWords_ConstructorParametersShouldMatchFieldNames_CSharp() + { + await VerifyCSharpAnalyzerAsync(@" + using System.Text.Json.Serialization; + + public class C1 + { + public int FirstProp { get; } + + public object SecondProp { get; } + + [JsonConstructor] + public C1(int {|#0:dropFirst|}, object {|#1:dropSecond|}) + { + this.FirstProp = dropFirst; + this.SecondProp = dropSecond; + } + }", + CA1071CSharpPropertyResultAt(0, "C1", "dropFirst", "FirstProp"), + CA1071CSharpPropertyResultAt(1, "C1", "dropSecond", "SecondProp")); + } + + [Fact] + public async Task CA1071_ClassPropsDoNotMatchReversedWords_ConstructorParametersShouldMatchFieldNames_Basic() + { + await VerifyBasicAnalyzerAsync(@" + Imports System.Text.Json.Serialization + + Public Class C1 + Property FirstProp() As Integer + Property SecondProp() as Object + + + Public Sub New({|#0:dropFirst|} as Integer, {|#1:dropSecond|} as Object) + Me.FirstProp = dropFirst + Me.SecondProp = dropSecond + End Sub + End Class", + CA1071BasicPropertyResultAt(0, "C1", "dropFirst", "FirstProp"), + CA1071BasicPropertyResultAt(1, "C1", "dropSecond", "SecondProp")); } [Fact] @@ -326,6 +369,48 @@ End Sub CA1071BasicFieldResultAt(1, "C1", "secondIField", "secondField")); } + [Fact] + public async Task CA1071_ClassFieldsDoNotMatchReversedWords_ConstructorParametersShouldMatchFieldNames_CSharp() + { + await VerifyCSharpAnalyzerAsync(@" + using System.Text.Json.Serialization; + + public class C1 + { + public int firstField; + public object secondField; + + [JsonConstructor] + public C1(int {|#0:fieldFirst|}, object {|#1:fieldSecond|}) + { + this.firstField = fieldFirst; + this.secondField = fieldSecond; + } + }", + CA1071CSharpFieldResultAt(0, "C1", "fieldFirst", "firstField"), + CA1071CSharpFieldResultAt(1, "C1", "fieldSecond", "secondField")); + } + + [Fact] + public async Task CA1071_ClassFieldsDoNotMatchReversedWords_ConstructorParametersShouldMatchFieldNames_Basic() + { + await VerifyBasicAnalyzerAsync(@" + Imports System.Text.Json.Serialization + + Public Class C1 + Public firstField as Integer + Public secondField as Object + + + Public Sub New({|#0:fieldFirst|} as Integer, {|#1:fieldSecond|} as Object) + Me.firstField = fieldFirst + Me.secondField = fieldSecond + End Sub + End Class", + CA1071BasicFieldResultAt(0, "C1", "fieldFirst", "firstField"), + CA1071BasicFieldResultAt(1, "C1", "fieldSecond", "secondField")); + } + [Fact] public async Task CA1071_ClassFieldsDoNotMatchNotJsonCtor_NoDiagnostics_CSharp() { @@ -673,25 +758,30 @@ public C1(int {|#0:firstProp|}, object {|#1:secondProp|}) } [Fact] - public async Task CA1071_RecordPropsDoNotMatchNotJsonCtor_NoDiagnostics_CSharp() + public async Task CA1071_RecordPropsDoNotMatch_ConstructorParametersShouldMatchPropertyNames_CSharp() { await VerifyCSharp9AnalyzerAsync(@" + using System.Text.Json.Serialization; + public record C1 { public int FirstProp { get; } public object SecondProp { get; } - public C1(int firstDrop, object secondDrop) + [JsonConstructor] + public C1(int {|#0:firstDrop|}, object {|#1:secondDrop|}) { this.FirstProp = firstDrop; this.SecondProp = secondDrop; } - }"); + }", + CA1071CSharpPropertyResultAt(0, "C1", "firstDrop", "FirstProp"), + CA1071CSharpPropertyResultAt(1, "C1", "secondDrop", "SecondProp")); } [Fact] - public async Task CA1071_RecordPropsDoNotMatch_ConstructorParametersShouldMatchPropertyNames_CSharp() + public async Task CA1071_RecordPropsDoNotMatchReversedWords_ConstructorParametersShouldMatchFieldNames_CSharp() { await VerifyCSharp9AnalyzerAsync(@" using System.Text.Json.Serialization; @@ -703,14 +793,32 @@ public record C1 public object SecondProp { get; } [JsonConstructor] - public C1(int {|#0:firstDrop|}, object {|#1:secondDrop|}) + public C1(int {|#0:dropFirst|}, object {|#1:dropSecond|}) + { + this.FirstProp = dropFirst; + this.SecondProp = dropSecond; + } + }", + CA1071CSharpPropertyResultAt(0, "C1", "dropFirst", "FirstProp"), + CA1071CSharpPropertyResultAt(1, "C1", "dropSecond", "SecondProp")); + } + + [Fact] + public async Task CA1071_RecordPropsDoNotMatchNotJsonCtor_NoDiagnostics_CSharp() + { + await VerifyCSharp9AnalyzerAsync(@" + public record C1 + { + public int FirstProp { get; } + + public object SecondProp { get; } + + public C1(int firstDrop, object secondDrop) { this.FirstProp = firstDrop; this.SecondProp = secondDrop; } - }", - CA1071CSharpPropertyResultAt(0, "C1", "firstDrop", "FirstProp"), - CA1071CSharpPropertyResultAt(1, "C1", "secondDrop", "SecondProp")); + }"); } [Fact] @@ -758,6 +866,28 @@ public C1(int {|#0:firstIField|}, object {|#1:secondIField|}) CA1071CSharpFieldResultAt(1, "C1", "secondIField", "secondField")); } + [Fact] + public async Task CA1071_RecordFieldsDoNotMatchReversedWords_ConstructorParametersShouldMatchFieldNames_CSharp() + { + await VerifyCSharp9AnalyzerAsync(@" + using System.Text.Json.Serialization; + + public record C1 + { + public int firstField; + public object secondField; + + [JsonConstructor] + public C1(int {|#0:fieldFirst|}, object {|#1:fieldSecond|}) + { + this.firstField = fieldFirst; + this.secondField = fieldSecond; + } + }", + CA1071CSharpFieldResultAt(0, "C1", "fieldFirst", "firstField"), + CA1071CSharpFieldResultAt(1, "C1", "fieldSecond", "secondField")); + } + [Fact] public async Task CA1071_RecordFieldsDoNotMatchAndTupleAssignment_ConstructorParametersShouldMatchFieldNames_CSharp() { From defb3c224c068e7badf029c2ce82ae4906166ce8 Mon Sep 17 00:00:00 2001 From: psxvoid Date: Tue, 9 Mar 2021 10:52:18 +0300 Subject: [PATCH 42/64] Analyzer - add regions, cleanup and organize tests --- ...rsShouldMatchPropertyAndFieldNamesTests.cs | 517 +++++++++++------- 1 file changed, 319 insertions(+), 198 deletions(-) diff --git a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs index 416a305eb6..195e403624 100644 --- a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs +++ b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs @@ -15,6 +15,8 @@ namespace Microsoft.NetCore.Analyzers.Runtime.UnitTests { public class ConstructorParametersShouldMatchPropertyAndFieldNamesTests { + #region Class Props Do Not Match Referenced Parameter Names + [Fact] public async Task CA1071_ClassPropsDoNotMatch_ConstructorParametersShouldMatchPropertyNames_CSharp() { @@ -24,7 +26,6 @@ await VerifyCSharpAnalyzerAsync(@" public class C1 { public int FirstProp { get; } - public object SecondProp { get; } [JsonConstructor] @@ -45,8 +46,8 @@ await VerifyBasicAnalyzerAsync(@" Imports System.Text.Json.Serialization Public Class C1 - Property FirstProp() As Integer - Property SecondProp() as Object + Public Property FirstProp() As Integer + Public Property SecondProp() as Object Public Sub New({|#0:firstDrop|} as Integer, {|#1:secondDrop|} as Object) @@ -65,7 +66,6 @@ await VerifyCSharpAnalyzerAsync(@" public class C1 { public int FirstProp { get; } - public object SecondProp { get; } public C1(int firstDrop, object secondDrop) @@ -81,8 +81,8 @@ public async Task CA1071_ClassPropsDoNotMatchNotJsonCtor_NoDiagnostics_Basic() { await VerifyBasicAnalyzerAsync(@" Public Class C1 - Property firstProp() As Integer - Property secondProp() as Object + Public Property firstProp() As Integer + Public Property secondProp() as Object Public Sub New(firstDrop as Integer, secondDrop as Object) Me.firstProp = firstDrop @@ -92,7 +92,7 @@ End Sub } [Fact] - public async Task CA1071_ClassPropsDoNotMatchReversedWords_ConstructorParametersShouldMatchFieldNames_CSharp() + public async Task CA1071_ClassPropsDoNotMatchReversedWords_ConstructorParametersShouldMatchPropertyNames_CSharp() { await VerifyCSharpAnalyzerAsync(@" using System.Text.Json.Serialization; @@ -100,7 +100,6 @@ await VerifyCSharpAnalyzerAsync(@" public class C1 { public int FirstProp { get; } - public object SecondProp { get; } [JsonConstructor] @@ -115,14 +114,14 @@ public C1(int {|#0:dropFirst|}, object {|#1:dropSecond|}) } [Fact] - public async Task CA1071_ClassPropsDoNotMatchReversedWords_ConstructorParametersShouldMatchFieldNames_Basic() + public async Task CA1071_ClassPropsDoNotMatchReversedWords_ConstructorParametersShouldMatchPropertyNames_Basic() { await VerifyBasicAnalyzerAsync(@" Imports System.Text.Json.Serialization Public Class C1 - Property FirstProp() As Integer - Property SecondProp() as Object + Public Property FirstProp() As Integer + Public Property SecondProp() as Object Public Sub New({|#0:dropFirst|} as Integer, {|#1:dropSecond|} as Object) @@ -135,7 +134,28 @@ End Sub } [Fact] - public async Task CA1071_ClassPropsDoNotMatchButMatchWithJsonPropertyName_ConstructorParametersShouldMatchFieldNames_CSharp() + public async Task CA1071_ClassPropsDoNotMatchAndTupleAssignment_ConstructorParametersShouldMatchPropertyNames_CSharp() + { + await VerifyCSharpAnalyzerAsync(@" + using System.Text.Json.Serialization; + + public class C1 + { + public int _FirstProp { get; } + public object _SecondProp { get; } + + [JsonConstructor] + public C1(int {|#0:firstProp|}, object {|#1:secondProp|}) + { + (this._FirstProp, this._SecondProp) = (firstProp, secondProp); + } + }", + CA1071CSharpPropertyResultAt(0, "C1", "firstProp", "_FirstProp"), + CA1071CSharpPropertyResultAt(1, "C1", "secondProp", "_SecondProp")); + } + + [Fact] + public async Task CA1071_ClassPropsDoNotMatchButMatchWithJsonPropertyName_ConstructorParametersShouldMatchPropertyNames_CSharp() { // This is the current behavior on deserialization - JsonPropertyName is ignored by the JsonConstructor's logic. await VerifyCSharpAnalyzerAsync(@" @@ -161,7 +181,7 @@ public C1(int {|#0:firstProp|}, object {|#1:secondProp|}) } [Fact] - public async Task CA1071_ClassPropsDoNotMatchButMatchWithJsonPropertyName_ConstructorParametersShouldMatchFieldNames_Basic() + public async Task CA1071_ClassPropsDoNotMatchButMatchWithJsonPropertyName_ConstructorParametersShouldMatchPropertyNames_Basic() { // This is the current behavior on deserialization - JsonPropertyName is ignored by the JsonConstructor's logic. await VerifyBasicAnalyzerAsync(@" @@ -184,27 +204,9 @@ End Sub CA1071BasicPropertyResultAt(1, "C1", "secondProp", "_SecondProp")); } - [Fact] - public async Task CA1071_ClassPropsDoNotMatchAndTupleAssignment_ConstructorParametersShouldMatchFieldNames_CSharp() - { - await VerifyCSharpAnalyzerAsync(@" - using System.Text.Json.Serialization; - - public class C1 - { - public int _FirstProp { get; } + #endregion - public object _SecondProp { get; } - - [JsonConstructor] - public C1(int {|#0:firstProp|}, object {|#1:secondProp|}) - { - (this._FirstProp, this._SecondProp) = (firstProp, secondProp); - } - }", - CA1071CSharpPropertyResultAt(0, "C1", "firstProp", "_FirstProp"), - CA1071CSharpPropertyResultAt(1, "C1", "secondProp", "_SecondProp")); - } + #region Class Props Match Referenced Parameter Names [Fact] public async Task CA1071_ClassPropsMatch_NoDiagnostics_CSharp() @@ -215,7 +217,6 @@ await VerifyCSharpAnalyzerAsync(@" public class C1 { public int FirstProp { get; } - public object SecondProp { get; } [JsonConstructor] @@ -234,8 +235,8 @@ await VerifyBasicAnalyzerAsync(@" Imports System.Text.Json.Serialization Public Class C1 - Property firstProp() As Integer - Property secondProp() as Object + Public Property firstProp() As Integer + Public Property secondProp() as Object Public Sub New(firstProp as Integer, secondProp as Object) @@ -246,7 +247,7 @@ End Sub } [Fact] - public async Task CA1071_ClassPropsMatchButUnreferenced_ConstructorParametersShouldMatchFieldNames_CSharp() + public async Task CA1071_ClassPropsMatchButUnreferenced_ConstructorParametersShouldBeBound_CSharp() { await VerifyCSharpAnalyzerAsync(@" using System.Text.Json.Serialization; @@ -254,7 +255,6 @@ await VerifyCSharpAnalyzerAsync(@" public class C1 { private int FirstProp { get; } - private object SecondProp { get; } [JsonConstructor] @@ -267,7 +267,7 @@ public C1(int {|#0:firstProp|}, object {|#1:secondProp|}) } [Fact] - public async Task CA1071_ClassPropsMatchButUnreferenced_ConstructorParametersShouldMatchFieldNames_Basic() + public async Task CA1071_ClassPropsMatchButUnreferenced_ConstructorParametersShouldBeBound_Basic() { await VerifyBasicAnalyzerAsync(@" Imports System.Text.Json.Serialization @@ -285,7 +285,7 @@ End Sub } [Fact] - public async Task CA1071_ClassPropsMatchButPrivate_ConstructorParametersShouldMatchFieldNames_CSharp() + public async Task CA1071_ClassPropsMatchButPrivate_ConstructorParametersShouldShouldMatchPublicProperties_CSharp() { await VerifyCSharpAnalyzerAsync(@" using System.Text.Json.Serialization; @@ -293,7 +293,6 @@ await VerifyCSharpAnalyzerAsync(@" public class C1 { private int FirstProp { get; } - private object SecondProp { get; } [JsonConstructor] @@ -308,7 +307,7 @@ public C1(int {|#0:firstProp|}, object {|#1:secondProp|}) } [Fact] - public async Task CA1071_ClassPropsMatchButPrivate_ConstructorParametersShouldMatchFieldNames_Basic() + public async Task CA1071_ClassPropsMatchButPrivate_ConstructorParametersShouldMatchPublicProperties_Basic() { await VerifyBasicAnalyzerAsync(@" Imports System.Text.Json.Serialization @@ -327,6 +326,10 @@ End Sub CA1071BasicPublicPropertyResultAt(1, "C1", "secondProp", "SecondProp")); } + #endregion + + #region Class Fields Do Not Match Referenced Parameter Names + [Fact] public async Task CA1071_ClassFieldsDoNotMatch_ConstructorParametersShouldMatchFieldNames_CSharp() { @@ -369,6 +372,38 @@ End Sub CA1071BasicFieldResultAt(1, "C1", "secondIField", "secondField")); } + [Fact] + public async Task CA1071_ClassFieldsDoNotMatchNotJsonCtor_NoDiagnostics_CSharp() + { + await VerifyCSharpAnalyzerAsync(@" + public class C1 + { + public int firstField; + public object secondField; + + public C1(int firstIField, object secondIField) + { + this.firstField = firstIField; + this.secondField = secondIField; + } + }"); + } + + [Fact] + public async Task CA1071_ClassFieldsDoNotMatchNotJsonCtor_NoDiagnostics_Basic() + { + await VerifyBasicAnalyzerAsync(@" + Public Class C1 + Public firstField as Integer + Public secondField as Object + + Public Sub New(firstIField as Integer, secondIField as Object) + Me.firstField = firstIField + Me.secondField = secondIField + End Sub + End Class"); + } + [Fact] public async Task CA1071_ClassFieldsDoNotMatchReversedWords_ConstructorParametersShouldMatchFieldNames_CSharp() { @@ -412,20 +447,24 @@ End Sub } [Fact] - public async Task CA1071_ClassFieldsDoNotMatchNotJsonCtor_NoDiagnostics_CSharp() + public async Task CA1071_ClassFieldsDoNotMatchAndTupleAssignment_ConstructorParametersShouldMatchFieldNames_CSharp() { await VerifyCSharpAnalyzerAsync(@" + using System.Text.Json.Serialization; + public class C1 { - public int firstField; - public object secondField; + public int _firstField; + public object _secondField; - public C1(int firstIField, object secondIField) + [JsonConstructor] + public C1(int {|#0:firstField|}, object {|#1:secondField|}) { - this.firstField = firstIField; - this.secondField = secondIField; + (_firstField, _secondField) = (firstField, secondField); } - }"); + }", + CA1071CSharpFieldResultAt(0, "C1", "firstField", "_firstField"), + CA1071CSharpFieldResultAt(1, "C1", "secondField", "_secondField")); } [Fact] @@ -478,51 +517,60 @@ End Sub CA1071BasicFieldResultAt(1, "C1", "secondField", "_secondField")); } - [Fact] - public async Task CA1071_ClassFieldsDoNotMatchNotJsonCtor_NoDiagnostics_Basic() - { - await VerifyBasicAnalyzerAsync(@" - Public Class C1 - Public firstField as Integer - Public secondField as Object + #endregion - Public Sub New(firstIField as Integer, secondIField as Object) - Me.firstField = firstIField - Me.secondField = secondIField - End Sub - End Class"); - } + #region Class Fields Match Referenced Parameter Names [Fact] - public async Task CA1071_ClassFieldsDoNotMatchAndTupleAssignment_ConstructorParametersShouldMatchFieldNames_CSharp() + public async Task CA1071_ClassFieldsMatchNoJsonInclude_NoDiagnostics_CSharp() { await VerifyCSharpAnalyzerAsync(@" using System.Text.Json.Serialization; public class C1 { - public int _firstField; - public object _secondField; + public int firstField; + public object secondField; [JsonConstructor] - public C1(int {|#0:firstField|}, object {|#1:secondField|}) + public C1(int firstField, object secondField) { - (_firstField, _secondField) = (firstField, secondField); + this.firstField = firstField; + this.secondField = secondField; } - }", - CA1071CSharpFieldResultAt(0, "C1", "firstField", "_firstField"), - CA1071CSharpFieldResultAt(1, "C1", "secondField", "_secondField")); + }"); } [Fact] - public async Task CA1071_ClassFieldsMatch_NoDiagnostics_CSharp() + public async Task CA1071_ClassFieldsMatchNoJsonInclude_NoDiagnostics_Basic() + { + await VerifyBasicAnalyzerAsync(@" + Imports System.Text.Json.Serialization + + Public Class C1 + Public firstField as Integer + Public secondField as Object + + + Public Sub New(firstField as Integer, secondField as Object) + Me.firstField = firstField + Me.secondField = secondField + End Sub + End Class"); + } + + [Fact] + public async Task CA1071_ClassFieldsMatchHasJsonInclude_NoDiagnostics_CSharp() { await VerifyCSharpAnalyzerAsync(@" using System.Text.Json.Serialization; public class C1 { + [JsonInclude] public int firstField; + + [JsonInclude] public object secondField; [JsonConstructor] @@ -531,18 +579,20 @@ public C1(int firstField, object secondField) this.firstField = firstField; this.secondField = secondField; } - }" - ); + }"); } [Fact] - public async Task CA1071_ClassFieldsMatch_NoDiagnostics_Basic() + public async Task CA1071_ClassFieldsMatchHasJsonInclude_NoDiagnostics_Basic() { await VerifyBasicAnalyzerAsync(@" Imports System.Text.Json.Serialization Public Class C1 + Public firstField as Integer + + Public secondField as Object @@ -554,7 +604,7 @@ End Sub } [Fact] - public async Task CA1071_ClassFieldsMatchButUnreferenced_ConstructorParametersShouldMatchFieldNames_CSharp() + public async Task CA1071_ClassFieldsMatchButUnreferenced_ConstructorParametersShouldBeBound_CSharp() { await VerifyCSharpAnalyzerAsync(@" using System.Text.Json.Serialization; @@ -574,7 +624,7 @@ public C1(int {|#0:firstField|}, object {|#1:secondField|}) } [Fact] - public async Task CA1071_ClassFieldsMatchButUnreferenced_ConstructorParametersShouldMatchFieldNames_Basic() + public async Task CA1071_ClassFieldsMatchButUnreferenced_ConstructorParametersShouldBeBound_Basic() { await VerifyBasicAnalyzerAsync(@" Imports System.Text.Json.Serialization @@ -592,61 +642,46 @@ End Sub } [Fact] - public async Task CA1071_ClassFieldsMatchButPrivateNoJsonInclude_ConstructorParametersShouldMatchFieldNames_CSharp() + public async Task CA1071_ClassFieldsMatchButPrivateNotJsonCtor_NoDiagnostics_CSharp() { await VerifyCSharpAnalyzerAsync(@" - using System.Text.Json.Serialization; - public class C1 { private int firstField; - private object secondField; - [JsonConstructor] - public C1(int {|#0:firstField|}, object {|#1:secondField|}) + public C1(int firstField, object secondField) { this.firstField = firstField; this.secondField = secondField; } - }", - CA1071CSharpPublicFieldResultAt(0, "C1", "firstField", "firstField"), - CA1071CSharpPublicFieldResultAt(1, "C1", "secondField", "secondField")); + }"); } [Fact] - public async Task CA1071_ClassFieldsMatchButPrivateNoJsonInclude_ConstructorParametersShouldMatchFieldNames_Basic() + public async Task CA1071_ClassFieldsMatchButPrivateNotJsonCtor_NoDiagnostics_Basic() { await VerifyBasicAnalyzerAsync(@" - Imports System.Text.Json.Serialization - Public Class C1 Private firstField as Integer - Private secondField as Object - - Public Sub New({|#0:firstField|} as Integer, {|#1:secondField|} as Object) + Public Sub New(firstField as Integer, secondField as Object) Me.firstField = firstField Me.secondField = secondField End Sub - End Class", - CA1071BasicPublicFieldResultAt(0, "C1", "firstField", "firstField"), - CA1071BasicPublicFieldResultAt(1, "C1", "secondField", "secondField")); + End Class"); } [Fact] - public async Task CA1071_ClassFieldsMatchButPrivateHasJsonInclude_ConstructorParametersShouldMatchFieldNames_CSharp() + public async Task CA1071_ClassFieldsMatchButPrivateNoJsonInclude_ConstructorParametersShouldMatchPublicFields_CSharp() { await VerifyCSharpAnalyzerAsync(@" using System.Text.Json.Serialization; - + public class C1 { - [JsonInclude] private int firstField; - - [JsonInclude] private object secondField; [JsonConstructor] @@ -661,16 +696,13 @@ public C1(int {|#0:firstField|}, object {|#1:secondField|}) } [Fact] - public async Task CA1071_ClassFieldsMatchButPrivateHasJsonInclude_ConstructorParametersShouldMatchFieldNames_Basic() + public async Task CA1071_ClassFieldsMatchButPrivateNoJsonInclude_ConstructorParametersShouldMatchPublicFields_Basic() { await VerifyBasicAnalyzerAsync(@" Imports System.Text.Json.Serialization - + Public Class C1 - Private firstField as Integer - - Private secondField as Object @@ -684,39 +716,59 @@ End Sub } [Fact] - public async Task CA1071_ClassFieldsMatchButPrivateNotJsonCtor_NoDiagnostics_CSharp() + public async Task CA1071_ClassFieldsMatchButPrivateHasJsonInclude_ConstructorParametersShouldMatchPublicFields_CSharp() { await VerifyCSharpAnalyzerAsync(@" + using System.Text.Json.Serialization; + public class C1 { + [JsonInclude] private int firstField; + + [JsonInclude] private object secondField; - public C1(int firstField, object secondField) + [JsonConstructor] + public C1(int {|#0:firstField|}, object {|#1:secondField|}) { this.firstField = firstField; this.secondField = secondField; } - }"); + }", + CA1071CSharpPublicFieldResultAt(0, "C1", "firstField", "firstField"), + CA1071CSharpPublicFieldResultAt(1, "C1", "secondField", "secondField")); } [Fact] - public async Task CA1071_ClassFieldsMatchButPrivateNotJsonCtor_NoDiagnostics_Basic() + public async Task CA1071_ClassFieldsMatchButPrivateHasJsonInclude_ConstructorParametersShouldMatchPublicFields_Basic() { await VerifyBasicAnalyzerAsync(@" + Imports System.Text.Json.Serialization + Public Class C1 + Private firstField as Integer + + Private secondField as Object - Public Sub New(firstField as Integer, secondField as Object) + + Public Sub New({|#0:firstField|} as Integer, {|#1:secondField|} as Object) Me.firstField = firstField Me.secondField = secondField End Sub - End Class"); + End Class", + CA1071BasicPublicFieldResultAt(0, "C1", "firstField", "firstField"), + CA1071BasicPublicFieldResultAt(1, "C1", "secondField", "secondField")); } + #endregion + + #region Record Props Do Not Match Referenced Parameter Names + [Fact] - public async Task CA1071_RecordPropsMatch_NoDiagnostics_CSharp() + public async Task CA1071_RecordPropsDoNotMatch_ConstructorParametersShouldMatchPropertyNames_CSharp() { await VerifyCSharp9AnalyzerAsync(@" using System.Text.Json.Serialization; @@ -724,41 +776,60 @@ await VerifyCSharp9AnalyzerAsync(@" public record C1 { public int FirstProp { get; } - public object SecondProp { get; } [JsonConstructor] - public C1(int firstProp, object secondProp) + public C1(int {|#0:firstDrop|}, object {|#1:secondDrop|}) { - this.FirstProp = firstProp; - this.SecondProp = secondProp; + this.FirstProp = firstDrop; + this.SecondProp = secondDrop; + } + }", + CA1071CSharpPropertyResultAt(0, "C1", "firstDrop", "FirstProp"), + CA1071CSharpPropertyResultAt(1, "C1", "secondDrop", "SecondProp")); + } + + [Fact] + public async Task CA1071_RecordPropsDoNotMatchNotJsonCtor_NoDiagnostics_CSharp() + { + await VerifyCSharp9AnalyzerAsync(@" + public record C1 + { + public int FirstProp { get; } + public object SecondProp { get; } + + public C1(int firstDrop, object secondDrop) + { + this.FirstProp = firstDrop; + this.SecondProp = secondDrop; } }"); } [Fact] - public async Task CA1071_RecordPropsMatchButUnreferenced_ConstructorParametersShouldMatchFieldNames_CSharp() + public async Task CA1071_RecordPropsDoNotMatchReversedWords_ConstructorParametersShouldMatchPropertyNames_CSharp() { await VerifyCSharp9AnalyzerAsync(@" using System.Text.Json.Serialization; public record C1 { - private int FirstProp { get; } - - private object SecondProp { get; } + public int FirstProp { get; } + public object SecondProp { get; } [JsonConstructor] - public C1(int {|#0:firstProp|}, object {|#1:secondProp|}) + public C1(int {|#0:dropFirst|}, object {|#1:dropSecond|}) { + this.FirstProp = dropFirst; + this.SecondProp = dropSecond; } }", - CA1071CSharpUnreferencedParamResultAt(0, "C1", "firstProp"), - CA1071CSharpUnreferencedParamResultAt(1, "C1", "secondProp")); + CA1071CSharpPropertyResultAt(0, "C1", "dropFirst", "FirstProp"), + CA1071CSharpPropertyResultAt(1, "C1", "dropSecond", "SecondProp")); } [Fact] - public async Task CA1071_RecordPropsDoNotMatch_ConstructorParametersShouldMatchPropertyNames_CSharp() + public async Task CA1071_RecordPropsDoNotMatchAndTupleAssignment_ConstructorParametersShouldMatchPropertyNames_CSharp() { await VerifyCSharp9AnalyzerAsync(@" using System.Text.Json.Serialization; @@ -766,14 +837,12 @@ await VerifyCSharp9AnalyzerAsync(@" public record C1 { public int FirstProp { get; } - public object SecondProp { get; } [JsonConstructor] public C1(int {|#0:firstDrop|}, object {|#1:secondDrop|}) { - this.FirstProp = firstDrop; - this.SecondProp = secondDrop; + (this.FirstProp, this.SecondProp) = (firstDrop, secondDrop); } }", CA1071CSharpPropertyResultAt(0, "C1", "firstDrop", "FirstProp"), @@ -781,68 +850,101 @@ public C1(int {|#0:firstDrop|}, object {|#1:secondDrop|}) } [Fact] - public async Task CA1071_RecordPropsDoNotMatchReversedWords_ConstructorParametersShouldMatchFieldNames_CSharp() + public async Task CA1071_RecordPropsDoNotMatchButMatchWithJsonPropertyName_ConstructorParametersShouldMatchPropertyNames_CSharp() { + // This is the current behavior on deserialization - JsonPropertyName is ignored by the JsonConstructor's logic. await VerifyCSharp9AnalyzerAsync(@" using System.Text.Json.Serialization; public record C1 { - public int FirstProp { get; } + [JsonPropertyName(""FirstProp"")] + public int _FirstProp { get; } - public object SecondProp { get; } + [JsonPropertyName(""SecondProp"")] + public object _SecondProp { get; } [JsonConstructor] - public C1(int {|#0:dropFirst|}, object {|#1:dropSecond|}) + public C1(int {|#0:firstProp|}, object {|#1:secondProp|}) { - this.FirstProp = dropFirst; - this.SecondProp = dropSecond; + this._FirstProp = firstProp; + this._SecondProp = secondProp; } }", - CA1071CSharpPropertyResultAt(0, "C1", "dropFirst", "FirstProp"), - CA1071CSharpPropertyResultAt(1, "C1", "dropSecond", "SecondProp")); + CA1071CSharpPropertyResultAt(0, "C1", "firstProp", "_FirstProp"), + CA1071CSharpPropertyResultAt(1, "C1", "secondProp", "_SecondProp")); } + #endregion + + #region Record Props Match Referenced Parameter Names + [Fact] - public async Task CA1071_RecordPropsDoNotMatchNotJsonCtor_NoDiagnostics_CSharp() + public async Task CA1071_RecordPropsMatch_NoDiagnostics_CSharp() { await VerifyCSharp9AnalyzerAsync(@" + using System.Text.Json.Serialization; + public record C1 { public int FirstProp { get; } - public object SecondProp { get; } - public C1(int firstDrop, object secondDrop) + [JsonConstructor] + public C1(int firstProp, object secondProp) { - this.FirstProp = firstDrop; - this.SecondProp = secondDrop; + this.FirstProp = firstProp; + this.SecondProp = secondProp; } }"); } [Fact] - public async Task CA1071_RecordPropsDoNotMatchAndTupleAssignment_ConstructorParametersShouldMatchPropertyNames_CSharp() + public async Task CA1071_RecordPropsMatchButUnreferenced_ConstructorParametersShouldBeBound_CSharp() { await VerifyCSharp9AnalyzerAsync(@" using System.Text.Json.Serialization; public record C1 { - public int FirstProp { get; } + private int FirstProp { get; } + private object SecondProp { get; } - public object SecondProp { get; } + [JsonConstructor] + public C1(int {|#0:firstProp|}, object {|#1:secondProp|}) + { + } + }", + CA1071CSharpUnreferencedParamResultAt(0, "C1", "firstProp"), + CA1071CSharpUnreferencedParamResultAt(1, "C1", "secondProp")); + } + + [Fact] + public async Task CA1071_RecordPropsMatchButPrivate_ConstructorParametersShouldShouldMatchPublicProperties_CSharp() + { + await VerifyCSharp9AnalyzerAsync(@" + using System.Text.Json.Serialization; + + public record C1 + { + private int FirstProp { get; } + private object SecondProp { get; } [JsonConstructor] - public C1(int {|#0:firstDrop|}, object {|#1:secondDrop|}) + public C1(int {|#0:firstProp|}, object {|#1:secondProp|}) { - (this.FirstProp, this.SecondProp) = (firstDrop, secondDrop); + this.FirstProp = firstProp; + this.SecondProp = secondProp; } }", - CA1071CSharpPropertyResultAt(0, "C1", "firstDrop", "FirstProp"), - CA1071CSharpPropertyResultAt(1, "C1", "secondDrop", "SecondProp")); + CA1071CSharpPublicPropertyResultAt(0, "C1", "firstProp", "FirstProp"), + CA1071CSharpPublicPropertyResultAt(1, "C1", "secondProp", "SecondProp")); } + #endregion + + #region Record Fields Do Not Match Referenced Parameter Names + [Fact] public async Task CA1071_RecordFieldsDoNotMatch_ConstructorParametersShouldMatchFieldNames_CSharp() { @@ -852,7 +954,6 @@ await VerifyCSharp9AnalyzerAsync(@" public record C1 { public int firstField; - public object secondField; [JsonConstructor] @@ -866,6 +967,23 @@ public C1(int {|#0:firstIField|}, object {|#1:secondIField|}) CA1071CSharpFieldResultAt(1, "C1", "secondIField", "secondField")); } + [Fact] + public async Task CA1071_RecordFieldsDoNotMatchNotJsonCtor_NoDiagnostics_CSharp() + { + await VerifyCSharp9AnalyzerAsync(@" + public record C1 + { + public int firstField; + public object secondField; + + public C1(int firstIField, object secondIField) + { + this.firstField = firstIField; + this.secondField = secondIField; + } + }"); + } + [Fact] public async Task CA1071_RecordFieldsDoNotMatchReversedWords_ConstructorParametersShouldMatchFieldNames_CSharp() { @@ -897,7 +1015,6 @@ await VerifyCSharp9AnalyzerAsync(@" public record C1 { public int firstField; - public object secondField; [JsonConstructor] @@ -911,7 +1028,7 @@ public C1(int {|#0:firstIField|}, object {|#1:secondIField|}) } [Fact] - public async Task CA1071_RecordPropsDoNotMatchButMatchWithJsonPropertyName_ConstructorParametersShouldMatchFieldNames_CSharp() + public async Task CA1071_RecordFieldsDoNotMatchButMatchWithJsonPropertyName_ConstructorParametersShouldMatchFieldNames_CSharp() { // This is the current behavior on deserialization - JsonPropertyName is ignored by the JsonConstructor's logic. await VerifyCSharp9AnalyzerAsync(@" @@ -919,25 +1036,29 @@ await VerifyCSharp9AnalyzerAsync(@" public record C1 { - [JsonPropertyName(""FirstProp"")] - public int _FirstProp { get; } + [JsonPropertyName(""firstField"")] + public int _firstField; - [JsonPropertyName(""SecondProp"")] - public object _SecondProp { get; } + [JsonPropertyName(""secondField"")] + public object _secondField; [JsonConstructor] - public C1(int {|#0:firstProp|}, object {|#1:secondProp|}) + public C1(int {|#0:firstField|}, object {|#1:secondField|}) { - this._FirstProp = firstProp; - this._SecondProp = secondProp; + this._firstField = firstField; + this._secondField = secondField; } }", - CA1071CSharpPropertyResultAt(0, "C1", "firstProp", "_FirstProp"), - CA1071CSharpPropertyResultAt(1, "C1", "secondProp", "_SecondProp")); + CA1071CSharpFieldResultAt(0, "C1", "firstField", "_firstField"), + CA1071CSharpFieldResultAt(1, "C1", "secondField", "_secondField")); } + #endregion + + #region Record Fields Match Referenced Parameter Names + [Fact] - public async Task CA1071_RecordFieldsMatch_NoDiagnostics_CSharp() + public async Task CA1071_RecordFieldsMatchNoJsonInclude_NoDiagnostics_CSharp() { await VerifyCSharp9AnalyzerAsync(@" using System.Text.Json.Serialization; @@ -945,7 +1066,6 @@ await VerifyCSharp9AnalyzerAsync(@" public record C1 { public int firstField; - public object secondField; [JsonConstructor] @@ -958,117 +1078,116 @@ public C1(int firstField, object secondField) } [Fact] - public async Task CA1071_RecordFieldsMatchButUnreferenced_ConstructorParametersShouldMatchFieldNames_CSharp() + public async Task CA1071_RecordFieldsMatchHasJsonInclude_NoDiagnostics_CSharp() { await VerifyCSharp9AnalyzerAsync(@" using System.Text.Json.Serialization; public record C1 { + [JsonInclude] public int firstField; + + [JsonInclude] public object secondField; [JsonConstructor] - public C1(int {|#0:firstField|}, object {|#1:secondField|}) + public C1(int firstField, object secondField) { + this.firstField = firstField; + this.secondField = secondField; } - }", - CA1071CSharpUnreferencedParamResultAt(0, "C1", "firstField"), - CA1071CSharpUnreferencedParamResultAt(1, "C1", "secondField")); + }"); } [Fact] - public async Task CA1071_RecordFieldsMatchButPrivateNoJsonInclude_ConstructorParametersShouldMatchFieldNames_CSharp() + public async Task CA1071_RecordFieldsMatchButUnreferenced_ConstructorParametersShouldBeBound_CSharp() { await VerifyCSharp9AnalyzerAsync(@" using System.Text.Json.Serialization; public record C1 { - private int firstField; - - private object secondField; + public int firstField; + public object secondField; [JsonConstructor] public C1(int {|#0:firstField|}, object {|#1:secondField|}) { - this.firstField = firstField; - this.secondField = secondField; } }", - CA1071CSharpPublicFieldResultAt(0, "C1", "firstField", "firstField"), - CA1071CSharpPublicFieldResultAt(1, "C1", "secondField", "secondField")); + CA1071CSharpUnreferencedParamResultAt(0, "C1", "firstField"), + CA1071CSharpUnreferencedParamResultAt(1, "C1", "secondField")); } [Fact] - public async Task CA1071_RecordFieldsMatchButPrivateHasJsonInclude_ConstructorParametersShouldMatchFieldNames_CSharp() + public async Task CA1071_RecordFieldsMatchButPrivateNotJsonCtor_NoDiagnostics_CSharp() { await VerifyCSharp9AnalyzerAsync(@" - using System.Text.Json.Serialization; - public record C1 { - [JsonInclude] private int firstField; - - [JsonInclude] private object secondField; - [JsonConstructor] - public C1(int {|#0:firstField|}, object {|#1:secondField|}) + public C1(int firstField, object secondField) { this.firstField = firstField; this.secondField = secondField; } - }", - CA1071CSharpPublicFieldResultAt(0, "C1", "firstField", "firstField"), - CA1071CSharpPublicFieldResultAt(1, "C1", "secondField", "secondField")); + }"); } [Fact] - public async Task CA1071_RecordFieldsMatchButPrivateNotJsonCtor_NoDiagnostics_CSharp() + public async Task CA1071_RecordFieldsMatchButPrivateNoJsonInclude_ConstructorParametersShouldMatchPublicFields_CSharp() { await VerifyCSharp9AnalyzerAsync(@" + using System.Text.Json.Serialization; + public record C1 { private int firstField; - private object secondField; - public C1(int firstField, object secondField) + [JsonConstructor] + public C1(int {|#0:firstField|}, object {|#1:secondField|}) { this.firstField = firstField; this.secondField = secondField; } - }"); + }", + CA1071CSharpPublicFieldResultAt(0, "C1", "firstField", "firstField"), + CA1071CSharpPublicFieldResultAt(1, "C1", "secondField", "secondField")); } [Fact] - public async Task CA1071_RecordFieldsDoNotMatchButMatchWithJsonPropertyName_ConstructorParametersShouldMatchFieldNames_CSharp() + public async Task CA1071_RecordFieldsMatchButPrivateHasJsonInclude_ConstructorParametersShouldMatchPublicFields_CSharp() { - // This is the current behavior on deserialization - JsonPropertyName is ignored by the JsonConstructor's logic. await VerifyCSharp9AnalyzerAsync(@" using System.Text.Json.Serialization; public record C1 { - [JsonPropertyName(""firstField"")] - public int _firstField; + [JsonInclude] + private int firstField; - [JsonPropertyName(""secondField"")] - public object _secondField; + [JsonInclude] + private object secondField; [JsonConstructor] public C1(int {|#0:firstField|}, object {|#1:secondField|}) { - this._firstField = firstField; - this._secondField = secondField; + this.firstField = firstField; + this.secondField = secondField; } }", - CA1071CSharpFieldResultAt(0, "C1", "firstField", "_firstField"), - CA1071CSharpFieldResultAt(1, "C1", "secondField", "_secondField")); + CA1071CSharpPublicFieldResultAt(0, "C1", "firstField", "firstField"), + CA1071CSharpPublicFieldResultAt(1, "C1", "secondField", "secondField")); } + #endregion + + #region Test Helpers + private static async Task VerifyCSharpAnalyzerAsync(string source, params DiagnosticResult[] expected) { var csharpTest = new VerifyCS.Test @@ -1158,5 +1277,7 @@ private DiagnosticResult CA1071BasicUnreferencedParamResultAt(int markupKey, par => VerifyVB.Diagnostic(ConstructorParametersShouldMatchPropertyAndFieldNamesAnalyzer.UnreferencedParameterRule) .WithLocation(markupKey) .WithArguments(arguments); + + #endregion } } \ No newline at end of file From d4345d5e99b95873e92c379c84d19989e353b997 Mon Sep 17 00:00:00 2001 From: psxvoid Date: Tue, 9 Mar 2021 11:07:01 +0300 Subject: [PATCH 43/64] Analyzer - simplify return in ShouldAnalyzerMethod --- ...onstructorParametersShouldMatchPropertyAndFieldNames.cs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs index 9eaf66b40f..2c7c7541fd 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs @@ -197,12 +197,7 @@ public bool ShouldAnalyzeMethod(IMethodSymbol method) } // We only care about constructors that are marked with JsonConstructor attribute. - if (!this.IsJsonConstructor(method)) - { - return false; - } - - return true; + return this.IsJsonConstructor(method); } public static void ReportUnusedParameters(SymbolAnalysisContext context, IMethodSymbol ctor, PooledConcurrentSet referencedParameters) From 2008be661e3cecb41b1f7efad850eac686d687a4 Mon Sep 17 00:00:00 2001 From: psxvoid Date: Tue, 9 Mar 2021 11:12:49 +0300 Subject: [PATCH 44/64] Analyzer - simplify supported members matching --- ...ametersShouldMatchPropertyAndFieldNames.cs | 34 ++----------------- 1 file changed, 2 insertions(+), 32 deletions(-) diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs index 2c7c7541fd..50a5f3fcfa 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs @@ -151,15 +151,8 @@ public static void AnalyzeOperationAndReport(OperationAnalysisContext context, P } IParameterSymbol param = operation.Parameter; - var field = referencedSymbol as IFieldSymbol; - var prop = referencedSymbol as IPropertySymbol; - if (field == null && prop == null) - { - return; - } - - if (IsSupportedField(field)) + if (referencedSymbol is IFieldSymbol field) { if (!IsParamMatchFieldName(param, field)) { @@ -170,11 +163,8 @@ public static void AnalyzeOperationAndReport(OperationAnalysisContext context, P { ReportFieldDiagnostic(context, FieldPublicRule, ParameterDiagnosticReason.FieldInappropriateVisibility, param, field); } - - return; } - - if (IsSupportedProp(prop)) + else if (referencedSymbol is IPropertySymbol prop) { if (!IsParamMatchPropName(param, prop)) { @@ -215,26 +205,6 @@ public static void ReportUnusedParameters(SymbolAnalysisContext context, IMethod referencedParameters.Free(context.CancellationToken); } - private static bool IsSupportedProp([NotNullWhen(true)] IPropertySymbol? prop) - { - if (prop == null) - { - return false; - } - - return true; - } - - private static bool IsSupportedField([NotNullWhen(true)] IFieldSymbol? field) - { - if (field == null) - { - return false; - } - - return true; - } - private static bool IsParamMatchFieldName(IParameterSymbol param, IFieldSymbol field) { if (param.Name.Length != field.Name.Length) From c0687c635bb01900fba861e0b2f949960f6beeaa Mon Sep 17 00:00:00 2001 From: psxvoid Date: Tue, 9 Mar 2021 11:23:03 +0300 Subject: [PATCH 45/64] Add TODO - referenced members are not static diagnostic --- .../ConstructorParametersShouldMatchPropertyAndFieldNames.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs index 50a5f3fcfa..c177b384ca 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs @@ -145,6 +145,7 @@ public static void AnalyzeOperationAndReport(OperationAnalysisContext context, P IMemberReferenceOperation? memberReferenceOperation = TryGetMemberReferenceOperation(operation); ISymbol? referencedSymbol = memberReferenceOperation?.GetReferencedMemberOrLocalOrParameter(); + // TODO: convert "IsStatic" to a separate diagnostic if (referencedSymbol == null || referencedSymbol.IsStatic) { return; From 313bdfd48177c1f66f20451dae1fcecee15bba8b Mon Sep 17 00:00:00 2001 From: psxvoid Date: Tue, 9 Mar 2021 11:34:52 +0300 Subject: [PATCH 46/64] Analyzer - format compilation start action registration --- ...ametersShouldMatchPropertyAndFieldNames.cs | 45 +++++++++---------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs index c177b384ca..dd24590859 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs @@ -86,37 +86,36 @@ public override void Initialize(AnalysisContext context) context.EnableConcurrentExecution(); context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None); - context.RegisterCompilationStartAction( - (compilationStartContext) => + context.RegisterCompilationStartAction((compilationStartContext) => + { + INamedTypeSymbol? jsonConstructorAttributeNamedSymbol = compilationStartContext.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemTextJsonSerializationJsonConstructorAttribute); + if (jsonConstructorAttributeNamedSymbol == null) { - INamedTypeSymbol? jsonConstructorAttributeNamedSymbol = compilationStartContext.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemTextJsonSerializationJsonConstructorAttribute); - if (jsonConstructorAttributeNamedSymbol == null) - { - return; - } + return; + } - var paramAnalyzer = new ParameterAnalyzer(jsonConstructorAttributeNamedSymbol); + var paramAnalyzer = new ParameterAnalyzer(jsonConstructorAttributeNamedSymbol); - compilationStartContext.RegisterSymbolStartAction((symbolStartContext) => - { - var constructors = ((INamedTypeSymbol)symbolStartContext.Symbol).InstanceConstructors; + compilationStartContext.RegisterSymbolStartAction((symbolStartContext) => + { + var constructors = ((INamedTypeSymbol)symbolStartContext.Symbol).InstanceConstructors; - foreach (var ctor in constructors) + foreach (var ctor in constructors) + { + if (paramAnalyzer.ShouldAnalyzeMethod(ctor)) { - if (paramAnalyzer.ShouldAnalyzeMethod(ctor)) - { - var referencedParameters = PooledConcurrentSet.GetInstance(); + var referencedParameters = PooledConcurrentSet.GetInstance(); - symbolStartContext.RegisterOperationAction( - context => ParameterAnalyzer.AnalyzeOperationAndReport(context, referencedParameters), - OperationKind.ParameterReference); + symbolStartContext.RegisterOperationAction( + context => ParameterAnalyzer.AnalyzeOperationAndReport(context, referencedParameters), + OperationKind.ParameterReference); - symbolStartContext.RegisterSymbolEndAction( - context => ParameterAnalyzer.ReportUnusedParameters(context, ctor, referencedParameters)); - } + symbolStartContext.RegisterSymbolEndAction( + context => ParameterAnalyzer.ReportUnusedParameters(context, ctor, referencedParameters)); } - }, SymbolKind.NamedType); - }); + } + }, SymbolKind.NamedType); + }); } internal enum ParameterDiagnosticReason From fa0fd41b7c6c84c8a16b40faf68c703cae93a0e8 Mon Sep 17 00:00:00 2001 From: psxvoid Date: Tue, 9 Mar 2021 11:53:04 +0300 Subject: [PATCH 47/64] Analyzer - merge name match logic into a single method --- ...ametersShouldMatchPropertyAndFieldNames.cs | 25 +++++-------------- 1 file changed, 6 insertions(+), 19 deletions(-) diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs index dd24590859..d8d0b4948d 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs @@ -154,7 +154,7 @@ public static void AnalyzeOperationAndReport(OperationAnalysisContext context, P if (referencedSymbol is IFieldSymbol field) { - if (!IsParamMatchFieldName(param, field)) + if (!IsParamMatchesReferencedMemberName(param, field)) { ReportFieldDiagnostic(context, FieldRule, ParameterDiagnosticReason.NameMismatch, param, field); } @@ -166,7 +166,7 @@ public static void AnalyzeOperationAndReport(OperationAnalysisContext context, P } else if (referencedSymbol is IPropertySymbol prop) { - if (!IsParamMatchPropName(param, prop)) + if (!IsParamMatchesReferencedMemberName(param, prop)) { ReportPropertyDiagnostic(context, PropertyNameRule, ParameterDiagnosticReason.NameMismatch, param, prop); } @@ -205,30 +205,17 @@ public static void ReportUnusedParameters(SymbolAnalysisContext context, IMethod referencedParameters.Free(context.CancellationToken); } - private static bool IsParamMatchFieldName(IParameterSymbol param, IFieldSymbol field) + private static bool IsParamMatchesReferencedMemberName(IParameterSymbol param, ISymbol referencedMember) { - if (param.Name.Length != field.Name.Length) + if (param.Name.Length != referencedMember.Name.Length) { return false; } var paramWords = WordParser.Parse(param.Name, WordParserOptions.SplitCompoundWords); - var fieldWords = WordParser.Parse(field.Name, WordParserOptions.SplitCompoundWords); + var memberWords = WordParser.Parse(referencedMember.Name, WordParserOptions.SplitCompoundWords); - return paramWords.SequenceEqual(fieldWords, StringComparer.OrdinalIgnoreCase); - } - - private static bool IsParamMatchPropName(IParameterSymbol param, IPropertySymbol prop) - { - if (param.Name.Length != prop.Name.Length) - { - return false; - } - - var paramWords = WordParser.Parse(param.Name, WordParserOptions.SplitCompoundWords); - var propWords = WordParser.Parse(prop.Name, WordParserOptions.SplitCompoundWords); - - return paramWords.SequenceEqual(propWords, StringComparer.OrdinalIgnoreCase); + return paramWords.SequenceEqual(memberWords, StringComparer.OrdinalIgnoreCase); } private bool IsJsonConstructor([NotNullWhen(returnValue: true)] IMethodSymbol? method) From 4d4a1ec7050a62ac7d04070899c7adc0ee469f97 Mon Sep 17 00:00:00 2001 From: psxvoid Date: Tue, 9 Mar 2021 12:02:24 +0300 Subject: [PATCH 48/64] Add "key" postfix to diagnostic parameter keys --- ...sShouldMatchPropertyAndFieldNames.Fixer.cs | 2 +- ...ametersShouldMatchPropertyAndFieldNames.cs | 19 ++++++++++--------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.Fixer.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.Fixer.cs index 7d0dc4e134..101c9ceece 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.Fixer.cs +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.Fixer.cs @@ -45,7 +45,7 @@ public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) } // This approach is very naive. Most likely we want to support NamingStyleOptions, available in Roslyn. - string newName = LowerFirstLetter(diagnostic.Properties[ConstructorParametersShouldMatchPropertyAndFieldNamesAnalyzer.ReferencedFieldOrPropertyName]); + string newName = LowerFirstLetter(diagnostic.Properties[ConstructorParametersShouldMatchPropertyAndFieldNamesAnalyzer.ReferencedFieldOrPropertyNameKey]); context.RegisterCodeFix( CodeAction.Create( diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs index d8d0b4948d..0d4b002d16 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs @@ -20,9 +20,10 @@ namespace Microsoft.NetCore.Analyzers.Runtime public sealed class ConstructorParametersShouldMatchPropertyAndFieldNamesAnalyzer : DiagnosticAnalyzer { internal const string RuleId = "CA1071"; - internal const string ReferencedFieldOrPropertyName = "ReferencedFieldOrPropertyName"; - internal const string DiagnosticReason = "DiagnosticReason"; - internal const string UnreferencedParameterName = "UnreferencedParameterName"; + + internal const string ReferencedFieldOrPropertyNameKey = "ReferencedFieldOrPropertyName"; + internal const string DiagnosticReasonKey = "DiagnosticReason"; + internal const string UnreferencedParameterNameKey = "UnreferencedParameterName"; private static readonly LocalizableString s_localizableTitle = new LocalizableResourceString(nameof(MicrosoftNetCoreAnalyzersResources.ConstructorParametersShouldMatchPropertyNamesTitle), MicrosoftNetCoreAnalyzersResources.ResourceManager, typeof(MicrosoftNetCoreAnalyzersResources)); @@ -246,8 +247,8 @@ private bool IsJsonConstructor([NotNullWhen(returnValue: true)] IMethodSymbol? m private static void ReportFieldDiagnostic(OperationAnalysisContext context, DiagnosticDescriptor diagnosticDescriptor, ParameterDiagnosticReason reason, IParameterSymbol param, IFieldSymbol field) { var properties = ImmutableDictionary.Empty - .SetItem(ReferencedFieldOrPropertyName, field.Name) - .SetItem(DiagnosticReason, reason.ToString()); + .SetItem(ReferencedFieldOrPropertyNameKey, field.Name) + .SetItem(DiagnosticReasonKey, reason.ToString()); context.ReportDiagnostic( param.CreateDiagnostic( @@ -261,8 +262,8 @@ private static void ReportFieldDiagnostic(OperationAnalysisContext context, Diag private static void ReportPropertyDiagnostic(OperationAnalysisContext context, DiagnosticDescriptor diagnosticDescriptor, ParameterDiagnosticReason reason, IParameterSymbol param, IPropertySymbol prop) { var properties = ImmutableDictionary.Empty - .SetItem(ReferencedFieldOrPropertyName, prop.Name) - .SetItem(DiagnosticReason, reason.ToString()); + .SetItem(ReferencedFieldOrPropertyNameKey, prop.Name) + .SetItem(DiagnosticReasonKey, reason.ToString()); context.ReportDiagnostic( param.CreateDiagnostic( @@ -276,8 +277,8 @@ private static void ReportPropertyDiagnostic(OperationAnalysisContext context, D private static void ReportUnreferencedParameterDiagnostic(SymbolAnalysisContext context, IParameterSymbol param) { var properties = ImmutableDictionary.Empty - .SetItem(UnreferencedParameterName, param.Name) - .SetItem(DiagnosticReason, ParameterDiagnosticReason.UnreferencedParameter.ToString()); + .SetItem(UnreferencedParameterNameKey, param.Name) + .SetItem(DiagnosticReasonKey, ParameterDiagnosticReason.UnreferencedParameter.ToString()); context.ReportDiagnostic( param.CreateDiagnostic( From e05915983f9a07366d33d8c57ae0919b25e51aa1 Mon Sep 17 00:00:00 2001 From: psxvoid Date: Wed, 23 Jun 2021 05:45:33 +0300 Subject: [PATCH 49/64] Analyzer - remove unused parameter analysis --- .../MicrosoftNetCoreAnalyzersResources.resx | 6 - ...ametersShouldMatchPropertyAndFieldNames.cs | 53 +------ .../MicrosoftNetCoreAnalyzersResources.cs.xlf | 10 -- .../MicrosoftNetCoreAnalyzersResources.de.xlf | 10 -- .../MicrosoftNetCoreAnalyzersResources.es.xlf | 10 -- .../MicrosoftNetCoreAnalyzersResources.fr.xlf | 10 -- .../MicrosoftNetCoreAnalyzersResources.it.xlf | 10 -- .../MicrosoftNetCoreAnalyzersResources.ja.xlf | 10 -- .../MicrosoftNetCoreAnalyzersResources.ko.xlf | 10 -- .../MicrosoftNetCoreAnalyzersResources.pl.xlf | 10 -- ...crosoftNetCoreAnalyzersResources.pt-BR.xlf | 10 -- .../MicrosoftNetCoreAnalyzersResources.ru.xlf | 10 -- .../MicrosoftNetCoreAnalyzersResources.tr.xlf | 10 -- ...osoftNetCoreAnalyzersResources.zh-Hans.xlf | 10 -- ...osoftNetCoreAnalyzersResources.zh-Hant.xlf | 10 -- ...rsShouldMatchPropertyAndFieldNamesTests.cs | 129 +----------------- 16 files changed, 4 insertions(+), 314 deletions(-) diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx index 088ce99b6d..343639d6f3 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx @@ -1543,10 +1543,4 @@ For a constructor having [JsonConstructor] attribute each parameter must be bound to a public field for proper deserialization. - - For proper deserialization, remove the unreferenced parameter '{1}' in the constructor of '{0}' - - - For a constructor having [JsonConstructor] attribute each parameter must be bound to a field or property for proper deserialization. - \ No newline at end of file diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs index 0d4b002d16..aaaa2bf0f6 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs @@ -6,7 +6,6 @@ using System.Linq; using Analyzer.Utilities; using Analyzer.Utilities.Extensions; -using Analyzer.Utilities.PooledObjects; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.Operations; @@ -23,7 +22,6 @@ public sealed class ConstructorParametersShouldMatchPropertyAndFieldNamesAnalyze internal const string ReferencedFieldOrPropertyNameKey = "ReferencedFieldOrPropertyName"; internal const string DiagnosticReasonKey = "DiagnosticReason"; - internal const string UnreferencedParameterNameKey = "UnreferencedParameterName"; private static readonly LocalizableString s_localizableTitle = new LocalizableResourceString(nameof(MicrosoftNetCoreAnalyzersResources.ConstructorParametersShouldMatchPropertyNamesTitle), MicrosoftNetCoreAnalyzersResources.ResourceManager, typeof(MicrosoftNetCoreAnalyzersResources)); @@ -36,9 +34,6 @@ public sealed class ConstructorParametersShouldMatchPropertyAndFieldNamesAnalyze private static readonly LocalizableString s_localizableMessageFieldPublic = new LocalizableResourceString(nameof(MicrosoftNetCoreAnalyzersResources.ConstructorParameterShouldMatchFieldWithPublicVisibility), MicrosoftNetCoreAnalyzersResources.ResourceManager, typeof(MicrosoftNetCoreAnalyzersResources)); private static readonly LocalizableString s_localizableDescriptionFieldPublic = new LocalizableResourceString(nameof(MicrosoftNetCoreAnalyzersResources.ConstructorParametersShouldMatchFieldWithPublicVisibilityDescription), MicrosoftNetCoreAnalyzersResources.ResourceManager, typeof(MicrosoftNetCoreAnalyzersResources)); - private static readonly LocalizableString s_localizableMessageUnreferencedParameter = new LocalizableResourceString(nameof(MicrosoftNetCoreAnalyzersResources.ConstructorParameterShouldBeReferenced), MicrosoftNetCoreAnalyzersResources.ResourceManager, typeof(MicrosoftNetCoreAnalyzersResources)); - private static readonly LocalizableString s_localizableDescriptionUnreferencedParameter = new LocalizableResourceString(nameof(MicrosoftNetCoreAnalyzersResources.ConstructorParameterShouldBeReferencedDescription), MicrosoftNetCoreAnalyzersResources.ResourceManager, typeof(MicrosoftNetCoreAnalyzersResources)); - internal static DiagnosticDescriptor PropertyNameRule = DiagnosticDescriptorHelper.Create(RuleId, s_localizableTitle, s_localizableMessageProperty, @@ -71,14 +66,6 @@ public sealed class ConstructorParametersShouldMatchPropertyAndFieldNamesAnalyze description: s_localizableDescriptionFieldPublic, isPortedFxCopRule: false, isDataflowRule: false); - internal static DiagnosticDescriptor UnreferencedParameterRule = DiagnosticDescriptorHelper.Create(RuleId, - s_localizableTitle, - s_localizableMessageUnreferencedParameter, - DiagnosticCategory.Design, - RuleLevel.BuildWarning, - description: s_localizableDescriptionUnreferencedParameter, - isPortedFxCopRule: false, - isDataflowRule: false); public override ImmutableArray SupportedDiagnostics => ImmutableArray.Create(PropertyNameRule, FieldRule); @@ -105,14 +92,9 @@ public override void Initialize(AnalysisContext context) { if (paramAnalyzer.ShouldAnalyzeMethod(ctor)) { - var referencedParameters = PooledConcurrentSet.GetInstance(); - symbolStartContext.RegisterOperationAction( - context => ParameterAnalyzer.AnalyzeOperationAndReport(context, referencedParameters), + context => ParameterAnalyzer.AnalyzeOperationAndReport(context), OperationKind.ParameterReference); - - symbolStartContext.RegisterSymbolEndAction( - context => ParameterAnalyzer.ReportUnusedParameters(context, ctor, referencedParameters)); } } }, SymbolKind.NamedType); @@ -136,12 +118,10 @@ public ParameterAnalyzer(INamedTypeSymbol jsonConstructorAttributeInfoType) _jsonConstructorAttributeInfoType = jsonConstructorAttributeInfoType; } - public static void AnalyzeOperationAndReport(OperationAnalysisContext context, PooledConcurrentSet referencedParameters) + public static void AnalyzeOperationAndReport(OperationAnalysisContext context) { var operation = (IParameterReferenceOperation)context.Operation; - referencedParameters.Add(operation.Parameter); - IMemberReferenceOperation? memberReferenceOperation = TryGetMemberReferenceOperation(operation); ISymbol? referencedSymbol = memberReferenceOperation?.GetReferencedMemberOrLocalOrParameter(); @@ -191,21 +171,6 @@ public bool ShouldAnalyzeMethod(IMethodSymbol method) return this.IsJsonConstructor(method); } - public static void ReportUnusedParameters(SymbolAnalysisContext context, IMethodSymbol ctor, PooledConcurrentSet referencedParameters) - { - foreach (var param in ctor.Parameters) - { - if (referencedParameters.Contains(param)) - { - continue; - } - - ReportUnreferencedParameterDiagnostic(context, param); - } - - referencedParameters.Free(context.CancellationToken); - } - private static bool IsParamMatchesReferencedMemberName(IParameterSymbol param, ISymbol referencedMember) { if (param.Name.Length != referencedMember.Name.Length) @@ -273,20 +238,6 @@ private static void ReportPropertyDiagnostic(OperationAnalysisContext context, D param.Name, prop.Name)); } - - private static void ReportUnreferencedParameterDiagnostic(SymbolAnalysisContext context, IParameterSymbol param) - { - var properties = ImmutableDictionary.Empty - .SetItem(UnreferencedParameterNameKey, param.Name) - .SetItem(DiagnosticReasonKey, ParameterDiagnosticReason.UnreferencedParameter.ToString()); - - context.ReportDiagnostic( - param.CreateDiagnostic( - UnreferencedParameterRule, - properties, - param.ContainingType.ToDisplayString(SymbolDisplayFormats.ShortSymbolDisplayFormat), - param.Name)); - } } } } \ 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 1412dc25d1..84b168052d 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.cs.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.cs.xlf @@ -177,16 +177,6 @@ , Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’} - - For proper deserialization, remove the unreferenced parameter '{1}' in the constructor of '{0}' - For proper deserialization, remove the unreferenced parameter '{1}' in the constructor of '{0}' - - - - For a constructor having [JsonConstructor] attribute each parameter must be bound to a field or property for proper deserialization. - For a constructor having [JsonConstructor] attribute each parameter must be bound to a field or property for proper deserialization. - - For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' 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 5c8866b415..f9728b7a2e 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.de.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.de.xlf @@ -177,16 +177,6 @@ , Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’} - - For proper deserialization, remove the unreferenced parameter '{1}' in the constructor of '{0}' - For proper deserialization, remove the unreferenced parameter '{1}' in the constructor of '{0}' - - - - For a constructor having [JsonConstructor] attribute each parameter must be bound to a field or property for proper deserialization. - For a constructor having [JsonConstructor] attribute each parameter must be bound to a field or property for proper deserialization. - - For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' 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 ee1528274d..6c2dc4012c 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.es.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.es.xlf @@ -177,16 +177,6 @@ , Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’} - - For proper deserialization, remove the unreferenced parameter '{1}' in the constructor of '{0}' - For proper deserialization, remove the unreferenced parameter '{1}' in the constructor of '{0}' - - - - For a constructor having [JsonConstructor] attribute each parameter must be bound to a field or property for proper deserialization. - For a constructor having [JsonConstructor] attribute each parameter must be bound to a field or property for proper deserialization. - - For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' 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 43cee97695..61f9a45938 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.fr.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.fr.xlf @@ -177,16 +177,6 @@ , Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’} - - For proper deserialization, remove the unreferenced parameter '{1}' in the constructor of '{0}' - For proper deserialization, remove the unreferenced parameter '{1}' in the constructor of '{0}' - - - - For a constructor having [JsonConstructor] attribute each parameter must be bound to a field or property for proper deserialization. - For a constructor having [JsonConstructor] attribute each parameter must be bound to a field or property for proper deserialization. - - For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' 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 aa6c44c4b4..bcbaba7ac7 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.it.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.it.xlf @@ -177,16 +177,6 @@ , Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’} - - For proper deserialization, remove the unreferenced parameter '{1}' in the constructor of '{0}' - For proper deserialization, remove the unreferenced parameter '{1}' in the constructor of '{0}' - - - - For a constructor having [JsonConstructor] attribute each parameter must be bound to a field or property for proper deserialization. - For a constructor having [JsonConstructor] attribute each parameter must be bound to a field or property for proper deserialization. - - For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' 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 6c6c5a8283..82c90b267e 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ja.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ja.xlf @@ -177,16 +177,6 @@ , Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’} - - For proper deserialization, remove the unreferenced parameter '{1}' in the constructor of '{0}' - For proper deserialization, remove the unreferenced parameter '{1}' in the constructor of '{0}' - - - - For a constructor having [JsonConstructor] attribute each parameter must be bound to a field or property for proper deserialization. - For a constructor having [JsonConstructor] attribute each parameter must be bound to a field or property for proper deserialization. - - For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' 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 24f4200090..d9970fc482 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ko.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ko.xlf @@ -177,16 +177,6 @@ , Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’} - - For proper deserialization, remove the unreferenced parameter '{1}' in the constructor of '{0}' - For proper deserialization, remove the unreferenced parameter '{1}' in the constructor of '{0}' - - - - For a constructor having [JsonConstructor] attribute each parameter must be bound to a field or property for proper deserialization. - For a constructor having [JsonConstructor] attribute each parameter must be bound to a field or property for proper deserialization. - - For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' 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 978d5b1755..5739565f66 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pl.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pl.xlf @@ -177,16 +177,6 @@ , Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’} - - For proper deserialization, remove the unreferenced parameter '{1}' in the constructor of '{0}' - For proper deserialization, remove the unreferenced parameter '{1}' in the constructor of '{0}' - - - - For a constructor having [JsonConstructor] attribute each parameter must be bound to a field or property for proper deserialization. - For a constructor having [JsonConstructor] attribute each parameter must be bound to a field or property for proper deserialization. - - For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' 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 bf9c9d467c..4d18167fb4 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 @@ -177,16 +177,6 @@ , Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’} - - For proper deserialization, remove the unreferenced parameter '{1}' in the constructor of '{0}' - For proper deserialization, remove the unreferenced parameter '{1}' in the constructor of '{0}' - - - - For a constructor having [JsonConstructor] attribute each parameter must be bound to a field or property for proper deserialization. - For a constructor having [JsonConstructor] attribute each parameter must be bound to a field or property for proper deserialization. - - For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' 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 bc66ea60ba..0560898cea 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ru.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ru.xlf @@ -177,16 +177,6 @@ , Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’} - - For proper deserialization, remove the unreferenced parameter '{1}' in the constructor of '{0}' - For proper deserialization, remove the unreferenced parameter '{1}' in the constructor of '{0}' - - - - For a constructor having [JsonConstructor] attribute each parameter must be bound to a field or property for proper deserialization. - For a constructor having [JsonConstructor] attribute each parameter must be bound to a field or property for proper deserialization. - - For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' 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 f1a5bf5d2c..804b3281da 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.tr.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.tr.xlf @@ -177,16 +177,6 @@ , Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’} - - For proper deserialization, remove the unreferenced parameter '{1}' in the constructor of '{0}' - For proper deserialization, remove the unreferenced parameter '{1}' in the constructor of '{0}' - - - - For a constructor having [JsonConstructor] attribute each parameter must be bound to a field or property for proper deserialization. - For a constructor having [JsonConstructor] attribute each parameter must be bound to a field or property for proper deserialization. - - For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' 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 07149d3e16..5020183ce4 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 @@ -177,16 +177,6 @@ , Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’} - - For proper deserialization, remove the unreferenced parameter '{1}' in the constructor of '{0}' - For proper deserialization, remove the unreferenced parameter '{1}' in the constructor of '{0}' - - - - For a constructor having [JsonConstructor] attribute each parameter must be bound to a field or property for proper deserialization. - For a constructor having [JsonConstructor] attribute each parameter must be bound to a field or property for proper deserialization. - - For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' 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 cae9a40df8..2c6de7b9c3 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 @@ -177,16 +177,6 @@ , Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’} - - For proper deserialization, remove the unreferenced parameter '{1}' in the constructor of '{0}' - For proper deserialization, remove the unreferenced parameter '{1}' in the constructor of '{0}' - - - - For a constructor having [JsonConstructor] attribute each parameter must be bound to a field or property for proper deserialization. - For a constructor having [JsonConstructor] attribute each parameter must be bound to a field or property for proper deserialization. - - For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' diff --git a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs index 195e403624..1a4f03cac6 100644 --- a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs +++ b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs @@ -190,7 +190,7 @@ Imports System.Text.Json.Serialization Public Class C1 Public Property _FirstProp() As Integer - + Public Property _SecondProp() as Object @@ -246,44 +246,6 @@ End Sub End Class"); } - [Fact] - public async Task CA1071_ClassPropsMatchButUnreferenced_ConstructorParametersShouldBeBound_CSharp() - { - await VerifyCSharpAnalyzerAsync(@" - using System.Text.Json.Serialization; - - public class C1 - { - private int FirstProp { get; } - private object SecondProp { get; } - - [JsonConstructor] - public C1(int {|#0:firstProp|}, object {|#1:secondProp|}) - { - } - }", - CA1071CSharpUnreferencedParamResultAt(0, "C1", "firstProp"), - CA1071CSharpUnreferencedParamResultAt(1, "C1", "secondProp")); - } - - [Fact] - public async Task CA1071_ClassPropsMatchButUnreferenced_ConstructorParametersShouldBeBound_Basic() - { - await VerifyBasicAnalyzerAsync(@" - Imports System.Text.Json.Serialization - - Public Class C1 - Private Property FirstProp() As Integer - Private Property SecondProp() as Object - - - Public Sub New({|#0:firstProp|} as Integer, {|#1:secondProp|} as Object) - End Sub - End Class", - CA1071BasicUnreferencedParamResultAt(0, "C1", "firstProp"), - CA1071BasicUnreferencedParamResultAt(1, "C1", "secondProp")); - } - [Fact] public async Task CA1071_ClassPropsMatchButPrivate_ConstructorParametersShouldShouldMatchPublicProperties_CSharp() { @@ -503,7 +465,7 @@ Imports System.Text.Json.Serialization Public Class C1 Public _firstField As Integer - + Public _secondField as Object @@ -603,43 +565,6 @@ End Sub End Class"); } - [Fact] - public async Task CA1071_ClassFieldsMatchButUnreferenced_ConstructorParametersShouldBeBound_CSharp() - { - await VerifyCSharpAnalyzerAsync(@" - using System.Text.Json.Serialization; - - public class C1 - { - public int firstField; - public object secondField; - - [JsonConstructor] - public C1(int {|#0:firstField|}, object {|#1:secondField|}) - { - } - }", - CA1071CSharpUnreferencedParamResultAt(0, "C1", "firstField"), - CA1071CSharpUnreferencedParamResultAt(1, "C1", "secondField")); - } - - [Fact] - public async Task CA1071_ClassFieldsMatchButUnreferenced_ConstructorParametersShouldBeBound_Basic() - { - await VerifyBasicAnalyzerAsync(@" - Imports System.Text.Json.Serialization - - Public Class C1 - Public firstField as Integer - Public secondField as Object - - - Public Sub New({|#0:firstField|} as Integer, {|#1:secondField|} as Object) - End Sub - End Class", - CA1071BasicUnreferencedParamResultAt(0, "C1", "firstField"), - CA1071BasicUnreferencedParamResultAt(1, "C1", "secondField")); - } [Fact] public async Task CA1071_ClassFieldsMatchButPrivateNotJsonCtor_NoDiagnostics_CSharp() @@ -899,26 +824,6 @@ public C1(int firstProp, object secondProp) }"); } - [Fact] - public async Task CA1071_RecordPropsMatchButUnreferenced_ConstructorParametersShouldBeBound_CSharp() - { - await VerifyCSharp9AnalyzerAsync(@" - using System.Text.Json.Serialization; - - public record C1 - { - private int FirstProp { get; } - private object SecondProp { get; } - - [JsonConstructor] - public C1(int {|#0:firstProp|}, object {|#1:secondProp|}) - { - } - }", - CA1071CSharpUnreferencedParamResultAt(0, "C1", "firstProp"), - CA1071CSharpUnreferencedParamResultAt(1, "C1", "secondProp")); - } - [Fact] public async Task CA1071_RecordPropsMatchButPrivate_ConstructorParametersShouldShouldMatchPublicProperties_CSharp() { @@ -1100,26 +1005,6 @@ public C1(int firstField, object secondField) }"); } - [Fact] - public async Task CA1071_RecordFieldsMatchButUnreferenced_ConstructorParametersShouldBeBound_CSharp() - { - await VerifyCSharp9AnalyzerAsync(@" - using System.Text.Json.Serialization; - - public record C1 - { - public int firstField; - public object secondField; - - [JsonConstructor] - public C1(int {|#0:firstField|}, object {|#1:secondField|}) - { - } - }", - CA1071CSharpUnreferencedParamResultAt(0, "C1", "firstField"), - CA1071CSharpUnreferencedParamResultAt(1, "C1", "secondField")); - } - [Fact] public async Task CA1071_RecordFieldsMatchButPrivateNotJsonCtor_NoDiagnostics_CSharp() { @@ -1268,16 +1153,6 @@ private DiagnosticResult CA1071BasicFieldResultAt(int markupKey, params string[] .WithLocation(markupKey) .WithArguments(arguments); - private DiagnosticResult CA1071CSharpUnreferencedParamResultAt(int markupKey, params string[] arguments) - => VerifyCS.Diagnostic(ConstructorParametersShouldMatchPropertyAndFieldNamesAnalyzer.UnreferencedParameterRule) - .WithLocation(markupKey) - .WithArguments(arguments); - - private DiagnosticResult CA1071BasicUnreferencedParamResultAt(int markupKey, params string[] arguments) - => VerifyVB.Diagnostic(ConstructorParametersShouldMatchPropertyAndFieldNamesAnalyzer.UnreferencedParameterRule) - .WithLocation(markupKey) - .WithArguments(arguments); - #endregion } } \ No newline at end of file From a95f8030da1fa4ad68b0f4c4c78582bdfcb4813b Mon Sep 17 00:00:00 2001 From: psxvoid Date: Wed, 23 Jun 2021 05:51:41 +0300 Subject: [PATCH 50/64] Analyzer - init using scoped context variable --- ...ructorParametersShouldMatchPropertyAndFieldNames.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs index aaaa2bf0f6..923321bd66 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs @@ -74,9 +74,9 @@ public override void Initialize(AnalysisContext context) context.EnableConcurrentExecution(); context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None); - context.RegisterCompilationStartAction((compilationStartContext) => + context.RegisterCompilationStartAction((context) => { - INamedTypeSymbol? jsonConstructorAttributeNamedSymbol = compilationStartContext.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemTextJsonSerializationJsonConstructorAttribute); + INamedTypeSymbol? jsonConstructorAttributeNamedSymbol = context.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemTextJsonSerializationJsonConstructorAttribute); if (jsonConstructorAttributeNamedSymbol == null) { return; @@ -84,15 +84,15 @@ public override void Initialize(AnalysisContext context) var paramAnalyzer = new ParameterAnalyzer(jsonConstructorAttributeNamedSymbol); - compilationStartContext.RegisterSymbolStartAction((symbolStartContext) => + context.RegisterSymbolStartAction((context) => { - var constructors = ((INamedTypeSymbol)symbolStartContext.Symbol).InstanceConstructors; + var constructors = ((INamedTypeSymbol)context.Symbol).InstanceConstructors; foreach (var ctor in constructors) { if (paramAnalyzer.ShouldAnalyzeMethod(ctor)) { - symbolStartContext.RegisterOperationAction( + context.RegisterOperationAction( context => ParameterAnalyzer.AnalyzeOperationAndReport(context), OperationKind.ParameterReference); } From 1e627444f1ba899051488b673796eae45674b65e Mon Sep 17 00:00:00 2001 From: psxvoid Date: Wed, 23 Jun 2021 06:32:05 +0300 Subject: [PATCH 51/64] Analyzer - fix build: invalid whitespace in tests --- ...ParametersShouldMatchPropertyAndFieldNamesTests.cs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs index 1a4f03cac6..7b563f9651 100644 --- a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs +++ b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs @@ -531,7 +531,7 @@ public class C1 { [JsonInclude] public int firstField; - + [JsonInclude] public object secondField; @@ -553,7 +553,7 @@ Imports System.Text.Json.Serialization Public Class C1 Public firstField as Integer - + Public secondField as Object @@ -565,7 +565,6 @@ End Sub End Class"); } - [Fact] public async Task CA1071_ClassFieldsMatchButPrivateNotJsonCtor_NoDiagnostics_CSharp() { @@ -603,7 +602,7 @@ public async Task CA1071_ClassFieldsMatchButPrivateNoJsonInclude_ConstructorPara { await VerifyCSharpAnalyzerAsync(@" using System.Text.Json.Serialization; - + public class C1 { private int firstField; @@ -625,7 +624,7 @@ public async Task CA1071_ClassFieldsMatchButPrivateNoJsonInclude_ConstructorPara { await VerifyBasicAnalyzerAsync(@" Imports System.Text.Json.Serialization - + Public Class C1 Private firstField as Integer Private secondField as Object @@ -992,7 +991,7 @@ public record C1 { [JsonInclude] public int firstField; - + [JsonInclude] public object secondField; From 1e1d3825ea05634fb8305715301a7a025c21f277 Mon Sep 17 00:00:00 2001 From: Pavel Sapehin Date: Mon, 28 Jun 2021 09:17:52 +0300 Subject: [PATCH 52/64] Analyzer - inline ExportFixProvider and Shared attributes Co-authored-by: Buyaa Namnan --- ...ructorParametersShouldMatchPropertyAndFieldNames.Fixer.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.Fixer.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.Fixer.cs index 101c9ceece..17ef5b39da 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.Fixer.cs +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.Fixer.cs @@ -17,8 +17,7 @@ namespace Microsoft.NetCore.Analyzers.Runtime /// CA1071: Constructor parameters should match property and field names. /// Based on . /// - [ExportCodeFixProvider(LanguageNames.CSharp, LanguageNames.VisualBasic)] - [Shared] + [ExportCodeFixProvider(LanguageNames.CSharp, LanguageNames.VisualBasic), [Shared] public sealed class ConstructorParametersShouldMatchPropertyAndFieldNamesFixer : CodeFixProvider { public override ImmutableArray FixableDiagnosticIds => ImmutableArray.Create(ConstructorParametersShouldMatchPropertyAndFieldNamesAnalyzer.RuleId); @@ -67,4 +66,4 @@ private static async Task GetUpdatedDocumentForParameterRenameAsync(Do return newSolution.GetDocument(document.Id)!; } } -} \ No newline at end of file +} From 9a727e4e6fb97c5603c669cc70c0a8d469f58b67 Mon Sep 17 00:00:00 2001 From: psxvoid Date: Mon, 28 Jun 2021 09:59:27 +0300 Subject: [PATCH 53/64] Revert "Analyzer - inline ExportFixProvider and Shared attributes" This reverts commit 1e1d3825ea05634fb8305715301a7a025c21f277. --- ...ructorParametersShouldMatchPropertyAndFieldNames.Fixer.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.Fixer.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.Fixer.cs index 17ef5b39da..101c9ceece 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.Fixer.cs +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.Fixer.cs @@ -17,7 +17,8 @@ namespace Microsoft.NetCore.Analyzers.Runtime /// CA1071: Constructor parameters should match property and field names. /// Based on . /// - [ExportCodeFixProvider(LanguageNames.CSharp, LanguageNames.VisualBasic), [Shared] + [ExportCodeFixProvider(LanguageNames.CSharp, LanguageNames.VisualBasic)] + [Shared] public sealed class ConstructorParametersShouldMatchPropertyAndFieldNamesFixer : CodeFixProvider { public override ImmutableArray FixableDiagnosticIds => ImmutableArray.Create(ConstructorParametersShouldMatchPropertyAndFieldNamesAnalyzer.RuleId); @@ -66,4 +67,4 @@ private static async Task GetUpdatedDocumentForParameterRenameAsync(Do return newSolution.GetDocument(document.Id)!; } } -} +} \ No newline at end of file From 8dacfcbab18cc739cf6d205e597d011b4a43782a Mon Sep 17 00:00:00 2001 From: psxvoid Date: Mon, 28 Jun 2021 10:08:42 +0300 Subject: [PATCH 54/64] Fixer - inline ExportFixProvider and Shared attributes (fixed) --- ...structorParametersShouldMatchPropertyAndFieldNames.Fixer.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.Fixer.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.Fixer.cs index 101c9ceece..8472b2c76e 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.Fixer.cs +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.Fixer.cs @@ -17,8 +17,7 @@ namespace Microsoft.NetCore.Analyzers.Runtime /// CA1071: Constructor parameters should match property and field names. /// Based on . /// - [ExportCodeFixProvider(LanguageNames.CSharp, LanguageNames.VisualBasic)] - [Shared] + [ExportCodeFixProvider(LanguageNames.CSharp, LanguageNames.VisualBasic), Shared] public sealed class ConstructorParametersShouldMatchPropertyAndFieldNamesFixer : CodeFixProvider { public override ImmutableArray FixableDiagnosticIds => ImmutableArray.Create(ConstructorParametersShouldMatchPropertyAndFieldNamesAnalyzer.RuleId); From ab492ca2d81d89b5eb7295a4194d03e0ec595890 Mon Sep 17 00:00:00 2001 From: psxvoid Date: Mon, 28 Jun 2021 10:35:00 +0300 Subject: [PATCH 55/64] Analyzer - use single diagnostic rule per analyzer --- .../MicrosoftNetCoreAnalyzersResources.resx | 79 ++++----- ...sShouldMatchPropertyAndFieldNames.Fixer.cs | 2 +- ...ametersShouldMatchPropertyAndFieldNames.cs | 52 ++---- .../MicrosoftNetCoreAnalyzersResources.cs.xlf | 39 +---- .../MicrosoftNetCoreAnalyzersResources.de.xlf | 39 +---- .../MicrosoftNetCoreAnalyzersResources.es.xlf | 39 +---- .../MicrosoftNetCoreAnalyzersResources.fr.xlf | 39 +---- .../MicrosoftNetCoreAnalyzersResources.it.xlf | 39 +---- .../MicrosoftNetCoreAnalyzersResources.ja.xlf | 39 +---- .../MicrosoftNetCoreAnalyzersResources.ko.xlf | 39 +---- .../MicrosoftNetCoreAnalyzersResources.pl.xlf | 39 +---- ...crosoftNetCoreAnalyzersResources.pt-BR.xlf | 39 +---- .../MicrosoftNetCoreAnalyzersResources.ru.xlf | 39 +---- .../MicrosoftNetCoreAnalyzersResources.tr.xlf | 39 +---- ...osoftNetCoreAnalyzersResources.zh-Hans.xlf | 39 +---- ...osoftNetCoreAnalyzersResources.zh-Hant.xlf | 39 +---- .../Microsoft.CodeAnalysis.NetAnalyzers.md | 2 +- .../Microsoft.CodeAnalysis.NetAnalyzers.sarif | 2 +- ...rsShouldMatchPropertyAndFieldNamesTests.cs | 162 +++++++----------- 19 files changed, 203 insertions(+), 603 deletions(-) diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx index 343639d6f3..2003b16d95 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx @@ -1,17 +1,17 @@  - @@ -1519,28 +1519,13 @@ and all other platforms This call site is reachable on: 'windows' 10.0.2000 and later, and all other platforms - - For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' - - - For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' - - - For proper deserialization, change the visibility of the bound property '{2}' to public + + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property or field '{2}' - - For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. + + For a constructor having [JsonConstructor] attribute each parameter name must match with a public property or field name for proper deserialization. - - For a constructor having [JsonConstructor] attribute each parameter must be bound to a public property for proper deserialization. - - + Constructor parameter names should match the bound property or field names - - For proper deserialization, change the visibility of the bound field '{2}' to public - - - For a constructor having [JsonConstructor] attribute each parameter must be bound to a public field for proper deserialization. - \ No newline at end of file diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.Fixer.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.Fixer.cs index 8472b2c76e..050e2fb036 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.Fixer.cs +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.Fixer.cs @@ -48,7 +48,7 @@ public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) context.RegisterCodeFix( CodeAction.Create( - string.Format(CultureInfo.CurrentCulture, MicrosoftNetCoreAnalyzersResources.ConstructorParametersShouldMatchPropertyNamesTitle, newName), + string.Format(CultureInfo.CurrentCulture, MicrosoftNetCoreAnalyzersResources.ConstructorParametersShouldMatchPropertyOrFieldNamesTitle, newName), cancellationToken => GetUpdatedDocumentForParameterRenameAsync(context.Document, declaredSymbol, newName, cancellationToken), nameof(ConstructorParametersShouldMatchPropertyAndFieldNamesFixer)), diagnostic); diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs index 923321bd66..717848a53a 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs @@ -20,54 +20,24 @@ public sealed class ConstructorParametersShouldMatchPropertyAndFieldNamesAnalyze { internal const string RuleId = "CA1071"; - internal const string ReferencedFieldOrPropertyNameKey = "ReferencedFieldOrPropertyName"; + internal const string ReferencedFieldOrPropertyNameKey = "ReferencedPropertyOrFieldName"; internal const string DiagnosticReasonKey = "DiagnosticReason"; - private static readonly LocalizableString s_localizableTitle = new LocalizableResourceString(nameof(MicrosoftNetCoreAnalyzersResources.ConstructorParametersShouldMatchPropertyNamesTitle), MicrosoftNetCoreAnalyzersResources.ResourceManager, typeof(MicrosoftNetCoreAnalyzersResources)); + private static readonly LocalizableString s_localizableTitle = new LocalizableResourceString(nameof(MicrosoftNetCoreAnalyzersResources.ConstructorParametersShouldMatchPropertyOrFieldNamesTitle), MicrosoftNetCoreAnalyzersResources.ResourceManager, typeof(MicrosoftNetCoreAnalyzersResources)); - private static readonly LocalizableString s_localizableMessageProperty = new LocalizableResourceString(nameof(MicrosoftNetCoreAnalyzersResources.ConstructorParameterShouldMatchPropertyName), MicrosoftNetCoreAnalyzersResources.ResourceManager, typeof(MicrosoftNetCoreAnalyzersResources)); - private static readonly LocalizableString s_localizableMessageField = new LocalizableResourceString(nameof(MicrosoftNetCoreAnalyzersResources.ConstructorParameterShouldMatchFieldName), MicrosoftNetCoreAnalyzersResources.ResourceManager, typeof(MicrosoftNetCoreAnalyzersResources)); - private static readonly LocalizableString s_localizableDescription = new LocalizableResourceString(nameof(MicrosoftNetCoreAnalyzersResources.ConstructorParametersShouldMatchPropertyNamesDescription), MicrosoftNetCoreAnalyzersResources.ResourceManager, typeof(MicrosoftNetCoreAnalyzersResources)); + private static readonly LocalizableString s_localizableMessage = new LocalizableResourceString(nameof(MicrosoftNetCoreAnalyzersResources.ConstructorParameterShouldMatchPropertyOrFieldName), MicrosoftNetCoreAnalyzersResources.ResourceManager, typeof(MicrosoftNetCoreAnalyzersResources)); + private static readonly LocalizableString s_localizableDescription = new LocalizableResourceString(nameof(MicrosoftNetCoreAnalyzersResources.ConstructorParametersShouldMatchPropertyOrFieldNamesDescription), MicrosoftNetCoreAnalyzersResources.ResourceManager, typeof(MicrosoftNetCoreAnalyzersResources)); - private static readonly LocalizableString s_localizableMessagePropertyPublic = new LocalizableResourceString(nameof(MicrosoftNetCoreAnalyzersResources.ConstructorParameterShouldMatchPropertyWithPublicVisibility), MicrosoftNetCoreAnalyzersResources.ResourceManager, typeof(MicrosoftNetCoreAnalyzersResources)); - private static readonly LocalizableString s_localizableDescriptionPropertyPublic = new LocalizableResourceString(nameof(MicrosoftNetCoreAnalyzersResources.ConstructorParametersShouldMatchPropertyWithPublicVisibilityDescription), MicrosoftNetCoreAnalyzersResources.ResourceManager, typeof(MicrosoftNetCoreAnalyzersResources)); - private static readonly LocalizableString s_localizableMessageFieldPublic = new LocalizableResourceString(nameof(MicrosoftNetCoreAnalyzersResources.ConstructorParameterShouldMatchFieldWithPublicVisibility), MicrosoftNetCoreAnalyzersResources.ResourceManager, typeof(MicrosoftNetCoreAnalyzersResources)); - private static readonly LocalizableString s_localizableDescriptionFieldPublic = new LocalizableResourceString(nameof(MicrosoftNetCoreAnalyzersResources.ConstructorParametersShouldMatchFieldWithPublicVisibilityDescription), MicrosoftNetCoreAnalyzersResources.ResourceManager, typeof(MicrosoftNetCoreAnalyzersResources)); - - internal static DiagnosticDescriptor PropertyNameRule = DiagnosticDescriptorHelper.Create(RuleId, + internal static DiagnosticDescriptor PropertyOrFieldNameRule = DiagnosticDescriptorHelper.Create(RuleId, s_localizableTitle, - s_localizableMessageProperty, + s_localizableMessage, DiagnosticCategory.Design, RuleLevel.BuildWarning, description: s_localizableDescription, isPortedFxCopRule: false, isDataflowRule: false); - internal static DiagnosticDescriptor FieldRule = DiagnosticDescriptorHelper.Create(RuleId, - s_localizableTitle, - s_localizableMessageField, - DiagnosticCategory.Design, - RuleLevel.BuildWarning, - description: s_localizableDescription, - isPortedFxCopRule: false, - isDataflowRule: false); - internal static DiagnosticDescriptor PropertyPublicRule = DiagnosticDescriptorHelper.Create(RuleId, - s_localizableTitle, - s_localizableMessagePropertyPublic, - DiagnosticCategory.Design, - RuleLevel.BuildWarning, - description: s_localizableDescriptionPropertyPublic, - isPortedFxCopRule: false, - isDataflowRule: false); - internal static DiagnosticDescriptor FieldPublicRule = DiagnosticDescriptorHelper.Create(RuleId, - s_localizableTitle, - s_localizableMessageFieldPublic, - DiagnosticCategory.Design, - RuleLevel.BuildWarning, - description: s_localizableDescriptionFieldPublic, - isPortedFxCopRule: false, - isDataflowRule: false); - public override ImmutableArray SupportedDiagnostics => ImmutableArray.Create(PropertyNameRule, FieldRule); + public override ImmutableArray SupportedDiagnostics => ImmutableArray.Create(PropertyOrFieldNameRule); public override void Initialize(AnalysisContext context) { @@ -137,24 +107,24 @@ public static void AnalyzeOperationAndReport(OperationAnalysisContext context) { if (!IsParamMatchesReferencedMemberName(param, field)) { - ReportFieldDiagnostic(context, FieldRule, ParameterDiagnosticReason.NameMismatch, param, field); + ReportFieldDiagnostic(context, PropertyOrFieldNameRule, ParameterDiagnosticReason.NameMismatch, param, field); } if (!field.IsPublic()) { - ReportFieldDiagnostic(context, FieldPublicRule, ParameterDiagnosticReason.FieldInappropriateVisibility, param, field); + ReportFieldDiagnostic(context, PropertyOrFieldNameRule, ParameterDiagnosticReason.FieldInappropriateVisibility, param, field); } } else if (referencedSymbol is IPropertySymbol prop) { if (!IsParamMatchesReferencedMemberName(param, prop)) { - ReportPropertyDiagnostic(context, PropertyNameRule, ParameterDiagnosticReason.NameMismatch, param, prop); + ReportPropertyDiagnostic(context, PropertyOrFieldNameRule, ParameterDiagnosticReason.NameMismatch, param, prop); } if (!prop.IsPublic()) { - ReportPropertyDiagnostic(context, PropertyPublicRule, ParameterDiagnosticReason.PropertyInappropriateVisibility, param, prop); + ReportPropertyDiagnostic(context, PropertyOrFieldNameRule, ParameterDiagnosticReason.PropertyInappropriateVisibility, param, prop); } } } 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 84b168052d..2cde552336 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.cs.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.cs.xlf @@ -177,46 +177,21 @@ , Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’} - - For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' - For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' + + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property or field '{2}' + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property or field '{2}' - - For proper deserialization, change the visibility of the bound field '{2}' to public - For proper deserialization, change the visibility of the bound field '{2}' to public + + For a constructor having [JsonConstructor] attribute each parameter name must match with a public property or field name for proper deserialization. + For a constructor having [JsonConstructor] attribute each parameter name must match with a public property or field name for proper deserialization. - - For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' - For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' - - - - For proper deserialization, change the visibility of the bound property '{2}' to public - For proper deserialization, change the visibility of the bound property '{2}' to public - - - - For a constructor having [JsonConstructor] attribute each parameter must be bound to a public field for proper deserialization. - For a constructor having [JsonConstructor] attribute each parameter must be bound to a public field for proper deserialization. - - - - For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. - For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. - - - + Constructor parameter names should match the bound property or field names Constructor parameter names should match the bound property or field names - - For a constructor having [JsonConstructor] attribute each parameter must be bound to a public property for proper deserialization. - For a constructor having [JsonConstructor] attribute each parameter must be bound to a public property for proper deserialization. - - When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0} Při deserializaci nedůvěryhodného vstupu není deserializace objektu {0} bezpečná. Objekt {1} je buď objektem {0}, nebo je z tohoto objektu odvozený. 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 f9728b7a2e..4bc070dbe5 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.de.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.de.xlf @@ -177,46 +177,21 @@ , Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’} - - For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' - For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' + + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property or field '{2}' + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property or field '{2}' - - For proper deserialization, change the visibility of the bound field '{2}' to public - For proper deserialization, change the visibility of the bound field '{2}' to public + + For a constructor having [JsonConstructor] attribute each parameter name must match with a public property or field name for proper deserialization. + For a constructor having [JsonConstructor] attribute each parameter name must match with a public property or field name for proper deserialization. - - For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' - For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' - - - - For proper deserialization, change the visibility of the bound property '{2}' to public - For proper deserialization, change the visibility of the bound property '{2}' to public - - - - For a constructor having [JsonConstructor] attribute each parameter must be bound to a public field for proper deserialization. - For a constructor having [JsonConstructor] attribute each parameter must be bound to a public field for proper deserialization. - - - - For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. - For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. - - - + Constructor parameter names should match the bound property or field names Constructor parameter names should match the bound property or field names - - For a constructor having [JsonConstructor] attribute each parameter must be bound to a public property for proper deserialization. - For a constructor having [JsonConstructor] attribute each parameter must be bound to a public property for proper deserialization. - - When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0} Beim Deserialisieren einer nicht vertrauenswürdigen Eingabe ist die Deserialisierung eines {0}-Objekts unsicher. "{1}" ist entweder "{0}" oder davon abgeleitet. 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 6c2dc4012c..b3e21020e9 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.es.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.es.xlf @@ -177,46 +177,21 @@ , Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’} - - For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' - For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' + + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property or field '{2}' + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property or field '{2}' - - For proper deserialization, change the visibility of the bound field '{2}' to public - For proper deserialization, change the visibility of the bound field '{2}' to public + + For a constructor having [JsonConstructor] attribute each parameter name must match with a public property or field name for proper deserialization. + For a constructor having [JsonConstructor] attribute each parameter name must match with a public property or field name for proper deserialization. - - For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' - For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' - - - - For proper deserialization, change the visibility of the bound property '{2}' to public - For proper deserialization, change the visibility of the bound property '{2}' to public - - - - For a constructor having [JsonConstructor] attribute each parameter must be bound to a public field for proper deserialization. - For a constructor having [JsonConstructor] attribute each parameter must be bound to a public field for proper deserialization. - - - - For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. - For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. - - - + Constructor parameter names should match the bound property or field names Constructor parameter names should match the bound property or field names - - For a constructor having [JsonConstructor] attribute each parameter must be bound to a public property for proper deserialization. - For a constructor having [JsonConstructor] attribute each parameter must be bound to a public property for proper deserialization. - - When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0} Cuando se deserializa una entrada que no es de confianza, no es segura la deserialización de un objeto {0}. "{1}" es {0} o se deriva de este. 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 61f9a45938..e8bbcce859 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.fr.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.fr.xlf @@ -177,46 +177,21 @@ , Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’} - - For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' - For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' + + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property or field '{2}' + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property or field '{2}' - - For proper deserialization, change the visibility of the bound field '{2}' to public - For proper deserialization, change the visibility of the bound field '{2}' to public + + For a constructor having [JsonConstructor] attribute each parameter name must match with a public property or field name for proper deserialization. + For a constructor having [JsonConstructor] attribute each parameter name must match with a public property or field name for proper deserialization. - - For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' - For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' - - - - For proper deserialization, change the visibility of the bound property '{2}' to public - For proper deserialization, change the visibility of the bound property '{2}' to public - - - - For a constructor having [JsonConstructor] attribute each parameter must be bound to a public field for proper deserialization. - For a constructor having [JsonConstructor] attribute each parameter must be bound to a public field for proper deserialization. - - - - For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. - For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. - - - + Constructor parameter names should match the bound property or field names Constructor parameter names should match the bound property or field names - - For a constructor having [JsonConstructor] attribute each parameter must be bound to a public property for proper deserialization. - For a constructor having [JsonConstructor] attribute each parameter must be bound to a public property for proper deserialization. - - When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0} Quand vous désérialisez une entrée non fiable, la désérialisation d'un objet {0} n'est pas une action sécurisée. '{1}' est égal à ou dérive de {0} 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 bcbaba7ac7..f98f093036 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.it.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.it.xlf @@ -177,46 +177,21 @@ , Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’} - - For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' - For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' + + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property or field '{2}' + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property or field '{2}' - - For proper deserialization, change the visibility of the bound field '{2}' to public - For proper deserialization, change the visibility of the bound field '{2}' to public + + For a constructor having [JsonConstructor] attribute each parameter name must match with a public property or field name for proper deserialization. + For a constructor having [JsonConstructor] attribute each parameter name must match with a public property or field name for proper deserialization. - - For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' - For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' - - - - For proper deserialization, change the visibility of the bound property '{2}' to public - For proper deserialization, change the visibility of the bound property '{2}' to public - - - - For a constructor having [JsonConstructor] attribute each parameter must be bound to a public field for proper deserialization. - For a constructor having [JsonConstructor] attribute each parameter must be bound to a public field for proper deserialization. - - - - For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. - For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. - - - + Constructor parameter names should match the bound property or field names Constructor parameter names should match the bound property or field names - - For a constructor having [JsonConstructor] attribute each parameter must be bound to a public property for proper deserialization. - For a constructor having [JsonConstructor] attribute each parameter must be bound to a public property for proper deserialization. - - When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0} Quando si deserializza input non attendibile, la deserializzazione di un oggetto {0} non è sicura. '{1}' è {0} o deriva da esso 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 82c90b267e..428f07cd4d 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ja.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ja.xlf @@ -177,46 +177,21 @@ , Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’} - - For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' - For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' + + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property or field '{2}' + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property or field '{2}' - - For proper deserialization, change the visibility of the bound field '{2}' to public - For proper deserialization, change the visibility of the bound field '{2}' to public + + For a constructor having [JsonConstructor] attribute each parameter name must match with a public property or field name for proper deserialization. + For a constructor having [JsonConstructor] attribute each parameter name must match with a public property or field name for proper deserialization. - - For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' - For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' - - - - For proper deserialization, change the visibility of the bound property '{2}' to public - For proper deserialization, change the visibility of the bound property '{2}' to public - - - - For a constructor having [JsonConstructor] attribute each parameter must be bound to a public field for proper deserialization. - For a constructor having [JsonConstructor] attribute each parameter must be bound to a public field for proper deserialization. - - - - For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. - For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. - - - + Constructor parameter names should match the bound property or field names Constructor parameter names should match the bound property or field names - - For a constructor having [JsonConstructor] attribute each parameter must be bound to a public property for proper deserialization. - For a constructor having [JsonConstructor] attribute each parameter must be bound to a public property for proper deserialization. - - When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0} 信頼されていない入力を逆シリアル化する場合、{0} オブジェクトの逆シリアル化は安全ではありません。'{1}' は {0} であるか、それから派生しています 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 d9970fc482..8027b0b925 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ko.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ko.xlf @@ -177,46 +177,21 @@ , Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’} - - For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' - For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' + + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property or field '{2}' + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property or field '{2}' - - For proper deserialization, change the visibility of the bound field '{2}' to public - For proper deserialization, change the visibility of the bound field '{2}' to public + + For a constructor having [JsonConstructor] attribute each parameter name must match with a public property or field name for proper deserialization. + For a constructor having [JsonConstructor] attribute each parameter name must match with a public property or field name for proper deserialization. - - For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' - For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' - - - - For proper deserialization, change the visibility of the bound property '{2}' to public - For proper deserialization, change the visibility of the bound property '{2}' to public - - - - For a constructor having [JsonConstructor] attribute each parameter must be bound to a public field for proper deserialization. - For a constructor having [JsonConstructor] attribute each parameter must be bound to a public field for proper deserialization. - - - - For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. - For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. - - - + Constructor parameter names should match the bound property or field names Constructor parameter names should match the bound property or field names - - For a constructor having [JsonConstructor] attribute each parameter must be bound to a public property for proper deserialization. - For a constructor having [JsonConstructor] attribute each parameter must be bound to a public property for proper deserialization. - - When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0} 신뢰할 수 없는 입력을 역직렬화하는 경우 {0} 개체를 역직렬화하는 것은 안전하지 않습니다. '{1}'은(는) {0}이거나 이 항목에서 파생됩니다. 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 5739565f66..f50abdcfc3 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pl.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pl.xlf @@ -177,46 +177,21 @@ , Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’} - - For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' - For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' + + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property or field '{2}' + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property or field '{2}' - - For proper deserialization, change the visibility of the bound field '{2}' to public - For proper deserialization, change the visibility of the bound field '{2}' to public + + For a constructor having [JsonConstructor] attribute each parameter name must match with a public property or field name for proper deserialization. + For a constructor having [JsonConstructor] attribute each parameter name must match with a public property or field name for proper deserialization. - - For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' - For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' - - - - For proper deserialization, change the visibility of the bound property '{2}' to public - For proper deserialization, change the visibility of the bound property '{2}' to public - - - - For a constructor having [JsonConstructor] attribute each parameter must be bound to a public field for proper deserialization. - For a constructor having [JsonConstructor] attribute each parameter must be bound to a public field for proper deserialization. - - - - For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. - For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. - - - + Constructor parameter names should match the bound property or field names Constructor parameter names should match the bound property or field names - - For a constructor having [JsonConstructor] attribute each parameter must be bound to a public property for proper deserialization. - For a constructor having [JsonConstructor] attribute each parameter must be bound to a public property for proper deserialization. - - When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0} Deserializowanie obiektu {0} podczas deserializacji niezaufanych danych wejściowych nie jest bezpieczne. Element „{1}” jest elementem {0} lub pochodzi od niego 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 4d18167fb4..0aaf4f3c97 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 @@ -177,46 +177,21 @@ , Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’} - - For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' - For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' + + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property or field '{2}' + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property or field '{2}' - - For proper deserialization, change the visibility of the bound field '{2}' to public - For proper deserialization, change the visibility of the bound field '{2}' to public + + For a constructor having [JsonConstructor] attribute each parameter name must match with a public property or field name for proper deserialization. + For a constructor having [JsonConstructor] attribute each parameter name must match with a public property or field name for proper deserialization. - - For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' - For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' - - - - For proper deserialization, change the visibility of the bound property '{2}' to public - For proper deserialization, change the visibility of the bound property '{2}' to public - - - - For a constructor having [JsonConstructor] attribute each parameter must be bound to a public field for proper deserialization. - For a constructor having [JsonConstructor] attribute each parameter must be bound to a public field for proper deserialization. - - - - For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. - For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. - - - + Constructor parameter names should match the bound property or field names Constructor parameter names should match the bound property or field names - - For a constructor having [JsonConstructor] attribute each parameter must be bound to a public property for proper deserialization. - For a constructor having [JsonConstructor] attribute each parameter must be bound to a public property for proper deserialization. - - When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0} Ao desserializar uma entrada não confiável, a desserialização de um objeto {0} não é segura. '{1}' é {0} ou deriva-se dele 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 0560898cea..052bd8cd4b 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ru.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ru.xlf @@ -177,46 +177,21 @@ , Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’} - - For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' - For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' + + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property or field '{2}' + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property or field '{2}' - - For proper deserialization, change the visibility of the bound field '{2}' to public - For proper deserialization, change the visibility of the bound field '{2}' to public + + For a constructor having [JsonConstructor] attribute each parameter name must match with a public property or field name for proper deserialization. + For a constructor having [JsonConstructor] attribute each parameter name must match with a public property or field name for proper deserialization. - - For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' - For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' - - - - For proper deserialization, change the visibility of the bound property '{2}' to public - For proper deserialization, change the visibility of the bound property '{2}' to public - - - - For a constructor having [JsonConstructor] attribute each parameter must be bound to a public field for proper deserialization. - For a constructor having [JsonConstructor] attribute each parameter must be bound to a public field for proper deserialization. - - - - For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. - For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. - - - + Constructor parameter names should match the bound property or field names Constructor parameter names should match the bound property or field names - - For a constructor having [JsonConstructor] attribute each parameter must be bound to a public property for proper deserialization. - For a constructor having [JsonConstructor] attribute each parameter must be bound to a public property for proper deserialization. - - When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0} При десериализации недоверенных входных данных десериализация объекта {0} является небезопасной. Объект "{1}" является объектом {0} или производным от него объектом. 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 804b3281da..271827a4fa 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.tr.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.tr.xlf @@ -177,46 +177,21 @@ , Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’} - - For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' - For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' + + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property or field '{2}' + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property or field '{2}' - - For proper deserialization, change the visibility of the bound field '{2}' to public - For proper deserialization, change the visibility of the bound field '{2}' to public + + For a constructor having [JsonConstructor] attribute each parameter name must match with a public property or field name for proper deserialization. + For a constructor having [JsonConstructor] attribute each parameter name must match with a public property or field name for proper deserialization. - - For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' - For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' - - - - For proper deserialization, change the visibility of the bound property '{2}' to public - For proper deserialization, change the visibility of the bound property '{2}' to public - - - - For a constructor having [JsonConstructor] attribute each parameter must be bound to a public field for proper deserialization. - For a constructor having [JsonConstructor] attribute each parameter must be bound to a public field for proper deserialization. - - - - For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. - For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. - - - + Constructor parameter names should match the bound property or field names Constructor parameter names should match the bound property or field names - - For a constructor having [JsonConstructor] attribute each parameter must be bound to a public property for proper deserialization. - For a constructor having [JsonConstructor] attribute each parameter must be bound to a public property for proper deserialization. - - When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0} Güvenilmeyen giriş seri durumdan çıkarılırken, {0} nesnesinin seri durumdan çıkarılması güvenli değildir. '{1}', {0} nesnesidir veya bu nesneden türetilmiştir 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 5020183ce4..a8e4219a60 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 @@ -177,46 +177,21 @@ , Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’} - - For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' - For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' + + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property or field '{2}' + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property or field '{2}' - - For proper deserialization, change the visibility of the bound field '{2}' to public - For proper deserialization, change the visibility of the bound field '{2}' to public + + For a constructor having [JsonConstructor] attribute each parameter name must match with a public property or field name for proper deserialization. + For a constructor having [JsonConstructor] attribute each parameter name must match with a public property or field name for proper deserialization. - - For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' - For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' - - - - For proper deserialization, change the visibility of the bound property '{2}' to public - For proper deserialization, change the visibility of the bound property '{2}' to public - - - - For a constructor having [JsonConstructor] attribute each parameter must be bound to a public field for proper deserialization. - For a constructor having [JsonConstructor] attribute each parameter must be bound to a public field for proper deserialization. - - - - For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. - For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. - - - + Constructor parameter names should match the bound property or field names Constructor parameter names should match the bound property or field names - - For a constructor having [JsonConstructor] attribute each parameter must be bound to a public property for proper deserialization. - For a constructor having [JsonConstructor] attribute each parameter must be bound to a public property for proper deserialization. - - When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0} 对不受信任的输入进行反序列化处理时,反序列化 {0} 对象是不安全的。“{1}”是或派生自 {0} 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 2c6de7b9c3..29fbf8801c 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 @@ -177,46 +177,21 @@ , Separator used for separating list of platform names: {API} is only supported on: {‘windows’, ‘browser’, ‘linux’} - - For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' - For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound field '{2}' + + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property or field '{2}' + For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property or field '{2}' - - For proper deserialization, change the visibility of the bound field '{2}' to public - For proper deserialization, change the visibility of the bound field '{2}' to public + + For a constructor having [JsonConstructor] attribute each parameter name must match with a public property or field name for proper deserialization. + For a constructor having [JsonConstructor] attribute each parameter name must match with a public property or field name for proper deserialization. - - For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' - For proper deserialization, change the name of parameter '{1}' in the constructor of '{0}' to match the bound property '{2}' - - - - For proper deserialization, change the visibility of the bound property '{2}' to public - For proper deserialization, change the visibility of the bound property '{2}' to public - - - - For a constructor having [JsonConstructor] attribute each parameter must be bound to a public field for proper deserialization. - For a constructor having [JsonConstructor] attribute each parameter must be bound to a public field for proper deserialization. - - - - For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. - For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. - - - + Constructor parameter names should match the bound property or field names Constructor parameter names should match the bound property or field names - - For a constructor having [JsonConstructor] attribute each parameter must be bound to a public property for proper deserialization. - For a constructor having [JsonConstructor] attribute each parameter must be bound to a public property for proper deserialization. - - When deserializing untrusted input, deserializing a {0} object is insecure. '{1}' either is or derives from {0} 還原序列化不受信任的輸入時,將 {0} 物件還原序列化並不安全。'{1}' 屬於或衍生自 {0} diff --git a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md index 28455edca1..18aff4b97d 100644 --- a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md +++ b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md @@ -578,7 +578,7 @@ Do not declare virtual events in a base class. Overridden events in a derived cl ## [CA1071](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1071): Constructor parameter names should match the bound property or field names -For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization. +For a constructor having [JsonConstructor] attribute each parameter name must match with a public property or field name for proper deserialization. |Item|Value| |-|-| diff --git a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif index 2e683b6fb1..550df5b6ee 100644 --- a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif +++ b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif @@ -1349,7 +1349,7 @@ "CA1071": { "id": "CA1071", "shortDescription": "Constructor parameter names should match the bound property or field names", - "fullDescription": "For a constructor having [JsonConstructor] attribute each parameter name must match with a property or field name for proper deserialization.", + "fullDescription": "For a constructor having [JsonConstructor] attribute each parameter name must match with a public property or field name for proper deserialization.", "defaultLevel": "warning", "helpUri": "https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1071", "properties": { diff --git a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs index 7b563f9651..75501621b3 100644 --- a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs +++ b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs @@ -35,8 +35,8 @@ public C1(int {|#0:firstDrop|}, object {|#1:secondDrop|}) this.SecondProp = secondDrop; } }", - CA1071CSharpPropertyResultAt(0, "C1", "firstDrop", "FirstProp"), - CA1071CSharpPropertyResultAt(1, "C1", "secondDrop", "SecondProp")); + CA1071CSharpPropertyOrFieldResultAt(0, "C1", "firstDrop", "FirstProp"), + CA1071CSharpPropertyOrFieldResultAt(1, "C1", "secondDrop", "SecondProp")); } [Fact] @@ -55,8 +55,8 @@ Public Sub New({|#0:firstDrop|} as Integer, {|#1:secondDrop|} as Object) Me.SecondProp = secondDrop End Sub End Class", - CA1071BasicPropertyResultAt(0, "C1", "firstDrop", "FirstProp"), - CA1071BasicPropertyResultAt(1, "C1", "secondDrop", "SecondProp")); + CA1071BasicPropertyOrFieldResultAt(0, "C1", "firstDrop", "FirstProp"), + CA1071BasicPropertyOrFieldResultAt(1, "C1", "secondDrop", "SecondProp")); } [Fact] @@ -109,8 +109,8 @@ public C1(int {|#0:dropFirst|}, object {|#1:dropSecond|}) this.SecondProp = dropSecond; } }", - CA1071CSharpPropertyResultAt(0, "C1", "dropFirst", "FirstProp"), - CA1071CSharpPropertyResultAt(1, "C1", "dropSecond", "SecondProp")); + CA1071CSharpPropertyOrFieldResultAt(0, "C1", "dropFirst", "FirstProp"), + CA1071CSharpPropertyOrFieldResultAt(1, "C1", "dropSecond", "SecondProp")); } [Fact] @@ -129,8 +129,8 @@ Public Sub New({|#0:dropFirst|} as Integer, {|#1:dropSecond|} as Object) Me.SecondProp = dropSecond End Sub End Class", - CA1071BasicPropertyResultAt(0, "C1", "dropFirst", "FirstProp"), - CA1071BasicPropertyResultAt(1, "C1", "dropSecond", "SecondProp")); + CA1071BasicPropertyOrFieldResultAt(0, "C1", "dropFirst", "FirstProp"), + CA1071BasicPropertyOrFieldResultAt(1, "C1", "dropSecond", "SecondProp")); } [Fact] @@ -150,8 +150,8 @@ public C1(int {|#0:firstProp|}, object {|#1:secondProp|}) (this._FirstProp, this._SecondProp) = (firstProp, secondProp); } }", - CA1071CSharpPropertyResultAt(0, "C1", "firstProp", "_FirstProp"), - CA1071CSharpPropertyResultAt(1, "C1", "secondProp", "_SecondProp")); + CA1071CSharpPropertyOrFieldResultAt(0, "C1", "firstProp", "_FirstProp"), + CA1071CSharpPropertyOrFieldResultAt(1, "C1", "secondProp", "_SecondProp")); } [Fact] @@ -176,8 +176,8 @@ public C1(int {|#0:firstProp|}, object {|#1:secondProp|}) this._SecondProp = secondProp; } }", - CA1071CSharpPropertyResultAt(0, "C1", "firstProp", "_FirstProp"), - CA1071CSharpPropertyResultAt(1, "C1", "secondProp", "_SecondProp")); + CA1071CSharpPropertyOrFieldResultAt(0, "C1", "firstProp", "_FirstProp"), + CA1071CSharpPropertyOrFieldResultAt(1, "C1", "secondProp", "_SecondProp")); } [Fact] @@ -200,8 +200,8 @@ Public Sub New({|#0:firstProp|} as Integer, {|#1:secondProp|} as Object) Me._SecondProp = secondProp End Sub End Class", - CA1071BasicPropertyResultAt(0, "C1", "firstProp", "_FirstProp"), - CA1071BasicPropertyResultAt(1, "C1", "secondProp", "_SecondProp")); + CA1071BasicPropertyOrFieldResultAt(0, "C1", "firstProp", "_FirstProp"), + CA1071BasicPropertyOrFieldResultAt(1, "C1", "secondProp", "_SecondProp")); } #endregion @@ -264,8 +264,8 @@ public C1(int {|#0:firstProp|}, object {|#1:secondProp|}) this.SecondProp = secondProp; } }", - CA1071CSharpPublicPropertyResultAt(0, "C1", "firstProp", "FirstProp"), - CA1071CSharpPublicPropertyResultAt(1, "C1", "secondProp", "SecondProp")); + CA1071CSharpPropertyOrFieldResultAt(0, "C1", "firstProp", "FirstProp"), + CA1071CSharpPropertyOrFieldResultAt(1, "C1", "secondProp", "SecondProp")); } [Fact] @@ -284,8 +284,8 @@ Public Sub New({|#0:firstProp|} as Integer, {|#1:secondProp|} as Object) Me.SecondProp = secondProp End Sub End Class", - CA1071BasicPublicPropertyResultAt(0, "C1", "firstProp", "FirstProp"), - CA1071BasicPublicPropertyResultAt(1, "C1", "secondProp", "SecondProp")); + CA1071BasicPropertyOrFieldResultAt(0, "C1", "firstProp", "FirstProp"), + CA1071BasicPropertyOrFieldResultAt(1, "C1", "secondProp", "SecondProp")); } #endregion @@ -310,8 +310,8 @@ public C1(int {|#0:firstIField|}, object {|#1:secondIField|}) this.secondField = secondIField; } }", - CA1071CSharpFieldResultAt(0, "C1", "firstIField", "firstField"), - CA1071CSharpFieldResultAt(1, "C1", "secondIField", "secondField")); + CA1071CSharpPropertyOrFieldResultAt(0, "C1", "firstIField", "firstField"), + CA1071CSharpPropertyOrFieldResultAt(1, "C1", "secondIField", "secondField")); } [Fact] @@ -330,8 +330,8 @@ Public Sub New({|#0:firstIField|} as Integer, {|#1:secondIField|} as Object) Me.secondField = secondIField End Sub End Class", - CA1071BasicFieldResultAt(0, "C1", "firstIField", "firstField"), - CA1071BasicFieldResultAt(1, "C1", "secondIField", "secondField")); + CA1071BasicPropertyOrFieldResultAt(0, "C1", "firstIField", "firstField"), + CA1071BasicPropertyOrFieldResultAt(1, "C1", "secondIField", "secondField")); } [Fact] @@ -384,8 +384,8 @@ public C1(int {|#0:fieldFirst|}, object {|#1:fieldSecond|}) this.secondField = fieldSecond; } }", - CA1071CSharpFieldResultAt(0, "C1", "fieldFirst", "firstField"), - CA1071CSharpFieldResultAt(1, "C1", "fieldSecond", "secondField")); + CA1071CSharpPropertyOrFieldResultAt(0, "C1", "fieldFirst", "firstField"), + CA1071CSharpPropertyOrFieldResultAt(1, "C1", "fieldSecond", "secondField")); } [Fact] @@ -404,8 +404,8 @@ Public Sub New({|#0:fieldFirst|} as Integer, {|#1:fieldSecond|} as Object) Me.secondField = fieldSecond End Sub End Class", - CA1071BasicFieldResultAt(0, "C1", "fieldFirst", "firstField"), - CA1071BasicFieldResultAt(1, "C1", "fieldSecond", "secondField")); + CA1071BasicPropertyOrFieldResultAt(0, "C1", "fieldFirst", "firstField"), + CA1071BasicPropertyOrFieldResultAt(1, "C1", "fieldSecond", "secondField")); } [Fact] @@ -425,8 +425,8 @@ public C1(int {|#0:firstField|}, object {|#1:secondField|}) (_firstField, _secondField) = (firstField, secondField); } }", - CA1071CSharpFieldResultAt(0, "C1", "firstField", "_firstField"), - CA1071CSharpFieldResultAt(1, "C1", "secondField", "_secondField")); + CA1071CSharpPropertyOrFieldResultAt(0, "C1", "firstField", "_firstField"), + CA1071CSharpPropertyOrFieldResultAt(1, "C1", "secondField", "_secondField")); } [Fact] @@ -451,8 +451,8 @@ public C1(int {|#0:firstField|}, object {|#1:secondField|}) this._secondField = secondField; } }", - CA1071CSharpFieldResultAt(0, "C1", "firstField", "_firstField"), - CA1071CSharpFieldResultAt(1, "C1", "secondField", "_secondField")); + CA1071CSharpPropertyOrFieldResultAt(0, "C1", "firstField", "_firstField"), + CA1071CSharpPropertyOrFieldResultAt(1, "C1", "secondField", "_secondField")); } [Fact] @@ -475,8 +475,8 @@ Public Sub New({|#0:firstField|} as Integer, {|#1:secondField|} as Object) Me._secondField = secondField End Sub End Class", - CA1071BasicFieldResultAt(0, "C1", "firstField", "_firstField"), - CA1071BasicFieldResultAt(1, "C1", "secondField", "_secondField")); + CA1071BasicPropertyOrFieldResultAt(0, "C1", "firstField", "_firstField"), + CA1071BasicPropertyOrFieldResultAt(1, "C1", "secondField", "_secondField")); } #endregion @@ -615,8 +615,8 @@ public C1(int {|#0:firstField|}, object {|#1:secondField|}) this.secondField = secondField; } }", - CA1071CSharpPublicFieldResultAt(0, "C1", "firstField", "firstField"), - CA1071CSharpPublicFieldResultAt(1, "C1", "secondField", "secondField")); + CA1071CSharpPropertyOrFieldResultAt(0, "C1", "firstField", "firstField"), + CA1071CSharpPropertyOrFieldResultAt(1, "C1", "secondField", "secondField")); } [Fact] @@ -635,8 +635,8 @@ Public Sub New({|#0:firstField|} as Integer, {|#1:secondField|} as Object) Me.secondField = secondField End Sub End Class", - CA1071BasicPublicFieldResultAt(0, "C1", "firstField", "firstField"), - CA1071BasicPublicFieldResultAt(1, "C1", "secondField", "secondField")); + CA1071BasicPropertyOrFieldResultAt(0, "C1", "firstField", "firstField"), + CA1071BasicPropertyOrFieldResultAt(1, "C1", "secondField", "secondField")); } [Fact] @@ -660,8 +660,8 @@ public C1(int {|#0:firstField|}, object {|#1:secondField|}) this.secondField = secondField; } }", - CA1071CSharpPublicFieldResultAt(0, "C1", "firstField", "firstField"), - CA1071CSharpPublicFieldResultAt(1, "C1", "secondField", "secondField")); + CA1071CSharpPropertyOrFieldResultAt(0, "C1", "firstField", "firstField"), + CA1071CSharpPropertyOrFieldResultAt(1, "C1", "secondField", "secondField")); } [Fact] @@ -683,8 +683,8 @@ Public Sub New({|#0:firstField|} as Integer, {|#1:secondField|} as Object) Me.secondField = secondField End Sub End Class", - CA1071BasicPublicFieldResultAt(0, "C1", "firstField", "firstField"), - CA1071BasicPublicFieldResultAt(1, "C1", "secondField", "secondField")); + CA1071BasicPropertyOrFieldResultAt(0, "C1", "firstField", "firstField"), + CA1071BasicPropertyOrFieldResultAt(1, "C1", "secondField", "secondField")); } #endregion @@ -709,8 +709,8 @@ public C1(int {|#0:firstDrop|}, object {|#1:secondDrop|}) this.SecondProp = secondDrop; } }", - CA1071CSharpPropertyResultAt(0, "C1", "firstDrop", "FirstProp"), - CA1071CSharpPropertyResultAt(1, "C1", "secondDrop", "SecondProp")); + CA1071CSharpPropertyOrFieldResultAt(0, "C1", "firstDrop", "FirstProp"), + CA1071CSharpPropertyOrFieldResultAt(1, "C1", "secondDrop", "SecondProp")); } [Fact] @@ -748,8 +748,8 @@ public C1(int {|#0:dropFirst|}, object {|#1:dropSecond|}) this.SecondProp = dropSecond; } }", - CA1071CSharpPropertyResultAt(0, "C1", "dropFirst", "FirstProp"), - CA1071CSharpPropertyResultAt(1, "C1", "dropSecond", "SecondProp")); + CA1071CSharpPropertyOrFieldResultAt(0, "C1", "dropFirst", "FirstProp"), + CA1071CSharpPropertyOrFieldResultAt(1, "C1", "dropSecond", "SecondProp")); } [Fact] @@ -769,8 +769,8 @@ public C1(int {|#0:firstDrop|}, object {|#1:secondDrop|}) (this.FirstProp, this.SecondProp) = (firstDrop, secondDrop); } }", - CA1071CSharpPropertyResultAt(0, "C1", "firstDrop", "FirstProp"), - CA1071CSharpPropertyResultAt(1, "C1", "secondDrop", "SecondProp")); + CA1071CSharpPropertyOrFieldResultAt(0, "C1", "firstDrop", "FirstProp"), + CA1071CSharpPropertyOrFieldResultAt(1, "C1", "secondDrop", "SecondProp")); } [Fact] @@ -795,8 +795,8 @@ public C1(int {|#0:firstProp|}, object {|#1:secondProp|}) this._SecondProp = secondProp; } }", - CA1071CSharpPropertyResultAt(0, "C1", "firstProp", "_FirstProp"), - CA1071CSharpPropertyResultAt(1, "C1", "secondProp", "_SecondProp")); + CA1071CSharpPropertyOrFieldResultAt(0, "C1", "firstProp", "_FirstProp"), + CA1071CSharpPropertyOrFieldResultAt(1, "C1", "secondProp", "_SecondProp")); } #endregion @@ -841,8 +841,8 @@ public C1(int {|#0:firstProp|}, object {|#1:secondProp|}) this.SecondProp = secondProp; } }", - CA1071CSharpPublicPropertyResultAt(0, "C1", "firstProp", "FirstProp"), - CA1071CSharpPublicPropertyResultAt(1, "C1", "secondProp", "SecondProp")); + CA1071CSharpPropertyOrFieldResultAt(0, "C1", "firstProp", "FirstProp"), + CA1071CSharpPropertyOrFieldResultAt(1, "C1", "secondProp", "SecondProp")); } #endregion @@ -867,8 +867,8 @@ public C1(int {|#0:firstIField|}, object {|#1:secondIField|}) this.secondField = secondIField; } }", - CA1071CSharpFieldResultAt(0, "C1", "firstIField", "firstField"), - CA1071CSharpFieldResultAt(1, "C1", "secondIField", "secondField")); + CA1071CSharpPropertyOrFieldResultAt(0, "C1", "firstIField", "firstField"), + CA1071CSharpPropertyOrFieldResultAt(1, "C1", "secondIField", "secondField")); } [Fact] @@ -906,8 +906,8 @@ public C1(int {|#0:fieldFirst|}, object {|#1:fieldSecond|}) this.secondField = fieldSecond; } }", - CA1071CSharpFieldResultAt(0, "C1", "fieldFirst", "firstField"), - CA1071CSharpFieldResultAt(1, "C1", "fieldSecond", "secondField")); + CA1071CSharpPropertyOrFieldResultAt(0, "C1", "fieldFirst", "firstField"), + CA1071CSharpPropertyOrFieldResultAt(1, "C1", "fieldSecond", "secondField")); } [Fact] @@ -927,8 +927,8 @@ public C1(int {|#0:firstIField|}, object {|#1:secondIField|}) (this.firstField, this.secondField) = (firstIField, secondIField); } }", - CA1071CSharpFieldResultAt(0, "C1", "firstIField", "firstField"), - CA1071CSharpFieldResultAt(1, "C1", "secondIField", "secondField")); + CA1071CSharpPropertyOrFieldResultAt(0, "C1", "firstIField", "firstField"), + CA1071CSharpPropertyOrFieldResultAt(1, "C1", "secondIField", "secondField")); } [Fact] @@ -953,8 +953,8 @@ public C1(int {|#0:firstField|}, object {|#1:secondField|}) this._secondField = secondField; } }", - CA1071CSharpFieldResultAt(0, "C1", "firstField", "_firstField"), - CA1071CSharpFieldResultAt(1, "C1", "secondField", "_secondField")); + CA1071CSharpPropertyOrFieldResultAt(0, "C1", "firstField", "_firstField"), + CA1071CSharpPropertyOrFieldResultAt(1, "C1", "secondField", "_secondField")); } #endregion @@ -1039,8 +1039,8 @@ public C1(int {|#0:firstField|}, object {|#1:secondField|}) this.secondField = secondField; } }", - CA1071CSharpPublicFieldResultAt(0, "C1", "firstField", "firstField"), - CA1071CSharpPublicFieldResultAt(1, "C1", "secondField", "secondField")); + CA1071CSharpPropertyOrFieldResultAt(0, "C1", "firstField", "firstField"), + CA1071CSharpPropertyOrFieldResultAt(1, "C1", "secondField", "secondField")); } [Fact] @@ -1064,8 +1064,8 @@ public C1(int {|#0:firstField|}, object {|#1:secondField|}) this.secondField = secondField; } }", - CA1071CSharpPublicFieldResultAt(0, "C1", "firstField", "firstField"), - CA1071CSharpPublicFieldResultAt(1, "C1", "secondField", "secondField")); + CA1071CSharpPropertyOrFieldResultAt(0, "C1", "firstField", "firstField"), + CA1071CSharpPropertyOrFieldResultAt(1, "C1", "secondField", "secondField")); } #endregion @@ -1112,43 +1112,13 @@ private static async Task VerifyBasicAnalyzerAsync(string source, params Diagnos await basicTest.RunAsync(); } - private DiagnosticResult CA1071CSharpPropertyResultAt(int markupKey, params string[] arguments) - => VerifyCS.Diagnostic(ConstructorParametersShouldMatchPropertyAndFieldNamesAnalyzer.PropertyNameRule) + private DiagnosticResult CA1071CSharpPropertyOrFieldResultAt(int markupKey, params string[] arguments) + => VerifyCS.Diagnostic(ConstructorParametersShouldMatchPropertyAndFieldNamesAnalyzer.PropertyOrFieldNameRule) .WithLocation(markupKey) .WithArguments(arguments); - private DiagnosticResult CA1071BasicPropertyResultAt(int markupKey, params string[] arguments) - => VerifyVB.Diagnostic(ConstructorParametersShouldMatchPropertyAndFieldNamesAnalyzer.PropertyNameRule) - .WithLocation(markupKey) - .WithArguments(arguments); - - private DiagnosticResult CA1071CSharpPublicPropertyResultAt(int markupKey, params string[] arguments) - => VerifyCS.Diagnostic(ConstructorParametersShouldMatchPropertyAndFieldNamesAnalyzer.PropertyPublicRule) - .WithLocation(markupKey) - .WithArguments(arguments); - - private DiagnosticResult CA1071BasicPublicPropertyResultAt(int markupKey, params string[] arguments) - => VerifyVB.Diagnostic(ConstructorParametersShouldMatchPropertyAndFieldNamesAnalyzer.PropertyPublicRule) - .WithLocation(markupKey) - .WithArguments(arguments); - - private DiagnosticResult CA1071CSharpPublicFieldResultAt(int markupKey, params string[] arguments) - => VerifyCS.Diagnostic(ConstructorParametersShouldMatchPropertyAndFieldNamesAnalyzer.FieldPublicRule) - .WithLocation(markupKey) - .WithArguments(arguments); - - private DiagnosticResult CA1071BasicPublicFieldResultAt(int markupKey, params string[] arguments) - => VerifyVB.Diagnostic(ConstructorParametersShouldMatchPropertyAndFieldNamesAnalyzer.FieldPublicRule) - .WithLocation(markupKey) - .WithArguments(arguments); - - private DiagnosticResult CA1071CSharpFieldResultAt(int markupKey, params string[] arguments) - => VerifyCS.Diagnostic(ConstructorParametersShouldMatchPropertyAndFieldNamesAnalyzer.FieldRule) - .WithLocation(markupKey) - .WithArguments(arguments); - - private DiagnosticResult CA1071BasicFieldResultAt(int markupKey, params string[] arguments) - => VerifyVB.Diagnostic(ConstructorParametersShouldMatchPropertyAndFieldNamesAnalyzer.FieldRule) + private DiagnosticResult CA1071BasicPropertyOrFieldResultAt(int markupKey, params string[] arguments) + => VerifyVB.Diagnostic(ConstructorParametersShouldMatchPropertyAndFieldNamesAnalyzer.PropertyOrFieldNameRule) .WithLocation(markupKey) .WithArguments(arguments); From b1deb98270c033918c1d1c4642d5cf2406cbef6d Mon Sep 17 00:00:00 2001 From: psxvoid Date: Thu, 8 Jul 2021 10:26:47 +0300 Subject: [PATCH 56/64] CodeFix - make bound field public (no message, not aligned) --- ...sShouldMatchPropertyAndFieldNames.Fixer.cs | 61 +++++++++++++--- ...ametersShouldMatchPropertyAndFieldNames.cs | 6 +- ...ldMatchPropertyAndFieldNamesTests.Fixer.cs | 69 +++++++++++++++++++ 3 files changed, 125 insertions(+), 11 deletions(-) diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.Fixer.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.Fixer.cs index 050e2fb036..3602ea5418 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.Fixer.cs +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.Fixer.cs @@ -1,5 +1,6 @@ // Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System; using System.Collections.Immutable; using System.Composition; using System.Globalization; @@ -8,8 +9,10 @@ using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CodeActions; using Microsoft.CodeAnalysis.CodeFixes; +using Microsoft.CodeAnalysis.Editing; using Microsoft.CodeAnalysis.Rename; using Microsoft.CodeQuality.Analyzers.ApiDesignGuidelines; +using static Microsoft.NetCore.Analyzers.Runtime.ConstructorParametersShouldMatchPropertyAndFieldNamesAnalyzer; namespace Microsoft.NetCore.Analyzers.Runtime { @@ -20,7 +23,9 @@ namespace Microsoft.NetCore.Analyzers.Runtime [ExportCodeFixProvider(LanguageNames.CSharp, LanguageNames.VisualBasic), Shared] public sealed class ConstructorParametersShouldMatchPropertyAndFieldNamesFixer : CodeFixProvider { - public override ImmutableArray FixableDiagnosticIds => ImmutableArray.Create(ConstructorParametersShouldMatchPropertyAndFieldNamesAnalyzer.RuleId); + private static readonly Type DiagnosticReasonEnumType = typeof(ParameterDiagnosticReason); + + public override ImmutableArray FixableDiagnosticIds => ImmutableArray.Create(RuleId); public sealed override FixAllProvider GetFixAllProvider() { @@ -43,18 +48,47 @@ public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) continue; } - // This approach is very naive. Most likely we want to support NamingStyleOptions, available in Roslyn. - string newName = LowerFirstLetter(diagnostic.Properties[ConstructorParametersShouldMatchPropertyAndFieldNamesAnalyzer.ReferencedFieldOrPropertyNameKey]); + var diagnosticReason = (ParameterDiagnosticReason)Enum.Parse(DiagnosticReasonEnumType, diagnostic.Properties[DiagnosticReasonKey]); - context.RegisterCodeFix( - CodeAction.Create( - string.Format(CultureInfo.CurrentCulture, MicrosoftNetCoreAnalyzersResources.ConstructorParametersShouldMatchPropertyOrFieldNamesTitle, newName), - cancellationToken => GetUpdatedDocumentForParameterRenameAsync(context.Document, declaredSymbol, newName, cancellationToken), - nameof(ConstructorParametersShouldMatchPropertyAndFieldNamesFixer)), - diagnostic); + switch (diagnosticReason) + { + case ParameterDiagnosticReason.NameMismatch: + RegisterParameterRenameCodeFix(context, diagnostic, declaredSymbol); + break; + case ParameterDiagnosticReason.FieldInappropriateVisibility: + case ParameterDiagnosticReason.PropertyInappropriateVisibility: + SyntaxNode fieldOrProperty = syntaxRoot.FindNode(diagnostic.AdditionalLocations[0].SourceSpan); + RegisterMakeFieldOrPropertyPublicCodeFix(context, diagnostic, fieldOrProperty); + break; + default: + throw new InvalidOperationException(); + }; } } + private static void RegisterParameterRenameCodeFix(CodeFixContext context, Diagnostic diagnostic, ISymbol declaredSymbol) + { + // This approach is very naive. Most likely we want to support NamingStyleOptions, available in Roslyn. + string newName = LowerFirstLetter(diagnostic.Properties[ReferencedFieldOrPropertyNameKey]); + + context.RegisterCodeFix( + CodeAction.Create( + string.Format(CultureInfo.CurrentCulture, MicrosoftNetCoreAnalyzersResources.ConstructorParametersShouldMatchPropertyOrFieldNamesTitle, newName), + cancellationToken => GetUpdatedDocumentForParameterRenameAsync(context.Document, declaredSymbol, newName, cancellationToken), + nameof(ConstructorParametersShouldMatchPropertyAndFieldNamesFixer)), + diagnostic); + } + + private static void RegisterMakeFieldOrPropertyPublicCodeFix(CodeFixContext context, Diagnostic diagnostic, SyntaxNode fieldOrProperty) + { + context.RegisterCodeFix( + CodeAction.Create( + string.Format(CultureInfo.CurrentCulture, MicrosoftNetCoreAnalyzersResources.ConstructorParametersShouldMatchPropertyOrFieldNamesTitle, fieldOrProperty), + cancellationToken => GetUpdatedDocumentForMakingFieldOrPropertyPublicAsync(context.Document, fieldOrProperty, cancellationToken), + nameof(ConstructorParametersShouldMatchPropertyAndFieldNamesFixer)), + diagnostic); + } + private static string LowerFirstLetter(string targetName) { return $"{targetName[0].ToString().ToLower(CultureInfo.CurrentCulture)}{targetName[1..]}"; @@ -65,5 +99,14 @@ private static async Task GetUpdatedDocumentForParameterRenameAsync(Do Solution newSolution = await Renamer.RenameSymbolAsync(document.Project.Solution, parameter, newName, null, cancellationToken).ConfigureAwait(false); return newSolution.GetDocument(document.Id)!; } + + private static async Task GetUpdatedDocumentForMakingFieldOrPropertyPublicAsync(Document document, SyntaxNode fieldOrProperty, CancellationToken cancellationToken) + { + DocumentEditor editor = await DocumentEditor.CreateAsync(document, cancellationToken).ConfigureAwait(false); + + editor.SetAccessibility(fieldOrProperty, Accessibility.Public); + + return editor.GetChangedDocument(); + } } } \ No newline at end of file diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs index 717848a53a..eb93b3c9f4 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs @@ -186,8 +186,9 @@ private static void ReportFieldDiagnostic(OperationAnalysisContext context, Diag .SetItem(DiagnosticReasonKey, reason.ToString()); context.ReportDiagnostic( - param.CreateDiagnostic( + param.Locations[0].CreateDiagnostic( diagnosticDescriptor, + reason == ParameterDiagnosticReason.FieldInappropriateVisibility ? field.Locations : ImmutableArray.Empty, properties, param.ContainingType.ToDisplayString(SymbolDisplayFormats.ShortSymbolDisplayFormat), param.Name, @@ -201,8 +202,9 @@ private static void ReportPropertyDiagnostic(OperationAnalysisContext context, D .SetItem(DiagnosticReasonKey, reason.ToString()); context.ReportDiagnostic( - param.CreateDiagnostic( + param.Locations[0].CreateDiagnostic( diagnosticDescriptor, + reason == ParameterDiagnosticReason.PropertyInappropriateVisibility ? prop.Locations : ImmutableArray.Empty, properties, param.ContainingType.ToDisplayString(SymbolDisplayFormats.ShortSymbolDisplayFormat), param.Name, diff --git a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.Fixer.cs b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.Fixer.cs index af101c1596..ca50d4a4bd 100644 --- a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.Fixer.cs +++ b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.Fixer.cs @@ -286,6 +286,75 @@ End Sub End Class"); } + [Fact] + public async Task CA1071_ClassSingleFieldPrivate_CSharp() + { + await VerifyCSharpCodeFixAsync(@" + using System.Text.Json.Serialization; + + public class C1 + { + private int firstField { get; } + + public object secondField { get; } + + [JsonConstructor] + public C1(int [|firstField|], object secondField) + { + this.firstField = firstField; + this.secondField = secondField; + } + }", + @" + using System.Text.Json.Serialization; + + public class C1 + { + public int firstField { get; } + + public object secondField { get; } + + [JsonConstructor] + public C1(int firstField, object secondField) + { + this.firstField = firstField; + this.secondField = secondField; + } + }"); + } + + [Fact] + public async Task CA1071_ClassSingleFieldPrivate_Basic() + { + await VerifyBasicCodeFixAsync(@" + Imports System.Text.Json.Serialization + + Public Class C1 + Private firstField As Integer + Public secondField as Object + + + Public Sub New([|firstField|] as Integer, secondField as Object) + Me.firstField = firstField + Me.secondField = secondField + End Sub + End Class", + @" + Imports System.Text.Json.Serialization + + Public Class C1 + Public firstField As Integer + + Public secondField as Object + + + Public Sub New(firstField as Integer, secondField as Object) + Me.firstField = firstField + Me.secondField = secondField + End Sub + End Class"); + } + private static async Task VerifyCSharpCodeFixAsync(string source, string expected) { var csharpTest = new VerifyCS.Test From 2008bfe804c0983aad764e731604e97ee4ffae17 Mon Sep 17 00:00:00 2001 From: psxvoid Date: Thu, 8 Jul 2021 10:28:15 +0300 Subject: [PATCH 57/64] Analyzer - remove unreferenced parameter diagnostic reason --- .../ConstructorParametersShouldMatchPropertyAndFieldNames.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs index eb93b3c9f4..50425dfe92 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs @@ -76,7 +76,6 @@ internal enum ParameterDiagnosticReason NameMismatch, PropertyInappropriateVisibility, FieldInappropriateVisibility, - UnreferencedParameter, } private sealed class ParameterAnalyzer From 194c3a2dc49fbc074d6983021c893f1b6c357c7a Mon Sep 17 00:00:00 2001 From: psxvoid Date: Tue, 13 Jul 2021 06:06:33 +0300 Subject: [PATCH 58/64] Analyzer - fix broken tests due to additional diagnostic location --- ...rsShouldMatchPropertyAndFieldNamesTests.cs | 102 ++++++++++-------- 1 file changed, 57 insertions(+), 45 deletions(-) diff --git a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs index 75501621b3..5abac3f171 100644 --- a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs +++ b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.cs @@ -254,18 +254,18 @@ await VerifyCSharpAnalyzerAsync(@" public class C1 { - private int FirstProp { get; } - private object SecondProp { get; } + private int {|#1:FirstProp|} { get; } + private object {|#3:SecondProp|} { get; } [JsonConstructor] - public C1(int {|#0:firstProp|}, object {|#1:secondProp|}) + public C1(int {|#0:firstProp|}, object {|#2:secondProp|}) { this.FirstProp = firstProp; this.SecondProp = secondProp; } }", - CA1071CSharpPropertyOrFieldResultAt(0, "C1", "firstProp", "FirstProp"), - CA1071CSharpPropertyOrFieldResultAt(1, "C1", "secondProp", "SecondProp")); + CA1071CSharpPropertyOrFieldResultAt(0, 1, "C1", "firstProp", "FirstProp"), + CA1071CSharpPropertyOrFieldResultAt(2, 3, "C1", "secondProp", "SecondProp")); } [Fact] @@ -275,17 +275,17 @@ await VerifyBasicAnalyzerAsync(@" Imports System.Text.Json.Serialization Public Class C1 - Private Property FirstProp() As Integer - Private Property SecondProp() as Object + Private Property {|#1:FirstProp|}() As Integer + Private Property {|#3:SecondProp|}() as Object - Public Sub New({|#0:firstProp|} as Integer, {|#1:secondProp|} as Object) + Public Sub New({|#0:firstProp|} as Integer, {|#2:secondProp|} as Object) Me.FirstProp = firstProp Me.SecondProp = secondProp End Sub End Class", - CA1071BasicPropertyOrFieldResultAt(0, "C1", "firstProp", "FirstProp"), - CA1071BasicPropertyOrFieldResultAt(1, "C1", "secondProp", "SecondProp")); + CA1071BasicPropertyOrFieldResultAt(0, 1, "C1", "firstProp", "FirstProp"), + CA1071BasicPropertyOrFieldResultAt(2, 3, "C1", "secondProp", "SecondProp")); } #endregion @@ -605,18 +605,18 @@ await VerifyCSharpAnalyzerAsync(@" public class C1 { - private int firstField; - private object secondField; + private int {|#1:firstField|}; + private object {|#3:secondField|}; [JsonConstructor] - public C1(int {|#0:firstField|}, object {|#1:secondField|}) + public C1(int {|#0:firstField|}, object {|#2:secondField|}) { this.firstField = firstField; this.secondField = secondField; } }", - CA1071CSharpPropertyOrFieldResultAt(0, "C1", "firstField", "firstField"), - CA1071CSharpPropertyOrFieldResultAt(1, "C1", "secondField", "secondField")); + CA1071CSharpPropertyOrFieldResultAt(0, 1, "C1", "firstField", "firstField"), + CA1071CSharpPropertyOrFieldResultAt(2, 3, "C1", "secondField", "secondField")); } [Fact] @@ -626,17 +626,17 @@ await VerifyBasicAnalyzerAsync(@" Imports System.Text.Json.Serialization Public Class C1 - Private firstField as Integer - Private secondField as Object + Private {|#1:firstField|} as Integer + Private {|#3:secondField|} as Object - Public Sub New({|#0:firstField|} as Integer, {|#1:secondField|} as Object) + Public Sub New({|#0:firstField|} as Integer, {|#2:secondField|} as Object) Me.firstField = firstField Me.secondField = secondField End Sub End Class", - CA1071BasicPropertyOrFieldResultAt(0, "C1", "firstField", "firstField"), - CA1071BasicPropertyOrFieldResultAt(1, "C1", "secondField", "secondField")); + CA1071BasicPropertyOrFieldResultAt(0, 1, "C1", "firstField", "firstField"), + CA1071BasicPropertyOrFieldResultAt(2, 3, "C1", "secondField", "secondField")); } [Fact] @@ -648,20 +648,20 @@ await VerifyCSharpAnalyzerAsync(@" public class C1 { [JsonInclude] - private int firstField; + private int {|#1:firstField|}; [JsonInclude] - private object secondField; + private object {|#3:secondField|}; [JsonConstructor] - public C1(int {|#0:firstField|}, object {|#1:secondField|}) + public C1(int {|#0:firstField|}, object {|#2:secondField|}) { this.firstField = firstField; this.secondField = secondField; } }", - CA1071CSharpPropertyOrFieldResultAt(0, "C1", "firstField", "firstField"), - CA1071CSharpPropertyOrFieldResultAt(1, "C1", "secondField", "secondField")); + CA1071CSharpPropertyOrFieldResultAt(0, 1, "C1", "firstField", "firstField"), + CA1071CSharpPropertyOrFieldResultAt(2, 3, "C1", "secondField", "secondField")); } [Fact] @@ -672,19 +672,19 @@ Imports System.Text.Json.Serialization Public Class C1 - Private firstField as Integer + Private {|#1:firstField|} as Integer - Private secondField as Object + Private {|#3:secondField|} as Object - Public Sub New({|#0:firstField|} as Integer, {|#1:secondField|} as Object) + Public Sub New({|#0:firstField|} as Integer, {|#2:secondField|} as Object) Me.firstField = firstField Me.secondField = secondField End Sub End Class", - CA1071BasicPropertyOrFieldResultAt(0, "C1", "firstField", "firstField"), - CA1071BasicPropertyOrFieldResultAt(1, "C1", "secondField", "secondField")); + CA1071BasicPropertyOrFieldResultAt(0, 1, "C1", "firstField", "firstField"), + CA1071BasicPropertyOrFieldResultAt(2, 3, "C1", "secondField", "secondField")); } #endregion @@ -831,18 +831,18 @@ await VerifyCSharp9AnalyzerAsync(@" public record C1 { - private int FirstProp { get; } - private object SecondProp { get; } + private int {|#1:FirstProp|} { get; } + private object {|#3:SecondProp|} { get; } [JsonConstructor] - public C1(int {|#0:firstProp|}, object {|#1:secondProp|}) + public C1(int {|#0:firstProp|}, object {|#2:secondProp|}) { this.FirstProp = firstProp; this.SecondProp = secondProp; } }", - CA1071CSharpPropertyOrFieldResultAt(0, "C1", "firstProp", "FirstProp"), - CA1071CSharpPropertyOrFieldResultAt(1, "C1", "secondProp", "SecondProp")); + CA1071CSharpPropertyOrFieldResultAt(0, 1, "C1", "firstProp", "FirstProp"), + CA1071CSharpPropertyOrFieldResultAt(2, 3, "C1", "secondProp", "SecondProp")); } #endregion @@ -1029,18 +1029,18 @@ await VerifyCSharp9AnalyzerAsync(@" public record C1 { - private int firstField; - private object secondField; + private int {|#1:firstField|}; + private object {|#3:secondField|}; [JsonConstructor] - public C1(int {|#0:firstField|}, object {|#1:secondField|}) + public C1(int {|#0:firstField|}, object {|#2:secondField|}) { this.firstField = firstField; this.secondField = secondField; } }", - CA1071CSharpPropertyOrFieldResultAt(0, "C1", "firstField", "firstField"), - CA1071CSharpPropertyOrFieldResultAt(1, "C1", "secondField", "secondField")); + CA1071CSharpPropertyOrFieldResultAt(0, 1, "C1", "firstField", "firstField"), + CA1071CSharpPropertyOrFieldResultAt(2, 3, "C1", "secondField", "secondField")); } [Fact] @@ -1052,20 +1052,20 @@ await VerifyCSharp9AnalyzerAsync(@" public record C1 { [JsonInclude] - private int firstField; + private int {|#1:firstField|}; [JsonInclude] - private object secondField; + private object {|#3:secondField|}; [JsonConstructor] - public C1(int {|#0:firstField|}, object {|#1:secondField|}) + public C1(int {|#0:firstField|}, object {|#2:secondField|}) { this.firstField = firstField; this.secondField = secondField; } }", - CA1071CSharpPropertyOrFieldResultAt(0, "C1", "firstField", "firstField"), - CA1071CSharpPropertyOrFieldResultAt(1, "C1", "secondField", "secondField")); + CA1071CSharpPropertyOrFieldResultAt(0, 1, "C1", "firstField", "firstField"), + CA1071CSharpPropertyOrFieldResultAt(2, 3, "C1", "secondField", "secondField")); } #endregion @@ -1117,11 +1117,23 @@ private DiagnosticResult CA1071CSharpPropertyOrFieldResultAt(int markupKey, para .WithLocation(markupKey) .WithArguments(arguments); + private DiagnosticResult CA1071CSharpPropertyOrFieldResultAt(int markupKeyParam, int markupKeyFieldOrProp, params string[] arguments) + => VerifyCS.Diagnostic(ConstructorParametersShouldMatchPropertyAndFieldNamesAnalyzer.PropertyOrFieldNameRule) + .WithLocation(markupKeyParam) + .WithLocation(markupKeyFieldOrProp) + .WithArguments(arguments); + private DiagnosticResult CA1071BasicPropertyOrFieldResultAt(int markupKey, params string[] arguments) => VerifyVB.Diagnostic(ConstructorParametersShouldMatchPropertyAndFieldNamesAnalyzer.PropertyOrFieldNameRule) .WithLocation(markupKey) .WithArguments(arguments); + private DiagnosticResult CA1071BasicPropertyOrFieldResultAt(int markupKey, int markupKeyFieldOrProp, params string[] arguments) + => VerifyVB.Diagnostic(ConstructorParametersShouldMatchPropertyAndFieldNamesAnalyzer.PropertyOrFieldNameRule) + .WithLocation(markupKey) + .WithLocation(markupKeyFieldOrProp) + .WithArguments(arguments); + #endregion } } \ No newline at end of file From a48762138bff67f95755e51360a4b1512506e9e7 Mon Sep 17 00:00:00 2001 From: psxvoid Date: Tue, 13 Jul 2021 06:33:13 +0300 Subject: [PATCH 59/64] CodeFix - add tests for single private property --- ...ldMatchPropertyAndFieldNamesTests.Fixer.cs | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.Fixer.cs b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.Fixer.cs index ca50d4a4bd..31f585b5d8 100644 --- a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.Fixer.cs +++ b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.Fixer.cs @@ -355,6 +355,74 @@ End Sub End Class"); } + [Fact] + public async Task CA1071_ClassSinglePropertyPrivate_CSharp() + { + await VerifyCSharpCodeFixAsync(@" + using System.Text.Json.Serialization; + + public class C1 + { + private int FirstProp { get; } + + public object SecondProp { get; } + + [JsonConstructor] + public C1(int [|firstProp|], object secondProp) + { + this.FirstProp = firstProp; + this.SecondProp = secondProp; + } + }", + @" + using System.Text.Json.Serialization; + + public class C1 + { + public int FirstProp { get; } + + public object SecondProp { get; } + + [JsonConstructor] + public C1(int firstProp, object secondProp) + { + this.FirstProp = firstProp; + this.SecondProp = secondProp; + } + }"); + } + + [Fact] + public async Task CA1071_ClassSinglePropertyPrivate_Basic() + { + await VerifyBasicCodeFixAsync(@" + Imports System.Text.Json.Serialization + + Public Class C1 + Private Property FirstProp() As Integer + Property SecondProp() as Object + + + Public Sub New([|firstProp|] as Integer, secondProp as Object) + Me.FirstProp = firstProp + Me.SecondProp = secondProp + End Sub + End Class", + @" + Imports System.Text.Json.Serialization + + Public Class C1 + Public Property FirstProp() As Integer + Property SecondProp() as Object + + + Public Sub New(firstProp as Integer, secondProp as Object) + Me.FirstProp = firstProp + Me.SecondProp = secondProp + End Sub + End Class"); + } + private static async Task VerifyCSharpCodeFixAsync(string source, string expected) { var csharpTest = new VerifyCS.Test From f38390df06e51a3a821ae5535e82ae280684ea23 Mon Sep 17 00:00:00 2001 From: psxvoid Date: Tue, 13 Jul 2021 06:45:04 +0300 Subject: [PATCH 60/64] CodeFix - add tests for multiple private fields and props --- ...ldMatchPropertyAndFieldNamesTests.Fixer.cs | 138 ++++++++++++++++++ 1 file changed, 138 insertions(+) diff --git a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.Fixer.cs b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.Fixer.cs index 31f585b5d8..48b2aadf8d 100644 --- a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.Fixer.cs +++ b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNamesTests.Fixer.cs @@ -423,6 +423,144 @@ End Sub End Class"); } + [Fact] + public async Task CA1071_ClassMultipleFieldsPrivate_CSharp() + { + await VerifyCSharpCodeFixAsync(@" + using System.Text.Json.Serialization; + + public class C1 + { + private int firstField { get; } + + private object secondField { get; } + + [JsonConstructor] + public C1(int [|firstField|], object [|secondField|]) + { + this.firstField = firstField; + this.secondField = secondField; + } + }", + @" + using System.Text.Json.Serialization; + + public class C1 + { + public int firstField { get; } + + public object secondField { get; } + + [JsonConstructor] + public C1(int firstField, object secondField) + { + this.firstField = firstField; + this.secondField = secondField; + } + }"); + } + + [Fact] + public async Task CA1071_ClassMultipleFieldsPrivate_Basic() + { + await VerifyBasicCodeFixAsync(@" + Imports System.Text.Json.Serialization + + Public Class C1 + Private firstField As Integer + Private secondField as Object + + + Public Sub New([|firstField|] as Integer, [|secondField|] as Object) + Me.firstField = firstField + Me.secondField = secondField + End Sub + End Class", + @" + Imports System.Text.Json.Serialization + + Public Class C1 + Public firstField As Integer + + Public secondField as Object + + + + Public Sub New(firstField as Integer, secondField as Object) + Me.firstField = firstField + Me.secondField = secondField + End Sub + End Class"); + } + + [Fact] + public async Task CA1071_ClassMultiplePropertiesPrivate_CSharp() + { + await VerifyCSharpCodeFixAsync(@" + using System.Text.Json.Serialization; + + public class C1 + { + private int FirstProp { get; } + + private object SecondProp { get; } + + [JsonConstructor] + public C1(int [|firstProp|], object [|secondProp|]) + { + this.FirstProp = firstProp; + this.SecondProp = secondProp; + } + }", + @" + using System.Text.Json.Serialization; + + public class C1 + { + public int FirstProp { get; } + + public object SecondProp { get; } + + [JsonConstructor] + public C1(int firstProp, object secondProp) + { + this.FirstProp = firstProp; + this.SecondProp = secondProp; + } + }"); + } + + [Fact] + public async Task CA1071_ClassMultiplePropertiesPrivate_Basic() + { + await VerifyBasicCodeFixAsync(@" + Imports System.Text.Json.Serialization + + Public Class C1 + Private Property FirstProp() As Integer + Private Property SecondProp() as Object + + + Public Sub New([|firstProp|] as Integer, [|secondProp|] as Object) + Me.FirstProp = firstProp + Me.SecondProp = secondProp + End Sub + End Class", + @" + Imports System.Text.Json.Serialization + + Public Class C1 + Public Property FirstProp() As Integer + Public Property SecondProp() as Object + + + Public Sub New(firstProp as Integer, secondProp as Object) + Me.FirstProp = firstProp + Me.SecondProp = secondProp + End Sub + End Class"); + } + private static async Task VerifyCSharpCodeFixAsync(string source, string expected) { var csharpTest = new VerifyCS.Test From 051d0670d8a3331d5d2c1ea2bf97860441b64235 Mon Sep 17 00:00:00 2001 From: psxvoid Date: Tue, 27 Jul 2021 06:22:56 +0300 Subject: [PATCH 61/64] Analyzer - use "Add" instead of "SetItem" --- ...nstructorParametersShouldMatchPropertyAndFieldNames.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs index 50425dfe92..8a04f3a2bd 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs @@ -181,8 +181,8 @@ private bool IsJsonConstructor([NotNullWhen(returnValue: true)] IMethodSymbol? m private static void ReportFieldDiagnostic(OperationAnalysisContext context, DiagnosticDescriptor diagnosticDescriptor, ParameterDiagnosticReason reason, IParameterSymbol param, IFieldSymbol field) { var properties = ImmutableDictionary.Empty - .SetItem(ReferencedFieldOrPropertyNameKey, field.Name) - .SetItem(DiagnosticReasonKey, reason.ToString()); + .Add(ReferencedFieldOrPropertyNameKey, field.Name) + .Add(DiagnosticReasonKey, reason.ToString()); context.ReportDiagnostic( param.Locations[0].CreateDiagnostic( @@ -197,8 +197,8 @@ private static void ReportFieldDiagnostic(OperationAnalysisContext context, Diag private static void ReportPropertyDiagnostic(OperationAnalysisContext context, DiagnosticDescriptor diagnosticDescriptor, ParameterDiagnosticReason reason, IParameterSymbol param, IPropertySymbol prop) { var properties = ImmutableDictionary.Empty - .SetItem(ReferencedFieldOrPropertyNameKey, prop.Name) - .SetItem(DiagnosticReasonKey, reason.ToString()); + .Add(ReferencedFieldOrPropertyNameKey, prop.Name) + .Add(DiagnosticReasonKey, reason.ToString()); context.ReportDiagnostic( param.Locations[0].CreateDiagnostic( From f86bf43f20bc06083131f161042fa5f2e36aa810 Mon Sep 17 00:00:00 2001 From: psxvoid Date: Tue, 27 Jul 2021 06:27:33 +0300 Subject: [PATCH 62/64] Analyzer - init jsonConstructorAttribute symbol using out var --- .../ConstructorParametersShouldMatchPropertyAndFieldNames.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs index 8a04f3a2bd..e361f1a31a 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs @@ -46,8 +46,7 @@ public override void Initialize(AnalysisContext context) context.RegisterCompilationStartAction((context) => { - INamedTypeSymbol? jsonConstructorAttributeNamedSymbol = context.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemTextJsonSerializationJsonConstructorAttribute); - if (jsonConstructorAttributeNamedSymbol == null) + if (!context.Compilation.TryGetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemTextJsonSerializationJsonConstructorAttribute, out var jsonConstructorAttributeNamedSymbol)) { return; } From 35b23465065aac1eb37f11cd56cc72128b1b4a93 Mon Sep 17 00:00:00 2001 From: psxvoid Date: Tue, 27 Jul 2021 06:32:13 +0300 Subject: [PATCH 63/64] Analyzer - Use ContainingType.Name instead of ToDisplayString --- .../ConstructorParametersShouldMatchPropertyAndFieldNames.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs index e361f1a31a..041e552ea2 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs @@ -188,7 +188,7 @@ private static void ReportFieldDiagnostic(OperationAnalysisContext context, Diag diagnosticDescriptor, reason == ParameterDiagnosticReason.FieldInappropriateVisibility ? field.Locations : ImmutableArray.Empty, properties, - param.ContainingType.ToDisplayString(SymbolDisplayFormats.ShortSymbolDisplayFormat), + param.ContainingType.Name, param.Name, field.Name)); } @@ -204,7 +204,7 @@ private static void ReportPropertyDiagnostic(OperationAnalysisContext context, D diagnosticDescriptor, reason == ParameterDiagnosticReason.PropertyInappropriateVisibility ? prop.Locations : ImmutableArray.Empty, properties, - param.ContainingType.ToDisplayString(SymbolDisplayFormats.ShortSymbolDisplayFormat), + param.ContainingType.Name, param.Name, prop.Name)); } From aafe0ded3bdad4d427a7ac26ba8df8bf0257f9f2 Mon Sep 17 00:00:00 2001 From: psxvoid Date: Tue, 27 Jul 2021 06:41:22 +0300 Subject: [PATCH 64/64] Analyzer - Remove parentheses from lambda param while passing context --- .../ConstructorParametersShouldMatchPropertyAndFieldNames.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs index 041e552ea2..9e7155e4f1 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/ConstructorParametersShouldMatchPropertyAndFieldNames.cs @@ -44,7 +44,7 @@ public override void Initialize(AnalysisContext context) context.EnableConcurrentExecution(); context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None); - context.RegisterCompilationStartAction((context) => + context.RegisterCompilationStartAction(context => { if (!context.Compilation.TryGetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemTextJsonSerializationJsonConstructorAttribute, out var jsonConstructorAttributeNamedSymbol)) { @@ -53,7 +53,7 @@ public override void Initialize(AnalysisContext context) var paramAnalyzer = new ParameterAnalyzer(jsonConstructorAttributeNamedSymbol); - context.RegisterSymbolStartAction((context) => + context.RegisterSymbolStartAction(context => { var constructors = ((INamedTypeSymbol)context.Symbol).InstanceConstructors;